From a8ff692f812689d954f72b5857a169b55bcefd82 Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Sun, 18 Feb 2024 21:17:06 +0000 Subject: [PATCH 001/200] fix fish labeler crafting (#822) * fix fish labeler crafting * hand labeler tag * remove dupe tag --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- Resources/Prototypes/Entities/Objects/Fun/toys.yml | 3 +++ .../Prototypes/Entities/Objects/Specific/rehydrateable.yml | 2 ++ Resources/Prototypes/Entities/Objects/Tools/hand_labeler.yml | 3 +++ Resources/Prototypes/Nyanotrasen/tags.yml | 3 +++ 4 files changed, 11 insertions(+) diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml index 75259bfaf76..5d655eb2b68 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml @@ -439,6 +439,9 @@ path: /Audio/Effects/bite.ogg angle: 0 animation: WeaponArcBite # Rrrr! + - type: Tag + tags: + - PlushieCarp # DeltaV - fish labeler craft - type: entity parent: BasePlushie diff --git a/Resources/Prototypes/Entities/Objects/Specific/rehydrateable.yml b/Resources/Prototypes/Entities/Objects/Specific/rehydrateable.yml index 2adce1e66b3..b51517786f0 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/rehydrateable.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/rehydrateable.yml @@ -204,6 +204,8 @@ handle: false sound: path: /Audio/Effects/bite.ogg + - type: Tag + tags: [] # DeltaV - remove PlushieCarp tag to prevent wasting - type: entity parent: BaseItem diff --git a/Resources/Prototypes/Entities/Objects/Tools/hand_labeler.yml b/Resources/Prototypes/Entities/Objects/Tools/hand_labeler.yml index 1d9bb47e0e6..7e883953363 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/hand_labeler.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/hand_labeler.yml @@ -25,3 +25,6 @@ - Item tags: - Structure + - type: Tag + tags: + - HandLabeler # DeltaV - fish labeler diff --git a/Resources/Prototypes/Nyanotrasen/tags.yml b/Resources/Prototypes/Nyanotrasen/tags.yml index 54f39b7b6ef..ff3b901b1cc 100644 --- a/Resources/Prototypes/Nyanotrasen/tags.yml +++ b/Resources/Prototypes/Nyanotrasen/tags.yml @@ -12,3 +12,6 @@ - type: Tag id: NormalityCrystal + +- type: Tag + id: PlushieCarp From db3ed7c35c7d0e24e6fe394b96e1e9406165b185 Mon Sep 17 00:00:00 2001 From: Tunguso4ka <71643624+Tunguso4ka@users.noreply.github.com> Date: Fri, 9 Feb 2024 01:05:43 +0200 Subject: [PATCH 002/200] Paper is now bad food (#25065) (cherry picked from commit 6c20938c46e4e2a21729aeb395b0fbd430552c48) --- Resources/Prototypes/Entities/Objects/Misc/paper.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Entities/Objects/Misc/paper.yml index d4d214f0e2d..282037b384b 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/paper.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/paper.yml @@ -61,6 +61,7 @@ solution: food delay: 7 forceFeedDelay: 7 + - type: BadFood - type: SolutionContainerManager solutions: food: From df7894cde6b062238bda6997d228d586d8a59d29 Mon Sep 17 00:00:00 2001 From: Ilya246 <57039557+Ilya246@users.noreply.github.com> Date: Fri, 9 Feb 2024 03:07:42 +0400 Subject: [PATCH 003/200] allow building atmos devices on lattice or thindow tiles (#25057) do (cherry picked from commit 5380f64cca7ffcf1f54e75e876e38a7cfb70b18d) --- .../Recipes/Construction/utilities.yml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/Resources/Prototypes/Recipes/Construction/utilities.yml b/Resources/Prototypes/Recipes/Construction/utilities.yml index bdb0c814a4a..1647e98bcea 100644 --- a/Resources/Prototypes/Recipes/Construction/utilities.yml +++ b/Resources/Prototypes/Recipes/Construction/utilities.yml @@ -475,7 +475,6 @@ - sprite: Structures/Piping/Atmospherics/vent.rsi state: vent_off conditions: - - !type:TileNotBlocked {} - !type:NoUnstackableInTile - type: construction @@ -497,7 +496,6 @@ - sprite: Structures/Piping/Atmospherics/vent.rsi state: vent_off conditions: - - !type:TileNotBlocked {} - !type:NoUnstackableInTile - type: construction @@ -519,7 +517,6 @@ - sprite: Structures/Piping/Atmospherics/scrubber.rsi state: scrub_off conditions: - - !type:TileNotBlocked {} - !type:NoUnstackableInTile - type: construction @@ -541,7 +538,6 @@ - sprite: Structures/Piping/Atmospherics/outletinjector.rsi state: injector conditions: - - !type:TileNotBlocked {} - !type:NoUnstackableInTile # ATMOS BINARY @@ -564,7 +560,6 @@ - sprite: Structures/Piping/Atmospherics/pump.rsi state: pumpPressure conditions: - - !type:TileNotBlocked {} - !type:NoUnstackableInTile - type: construction @@ -586,7 +581,6 @@ - sprite: Structures/Piping/Atmospherics/pump.rsi state: pumpVolume conditions: - - !type:TileNotBlocked {} - !type:NoUnstackableInTile - type: construction @@ -608,7 +602,6 @@ - sprite: Structures/Piping/Atmospherics/pump.rsi state: pumpPassiveGate conditions: - - !type:TileNotBlocked {} - !type:NoUnstackableInTile - type: construction @@ -630,7 +623,6 @@ - sprite: Structures/Piping/Atmospherics/pump.rsi state: pumpManualValve conditions: - - !type:TileNotBlocked {} - !type:NoUnstackableInTile - type: construction @@ -652,7 +644,6 @@ - sprite: Structures/Piping/Atmospherics/pump.rsi state: pumpSignalValve conditions: - - !type:TileNotBlocked {} - !type:NoUnstackableInTile - type: construction @@ -674,7 +665,6 @@ - sprite: Structures/Piping/Atmospherics/gascanisterport.rsi state: gasCanisterPort conditions: - - !type:TileNotBlocked {} - !type:NoUnstackableInTile - type: construction @@ -695,8 +685,6 @@ state: pipeStraight - sprite: Structures/Piping/Atmospherics/vent.rsi state: vent_off - conditions: - - !type:TileNotBlocked {} - type: construction id: HeatExchanger @@ -711,8 +699,6 @@ icon: sprite: Structures/Piping/Atmospherics/heatexchanger.rsi state: heStraight - conditions: - - !type:TileNotBlocked {} # ATMOS TRINARY - type: construction @@ -730,7 +716,6 @@ state: gasFilter mirror: GasFilterFlipped conditions: - - !type:TileNotBlocked {} - !type:NoUnstackableInTile - type: construction @@ -749,7 +734,6 @@ state: gasFilterF mirror: GasFilter conditions: - - !type:TileNotBlocked {} - !type:NoUnstackableInTile - type: construction @@ -767,7 +751,6 @@ state: gasMixer mirror: GasMixerFlipped conditions: - - !type:TileNotBlocked {} - !type:NoUnstackableInTile - type: construction @@ -786,7 +769,6 @@ state: gasMixerF mirror: GasMixer conditions: - - !type:TileNotBlocked - !type:NoUnstackableInTile - type: construction @@ -803,7 +785,6 @@ sprite: Structures/Piping/Atmospherics/pneumaticvalve.rsi state: off conditions: - - !type:TileNotBlocked - !type:NoUnstackableInTile # INTERCOM From 47855327c37f3a56df431b7137def52fdf2aac6b Mon Sep 17 00:00:00 2001 From: Krunklehorn <42424291+Krunklehorn@users.noreply.github.com> Date: Thu, 8 Feb 2024 18:08:06 -0500 Subject: [PATCH 004/200] Remove tail wag emote text (#25054) Removed emote text (cherry picked from commit af21657cc37ce14675df38cb7fcf44dcc39bcb3c) --- Content.Server/Wagging/WaggingSystem.cs | 5 ----- Resources/Locale/en-US/actions/actions/wagging.ftl | 3 --- 2 files changed, 8 deletions(-) diff --git a/Content.Server/Wagging/WaggingSystem.cs b/Content.Server/Wagging/WaggingSystem.cs index 5d4163fa65f..7e9ffbbc8f4 100644 --- a/Content.Server/Wagging/WaggingSystem.cs +++ b/Content.Server/Wagging/WaggingSystem.cs @@ -1,5 +1,4 @@ using Content.Server.Actions; -using Content.Server.Chat.Systems; using Content.Server.Humanoid; using Content.Shared.Humanoid; using Content.Shared.Humanoid.Markings; @@ -16,7 +15,6 @@ namespace Content.Server.Wagging; public sealed class WaggingSystem : EntitySystem { [Dependency] private readonly ActionsSystem _actions = default!; - [Dependency] private readonly ChatSystem _chat = default!; [Dependency] private readonly HumanoidAppearanceSystem _humanoidAppearance = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; @@ -102,9 +100,6 @@ public bool TryToggleWagging(EntityUid uid, WaggingComponent? wagging = null, Hu humanoid: humanoid); } - var emoteText = Loc.GetString(wagging.Wagging ? "wagging-emote-start" : "wagging-emote-stop", ("ent", uid)); - _chat.TrySendInGameICMessage(uid, emoteText, InGameICChatType.Emote, ChatTransmitRange.Normal); // Ok while emotes dont have radial menu - return true; } } diff --git a/Resources/Locale/en-US/actions/actions/wagging.ftl b/Resources/Locale/en-US/actions/actions/wagging.ftl index 2fbcb676f4e..da0cfa0f27b 100644 --- a/Resources/Locale/en-US/actions/actions/wagging.ftl +++ b/Resources/Locale/en-US/actions/actions/wagging.ftl @@ -1,5 +1,2 @@ action-name-toggle-wagging = Wagging Tail action-description-toggle-wagging = Start or stop wagging tail. - -wagging-emote-start = starts wagging {POSS-ADJ($ent)} tail. -wagging-emote-stop = stops wagging {POSS-ADJ($ent)} tail. \ No newline at end of file From 6b225dd84c61c5d0fc7c2e41fb921eb17cb02c6a Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 8 Feb 2024 23:08:47 +0000 Subject: [PATCH 005/200] Automatic changelog update (cherry picked from commit 3f0572b4e6a3c0bbc21e12c2a9c9a1ac2f7e32d8) --- 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 ebc431b9428..65918e8bd8c 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,5 @@ Order: 1 Entries: -- author: brainfood1183 - changes: - - message: Crystals now drop crystal shards, you can use them to craft colored light - tubes. - type: Add - id: 5400 - time: '2023-12-16T22:20:14.0000000+00:00' - url: null - author: Ilya246 changes: - message: Pens now embed and deal damage on throw like spears. @@ -3885,3 +3877,10 @@ Order: 1 id: 5899 time: '2024-02-07T08:49:06.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25016 +- author: Ilya246 + changes: + - message: Atmos devices can now be built behind directional windows and on lattice. + type: Tweak + id: 5900 + time: '2024-02-08T23:07:42.0000000+00:00' + url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25057 From 8a14ecf2156f46571c579f883c94abc816ee7d06 Mon Sep 17 00:00:00 2001 From: Ubaser <134914314+UbaserB@users.noreply.github.com> Date: Fri, 9 Feb 2024 10:09:00 +1100 Subject: [PATCH 006/200] Small t-ray scanner resprite (#25047) add (cherry picked from commit 601da0c3a33279beff818f82913ed2583e48c642) --- .../Textures/Objects/Tools/t-ray.rsi/meta.json | 2 +- .../Objects/Tools/t-ray.rsi/tray-off.png | Bin 363 -> 1394 bytes .../Objects/Tools/t-ray.rsi/tray-on.png | Bin 508 -> 1629 bytes 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Textures/Objects/Tools/t-ray.rsi/meta.json b/Resources/Textures/Objects/Tools/t-ray.rsi/meta.json index c1929a1efe3..e79ca362989 100644 --- a/Resources/Textures/Objects/Tools/t-ray.rsi/meta.json +++ b/Resources/Textures/Objects/Tools/t-ray.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "/tg/station, 'icons/obj/device.dmi', commit 2b8b045d", + "copyright": "/tg/station, 'icons/obj/device.dmi' commit 2b8b045d, redrawn by Ubaser.", "size": { "x": 32, "y": 32 }, "states": [ { "name": "tray-on" , "delays": [[0.1, 1.0]]}, diff --git a/Resources/Textures/Objects/Tools/t-ray.rsi/tray-off.png b/Resources/Textures/Objects/Tools/t-ray.rsi/tray-off.png index d4a6da02cd4adf831b4f41d8f9760be4c9defb7b..9ca7ff2ca4ccfe9228d05c99db4b2d802232df36 100644 GIT binary patch literal 1394 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}e5nzhX}-P; zT0k}j5QD&_;K@Lev%n*=n1MlK76>znTPbd0U|`P642dX-@b$4u&d=3LOvz75)vL%Y z0PC`;umUo3Q%e#RDspr3imfVamB1>jfNYSkzLEl1NlCV?QiN}Sf^&XRs)CuGfu4bq z9hZWFf=y9MnpKdC8&o@xXRDM^Qc_^0uU}qXu2*iXmtT~wZ)j<0sc&GUZ)BtkRH0j3 znOBlnp_^B%3^4>|j!SBBa#3bMNoIbY0?6FNr2NtnTO}osMQ{LdXG${Mo`TY%9I!1Z z$@-}|sky0nCB^!NdWQPg^p#|$AzYYO3=Ixo!03ZyfZ7bOYV#~8Nj3q7lxqdhJy8Dv z9hwZbx40xlA4!3}k%57Qu7Q!Rk)=M|e?aHkq$FFFWR~Qlf&&ijA8-gd=9Hj{g4Bb8 zASV+PvQ{~XdFi%F6}l;@X^EvdB}#UlzV7ixrWWQl`Vdv9x*?*dhT7<3vEK&dYpckh z)Z+Y{Qc$?t8JU^bfWrbs6cGau9T8Y{Ad8~w2*}7U$p@yWqReE^ypq(Sf+Aq*g4hVP z54Q?*vk;bt=4F=H89@y|6Gqa76gyUqMJ46=McETsxW;J_TmlW=|K#kO_h~9iQ@oC@BoJs$E-zxoU&e+7mkd>qq{@A`-Ld5&x&m*(Ew=s8YZJ1ys z=EPNS@_u3TQG;IH7yW&W%%@EjC}p>Y^6;n^tURXc7q*D;=a}+ieu7Zh9|`np8EMs(CK)`H9^^fk$E0R`!wdHcGS7#_Hyr c;L^sx@O?*m$fM`RKA`f>)78&qol`;+0K{(8F#rGn delta 337 zcmV-X0j~b?3hM%pBYy!hNklQ@e=&e?H&D5NF|4 zXE=Rm1xaR+>;RbMg@uI}a{c}NWIKX|ScNdlot&Jo%J=v8lYeSA0|NsC0~1-gs0fCJ z17c%iiAvqXsw3F}v;;(@S~oYh|F2)aCa6wSRFq-Yu3aSM1d_6$uAw7?oRKMp+@o`+ z87`mSPgXW0DGKC_Oc}OJOkpq*d;%An^xG1vqiEs)1_lO(x`qaZriKQ%<=m0143mCa z($4|s-perfq{!6(<&uTp0;+yu%QG j|3irE%4igff>8hfm7H+)^VKBa00000NkvXXu0mjfwbY)P diff --git a/Resources/Textures/Objects/Tools/t-ray.rsi/tray-on.png b/Resources/Textures/Objects/Tools/t-ray.rsi/tray-on.png index 5f9c84afd85ac57ed3c2edb428ee8b138758c10a..5c4ba77cfed8b7656be34c6f82efca1178dfa015 100644 GIT binary patch literal 1629 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBH!3HE3&8=$zQjEnx?oJHr&dIz4a`;jsJkxxA z8MJ_G4j=}BOTm+YBxiv~WHAGS#w-wK6t_~`#K6Fuml+aK65;D(m7Jfemza{Dl&V*e zTL9K&Q(*;U=BAb;Dpcg=MLA$w zQj+ykb5e6t^Gb^K4fPE5vFR(xOhdRZuNWE}z<|*Q$pEz(VAbYXP?Br{3@O(NpnIVH z13EMrY;SQ%iawG8eIo+{3ta;vT_a0oQqvMkb4rx#Jbm5cjZ7`fZS*0kP<2B@Q4O`x$6~(?$k$ep zL8-<0Ii;X*w=*&`u>pq#iYOumAUYzj>OdAn*AbABUy=_@QAL@_o_QsyMFmB`)CI8- zY9DSD=w=}-56#Ogu`_}ifF_Kj3n_N29E(cI^NX@Wz%hXcMx08Z#z2A;DTP9kKREb- z>EDjaMjxJ+?6`I`Equzrz?A3d;uw;_nw%iPx>(UbiU~#}IX6soXar=NdI`pHK*Zu+Z|J>$IEPx-X$N9&*W zD6}`|xQVx~Txiyt#~=H4f9UaV|L42%NF26dD`M#3oy@$lxifGw+sxnBjj9g3IsQug z3B!R^4ab_M+&b^l`MY7-|7(T?2@9?WKH0^XqQ63B!I8R2rx_+BJBt1LStES-uFjrU zDWWbCY=Qy{mi<*>XE^ie&><(D^l#t48(**zNceVsW(?=H|2O_w@`UwiCX{*QS)cs2 zIpIfB1B1ph$9d&NO(BghPB}I@cr$F0e^M#wn!3T1%Rl8|&IAh$0S`uzsf$^=L#{Jtk~g|&X*-58fN}H`1ZKUZPy^Kj^19? zRdwoNvMblM&g4GzIc-~{zBOy{>bhGf(@Qtbn__n;d1cnkSvhVQXs(VRL+`w}4}U zFMGq?e|`(j7JF=(yN2OM&40aFsy#eT4(IE4@p}qpObU7K^oCtDz9ULfT!U z@80{40|WwrKp+sXAjt|%q_3$YD|G4n_p4jfNMii=Qus%E$A6}5y!zwuh4oKXdUE;k zeiE+w-*O&{eA*tI95)Ys56fUlR_OOf%M$l)?4Y5SnC5Z<55Mg{8S+dfW4V^k=eZZb z@IRI=0RT0=Q7k{49)(VKn(s<SYjz(eQKNsJp9ZbL;kgQOMLLP`EMUXZu$iRfk3cm Z`~W3O9|s|xPP_mB002ovPDHLkV1izg Date: Thu, 8 Feb 2024 23:10:05 +0000 Subject: [PATCH 007/200] Automatic changelog update (cherry picked from commit e57cfea9f60a969a8f6de7a0f9a1d796a6d78af1) --- 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 65918e8bd8c..1af050767d6 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Ilya246 - changes: - - message: Pens now embed and deal damage on throw like spears. - type: Add - id: 5401 - time: '2023-12-16T22:23:08.0000000+00:00' - url: null - author: Emisse changes: - message: Svalinn Laser Pistol and accompanying T3 tech. @@ -3884,3 +3877,10 @@ Order: 1 id: 5900 time: '2024-02-08T23:07:42.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25057 +- author: Ubaser + changes: + - message: T-Ray scanner sprite is tweaked. + type: Tweak + id: 5901 + time: '2024-02-08T23:09:00.0000000+00:00' + url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25047 From 5c93eca7d88ef5a567a3c360a7cd6d6ce075ec73 Mon Sep 17 00:00:00 2001 From: nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com> Date: Fri, 9 Feb 2024 01:12:04 +0200 Subject: [PATCH 008/200] Fix brig timer labels to displaying correctly. (#25033) * Fix brig timer labels to displaying correctly. The TextScreenSystem was expecting a string, but the value inputted for the label was an array of strings. * Address nitpick This should do the exact same thing but it is semantically clearer I guess. (cherry picked from commit 1a3ce6cf2c50d59e91f682011f58e3345f48e86e) --- Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs b/Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs index 0426ee7cc36..f9c2d3430e9 100644 --- a/Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs +++ b/Content.Server/DeviceLinking/Systems/SignalTimerSystem.cs @@ -68,7 +68,7 @@ public void Trigger(EntityUid uid, SignalTimerComponent signalTimer) if (TryComp(uid, out var appearance)) { - _appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, new[] { signalTimer.Label }, appearance); + _appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, signalTimer.Label, appearance); } _audio.PlayPvs(signalTimer.DoneSound, uid); @@ -142,7 +142,7 @@ private void OnTextChangedMessage(EntityUid uid, SignalTimerComponent component, component.Label = args.Text[..Math.Min(5, args.Text.Length)]; if (!HasComp(uid)) - _appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, new string?[] { component.Label }); + _appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, component.Label); } /// @@ -186,7 +186,7 @@ public void OnStartTimer(EntityUid uid, SignalTimerComponent component) if (appearance != null) { _appearanceSystem.SetData(uid, TextScreenVisuals.TargetTime, timer.TriggerTime, appearance); - _appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, new string?[] { }, appearance); + _appearanceSystem.SetData(uid, TextScreenVisuals.ScreenText, string.Empty, appearance); } _signalSystem.InvokePort(uid, component.StartPort); From 9a5206051b1168c4b11a4a78100d941272ae0ce0 Mon Sep 17 00:00:00 2001 From: crazybrain23 <44417085+crazybrain23@users.noreply.github.com> Date: Thu, 8 Feb 2024 23:13:06 +0000 Subject: [PATCH 009/200] fix follow comannd help locale (#25032) (cherry picked from commit f77550dc83c52b693ac7f18214514df280e3f2f6) --- Content.Server/Administration/Commands/FollowCommand.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Server/Administration/Commands/FollowCommand.cs b/Content.Server/Administration/Commands/FollowCommand.cs index 1ced6cf8dde..9f94f83b4d3 100644 --- a/Content.Server/Administration/Commands/FollowCommand.cs +++ b/Content.Server/Administration/Commands/FollowCommand.cs @@ -11,8 +11,8 @@ public sealed class FollowCommand : IConsoleCommand [Dependency] private readonly IEntityManager _entManager = default!; public string Command => "follow"; - public string Description => Loc.GetString("add-uplink-command-description"); - public string Help => Loc.GetString("add-uplink-command-help"); + public string Description => Loc.GetString("follow-command-description"); + public string Help => Loc.GetString("follow-command-help"); public void Execute(IConsoleShell shell, string argStr, string[] args) { From 3872c7a6e3ff4620d1629e923a5164e43326032e Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 8 Feb 2024 23:13:10 +0000 Subject: [PATCH 010/200] Automatic changelog update (cherry picked from commit 8422216f3fccd4c9513c48631e654e26b43f36fb) --- 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 1af050767d6..8e28d9000d3 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Emisse - changes: - - message: Svalinn Laser Pistol and accompanying T3 tech. - type: Add - id: 5402 - time: '2023-12-17T03:43:50.0000000+00:00' - url: null - author: mirrorcult changes: - message: You can now pet the recycler @@ -3884,3 +3877,10 @@ Order: 1 id: 5901 time: '2024-02-08T23:09:00.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25047 +- author: nikthechampiongr + changes: + - message: Brig timers display their label properly again. + type: Fix + id: 5902 + time: '2024-02-08T23:12:05.0000000+00:00' + url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25033 From 6c559d9ce20960252ce167d13cf1c73c4cb915c0 Mon Sep 17 00:00:00 2001 From: Vero <73014819+vero5123@users.noreply.github.com> Date: Thu, 8 Feb 2024 18:15:12 -0500 Subject: [PATCH 011/200] Fixes indestructible mop buckets (#25001) * destructible mop buckets * remove wwod * spacing --------- Co-authored-by: doom (cherry picked from commit 717d4230e2044448810e73ae5e7aed2ab7956ec7) --- .../Entities/Objects/Specific/Janitorial/janitor.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml index 06cf99cc316..ce4eef7453a 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml @@ -172,6 +172,16 @@ - type: GuideHelp guides: - Janitorial + - type: Damageable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 70 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: entity name: mop bucket From 98ce6dac2725f89ae7c1ae84ca3bdf574dec143e Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 8 Feb 2024 23:16:18 +0000 Subject: [PATCH 012/200] Automatic changelog update (cherry picked from commit a6de63cfd0bfe9a099b8e9ccebb7a3a9bc221099) --- 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 8e28d9000d3..dc0042fee17 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: mirrorcult - changes: - - message: You can now pet the recycler - type: Add - id: 5403 - time: '2023-12-17T07:44:37.0000000+00:00' - url: null - author: Ubaser changes: - message: Mindbreaker is now hallucinogenic. @@ -3884,3 +3877,10 @@ Order: 1 id: 5902 time: '2024-02-08T23:12:05.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25033 +- author: vero5123 + changes: + - message: fixes mop buckets being indestructible. + type: Fix + id: 5903 + time: '2024-02-08T23:15:12.0000000+00:00' + url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25001 From 471f2ac24b0dc78a6724d790ca6e9e7813e87310 Mon Sep 17 00:00:00 2001 From: Adrian16199 <144424013+adrian16199@users.noreply.github.com> Date: Fri, 9 Feb 2024 00:17:00 +0100 Subject: [PATCH 013/200] Straw hat. (#24997) * Straw hat. A craftable, flammable straw hat. Thats it. * seems to made it go in flames! (cherry picked from commit 007adfc8a6660daf923891b873399d6061642ce7) --- .../Entities/Clothing/Head/hats.yml | 47 +++++++++++++++++- .../Objects/Consumable/Food/produce.yml | 4 +- .../Recipes/Crafting/Graphs/strawhat.yml | 31 ++++++++++++ .../Recipes/Crafting/improvised.yml | 13 +++++ Resources/Prototypes/tags.yml | 3 ++ .../straw_hat.rsi/equipped-HELMET-hamster.png | Bin 0 -> 983 bytes .../Hats/straw_hat.rsi/equipped-HELMET.png | Bin 0 -> 982 bytes .../Clothing/Head/Hats/straw_hat.rsi/icon.png | Bin 0 -> 743 bytes .../Head/Hats/straw_hat.rsi/inhand-left.png | Bin 0 -> 963 bytes .../Head/Hats/straw_hat.rsi/inhand-right.png | Bin 0 -> 932 bytes .../Head/Hats/straw_hat.rsi/meta.json | 30 +++++++++++ 11 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 Resources/Prototypes/Recipes/Crafting/Graphs/strawhat.yml create mode 100644 Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/equipped-HELMET-hamster.png create mode 100644 Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/equipped-HELMET.png create mode 100644 Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/icon.png create mode 100644 Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/inhand-left.png create mode 100644 Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/inhand-right.png create mode 100644 Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/meta.json diff --git a/Resources/Prototypes/Entities/Clothing/Head/hats.yml b/Resources/Prototypes/Entities/Clothing/Head/hats.yml index 1e38246bd06..c74d82411a2 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hats.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hats.yml @@ -978,4 +978,49 @@ - type: Sprite sprite: Clothing/Head/Hats/cowboyhatbountyhunter.rsi - type: Clothing - sprite: Clothing/Head/Hats/cowboyhatbountyhunter.rsi \ No newline at end of file + sprite: Clothing/Head/Hats/cowboyhatbountyhunter.rsi + +- type: entity + parent: ClothingHeadBase + id: ClothingHeadHatStrawHat + name: straw hat + description: A fancy hat for hot days! Not recommended to wear near fires. + components: + - type: Sprite + sprite: Clothing/Head/Hats/straw_hat.rsi + - type: Clothing + sprite: Clothing/Head/Hats/straw_hat.rsi + - type: Construction + graph: StrawHat + node: strawhat + - type: Tag + tags: + - HamsterWearable + - type: Flammable + fireSpread: true + canResistFire: false + alwaysCombustible: true + canExtinguish: true + damage: + types: + Heat: 1 + - type: Damageable + damageModifierSet: Wood + - type: Appearance + - type: FireVisuals + sprite: Effects/fire.rsi + normalState: fire + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 15 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + Ash: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml index 5c7516f2da4..5d1a3afbec2 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml @@ -52,9 +52,9 @@ Quantity: 10 - type: Produce seedId: wheat - - type: Tag # Delta V straw hat + - type: Tag tags: - - Wheat # End of Delta V straw hat + - Wheat - type: entity name: oat bushel diff --git a/Resources/Prototypes/Recipes/Crafting/Graphs/strawhat.yml b/Resources/Prototypes/Recipes/Crafting/Graphs/strawhat.yml new file mode 100644 index 00000000000..7203a4fdfb3 --- /dev/null +++ b/Resources/Prototypes/Recipes/Crafting/Graphs/strawhat.yml @@ -0,0 +1,31 @@ +- type: constructionGraph + id: StrawHat + start: start + graph: + - node: start + edges: + - to: strawhat + steps: + - tag: Wheat + name: Wheat Bushel + icon: + sprite: Objects/Specific/Hydroponics/wheat.rsi + state: produce + - tag: Wheat + name: Wheat Bushel + icon: + sprite: Objects/Specific/Hydroponics/wheat.rsi + state: produce + - tag: Wheat + name: Wheat Bushel + icon: + sprite: Objects/Specific/Hydroponics/wheat.rsi + state: produce + - tag: Wheat + name: Wheat Bushel + icon: + sprite: Objects/Specific/Hydroponics/wheat.rsi + state: produce + doAfter: 10 + - node: strawhat + entity: ClothingHeadHatStrawHat diff --git a/Resources/Prototypes/Recipes/Crafting/improvised.yml b/Resources/Prototypes/Recipes/Crafting/improvised.yml index ba4eab57c94..12fbe97e28f 100644 --- a/Resources/Prototypes/Recipes/Crafting/improvised.yml +++ b/Resources/Prototypes/Recipes/Crafting/improvised.yml @@ -201,3 +201,16 @@ sprite: Objects/Materials/materials.rsi state: cloth_3 objectType: Item + +- type: construction + name: straw hat + id: strawHat + graph: StrawHat + startNode: start + targetNode: strawhat + category: construction-category-clothing + description: A fancy hat for hot days! Not recommended to wear near fires. + icon: + sprite: Clothing/Head/Hats/straw_hat.rsi + state: icon + objectType: Item diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index f9b207ba6ec..4d85f488a14 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -1169,6 +1169,9 @@ - type: Tag id: WetFloorSign +- type: Tag + id: Wheat + - type: Tag id: WhitelistChameleon diff --git a/Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/equipped-HELMET-hamster.png b/Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/equipped-HELMET-hamster.png new file mode 100644 index 0000000000000000000000000000000000000000..10a56e316be5029847778984dfbb740cf4781671 GIT binary patch literal 983 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV9d*Ob`Ho)PG(@xm{>Y-xA)-y zkz@61{kJ??(9z-CuEi%-(_rDn8hd5o+Jvi1dtWlolA0tU7=G}mV}U?y4evkpU0mz9 znig;<<-OY{rup%XTgJqy!)Jefy!%_$Z(l>b+Iq>dzbq20$GiO8o47lVCS2BLlzORj zrXXnZ*_$^)=G0%mZfh6%{?MxH|G#IgyC!<~+JWmjHp^yCQ`Wg`u=&}HuI;VXTXTwB ze|S_}n8et+e(JnWKU@osJ?1|eW@E)!chz{t%10rh*^#FO7|`@&rrb~Bf1eFsJWXMsm#F#`j)5C}6~x?A^$fq{wN)5S5QBJS<1jb6--0&V6} zoE5h+7Wy(dT3qnE;FnX&IRD5c_6=V=YZ#+F(+~JPbYSva+#2g=8L@`e5efRQ2V~w5^Xn&onddmwe8uu*F?p(`L)I7j+Ha zUTt;vS6lgW<9iMdsmI5rWqQ9?o#NM!YjTP6f-GZIPWP;9FZvu#>}FJx_{74#cO~n) zOL^PcPkrIARLj(45ZZkF+_vMT6K|zn&-^~;{g u`})_ZC>GVM=FDMZ6kx!L8uz literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/equipped-HELMET.png new file mode 100644 index 0000000000000000000000000000000000000000..2ddd8f3209755697759ef3afc1add074023b47c7 GIT binary patch literal 982 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV9d*Ob`Ho)PG(@xm{>Y-xA)-y zkz@6_wF^ZBWnE;ft{e|=6gd*8bz`a37ST1kR5CAfuGqLG$wX?kN@P1hp2K-pO5dW_8(mS>g$46U;pp55BFAkE%6{*NX}Gew~o$bfq1>>F7p=a-aXR< z?}_)_Fk0}T^-^iSyy$bAy3m~ELc$NiZJl?@ulb*#oG;$W-g5Y;)6pOE+-p4zqGx$} zy`6Tq*||v~(CI};#1e;@jw@A9zRACTVS4^7)sGUNwnZEibMM4nJa0`Jj?qLo-9+fa zmWxiaS(*wK%v~_|#xEwj&ZYbbFDL(C+BWH2!`wrSER)>0ch9L>aipj4d})4Z`Z-(H zpZq~7Gw0SnyS;PC5Az_=d7B@9yK!$@wL!Lo)xG;aw7#mDG$uHPo^#d@E| ztxKW9YNdcoRJ~i&;ls)6-fez!+3c6!>u1iF70$lx+WxuV>&{zigpJ+x_Rb29wm!e~ z&)z&|)z|(dUZ1U^i&D-o`PuYm7U-|CW@GsHYHcB#^!{n2GWsHfz?K5hR3NQY+_i(Mb z{_fx39s2g=#Vyj;n$q=ST|wstmWE1>E&lQ?GoAfquPXdB7h;?s5}Ur}wZf~W_;mRb zyi5uVc+rR5ELzgaindjGr*D1y={0-y@t)Nz3R~RuHEp(Rdr{Z$?bTLyf3=lAH@@fa zka~RV*OsNJt~tGXlGxHNk+Lx8hg_8rqh3uSKazw&I~taBDGf4}e&Qaav0>p+?S h10w?P)sJi7fW$y@qymzHYfh^2e_6#Z4C2xpSnYZF^asP^`#cOOv+ojZE?$M$ z65FlotPF;x>{uOe{`5}m8Adx002ovPDHLkV1gywR!;x` literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..5cd89c082b142aba2fcaa1e0e1ef55b9d2db9c67 GIT binary patch literal 963 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV9d*Ob`Ho)PG(@xm{>Z|(wjL@ zq}5*7RBxh4S4YH>j--hTG&+{L82E1K5bU|7GTHZp(HRww4Wc;E;Y?*09%vi>uqwv=%AXYL9Vn3lDlcS4IMlWws>=ViSSmmngb-m@vk{6tn zMpHuG)qggbJXv__J3sp^w$ayq8(5Sr4BEElee&s5a~l3~>J{_W#}&=`C$jg>1)KH< zx0*h$ZWFuR+?^{?ab>aF7Ok79wj((A?$5OJI_v2oo4p<~G72zYpa?UjshKJ@<##)L_b(T}>s3%J@cViHHQU&)u0@;J zf{#ev4EnIUw|B~$rMJUb4n8{{n*TX}-Fgwx8*l9Gl)uWgDW{n%tNgn#Yk^_?=UE~7 z-Oju6Yy~@&_og&2H!UssGs3Ejna=oi_;Hli{{s1^uT%}6-3*C6@@u8( z-?#f0ny>g*=DqUyy?UYQuO5Lxv!f61^!s48Nq6q9b<0zHZ5?CPpG#Ivmzks8P=6zD zeOZ!Ulh;4>Pm^|pWj|D?(D(fF=9B5x^)Ba6roU8geZb>zf5s#UagVqMRxX!}J?@H! z^ZuOhZ??yRDO?Vl79LUKPMNt}uanVCfq@A>>UK|1lU7zsd&lzhu5^Lrw4DqNoPMwG zIlTPN9OIWfXWDz-fXAW#KkQ}xJg?EDZ|4ezSEApn4qw}G(`@<9s?F=a+)JGJ?By9I z1Mhn|J3n(4zn**i(rSww`^^j*4$-@9SDz7I)@}3BTDSIlB0It*-u@57)yp3z3R*qa Q0;UZHPgg&ebxsLQ03_I?)&Kwi literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..8ad5764d3c372555106c27dc7a4dbc362c02d50d GIT binary patch literal 932 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV9d*Ob`Ho)PG(@xm{>Z|(wjL@ zq;>xh(cUEiE-s3#U9F7b0^Xeovoa>S6l702sUoC zujE;&XI#@3Ux~fXzawPt_tkM<-(QV+%X#Rc9x+Rl5_`cQ0?)ieP+ zF*(CjhlkQjk9+@FWfA(w|7erMq>1fYEWs)5S5QBJS<1jb4WXMB4JV1{v&n zv7nn(kZBj^uFlo^4<=juVvwyBia!v#E3zP%qa#3E_D+vfNYejPoi9CCnQytF{Fhm_ z=%nrU|NDz)@jSOU-p%6CfPoTjaa=jYGk?BG@ZNp(SJt{NkIt;92;FsDXouD>?z9b+ zTXzP0D864?)R1uU#fB%L7ws1}@7bgF&a#hvT4Dd!Kdo6C7@S{!xT=5ax8&LBJ|(u# z%f8*?zGwAz7q|KSO{Lyf7ktfsZ^rdYUw=~2-%=aStk(~V>Vq$={^xgl=j`3@6{NE} zoi7|+x_;~J7Z;sA8S_TjpUL{`@yh0m=HHv$Z`W*{#Kkh@kGoI``x&!G_ns*j*A@Ip zco+L%ar~L*U-=~*C(IAZzG(5~)OF7<-b$b2mSjCt{BLSJ{bb>v?Wcq?O)DRNI4z;# zz=R*wvAE^+guFcZ+w<4$@tvla5%o|)1_{AW7GeaH?!Cos(v63xB0=gXDyw6$l1 leP7ugF7|{6{Q;Fm|NNH6iOtc|4*?^e!PC{xWt~$(69CwhpIHC^ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/meta.json b/Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/meta.json new file mode 100644 index 00000000000..a3cde84524c --- /dev/null +++ b/Resources/Textures/Clothing/Head/Hats/straw_hat.rsi/meta.json @@ -0,0 +1,30 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Made by Adrian16199", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-HELMET", + "directions": 4 + }, + { + "name": "equipped-HELMET-hamster", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} From 78767f27e80ef366a684b77292d9bf11447f4918 Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 8 Feb 2024 23:18:06 +0000 Subject: [PATCH 014/200] Automatic changelog update (cherry picked from commit a81ce947a15bdeb16226332c3d24643ca4ab4024) --- 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 dc0042fee17..c25c5198d25 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Ubaser - changes: - - message: Mindbreaker is now hallucinogenic. - type: Tweak - id: 5404 - time: '2023-12-17T07:44:54.0000000+00:00' - url: null - author: JoeHammad changes: - message: Paramedics now have a rollerbed in their bag by default @@ -3884,3 +3877,10 @@ Order: 1 id: 5903 time: '2024-02-08T23:15:12.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25001 +- author: Adrian16199 + changes: + - message: Added a straw hat that can be crafted with wheat. + type: Add + id: 5904 + time: '2024-02-08T23:17:01.0000000+00:00' + url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24997 From 510d06eac6f0abef0d0e06da36333923efc5c227 Mon Sep 17 00:00:00 2001 From: Sk1tch Date: Thu, 8 Feb 2024 15:23:34 -0800 Subject: [PATCH 015/200] Alphabetically sorted guidebook entries (#24963) * - Renamed GetSortedRootEntries to GetSortedEntries and added child sorting logic - Removed unessesary Tree.SetAllExpanded(true) call in RepopulateTree * Adding back deleted setallexpanded call to check if test passes --------- Co-authored-by: Your Name (cherry picked from commit 3b2921a3ccc5adfdd6d7c4020e814e4d56b5b3e3) --- .../Controls/GuidebookWindow.xaml.cs | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Content.Client/Guidebook/Controls/GuidebookWindow.xaml.cs b/Content.Client/Guidebook/Controls/GuidebookWindow.xaml.cs index 113c192beb9..4776386c1dd 100644 --- a/Content.Client/Guidebook/Controls/GuidebookWindow.xaml.cs +++ b/Content.Client/Guidebook/Controls/GuidebookWindow.xaml.cs @@ -98,22 +98,33 @@ public void UpdateGuides( } } - private IEnumerable GetSortedRootEntries(List? rootEntries) + private IEnumerable GetSortedEntries(List? rootEntries) { if (rootEntries == null) { HashSet entries = new(_entries.Keys); foreach (var entry in _entries.Values) { + if (entry.Children.Count > 0) + { + var sortedChildren = entry.Children + .Select(childId => _entries[childId]) + .OrderBy(childEntry => childEntry.Priority) + .ThenBy(childEntry => Loc.GetString(childEntry.Name)) + .Select(childEntry => childEntry.Id) + .ToList(); + + entry.Children = sortedChildren; + } entries.ExceptWith(entry.Children); } rootEntries = entries.ToList(); } return rootEntries - .Select(x => _entries[x]) - .OrderBy(x => x.Priority) - .ThenBy(x => Loc.GetString(x.Name)); + .Select(rootEntryId => _entries[rootEntryId]) + .OrderBy(rootEntry => rootEntry.Priority) + .ThenBy(rootEntry => Loc.GetString(rootEntry.Name)); } private void RepopulateTree(List? roots = null, string? forcedRoot = null) @@ -123,7 +134,7 @@ private void RepopulateTree(List? roots = null, string? forcedRoot = nul HashSet addedEntries = new(); TreeItem? parent = forcedRoot == null ? null : AddEntry(forcedRoot, null, addedEntries); - foreach (var entry in GetSortedRootEntries(roots)) + foreach (var entry in GetSortedEntries(roots)) { AddEntry(entry.Id, parent, addedEntries); } From a096be29e76aa5de579aeba6ad583e65d8d872c2 Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 8 Feb 2024 23:24:40 +0000 Subject: [PATCH 016/200] Automatic changelog update (cherry picked from commit 9e79a26830830068b7f1a47f0b5e7b987fc7fead) --- 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 c25c5198d25..048db9ca18c 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: JoeHammad - changes: - - message: Paramedics now have a rollerbed in their bag by default - type: Add - id: 5405 - time: '2023-12-17T09:55:29.0000000+00:00' - url: null - author: Ilya246 changes: - message: Large cardboard boxes and stealth boxes now inherit their mover's access. @@ -3884,3 +3877,10 @@ Order: 1 id: 5904 time: '2024-02-08T23:17:01.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24997 +- author: Sk1tch + changes: + - message: Guidebook entries are now alphabetically sorted + type: Tweak + id: 5905 + time: '2024-02-08T23:23:35.0000000+00:00' + url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24963 From dd5e666d940f61b0cf9c540698358efcef82fe3e Mon Sep 17 00:00:00 2001 From: Debug <49997488+DebugOk@users.noreply.github.com> Date: Sun, 18 Feb 2024 22:37:41 +0100 Subject: [PATCH 017/200] Revert "Straw hat (#527)" This reverts commit 1959db69 --- .../DeltaV/Entities/Clothing/Head/hats.yml | 18 ---------- .../Recipes/Crafting/Graphs/strawhat.yml | 31 ------------------ .../DeltaV/Recipes/Crafting/improvised.yml | 12 ------- Resources/Prototypes/DeltaV/tags.yml | 3 -- .../straw_hat.rsi/equipped-HELMET-hamster.png | Bin 983 -> 0 bytes .../Hats/straw_hat.rsi/equipped-HELMET.png | Bin 982 -> 0 bytes .../Clothing/Head/Hats/straw_hat.rsi/icon.png | Bin 743 -> 0 bytes .../Head/Hats/straw_hat.rsi/inhand-left.png | Bin 963 -> 0 bytes .../Head/Hats/straw_hat.rsi/inhand-right.png | Bin 932 -> 0 bytes .../Head/Hats/straw_hat.rsi/meta.json | 30 ----------------- 10 files changed, 94 deletions(-) delete mode 100644 Resources/Prototypes/DeltaV/Recipes/Crafting/Graphs/strawhat.yml delete mode 100644 Resources/Prototypes/DeltaV/Recipes/Crafting/improvised.yml delete mode 100644 Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/equipped-HELMET-hamster.png delete mode 100644 Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/equipped-HELMET.png delete mode 100644 Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/icon.png delete mode 100644 Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/inhand-left.png delete mode 100644 Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/inhand-right.png delete mode 100644 Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/meta.json diff --git a/Resources/Prototypes/DeltaV/Entities/Clothing/Head/hats.yml b/Resources/Prototypes/DeltaV/Entities/Clothing/Head/hats.yml index 22167ae0385..1c5cef39af1 100644 --- a/Resources/Prototypes/DeltaV/Entities/Clothing/Head/hats.yml +++ b/Resources/Prototypes/DeltaV/Entities/Clothing/Head/hats.yml @@ -192,21 +192,3 @@ sprite: DeltaV/Clothing/Head/Hats/beret_corpsman.rsi - type: Clothing sprite: DeltaV/Clothing/Head/Hats/beret_corpsman.rsi - -- type: entity - parent: ClothingHeadBase - id: ClothingHeadHatStrawHat - name: straw hat - description: A fancy hat for hot days! Not recommended to wear near fires. - components: - - type: Sprite - sprite: DeltaV/Clothing/Head/Hats/straw_hat.rsi - - type: Clothing - sprite: DeltaV/Clothing/Head/Hats/straw_hat.rsi - - type: Construction - graph: StrawHat - node: strawhat - - type: Tag - tags: - - HamsterWearable - diff --git a/Resources/Prototypes/DeltaV/Recipes/Crafting/Graphs/strawhat.yml b/Resources/Prototypes/DeltaV/Recipes/Crafting/Graphs/strawhat.yml deleted file mode 100644 index 7203a4fdfb3..00000000000 --- a/Resources/Prototypes/DeltaV/Recipes/Crafting/Graphs/strawhat.yml +++ /dev/null @@ -1,31 +0,0 @@ -- type: constructionGraph - id: StrawHat - start: start - graph: - - node: start - edges: - - to: strawhat - steps: - - tag: Wheat - name: Wheat Bushel - icon: - sprite: Objects/Specific/Hydroponics/wheat.rsi - state: produce - - tag: Wheat - name: Wheat Bushel - icon: - sprite: Objects/Specific/Hydroponics/wheat.rsi - state: produce - - tag: Wheat - name: Wheat Bushel - icon: - sprite: Objects/Specific/Hydroponics/wheat.rsi - state: produce - - tag: Wheat - name: Wheat Bushel - icon: - sprite: Objects/Specific/Hydroponics/wheat.rsi - state: produce - doAfter: 10 - - node: strawhat - entity: ClothingHeadHatStrawHat diff --git a/Resources/Prototypes/DeltaV/Recipes/Crafting/improvised.yml b/Resources/Prototypes/DeltaV/Recipes/Crafting/improvised.yml deleted file mode 100644 index e01a510653a..00000000000 --- a/Resources/Prototypes/DeltaV/Recipes/Crafting/improvised.yml +++ /dev/null @@ -1,12 +0,0 @@ -- type: construction - name: straw hat - id: strawHat - graph: StrawHat - startNode: start - targetNode: strawhat - category: construction-category-clothing - description: A fancy hat for hot days! Not recommended to wear near fires. - icon: - sprite: DeltaV/Clothing/Head/Hats/straw_hat.rsi - state: icon - objectType: Item diff --git a/Resources/Prototypes/DeltaV/tags.yml b/Resources/Prototypes/DeltaV/tags.yml index 72181758e38..6a1efcfa695 100644 --- a/Resources/Prototypes/DeltaV/tags.yml +++ b/Resources/Prototypes/DeltaV/tags.yml @@ -36,9 +36,6 @@ - type: Tag id: BionicSyrinxImplant -- type: Tag - id: Wheat - - type: Tag id: PaperSlip diff --git a/Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/equipped-HELMET-hamster.png b/Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/equipped-HELMET-hamster.png deleted file mode 100644 index 10a56e316be5029847778984dfbb740cf4781671..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 983 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV9d*Ob`Ho)PG(@xm{>Y-xA)-y zkz@61{kJ??(9z-CuEi%-(_rDn8hd5o+Jvi1dtWlolA0tU7=G}mV}U?y4evkpU0mz9 znig;<<-OY{rup%XTgJqy!)Jefy!%_$Z(l>b+Iq>dzbq20$GiO8o47lVCS2BLlzORj zrXXnZ*_$^)=G0%mZfh6%{?MxH|G#IgyC!<~+JWmjHp^yCQ`Wg`u=&}HuI;VXTXTwB ze|S_}n8et+e(JnWKU@osJ?1|eW@E)!chz{t%10rh*^#FO7|`@&rrb~Bf1eFsJWXMsm#F#`j)5C}6~x?A^$fq{wN)5S5QBJS<1jb6--0&V6} zoE5h+7Wy(dT3qnE;FnX&IRD5c_6=V=YZ#+F(+~JPbYSva+#2g=8L@`e5efRQ2V~w5^Xn&onddmwe8uu*F?p(`L)I7j+Ha zUTt;vS6lgW<9iMdsmI5rWqQ9?o#NM!YjTP6f-GZIPWP;9FZvu#>}FJx_{74#cO~n) zOL^PcPkrIARLj(45ZZkF+_vMT6K|zn&-^~;{g u`})_ZC>GVM=FDMZ6kx!L8uz diff --git a/Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/equipped-HELMET.png b/Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/equipped-HELMET.png deleted file mode 100644 index 2ddd8f3209755697759ef3afc1add074023b47c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 982 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV9d*Ob`Ho)PG(@xm{>Y-xA)-y zkz@6_wF^ZBWnE;ft{e|=6gd*8bz`a37ST1kR5CAfuGqLG$wX?kN@P1hp2K-pO5dW_8(mS>g$46U;pp55BFAkE%6{*NX}Gew~o$bfq1>>F7p=a-aXR< z?}_)_Fk0}T^-^iSyy$bAy3m~ELc$NiZJl?@ulb*#oG;$W-g5Y;)6pOE+-p4zqGx$} zy`6Tq*||v~(CI};#1e;@jw@A9zRACTVS4^7)sGUNwnZEibMM4nJa0`Jj?qLo-9+fa zmWxiaS(*wK%v~_|#xEwj&ZYbbFDL(C+BWH2!`wrSER)>0ch9L>aipj4d})4Z`Z-(H zpZq~7Gw0SnyS;PC5Az_=d7B@9yK!$@wL!Lo)xG;aw7#mDG$uHPo^#d@E| ztxKW9YNdcoRJ~i&;ls)6-fez!+3c6!>u1iF70$lx+WxuV>&{zigpJ+x_Rb29wm!e~ z&)z&|)z|(dUZ1U^i&D-o`PuYm7U-|CW@GsHYHcB#^!{n2GWsHfz?K5hR3NQY+_i(Mb z{_fx39s2g=#Vyj;n$q=ST|wstmWE1>E&lQ?GoAfquPXdB7h;?s5}Ur}wZf~W_;mRb zyi5uVc+rR5ELzgaindjGr*D1y={0-y@t)Nz3R~RuHEp(Rdr{Z$?bTLyf3=lAH@@fa zka~RV*OsNJt~tGXlGxHNk+Lx8hg_8rqh3uSKazw&I~taBDGf4}e&Qaav0>p+?S h10w?P)sJi7fW$y@qymzHYfh^2e_6#Z4C2xpSnYZF^asP^`#cOOv+ojZE?$M$ z65FlotPF;x>{uOe{`5}m8Adx002ovPDHLkV1gywR!;x` diff --git a/Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/inhand-left.png b/Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/inhand-left.png deleted file mode 100644 index 5cd89c082b142aba2fcaa1e0e1ef55b9d2db9c67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 963 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV9d*Ob`Ho)PG(@xm{>Z|(wjL@ zq}5*7RBxh4S4YH>j--hTG&+{L82E1K5bU|7GTHZp(HRww4Wc;E;Y?*09%vi>uqwv=%AXYL9Vn3lDlcS4IMlWws>=ViSSmmngb-m@vk{6tn zMpHuG)qggbJXv__J3sp^w$ayq8(5Sr4BEElee&s5a~l3~>J{_W#}&=`C$jg>1)KH< zx0*h$ZWFuR+?^{?ab>aF7Ok79wj((A?$5OJI_v2oo4p<~G72zYpa?UjshKJ@<##)L_b(T}>s3%J@cViHHQU&)u0@;J zf{#ev4EnIUw|B~$rMJUb4n8{{n*TX}-Fgwx8*l9Gl)uWgDW{n%tNgn#Yk^_?=UE~7 z-Oju6Yy~@&_og&2H!UssGs3Ejna=oi_;Hli{{s1^uT%}6-3*C6@@u8( z-?#f0ny>g*=DqUyy?UYQuO5Lxv!f61^!s48Nq6q9b<0zHZ5?CPpG#Ivmzks8P=6zD zeOZ!Ulh;4>Pm^|pWj|D?(D(fF=9B5x^)Ba6roU8geZb>zf5s#UagVqMRxX!}J?@H! z^ZuOhZ??yRDO?Vl79LUKPMNt}uanVCfq@A>>UK|1lU7zsd&lzhu5^Lrw4DqNoPMwG zIlTPN9OIWfXWDz-fXAW#KkQ}xJg?EDZ|4ezSEApn4qw}G(`@<9s?F=a+)JGJ?By9I z1Mhn|J3n(4zn**i(rSww`^^j*4$-@9SDz7I)@}3BTDSIlB0It*-u@57)yp3z3R*qa Q0;UZHPgg&ebxsLQ03_I?)&Kwi diff --git a/Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/inhand-right.png b/Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/inhand-right.png deleted file mode 100644 index 8ad5764d3c372555106c27dc7a4dbc362c02d50d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 932 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV9d*Ob`Ho)PG(@xm{>Z|(wjL@ zq;>xh(cUEiE-s3#U9F7b0^Xeovoa>S6l702sUoC zujE;&XI#@3Ux~fXzawPt_tkM<-(QV+%X#Rc9x+Rl5_`cQ0?)ieP+ zF*(CjhlkQjk9+@FWfA(w|7erMq>1fYEWs)5S5QBJS<1jb4WXMB4JV1{v&n zv7nn(kZBj^uFlo^4<=juVvwyBia!v#E3zP%qa#3E_D+vfNYejPoi9CCnQytF{Fhm_ z=%nrU|NDz)@jSOU-p%6CfPoTjaa=jYGk?BG@ZNp(SJt{NkIt;92;FsDXouD>?z9b+ zTXzP0D864?)R1uU#fB%L7ws1}@7bgF&a#hvT4Dd!Kdo6C7@S{!xT=5ax8&LBJ|(u# z%f8*?zGwAz7q|KSO{Lyf7ktfsZ^rdYUw=~2-%=aStk(~V>Vq$={^xgl=j`3@6{NE} zoi7|+x_;~J7Z;sA8S_TjpUL{`@yh0m=HHv$Z`W*{#Kkh@kGoI``x&!G_ns*j*A@Ip zco+L%ar~L*U-=~*C(IAZzG(5~)OF7<-b$b2mSjCt{BLSJ{bb>v?Wcq?O)DRNI4z;# zz=R*wvAE^+guFcZ+w<4$@tvla5%o|)1_{AW7GeaH?!Cos(v63xB0=gXDyw6$l1 leP7ugF7|{6{Q;Fm|NNH6iOtc|4*?^e!PC{xWt~$(69CwhpIHC^ diff --git a/Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/meta.json b/Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/meta.json deleted file mode 100644 index 1885732f2b5..00000000000 --- a/Resources/Textures/DeltaV/Clothing/Head/Hats/straw_hat.rsi/meta.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "version": 1, - "license": "CC-BY-SA-3.0", - "copyright": "Made by Adrian16199", - "size": { - "x": 32, - "y": 32 - }, - "states": [ - { - "name": "icon" - }, - { - "name": "equipped-HELMET", - "directions": 4 - }, - { - "name": "equipped-HELMET-hamster", - "directions": 4 - }, - { - "name": "inhand-left", - "directions": 4 - }, - { - "name": "inhand-right", - "directions": 4 - } - ] -} From 15a31fff9b2e825370ad90728e313b8f3653d968 Mon Sep 17 00:00:00 2001 From: Armok <155400926+ARMOKS@users.noreply.github.com> Date: Fri, 9 Feb 2024 14:46:43 -0700 Subject: [PATCH 018/200] Syndicate key grammar fix (#25085) * Syndicate encryption key grammar fix An encryption key used by... wait... Who is owner of this chip? > An encryption key used by... wait... Who is the owner of this chip? * Syndicate key grammar fix An encryption key used by... wait... Who is owner of this chip? > An encryption key used by... wait... Who is the owner of this chip? (cherry picked from commit de0d5e4af64b16e64cf71c8c0406970f2a543280) --- .../Prototypes/Entities/Objects/Devices/encryption_keys.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml b/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml index 1c8a14dc76b..95dfcd65f2a 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml @@ -203,7 +203,7 @@ parent: EncryptionKey id: EncryptionKeySyndie name: blood-red encryption key - description: An encryption key used by... wait... Who is owner of this chip? + description: An encryption key used by... wait... Who is the owner of this chip? components: - type: EncryptionKey channels: From d1561c874dbb8030b801c8861a5fbedad51dd7b9 Mon Sep 17 00:00:00 2001 From: Kevin Zheng Date: Fri, 9 Feb 2024 17:21:48 -0800 Subject: [PATCH 019/200] Fix hybridization seedless probability (#25084) Fix comparison Hybrids (different plants being crossed) are supposed to have a high chance of becoming seedless to balance overpowered plants. However, a logic error in the comparison gave seedless to plants when they were from the same seed (not hybrids) rather than the other way around. Reported by: @genderGeometries (cherry picked from commit 28755f5405cb4415da1256ac75e1d5496c497231) --- Content.Server/Botany/Systems/MutationSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/Botany/Systems/MutationSystem.cs b/Content.Server/Botany/Systems/MutationSystem.cs index cfa944a221a..c7ce5d47efa 100644 --- a/Content.Server/Botany/Systems/MutationSystem.cs +++ b/Content.Server/Botany/Systems/MutationSystem.cs @@ -131,7 +131,7 @@ public SeedData Cross(SeedData a, SeedData b) // Hybrids have a high chance of being seedless. Balances very // effective hybrid crossings. - if (a.Name == result.Name && Random(0.7f)) + if (a.Name != result.Name && Random(0.7f)) { result.Seedless = true; } From aa482a50b2569404afc28bfc797f17c9d6f30fdb Mon Sep 17 00:00:00 2001 From: PoorMansDreams <150595537+PoorMansDreams@users.noreply.github.com> Date: Fri, 9 Feb 2024 17:57:42 -0800 Subject: [PATCH 020/200] Added Tourniquets to stop bleeds (#23198) * Fixed Error with RobustToolbox Edits. Removed the addition of secbelt tag from assault belt. * Resprite of the monstrosity * Resprite of the tourniquet NO LONGER PHALLUS SHAPED * too bright, now darker and edgier * Tourniquet resprite * metajson yay (cherry picked from commit bd4e2c35ec0a101485906228859366317ff60c37) --- .../VendingMachines/Inventories/sec.yml | 1 + .../Objects/Specific/Medical/healing.yml | 27 +++++++++++++++++- .../Specific/Medical/medical.rsi/meta.json | 4 +++ .../Medical/medical.rsi/tourniquet.png | Bin 0 -> 300 bytes 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 Resources/Textures/Objects/Specific/Medical/medical.rsi/tourniquet.png diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml index d86129cd782..6d1e0cc7d81 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/sec.yml @@ -8,6 +8,7 @@ ClusterBangFull: 2 GrenadeStinger: 4 Flash: 5 + Tourniquet: 5 FlashlightSeclite: 5 ClothingEyesGlassesSunglasses: 2 ClothingEyesHudSecurity: 2 diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml index ebb32ae5b40..b7da58fb414 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml @@ -224,7 +224,32 @@ components: - type: Stack lingering: true - +- type: entity + parent: BaseHealingItem + id: Tourniquet + name: tourniquet + description: Stops bleeding! Hopefully. + components: + - type: Tag + tags: + - SecBeltEquip + - type: Sprite + state: tourniquet + - type: Healing + damageContainers: + - Biological + damage: + groups: + Brute: 5 # Tourniquets HURT! + types: + Asphyxiation: 5 # Essentially Stopping all blood reaching a part of your body + bloodlossModifier: -10 # Tourniquets stop bleeding + delay: 0.5 + healingBeginSound: + path: "/Audio/Items/Medical/brutepack_begin.ogg" + healingEndSound: + path: "/Audio/Items/Medical/brutepack_end.ogg" + - type: entity name: roll of gauze description: Some sterile gauze to wrap around bloody stumps. diff --git a/Resources/Textures/Objects/Specific/Medical/medical.rsi/meta.json b/Resources/Textures/Objects/Specific/Medical/medical.rsi/meta.json index 79d08e485b9..e4f039ada9b 100644 --- a/Resources/Textures/Objects/Specific/Medical/medical.rsi/meta.json +++ b/Resources/Textures/Objects/Specific/Medical/medical.rsi/meta.json @@ -3,6 +3,7 @@ "license": "CC-BY-SA-3.0", "copyright": "Taken from cev-eris at https://github.com/discordia-space/CEV-Eris/commit/740ff31a81313086cf16761f3677cf1e2ab46c93 and Taken from tgstation at https://github.com/tgstation/tgstation/blob/623290915c2292b56da11048deb62d758e1e3fb4/icons/obj/bloodpack.dmi, Blood pack redone by Ubaser", "copyright": "Taken from https://github.com/tgstation/tgstation/blob/a3568da5634e756d0849480104afda402c6f1c3c/icons/obj/medical/stack_medical.dmi", + "copyright": "Tourniquet Sprite by PoorMansDreams", "size": { "x": 32, "y": 32 @@ -25,6 +26,9 @@ { "name": "gauze" }, + { + "name": "tourniquet" + }, { "name": "morphine" }, diff --git a/Resources/Textures/Objects/Specific/Medical/medical.rsi/tourniquet.png b/Resources/Textures/Objects/Specific/Medical/medical.rsi/tourniquet.png new file mode 100644 index 0000000000000000000000000000000000000000..fce355eb9ef004d97661dc521e501d584bfd41e6 GIT binary patch literal 300 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCil21AIbUrKDtZb@hXSLMqD}fZ*A)ch1hPhjq<>@=0g*KLJvlB|(0{|Dk{( z*uO#uBv{}PSWfp9Fn)Jq-*Wq~iE8S}%mJc>tmOEVj>iw=PfmgNfCu2$B)pb5g fCzi5qxW+xTP-e!{xtc(iF)(<#`njxgN@xNAE;4OQ literal 0 HcmV?d00001 From a626ecb2467d91fa1f7a5aa50399bf4cd6861fce Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 10 Feb 2024 02:07:10 +0000 Subject: [PATCH 021/200] Automatic changelog update (cherry picked from commit d6c6c1d9820b072e4c41010a1b8a0ba8574389c8) --- 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 048db9ca18c..fda038261f6 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Ilya246 - changes: - - message: Large cardboard boxes and stealth boxes now inherit their mover's access. - type: Fix - id: 5406 - time: '2023-12-17T09:55:40.0000000+00:00' - url: null - author: TheShuEd changes: - message: Changed hypodart cost from 3 to 2 tc @@ -3884,3 +3877,10 @@ Order: 1 id: 5905 time: '2024-02-08T23:23:35.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24963 +- author: FairlySadPanda + changes: + - message: Swapped out the Skelly Vs The Rev art with a new, higher-res version. + type: Tweak + id: 5906 + time: '2024-02-10T02:06:02.0000000+00:00' + url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25088 From 8d7e6ec58bfb40f168aadad28e9e0c5079c75d24 Mon Sep 17 00:00:00 2001 From: lapatison <100279397+lapatison@users.noreply.github.com> Date: Sat, 10 Feb 2024 07:30:24 +0300 Subject: [PATCH 022/200] Minor airlock assembly clean up (#25073) 1 (cherry picked from commit 39b01fda09cb4a175cac2d6843cdc7b0f54a114c) --- .../Structures/Doors/Airlocks/assembly.yml | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/assembly.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/assembly.yml index 2fc5817287f..bb9d5cccdd6 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/assembly.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/assembly.yml @@ -2,7 +2,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyAtmospherics - name: airlock assembly suffix: Atmospherics components: - type: Sprite @@ -12,7 +11,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyAtmosphericsGlass - name: airlock assembly suffix: Atmospherics, Glass components: - type: Sprite @@ -23,7 +21,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyCargo - name: airlock assembly suffix: Cargo components: - type: Sprite @@ -33,7 +30,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyCargoGlass - name: airlock assembly suffix: Cargo, Glass components: - type: Sprite @@ -44,7 +40,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyCommand - name: airlock assembly suffix: Command components: - type: Sprite @@ -54,7 +49,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyCommandGlass - name: airlock assembly suffix: Command, Glass components: - type: Sprite @@ -65,7 +59,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyEngineering - name: airlock assembly suffix: Engineering components: - type: Sprite @@ -75,7 +68,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyEngineeringGlass - name: airlock assembly suffix: Engineering, Glass components: - type: Sprite @@ -86,7 +78,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyExternal - name: airlock assembly suffix: External components: - type: Sprite @@ -96,7 +87,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyExternalGlass - name: airlock assembly suffix: External, Glass components: - type: Sprite @@ -107,7 +97,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyGlass - name: airlock assembly suffix: Glass components: - type: Sprite @@ -118,7 +107,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyFreezer - name: airlock assembly suffix: Freezer components: - type: Sprite @@ -129,7 +117,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyMaintenance - name: airlock assembly suffix: Maintenance components: - type: Sprite @@ -139,7 +126,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyMaintenanceGlass - name: airlock assembly suffix: Maintenance, Glass components: - type: Sprite @@ -150,7 +136,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyMedical - name: airlock assembly suffix: Medical components: - type: Sprite @@ -160,7 +145,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyMedicalGlass - name: airlock assembly suffix: Medical, Glass components: - type: Sprite @@ -171,7 +155,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyScience - name: airlock assembly suffix: Science components: - type: Sprite @@ -181,7 +164,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyScienceGlass - name: airlock assembly suffix: Science, Glass components: - type: Sprite @@ -192,7 +174,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblySecurity - name: airlock assembly suffix: Security components: - type: Sprite @@ -202,7 +183,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblySecurityGlass - name: airlock assembly suffix: Security, Glass components: - type: Sprite @@ -213,7 +193,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyShuttle - name: airlock assembly suffix: Shuttle components: - type: Sprite @@ -223,7 +202,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyShuttleGlass - name: airlock assembly suffix: Shuttle, Glass components: - type: Sprite @@ -234,7 +212,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyVirology - name: airlock assembly suffix: Virology components: - type: Sprite @@ -244,7 +221,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyVirologyGlass - name: airlock assembly suffix: Virology, Glass components: - type: Sprite @@ -255,7 +231,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyCentralCommand - name: airlock assembly suffix: CentralCommand components: - type: Sprite @@ -265,7 +240,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyCentralCommandGlass - name: airlock assembly suffix: CentralCommand, Glass components: - type: Sprite @@ -276,7 +250,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyMining - name: airlock assembly suffix: Mining components: - type: Sprite @@ -286,7 +259,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyMiningGlass - name: airlock assembly suffix: Mining, Glass components: - type: Sprite @@ -297,7 +269,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblySyndicate - name: airlock assembly suffix: Syndicate components: - type: Sprite @@ -307,7 +278,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblySyndicateGlass - name: airlock assembly suffix: Syndicate, Glass components: - type: Sprite @@ -318,7 +288,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyShuttleSyndicate - name: airlock assembly suffix: ShuttleSyndicate components: - type: Sprite @@ -328,7 +297,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyShuttleSyndicateGlass - name: airlock assembly suffix: ShuttleSyndicate, Glass components: - type: Sprite @@ -339,7 +307,6 @@ - type: entity parent: AirlockAssembly id: AirlockAssemblyHighSec - name: airlock assembly suffix: HighSec components: - type: Sprite From 1efd153b83f64edd1a06ac71c3af6d6a2e6759d2 Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Sat, 10 Feb 2024 03:00:52 -0500 Subject: [PATCH 023/200] prevent opening debug menus without perms (#25091) prevent people without permissions from opening the tile, entityspawn, or decal menus (cherry picked from commit 2293f46bcac38c73a212fc34ee77d2839cd8558b) --- .../Systems/Sandbox/SandboxUIController.cs | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs b/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs index 3ab36a9166a..752c89ca970 100644 --- a/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs +++ b/Content.Client/UserInterface/Systems/Sandbox/SandboxUIController.cs @@ -30,6 +30,7 @@ public sealed class SandboxUIController : UIController, IOnStateChanged EntitySpawningController.ToggleWindow())); + InputCmdHandler.FromDelegate(_ => + { + if (!_admin.CanAdminPlace()) + return; + EntitySpawningController.ToggleWindow(); + })); _input.SetInputCommand(ContentKeyFunctions.OpenSandboxWindow, InputCmdHandler.FromDelegate(_ => ToggleWindow())); _input.SetInputCommand(ContentKeyFunctions.OpenTileSpawnWindow, - InputCmdHandler.FromDelegate(_ => TileSpawningController.ToggleWindow())); + InputCmdHandler.FromDelegate(_ => + { + if (!_admin.CanAdminPlace()) + return; + TileSpawningController.ToggleWindow(); + })); _input.SetInputCommand(ContentKeyFunctions.OpenDecalSpawnWindow, - InputCmdHandler.FromDelegate(_ => DecalPlacerController.ToggleWindow())); + InputCmdHandler.FromDelegate(_ => + { + if (!_admin.CanAdminPlace()) + return; + DecalPlacerController.ToggleWindow(); + })); CommandBinds.Builder .Bind(ContentKeyFunctions.EditorCopyObject, new PointerInputCmdHandler(Copy)) From 321df5db54a99ae7f30fd257bf753b67deccb269 Mon Sep 17 00:00:00 2001 From: potato1234_x <79580518+potato1234x@users.noreply.github.com> Date: Sat, 10 Feb 2024 18:21:44 +1000 Subject: [PATCH 024/200] Laughin' Peas (#25089) * laughter * make clownmobs bleed laughter * laughin syrup and laughter recipe * add laughin peas (cherry picked from commit 667cebef52ae656760f806edbd4c550996d3dd6d) --- Resources/Locale/en-US/reagents/laughter.ftl | 1 + .../meta/consumable/food/condiments.ftl | 3 ++ Resources/Locale/en-US/reagents/meta/fun.ftl | 4 ++ .../en-US/reagents/meta/physical-desc.ftl | 1 + Resources/Locale/en-US/seeds/seeds.ftl | 2 + .../Prototypes/Entities/Mobs/NPCs/animals.yml | 3 ++ .../Entities/Mobs/NPCs/behonker.yml | 3 ++ .../Objects/Consumable/Food/produce.yml | 30 +++++++++++++++ .../Objects/Specific/Hydroponics/seeds.yml | 11 ++++++ Resources/Prototypes/Hydroponics/seeds.yml | 35 ++++++++++++++++++ .../Reagents/Consumable/Food/condiments.yml | 10 +++++ Resources/Prototypes/Reagents/fun.yml | 21 +++++++++++ .../Prototypes/Recipes/Reactions/fun.yml | 10 +++++ .../Hydroponics/laughin_pea.rsi/dead.png | Bin 0 -> 250 bytes .../Hydroponics/laughin_pea.rsi/harvest.png | Bin 0 -> 410 bytes .../Hydroponics/laughin_pea.rsi/meta.json | 32 ++++++++++++++++ .../Hydroponics/laughin_pea.rsi/produce.png | Bin 0 -> 344 bytes .../Hydroponics/laughin_pea.rsi/seed.png | Bin 0 -> 300 bytes .../Hydroponics/laughin_pea.rsi/stage-1.png | Bin 0 -> 266 bytes .../Hydroponics/laughin_pea.rsi/stage-2.png | Bin 0 -> 297 bytes .../Hydroponics/laughin_pea.rsi/stage-3.png | Bin 0 -> 364 bytes 21 files changed, 166 insertions(+) create mode 100644 Resources/Locale/en-US/reagents/laughter.ftl create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/dead.png create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/harvest.png create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/meta.json create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/produce.png create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/seed.png create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/stage-1.png create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/stage-2.png create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/stage-3.png diff --git a/Resources/Locale/en-US/reagents/laughter.ftl b/Resources/Locale/en-US/reagents/laughter.ftl new file mode 100644 index 00000000000..b9f7c583cdd --- /dev/null +++ b/Resources/Locale/en-US/reagents/laughter.ftl @@ -0,0 +1 @@ +laughter-effect-control-laughter = You can't contain your laughter! diff --git a/Resources/Locale/en-US/reagents/meta/consumable/food/condiments.ftl b/Resources/Locale/en-US/reagents/meta/consumable/food/condiments.ftl index a448b45a10f..38cd16b01c7 100644 --- a/Resources/Locale/en-US/reagents/meta/consumable/food/condiments.ftl +++ b/Resources/Locale/en-US/reagents/meta/consumable/food/condiments.ftl @@ -22,6 +22,9 @@ reagent-desc-ketchup = Made from pureed tomatoes and flavored with spices. reagent-name-ketchunaise = ketchunaise reagent-desc-ketchunaise = So-called Russian dressing, popular among Space Americans. +reagent-name-laughin-syrup = laughin' syrup +reagent-desc-laughin-syrup = The product of juicing Laughin' Peas. Fizzy, and seems to change flavour based on what it's used with! + reagent-name-mayo = mayonnaise reagent-desc-mayo = Creamy sauce, made from oil, egg, and some (edible) acid. diff --git a/Resources/Locale/en-US/reagents/meta/fun.ftl b/Resources/Locale/en-US/reagents/meta/fun.ftl index 510d9d084aa..68de618a365 100644 --- a/Resources/Locale/en-US/reagents/meta/fun.ftl +++ b/Resources/Locale/en-US/reagents/meta/fun.ftl @@ -21,3 +21,7 @@ reagent-desc-razorium = A strange, non-newtonian chemical. It is produced when t reagent-name-fresium = Fresium reagent-desc-fresium = A mysterious compound that slows the vibration of atoms and molecules... somehow. In layman's terms, it makes things cold... REALLY cold. Can cause long-lasting movement issues if ingested. + +reagent-name-laughter = Laughter +reagent-desc-laughter = Some say that this is the best medicine, but recent studies have proven that to be untrue. + diff --git a/Resources/Locale/en-US/reagents/meta/physical-desc.ftl b/Resources/Locale/en-US/reagents/meta/physical-desc.ftl index 381dece90f9..88ec3c47266 100644 --- a/Resources/Locale/en-US/reagents/meta/physical-desc.ftl +++ b/Resources/Locale/en-US/reagents/meta/physical-desc.ftl @@ -93,6 +93,7 @@ reagent-physical-desc-energizing = energizing reagent-physical-desc-exhilarating = exhilarating reagent-physical-desc-vibrant = vibrant reagent-physical-desc-fluffy = fluffy +reagent-physical-desc-funny = funny reagent-physical-desc-alkaline = alkaline reagent-physical-desc-reflective = reflective reagent-physical-desc-holy = holy diff --git a/Resources/Locale/en-US/seeds/seeds.ftl b/Resources/Locale/en-US/seeds/seeds.ftl index f4c136e2952..dca67fa04c4 100644 --- a/Resources/Locale/en-US/seeds/seeds.ftl +++ b/Resources/Locale/en-US/seeds/seeds.ftl @@ -71,6 +71,8 @@ seeds-poppy-name = poppy seeds-poppy-display-name = poppies seeds-aloe-name = aloe seeds-aloe-display-name = aloe +seeds-laughin-pea-name = laughin' peas +seeds-laughin-pea-display-name = laughin' peas seeds-lingzhi-name = lingzhi seeds-lingzhi-display-name = lingzhi seeds-ambrosiavulgaris-name = ambrosia vulgaris diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 3fde1d6ddf6..a343f63ba58 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -2236,6 +2236,9 @@ collection: FootstepClownFast - type: Speech speechVerb: Cluwne + - type: Bloodstream + bloodMaxVolume: 150 + bloodReagent: Laughter - type: entity name: possum diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml b/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml index 3b3b9b44120..bc63deeac36 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml @@ -112,6 +112,9 @@ Radiation: 10 - type: Input context: "human" + - type: Bloodstream + bloodMaxVolume: 300 + bloodReagent: Laughter - type: entity name: behonker diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml index 5d1a3afbec2..96afd850536 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml @@ -95,6 +95,36 @@ - type: Produce seedId: sugarcane +- type: entity + parent: FoodProduceBase + id: FoodLaughinPeaPod + name: laughin' pea pod + description: The clown's favorite plant. + components: + - type: FlavorProfile + flavors: + - peas + - type: SolutionContainerManager + solutions: + food: + maxVol: 7 + reagents: + - ReagentId: Nutriment + Quantity: 3 + - ReagentId: Sugar + Quantity: 2 + - ReagentId: Laughter + Quantity: 2 + - type: Extractable + juiceSolution: + reagents: + - ReagentId: LaughinSyrup + Quantity: 5 + - type: Sprite + sprite: Objects/Specific/Hydroponics/laughin_pea.rsi + - type: Produce + seedId: laughinPea + - type: entity name: tower-cap log description: It's better than bad, it's good! diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml index 2bbb720259d..affdc79defa 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml @@ -82,6 +82,17 @@ - type: Sprite sprite: Objects/Specific/Hydroponics/garlic.rsi +- type: entity + parent: SeedBase + id: LaughinPeaSeeds + name: packet of laughin' pea pods + description: "These seeds give off a very soft purple glow.. they should grow into Laughin' Peas." + components: + - type: Seed + seedId: laughinPea + - type: Sprite + sprite: Objects/Specific/Hydroponics/laughin_pea.rsi + - type: entity parent: SeedBase name: packet of lemon seeds diff --git a/Resources/Prototypes/Hydroponics/seeds.yml b/Resources/Prototypes/Hydroponics/seeds.yml index 7c94546602c..649ffa85224 100644 --- a/Resources/Prototypes/Hydroponics/seeds.yml +++ b/Resources/Prototypes/Hydroponics/seeds.yml @@ -136,6 +136,39 @@ Max: 4 PotencyDivisor: 25 +- type: seed + id: laughinPea + name: seeds-laughin-pea-name + noun: seeds-noun-seeds + displayName: seeds-laughin-pea-display-name + plantRsi: Objects/Specific/Hydroponics/laughin_pea.rsi + packetPrototype: LaughinPeaSeeds + productPrototypes: + - FoodLaughinPeaPod + lifespan: 25 + growthStages: 3 + maturation: 8 + production: 6 + yield: 3 + potency: 25 + idealLight: 8 + harvestRepeat: Repeat + nutrientConsumption: 0.6 + waterConsumption: 0.6 + chemicals: + Nutriment: + Min: 1 + Max: 3 + PotencyDivisor: 33 + Sugar: + Min: 1 + Max: 5 + PotencyDivisor: 50 + Laughter: + Min: 1 + Max: 5 + PotencyDivisor: 50 + - type: seed id: lemon name: seeds-lemon-name @@ -1344,6 +1377,8 @@ packetPrototype: PeaSeeds productPrototypes: - FoodPeaPod + mutationPrototypes: + - laughinPea lifespan: 25 growthStages: 3 maturation: 8 diff --git a/Resources/Prototypes/Reagents/Consumable/Food/condiments.yml b/Resources/Prototypes/Reagents/Consumable/Food/condiments.yml index f980f5066aa..8fbfd3cd64b 100644 --- a/Resources/Prototypes/Reagents/Consumable/Food/condiments.yml +++ b/Resources/Prototypes/Reagents/Consumable/Food/condiments.yml @@ -77,6 +77,16 @@ color: "#fba399" recognizable: true +- type: reagent + id: LaughinSyrup + name: reagent-name-laughin-syrup + group: Foods + desc: reagent-desc-laughin-syrup + physicalDesc: reagent-physical-desc-funny + flavor: sweet + color: "#803280" + recognizable: true + - type: reagent id: Mayo name: reagent-name-mayo diff --git a/Resources/Prototypes/Reagents/fun.yml b/Resources/Prototypes/Reagents/fun.yml index d22e2213ace..25b0e8da809 100644 --- a/Resources/Prototypes/Reagents/fun.yml +++ b/Resources/Prototypes/Reagents/fun.yml @@ -298,3 +298,24 @@ messages: [ "fresium-effect-frozen"] probability: 0.4 +- type: reagent + id: Laughter + name: reagent-name-laughter + group: Special + desc: reagent-desc-laughter + physicalDesc: reagent-physical-desc-funny + flavor: funny + color: "#FF4DD2" + slippery: true #clown juice gotta slip + metabolisms: + Medicine: + effects: + - !type:Emote + emote: Laugh + probability: 0.3 + - !type:PopupMessage + type: Local + visualType: Large + messages: [ "laughter-effect-control-laughter" ] + probability: 0.2 + diff --git a/Resources/Prototypes/Recipes/Reactions/fun.yml b/Resources/Prototypes/Recipes/Reactions/fun.yml index 818030a3b33..a8ccd5f0455 100644 --- a/Resources/Prototypes/Recipes/Reactions/fun.yml +++ b/Resources/Prototypes/Recipes/Reactions/fun.yml @@ -161,3 +161,13 @@ Carbon: 3 Sugar: 2 +- type: reaction + id: Laughter + reactants: + JuiceBanana: + amount: 1 + Sugar: + amount: 1 + products: + Laughter: 2 + diff --git a/Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/dead.png b/Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/dead.png new file mode 100644 index 0000000000000000000000000000000000000000..ded6b2eb7733d1c1a650240da8cf45fdaac6ccc0 GIT binary patch literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCim11AIbUYg779t-rf!_SVVui-2N_KOUa~q*zOW{DS`j0mJWYe8E5g&H|6f zVg?4j!ywFfJby(BP%zok#WBRf|7~9&-vI>FO~98H1NF?hQAxvX&;$;@*MnM_kW7--#tnHFKJ)=5%K+n^Ydl;{}1N5ShRK6Sia5gxYYAJYSs9m-s5 z^DH0rGR#|c_uxm{!h=lZKN=>bg{h_gV#s0CZMeY9AQ!gwYRn0S`-i4{-0*5KZ-*c& z?}|C4ZmXanMpx|6j7sn6_|ECwc z#SSU(uwIzqkg@em{qAKmX7S6&T7K$X5F;n@BK}i8L!On#Mz#pyau&XcQ<)tcSXOM- zW=rW6_`HiTQs2X>aA(7twM?u0bl>q!mF(`*m78)bZx!c)ExD^cM3?2+#2#u+b!7?q z$f=_(G@L XLIb{K^DV`J4rTCk^>bP0l+XkKgjI;8 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/seed.png b/Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/seed.png new file mode 100644 index 0000000000000000000000000000000000000000..a4ad791bb1a13aa17e829660ea81face1099de69 GIT binary patch literal 300 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCik70(?ST=P}IMtG44>?8V#lH#W(xyQTT*y3Ct@i~jxJ@PC!eoA1-U0~Ov; z;hh4ccuIo&g8w4`gV6nR=YZmz1s;*b3=DjSL74G){)!Z!V5O&vV~Bw gaCi6LhNUG;Om(UUZy$PjALs}MPgg&ebxsLQ0LBe>{{R30 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/stage-1.png b/Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/stage-1.png new file mode 100644 index 0000000000000000000000000000000000000000..1c710f40db2fb3062341f07ac7eaa10668bc606f GIT binary patch literal 266 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCilo1AIbU>&;#*)B9hh^JuNz|NjjC92pj#Q$HKZb6}y<^ES1!w@hws;ol5Y z%UoG(2&8yRg8YL2BLN267fNkF3C;qK$YKTtzQZ8Qcszea3Q#cE)5S5w!vAfbuT+Bq zhs)M8`*-}W^QVQ9p0-1U4t2@eH1>elF{r5}E+ur(+8M literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/stage-2.png b/Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/stage-2.png new file mode 100644 index 0000000000000000000000000000000000000000..157a081b35d7131100b5347291ed80199402f74d GIT binary patch literal 297 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCik70(?ST_ayyqv;CN*aBaQI|1zCNFN~i3Px@DH_Uf$I>4i?uZz^5~Dr7J} zdIw1Ilmz(&|3?4@q5J2~0mV5BJR*x382Ao@Fyrz36)8Z$GEW!B5DWjeecpTx3Op{X zPj3IdfBh2Q)=tB`*biboTh4Q`*KS~a8s22g928M}Uu5E;D3v7w8WG$q@dthj$M@t2 zaTP5)B&cz(?cXUj?LB9TmPVLLRyX%_ab2~&%wj1m^=k3LWTt}~rB<9z-l8bp&Y7Q+ c=v2bE^qJP}-+yj60bRi0>FVdQ&MBb@0OLt>L;wH) literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/stage-3.png b/Resources/Textures/Objects/Specific/Hydroponics/laughin_pea.rsi/stage-3.png new file mode 100644 index 0000000000000000000000000000000000000000..311098b975ae4171a9e42c3e426a762dc137a72c GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCikd1AIbU>&;&Mulv6z>Hm+2@0YYMzA$>0rEqP%%l|gpk7YWK{wMuAD|ULJ z)AO5(*MT}}POa|*Qv4-Be!>4y0K=6#GZq4+I14-?iy0XB4ude`@%$AjK*6=1E{-7< z{%W!LY$)vbwp}?nS>E=A^o31*si8?ZD7@QhUjo`~|B-ts5KC%XkkwdMNxXzVyMD tHwP9q&XZdAc+=TMmam)tHF!N?TlmLBeO Date: Sat, 10 Feb 2024 08:22:50 +0000 Subject: [PATCH 025/200] Automatic changelog update (cherry picked from commit 83be2131a031ae4bd15781e7e65c5be957e2fdae) --- 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 fda038261f6..55cb9d072e5 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: TheShuEd - changes: - - message: Changed hypodart cost from 3 to 2 tc - type: Tweak - id: 5407 - time: '2023-12-17T16:08:11.0000000+00:00' - url: null - author: yathxyz changes: - message: Fixed nix devShell @@ -3884,3 +3877,11 @@ Order: 1 id: 5906 time: '2024-02-10T02:06:02.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25088 +- author: Potato1234_x + changes: + - message: Added laughin' peas, a new mutation for peas that can be ground into + Laughter, a chem that forces people to laugh. + type: Add + id: 5907 + time: '2024-02-10T08:21:44.0000000+00:00' + url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25089 From 6ef8f014f43f233f227d37719aec07224191fd32 Mon Sep 17 00:00:00 2001 From: Hanz <41141796+Hanzdegloker@users.noreply.github.com> Date: Sat, 10 Feb 2024 03:41:54 -0500 Subject: [PATCH 026/200] QM drip DLC (#24477) * New Drip for the QM QM beret and QM formal uniform * Asd Asd * Adds the new clothing to the uniform printer what it says on the tin * I always forget to update the copyright RAAAAAH yup (cherry picked from commit 400036b9624620900012e891b230ab6029d9bc22) --- .../Catalog/Fills/Lockers/dressers.yml | 2 ++ .../Entities/Clothing/Head/hats.yml | 16 ++++++++++ .../Entities/Clothing/Uniforms/jumpsuits.yml | 13 +++++++- .../Entities/Structures/Machines/lathe.yml | 2 ++ .../Prototypes/Recipes/Lathes/clothing.yml | 15 +++++++++ .../beret_qm.rsi/equipped-HELMET-hamster.png | Bin 0 -> 886 bytes .../Hats/beret_qm.rsi/equipped-HELMET.png | Bin 0 -> 853 bytes .../Clothing/Head/Hats/beret_qm.rsi/icon.png | Bin 0 -> 741 bytes .../Head/Hats/beret_qm.rsi/inhand-left.png | Bin 0 -> 811 bytes .../Head/Hats/beret_qm.rsi/inhand-right.png | Bin 0 -> 801 bytes .../Clothing/Head/Hats/beret_qm.rsi/meta.json | 30 ++++++++++++++++++ .../qmformal.rsi/equipped-INNERCLOTHING.png | Bin 0 -> 1838 bytes .../Uniforms/Jumpsuit/qmformal.rsi/icon.png | Bin 0 -> 920 bytes .../Jumpsuit/qmformal.rsi/inhand-left.png | Bin 0 -> 1065 bytes .../Jumpsuit/qmformal.rsi/inhand-right.png | Bin 0 -> 1094 bytes .../Uniforms/Jumpsuit/qmformal.rsi/meta.json | 26 +++++++++++++++ 16 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/equipped-HELMET-hamster.png create mode 100644 Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/equipped-HELMET.png create mode 100644 Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/icon.png create mode 100644 Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/inhand-left.png create mode 100644 Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/inhand-right.png create mode 100644 Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/meta.json create mode 100644 Resources/Textures/Clothing/Uniforms/Jumpsuit/qmformal.rsi/equipped-INNERCLOTHING.png create mode 100644 Resources/Textures/Clothing/Uniforms/Jumpsuit/qmformal.rsi/icon.png create mode 100644 Resources/Textures/Clothing/Uniforms/Jumpsuit/qmformal.rsi/inhand-left.png create mode 100644 Resources/Textures/Clothing/Uniforms/Jumpsuit/qmformal.rsi/inhand-right.png create mode 100644 Resources/Textures/Clothing/Uniforms/Jumpsuit/qmformal.rsi/meta.json diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml b/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml index 7a6ed2d3b13..e0abc204c15 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/dressers.yml @@ -77,6 +77,8 @@ contents: - id: ClothingNeckCloakQm - id: ClothingHeadsetCargo + - id: ClothingHeadHatBeretQM + - id: ClothingUniformJumpsuitQMFormal - id: ClothingUniformJumpsuitQMTurtleneck - id: ClothingUniformJumpskirtQMTurtleneck - id: ClothingHandsGlovesColorBrown diff --git a/Resources/Prototypes/Entities/Clothing/Head/hats.yml b/Resources/Prototypes/Entities/Clothing/Head/hats.yml index c74d82411a2..f4045a75ea2 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hats.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hats.yml @@ -84,6 +84,22 @@ - HamsterWearable - WhitelistChameleon +- type: entity + parent: ClothingHeadBase + id: ClothingHeadHatBeretQM + name: quartermaster's beret + description: A beret with the cargo's insignia emblazoned on it. For quartermasters that are more inclined towards style. + components: + - type: Sprite + sprite: Clothing/Head/Hats/beret_qm.rsi + - type: Clothing + sprite: Clothing/Head/Hats/beret_qm.rsi + - type: Tag + tags: + - ClothMade + - HamsterWearable + - WhitelistChameleon + - type: entity parent: ClothingHeadBase id: ClothingHeadHatBeretHoS diff --git a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml index 46827f8b606..df51b6438d1 100644 --- a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml @@ -493,6 +493,17 @@ - type: Clothing sprite: Clothing/Uniforms/Jumpsuit/qmturtle.rsi +- type: entity + parent: ClothingUniformBase + id: ClothingUniformJumpsuitQMFormal + name: quartermasters's formal suit + description: Inspired by the quartermasters of military's past, the perfect outfit for supplying a formal occasion. + components: + - type: Sprite + sprite: Clothing/Uniforms/Jumpsuit/qmformal.rsi + - type: Clothing + sprite: Clothing/Uniforms/Jumpsuit/qmformal.rsi + - type: entity parent: ClothingUniformBase id: ClothingUniformJumpsuitResearchDirector @@ -1447,4 +1458,4 @@ - type: Sprite sprite: Clothing/Uniforms/Jumpsuit/familiar_garbs.rsi - type: Clothing - sprite: Clothing/Uniforms/Jumpsuit/familiar_garbs.rsi \ No newline at end of file + sprite: Clothing/Uniforms/Jumpsuit/familiar_garbs.rsi diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index f251f158b80..1b17954f3d8 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -988,10 +988,12 @@ - ClothingUniformJumpsuitPrisoner - ClothingUniformJumpskirtPrisoner - ClothingHeadHatQMsoft + - ClothingHeadHatBeretQM - ClothingUniformJumpsuitQM - ClothingUniformJumpskirtQM - ClothingUniformJumpsuitQMTurtleneck - ClothingUniformJumpskirtQMTurtleneck + - ClothingUniformJumpsuitQMFormal - ClothingHeadHatBeretRND - ClothingUniformJumpsuitResearchDirector - ClothingUniformJumpskirtResearchDirector diff --git a/Resources/Prototypes/Recipes/Lathes/clothing.yml b/Resources/Prototypes/Recipes/Lathes/clothing.yml index 566e33e3f31..b1d14dbe6c1 100644 --- a/Resources/Prototypes/Recipes/Lathes/clothing.yml +++ b/Resources/Prototypes/Recipes/Lathes/clothing.yml @@ -474,6 +474,13 @@ materials: Cloth: 300 +- type: latheRecipe + id: ClothingUniformJumpsuitQMFormal + result: ClothingUniformJumpsuitQMFormal + completetime: 4 + materials: + Cloth: 300 + - type: latheRecipe id: ClothingUniformJumpskirtQM result: ClothingUniformJumpskirtQM @@ -979,6 +986,14 @@ Cloth: 100 Durathread: 50 +- type: latheRecipe + id: ClothingHeadHatBeretQM + result: ClothingHeadHatBeretQM + completetime: 2 + materials: + Cloth: 100 + Durathread: 50 + - type: latheRecipe id: ClothingHeadHatBeretCmo result: ClothingHeadHatBeretCmo diff --git a/Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/equipped-HELMET-hamster.png b/Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/equipped-HELMET-hamster.png new file mode 100644 index 0000000000000000000000000000000000000000..c9197282c651bf6e7c3deb42a8e1c579cc377c11 GIT binary patch literal 886 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 XOU`AZv&xP;00000NkvXXu0mjfm`FP2 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..4c59df75503d8937fd3484c6901ee5d7f3642f40 GIT binary patch literal 811 zcmV+`1JwM9P)EX>4Tx04R}tkv&MmP!xqv(@I4u4t6NwkfAzR5EXHhRxE;r(pG5I!Q`cX(4-+r zad8w}3l9D)RvlcNb#-tR1i>E=X9p)m7b)?+q|hS93y=44-aUu+?gNBYjj3i}5>PeE z$Ry)pzOX6=U*SUp0s?@^gBRMb|oT&FdPB$kju8X{ygP(=+EVzg_dn8?t1+`~WO_|xQ)$yEg- z#{%k5Avu2VKlnXcvot;BCWYca--~U3i~+%2pxw0X?_=9;p8)=6;7aTI>n&jJlk{d+ ziyi?(+rY(jSCjXE%N-!{q)Ue6NPb#EsRX>A(Ki)<;agx}&7E849H$RJj%Kxd0~{Oz z<7LWT_jq@I@7(_F>CEp3;s|nWBjXb-00006VoOIv0O|nh0P25@IuQT>010qNS#tmY z4#NNd4#NS*Z>VGd000McNliru=m8i55ec?UKw^n87$oAP~T2+jJs{-6l*CYX5-UzJ1k2Zfw- zQ`hevo?6{2OB3I$l_YDeoO7-F{JJbn{ORGo&(g$)=)bYP=C$ZT4G#bS000000001V zXJUHT`rg3UPxcR@4B+eD!RQxyo8Rt#B7i*4{YP;%8N9Ab2sV}gPL7YJb`E-*t8?ia pO#t6)hfKZ))!|<$002ovPDHLkV1kFKWKRG9 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..1f8ff310244f2e5b77e1cc6bc3daf6b5625cde53 GIT binary patch literal 801 zcmV++1K#|JP)EX>4Tx04R}tkv&MmP!xqv(@I4u4t6NwkfAzR5EXHhRxE;r(pG5I!Q`cX(4-+r zad8w}3l9D)RvlcNb#-tR1i>E=X9p)m7b)?+q|hS93y=44-aUu+?gNBYjj3i}5>PeE z$Ry)pzOX6=U*SUp0s?@^gBRMb|oT&FdPB$kju8X{ygP(=+EVzg_dn8?t1+`~WO_|xQ)$yEg- z#{%k5Avu2VKlnXcvot;BCWYca--~U3i~+%2pxw0X?_=9;p8)=6;7aTI>n&jJlk{d+ ziyi?(+rY(jSCjXE%N-!{q)Ue6NPb#EsRX>A(Ki)<;agx}&7E849H$RJj%Kxd0~{Oz z<7LWT_jq@I@7(_F>CEp3;s|nWBjXb-00006VoOIv0O|nh0P25@IuQT>010qNS#tmY z4#NNd4#NS*Z>VGd000McNliru=m8i55f(c|O_u-w0Uk+2K~#9!?b@ME13?hR@$Zt+ zya5hdajCde912kfs=@FKybUjaC=!W4fuI!xQCW2%P1Bl7(3>oRkX$#ngro>|`~RuS z=H@ap+3blO2><{9007{?6n%@A7i0hZe0Tp)q*hcn|J8b<=lNT-2I~txKRxNJe0?mH zMuhpd&5cx6M}5*;3BAofltT z7fI}Zx+;B`yCj*JoOAIy>Z6pq_Iz_3HDdThxhSWH()dzLrMU*FtgqX3`sxE<79ORhO-2z f6%GIZaPU3>d{c5iD6v}u00000NkvXXu0mjfP&-@5 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/meta.json b/Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/meta.json new file mode 100644 index 00000000000..8591b0feabb --- /dev/null +++ b/Resources/Textures/Clothing/Head/Hats/beret_qm.rsi/meta.json @@ -0,0 +1,30 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/4f6190e2895e09116663ef282d3ce1d8b35c032e, recoloured by Hanzdegloker", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-HELMET", + "directions": 4 + }, + { + "name": "equipped-HELMET-hamster", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/qmformal.rsi/equipped-INNERCLOTHING.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/qmformal.rsi/equipped-INNERCLOTHING.png new file mode 100644 index 0000000000000000000000000000000000000000..3fa68c11d463df44934bca0056f62a3e470eb772 GIT binary patch literal 1838 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/qmformal.rsi/inhand-left.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/qmformal.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..e5c39a74eb8cb344cddcc7888447d2cd61c250c5 GIT binary patch literal 1065 zcmV+^1lIeBP)EX>4Tx04R}tkv&MmP!xqv(@I4u4t6NwkfAzR5EXHhRxE;r(pG5I!Q`cX(4-+r zad8w}3l9D)RvlcNb#-tR1i>E=X9p)m7b)?+q|hS93y=44-aUu+?gNBYjj3i}5>PeE z$Ry)pzOX6=U*SUp0s?@^gBRMb|oT&FdPB$kju8X{ygP(=+EVzg_dn8?t1+`~WO_|xQ)$yEg- z#{%k5Avu2VKlnXcvot;BCWYca--~U3i~+%2pxw0X?_=9;p8)=6;7aTI>n&jJlk{d+ ziyi?(+rY(jSCjXE%N-!{q)Ue6NPb#EsRX>A(Ki)<;agx}&7E849H$RJj%Kxd0~{Oz z<7LWT_jq@I@7(_F>CEp3;s|nWBjXb-00006VoOIv0O|nh0P25@IuQT>010qNS#tmY z4#NNd4#NS*Z>VGd000McNliru=m8i58zp{v#0vlb0wzgBK~#9!?U_Gl6Hy$;zb~c` zN&?qE2ToGZp<^-NC;?~d)Jdfjad0eXheA6vL!k~GLUAY#MV&fHOABHl6gntqvlOIQ z5GUc~&nqb*VB2$$J8~*Y$;w#m ze>ejGXkVRY;zBY<%dzp-`CfX&0|?pua1tH&jm<-AjlQw@ zKh8^dL<3maJXH0DL95yZ0DP}3#Ku;&je5giW%E!;coMk+Ith2IbLW!uhz8KAwqrXN z?qwWKpr&05z;=O}a_P_aqCj;j zfL;`+DL9DD0@b+yY!|3bUICqSTcA1}fQ`$2VkQ>bvghW1*($) j*ep<;EE!p#5@L-XKi}0IK{O3r00000NkvXXu0mjfjVRcA literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/qmformal.rsi/inhand-right.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/qmformal.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..014ac5f9ec6d68f6104a4fdd1db8816aa7b314fb GIT binary patch literal 1094 zcmV-M1iAZ(P)EX>4Tx04R}tkv&MmP!xqv(@I4u4t6NwkfAzR5EXHhRxE;r(pG5I!Q`cX(4-+r zad8w}3l9D)RvlcNb#-tR1i>E=X9p)m7b)?+q|hS93y=44-aUu+?gNBYjj3i}5>PeE z$Ry)pzOX6=U*SUp0s?@^gBRMb|oT&FdPB$kju8X{ygP(=+EVzg_dn8?t1+`~WO_|xQ)$yEg- z#{%k5Avu2VKlnXcvot;BCWYca--~U3i~+%2pxw0X?_=9;p8)=6;7aTI>n&jJlk{d+ ziyi?(+rY(jSCjXE%N-!{q)Ue6NPb#EsRX>A(Ki)<;agx}&7E849H$RJj%Kxd0~{Oz z<7LWT_jq@I@7(_F>CEp3;s|nWBjXb-00006VoOIv0RI600RN!9r;`8x010qNS#tmY z4#NNd4#NS*Z>VGd000McNliru=m8i593Vkarb7S#0z*keK~#9!?U_Gl6Hy$;zb~c` zN&?qE2ToGZ!Lb-{lz_8!a#E2Z4vqzN5bR(EL5B{ZI24DXPEKNJp|lW$4hq^V1t}K9 zNqA{;5(xpd=OB0H(wO9OPkg`f{VXqcmwSBQC%HS4FF*((gb+dqA%qY@{!lKL{a)Kg zA+ze-v9$2WKYr>oa=9EfpWMNTGna7j@-@7CzKqZBU*P=phiEh!`10`sZp__QHY_?x z=5*&|mCYsO_tH3U9GuH%0j$AwZ(&NUVJe@+*NwZ__dHZS{jla!Pm(#+zH#sB*<%1O z;W!wb%m4sdC+8yL=wt>Hj$_T@lV*+xC_a7rGdLk2v$qf#JCFZwl4eeI+xhz4xA67I z^gOiI7@3~$dfXO<&3s6};>xb7)jc$;Edapx%KgaLthP|AdstlARkkcXN#<0)$pee+ zHf<+P=AHtY)mFr2V7ToWo3(B6aWnr_z`o~&cT(4N!#irQ9{>u4f>k$zVKVo<1PQ}5lR4GT=uB}705DVBikP&OxS4wjm@Vxu zp;q^>y;=$<93OM6Tllb^Fc`u@+OIu`JnXe1teDHMg>T$%#8{NkXV@;6CklNH~tN1M`C4e zOn}77+?W7~mH9up1SD4G#so;L%#8|=SeY9UAh9wx_G1WO{d{Ek1vyC79aFXJ9{>OV M07*qoM6N<$f@3-Iu>b%7 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/qmformal.rsi/meta.json b/Resources/Textures/Clothing/Uniforms/Jumpsuit/qmformal.rsi/meta.json new file mode 100644 index 00000000000..7f5c61326f2 --- /dev/null +++ b/Resources/Textures/Clothing/Uniforms/Jumpsuit/qmformal.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Spritework done by Hanzdegloker", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-INNERCLOTHING", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} From 33a715c9cb237c2f581106c4705f02d1c6e1011b Mon Sep 17 00:00:00 2001 From: Ubaser <134914314+ubaserb@users.noreply.github.com> Date: Sat, 10 Feb 2024 09:42:55 +0100 Subject: [PATCH 027/200] EMT Belt Part 2 (#24289) * add * fix * aaaa (cherry picked from commit b07e8abedbf886aebad52d6fb66048cbac1bf3dc) --- .../Prototypes/Catalog/Fills/Items/belt.yml | 5 ++-- .../Entities/Clothing/Belt/belts.yml | 11 ++++++++ .../Roles/Jobs/Medical/paramedic.yml | 2 +- .../Clothing/Belt/emt.rsi/equipped-BELT.png | Bin 0 -> 1479 bytes .../Textures/Clothing/Belt/emt.rsi/icon.png | Bin 0 -> 1464 bytes .../Clothing/Belt/emt.rsi/inhand-left.png | Bin 0 -> 1504 bytes .../Clothing/Belt/emt.rsi/inhand-right.png | Bin 0 -> 1485 bytes .../Textures/Clothing/Belt/emt.rsi/meta.json | 26 ++++++++++++++++++ 8 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 Resources/Textures/Clothing/Belt/emt.rsi/equipped-BELT.png create mode 100644 Resources/Textures/Clothing/Belt/emt.rsi/icon.png create mode 100644 Resources/Textures/Clothing/Belt/emt.rsi/inhand-left.png create mode 100644 Resources/Textures/Clothing/Belt/emt.rsi/inhand-right.png create mode 100644 Resources/Textures/Clothing/Belt/emt.rsi/meta.json diff --git a/Resources/Prototypes/Catalog/Fills/Items/belt.yml b/Resources/Prototypes/Catalog/Fills/Items/belt.yml index 8a27e36f08b..976d2a4307f 100644 --- a/Resources/Prototypes/Catalog/Fills/Items/belt.yml +++ b/Resources/Prototypes/Catalog/Fills/Items/belt.yml @@ -84,9 +84,8 @@ - id: EmergencyMedipen #You never know what people are going to latejoin into - type: entity - id: ClothingBeltParamedicFilled - parent: ClothingBeltMedical #in the future, make this a seperate prototype so it can have a unique, darker sprite - name: EMT belt + id: ClothingBeltMedicalEMTFilled + parent: ClothingBeltMedicalEMT suffix: Paramedic,Filled components: - type: StorageFill diff --git a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml index de6c7754695..0effc02da61 100644 --- a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml +++ b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml @@ -303,6 +303,17 @@ sprite: Clothing/Belt/belt_overlay.rsi - type: Appearance +- type: entity + parent: ClothingBeltMedical + id: ClothingBeltMedicalEMT + name: EMT belt + description: Perfect for holding various equipment for medical emergencies. + components: + - type: Sprite + sprite: Clothing/Belt/emt.rsi + - type: Clothing + sprite: Clothing/Belt/emt.rsi + - type: entity parent: ClothingBeltStorageBase id: ClothingBeltPlant diff --git a/Resources/Prototypes/Roles/Jobs/Medical/paramedic.yml b/Resources/Prototypes/Roles/Jobs/Medical/paramedic.yml index 84d1cf76be9..e4ae7a7dd50 100644 --- a/Resources/Prototypes/Roles/Jobs/Medical/paramedic.yml +++ b/Resources/Prototypes/Roles/Jobs/Medical/paramedic.yml @@ -32,7 +32,7 @@ shoes: ClothingShoesColorBlue id: ParamedicPDA ears: ClothingHeadsetMedical - belt: ClothingBeltParamedicFilled + belt: ClothingBeltMedicalEMTFilled pocket1: HandheldGPSBasic # DeltaV - Give Paramedics useful tools on spawn pocket2: HandheldCrewMonitor # DeltaV - Give Paramedics useful tools on spawn innerClothingSkirt: ClothingUniformJumpskirtParamedic diff --git a/Resources/Textures/Clothing/Belt/emt.rsi/equipped-BELT.png b/Resources/Textures/Clothing/Belt/emt.rsi/equipped-BELT.png new file mode 100644 index 0000000000000000000000000000000000000000..34698f72858fd2d84ea837d5309eccd25602a1b7 GIT binary patch literal 1479 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|_);T0(|mmy zw18|5AO?X;!IOa`XMsm#F$06fED&ZCw^H21z`$IQ84^(v;p=0SoS&h?X&sHg;q@=(~U%$M(T(8_%FTW^V-_X+1Qs2Nx-^fT8s6w~6 zGOr}DLN~8i8Da>`9GBGM~RsBTId_|A5Z7NlCUU$t=l91qU45Kj08_%qc+?1*r!G zK~5$pWUX=%^U`gVDs)p)(-KQ_N|fwU3rjN#3Q|*aom_oFZ1f>YQH_9zqMB@@kHrx- zAg^0R2Bj9~=ahm1-_FR)#0DH7D58jHfar+8ssmXRT}MDhen~zsSrug_d*+p-78Mi$ zlNiKCsC~FqpqquTJTxz}#Lft60Gcq8E~F^3ax5w-&o9aj0Y?W~SmIO%H4751NNE+4 z5x{W(%n5c}Hu~^fWyf`4xiTj(`=0Z3aSW+oe0$5#`*45&`-ko$rp{b*SqcN$uL}jJ z%sq33|G|RQZ^a8%JV@K$r1YX(VEH0%vCJ1i1)>YrrfHZoKTvA?@os9k)2uN08G8Tt zPwg%Dy}xz;Bu)301_l-d21X7C1||Vy=7Ie}1|@ZCU+?m~_jTI!CH-aH7Wd6<*BXC5 zH#>axb^F@A?|(=AJ^Q7-J}Ua2+?k-ez##rxlvf8~osF$C6o6iQ6e+>|IG(q-BnskZZ3Ov;hH*-~GN ztnSQxF2b#m`$q0mbi?MT;@NvAOGn;cfB)G%CDs~I8BR>sV)|i$MdP05pJTlDcfGc= z+<7hQblui&&vW03SBI`;-=ck!S?ulcX~v(o#cBy&U)#LwjIsEiLPa5Cj%_nsA4E1x zI&rgOd*7y|t<|~=cAmCe&%gS;H3>9kDza$o_U5?yIrfbDlKuUUEjZ5$yl4?S@Vvs~ z;pfFR^Pe+U$d_0h3pbfidQV@uNnt{=f!6AId(L0GQhfp`a3ve_rL_CKPo#W(3@SuD MUHx3vIVCg!0Pqm_00000 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Belt/emt.rsi/icon.png b/Resources/Textures/Clothing/Belt/emt.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..80abde938235ef2fc55fbd87317a5ba7d2c0ed94 GIT binary patch literal 1464 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}e5nzhX}-P; zT0k}j5QD&_;K@Lev%n*=n1MlK76>znTPbd0U|>$m42dX-@b$4u&d=3LOvz75)vL%Y z0PC`;umUo3Q%e#RDspr3imfVamB1>jfNYSkzLEl1NlCV?QiN}Sf^&XRs)CuGfu4bq z9hZWFf=y9MnpKdC8&o@xXRDM^Qc_^0uU}qXu2*iXmtT~wZ)j<0sc&GUZ)BtkRH0j3 znOBlnp_^B%3^4>|j!SBBa#3bMNoIbY0?6FNr2NtnTO}osMQ{LdXG${Mo`TY%9I!1Z z$@-}|sky0nCB^!NdWQPg^p#|$AzYYO3=Ixo!03ZyfZ7bOYV#~8Nj3q7lxqdhJy8Dv z9hwZbx40xlA4!3}k%57Qu7Q!Rk)=M|e?aHkq$FFFWR~Qlf&&ijA8-gd=9Hj{g4Bb8 zASV+PvQ{~XdFi%F6}l;@X^EvdB}#Ug$@zIU`VbYUIw7K{2HNOjvD*gZW2?xZ)Z+Y{ zQc#%N8JU^bfWrYr6cPFm9T8Y{Ad8~w2*}7U$p@yUqReE^ypq(Sf+Aqbg4hVP54Q?* zvk;bt=4F=H89@y|6Gqa76f;(iMJ46=McE4Za{fKx?mDMN-05BQ`#aU= zZ1q_hSc@Ah56Jv@&sSh?sxbZZ#0|5&mKv4bU)gYYiOqRurHLP|E_iLVB}(_ZjgQX? z1{HDFi@6c2uim+%?`XsI@@v(F95cshsqynV;wL|>^}W2{Zl3e@+q^l?t^~+*x-I@@ zR9(P%Q^Q~Ge7UXb84K6A_gnuOD|t?;7BT7MUc~t*K*vh3zFNX=)(K|W6FKh~)bBSW zEmN2#reM6^Yn6Yw)wBMj&E{UxEut`x^)AKw3hvfVez^U ze#S&cB`6_-OXvJbKmFgj983~zjD}u+6lHH(9&uAp?sj0Tif!~*ZXDFWQl-uN=-4)0 zkB;+wbCfmPJ{G0==dIG3^1k2py?mi#S<|m5mOrmJH)a^Kdfb=tX_dez8Xf+^aG#6{{(|eO;1-pmvv4FO#lmB B_Nf2> literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Belt/emt.rsi/inhand-left.png b/Resources/Textures/Clothing/Belt/emt.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..460be7e4849882f84461d2158ae8055b0a150de3 GIT binary patch literal 1504 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|_);T0(|mmy zw18|5AO?X;!IOa`XMsm#F$06fED&ZCw^H21z`$IQ84^(v;p=0SoS&h?X&sHg;q@=(~U%$M(T(8_%FTW^V-_X+1Qs2Nx-^fT8s6w~6 zGOr}DLN~8i8Da>`9GBGM~RsBTId_|A5Z7NlCUU$t=l91qU45Kj08_%qc+?1*r!G zK~5$pWUX=%^U`gVDs)p)(-KQ_N|fwU3rjN#3Q|*aom_oFZ1f>YQH_9zqMB@@kHrx- zAg^0R2Bj9~=ahm1-_FR)#0DH7D58jHfar+8ssmXRT}MDhen~zsSrug_d*+p-78Mi$ zlNiKCsC~FqpqquTJTxz}#Lft60Gcq8E~F^3ax5w-&o9aj0Y?W~SmIO%H4751NNE+4 z5x{W(%n5c}Hu~^fWyf`4xiTj(`#$${aSW+oe0$5#`>=xu`-kq5Q1RPd+qxcT_&G+O ze6(c#fygEEJuluo>-m>OtK_n8%pIXyw?YHjH~a4_(yTN&xpzsz|JYf3?(8l9{@VET zN)bDO1_l-d21X7C1}1do1GNh;<6ao>Y>l3_|K^nCw&&C*YU>^kin?HWP2%3pWgchp zxt?#HJe}#ndik5CbJqXPZa-(agJmg$N&EJgy-pvW?apz(*)71H@mBWr_4mG}QJinA z{H|XKlzzO&&vVAfM+_n9SMLX{z015T<)1<6l_K5$dvuJCT;69JS84rve$^MFQ$hBZ zC0;c=e=V$k`N5oKua^yt54;1i*DkrQY1wNagW+BzUmW0kQ?BoAdGO(@oyU%zXWcjN zTShPh7zv(sW7E*A2qzieL`GiS9jmqYH0%6Yre z#g6MP@|g24UZHEzkt;8MA8~%>#&cj#PuA__KAJZTt|x_-#J}=;7C7Sq@1EMZyByRs zt}%vg`TIrAPHN#Id&_2r@7zCUx_{SI`Lh4c7k=f)GH<4zzMvwT!PC{xWt~$(69Ciw B4^;pF literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Belt/emt.rsi/inhand-right.png b/Resources/Textures/Clothing/Belt/emt.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..7222bcf7b3d6be26e976cfd3f243872bbea49d94 GIT binary patch literal 1485 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|_);T0(|mmy zw18|5AO?X;!IOa`XMsm#F$06fED&ZCw^H21z`$IQ84^(v;p=0SoS&h?X&sHg;q@=(~U%$M(T(8_%FTW^V-_X+1Qs2Nx-^fT8s6w~6 zGOr}DLN~8i8Da>`9GBGM~RsBTId_|A5Z7NlCUU$t=l91qU45Kj08_%qc+?1*r!G zK~5$pWUX=%^U`gVDs)p)(-KQ_N|fwU3rjN#3Q|*aom_oFZ1f>YQH_9zqMB@@kHrx- zAg^0R2Bj9~=ahm1-_FR)#0DH7D58jHfar+8ssmXRT}MDhen~zsSrug_d*+p-78Mi$ zlNiKCsC~FqpqquTJTxz}#Lft60Gcq8E~F^3ax5w-&o9aj0Y?W~SmIO%H4751NNE+4 z5x{W(%n5c}Hu~^fWyf`4xiTj(`(E*MaSW+oe0y`h_hAPS_7B}#x)*eBYb*&m;`?IS z5iLp9ql$|+C;Vp?|IhrN+4Xs!95+SO0}F(2y;{)R;eAFpGuY#k(9UPY;HZ*osIOf+)_Fa7__T#r2{TJcKmhCG!sy(?Pht(#w ze9F^Ti)U1q&onq{z4u4--k7wF3?;^UnNo9%>vC6f?u*xPn55v!vTN@f4NtLt))&`* z@Oug}YN$uqoY#J8UlHgzQ5>riAr4Pb-|+5z$mw~#cf~tqP1tsJ@j2hDKd+xfRAs2< z9+~>KHh)*W;hwjP^E!8LK76IHjZvs9WBIO?bzH{_mzrT z`|rDW)ArozHD6xN2vg@~iM_t`{Nz-x%^PwSTiZ1Rx1Kj(tG0Z(#{sMzopr01&zQ@&Et; literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Belt/emt.rsi/meta.json b/Resources/Textures/Clothing/Belt/emt.rsi/meta.json new file mode 100644 index 00000000000..8f6acfe1245 --- /dev/null +++ b/Resources/Textures/Clothing/Belt/emt.rsi/meta.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Drawn by Ubaser.", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "equipped-BELT", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} From c39df888d29f87ba73bde418427302f199023188 Mon Sep 17 00:00:00 2001 From: themias <89101928+themias@users.noreply.github.com> Date: Sat, 10 Feb 2024 09:44:19 +0100 Subject: [PATCH 028/200] Flipped caps real (#24961) * Flipped caps real * oops * whoops * flip not fold * fix formatting * cargosoft formatting (cherry picked from commit f7a3ea6dcfb0f43b136cef74ea7115bec63cbfd3) --- .../Components/FoldableClothingComponent.cs | 13 + .../EntitySystems/FoldableClothingSystem.cs | 32 ++- Content.Shared/Foldable/FoldableComponent.cs | 6 + Content.Shared/Foldable/FoldableSystem.cs | 2 +- .../components/foldable-component.ftl | 2 + .../Entities/Clothing/Head/soft.yml | 235 ++++++++---------- .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon_flipped.png} | Bin .../Head/Soft/bizarresoft.rsi/meta.json | 15 ++ .../Soft/bizarresoft_flipped.rsi/meta.json | 26 -- .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon_flipped.png} | Bin .../Head/Soft/blacksoft.rsi/meta.json | 15 ++ .../Head/Soft/blacksoft_flipped.rsi/meta.json | 26 -- .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon_flipped.png} | Bin .../Clothing/Head/Soft/bluesoft.rsi/meta.json | 15 ++ .../Head/Soft/bluesoft_flipped.rsi/meta.json | 26 -- .../flipped-equipped-HELMET-hamster.png | Bin 0 -> 375 bytes .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon_flipped.png} | Bin .../Head/Soft/cargosoft.rsi/meta.json | 19 ++ .../Head/Soft/cargosoft_flipped.rsi/meta.json | 26 -- .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon_flipped.png} | Bin .../Clothing/Head/Soft/corpsoft.rsi/meta.json | 15 ++ .../Head/Soft/corpsoft_flipped.rsi/meta.json | 26 -- .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon_flipped.png} | Bin .../Head/Soft/greensoft.rsi/meta.json | 15 ++ .../Head/Soft/greensoft_flipped.rsi/meta.json | 26 -- .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon_flipped.png} | Bin .../Clothing/Head/Soft/greysoft.rsi/meta.json | 15 ++ .../Head/Soft/greysoft_flipped.rsi/meta.json | 26 -- .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon_flipped.png} | Bin .../Clothing/Head/Soft/mimesoft.rsi/meta.json | 15 ++ .../Head/Soft/mimesoft_flipped.rsi/meta.json | 26 -- .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon_flipped.png} | Bin .../Head/Soft/orangesoft.rsi/meta.json | 15 ++ .../Soft/orangesoft_flipped.rsi/meta.json | 26 -- .../equipped-HELMET-hamster.png | Bin 20825 -> 388 bytes .../flipped-equipped-HELMET-hamster.png | Bin 0 -> 399 bytes .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon_flipped.png} | Bin .../Head/Soft/paramedicsoft.rsi/meta.json | 19 ++ .../Soft/paramedicsoft_flipped.rsi/meta.json | 26 -- .../flipped-equipped-HELMET-hamster.png | Bin 0 -> 406 bytes .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon_flipped.png} | Bin .../Head/Soft/purplesoft.rsi/meta.json | 19 ++ .../Soft/purplesoft_flipped.rsi/meta.json | 26 -- .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon.png => qmsoft.rsi/icon_flipped.png} | Bin .../Clothing/Head/Soft/qmsoft.rsi/meta.json | 15 ++ .../Head/Soft/qmsoft_flipped.rsi/meta.json | 26 -- .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon.png => redsoft.rsi/icon_flipped.png} | Bin .../Clothing/Head/Soft/redsoft.rsi/meta.json | 15 ++ .../Head/Soft/redsoft_flipped.rsi/meta.json | 26 -- .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon.png => secsoft.rsi/icon_flipped.png} | Bin .../Clothing/Head/Soft/secsoft.rsi/meta.json | 15 ++ .../Head/Soft/secsoft_flipped.rsi/meta.json | 26 -- .../flipped-equipped-HELMET.png} | Bin .../flipped-inhand-left.png} | Bin .../flipped-inhand-right.png} | Bin .../icon_flipped.png} | Bin .../Head/Soft/yellowsoft.rsi/meta.json | 15 ++ .../Soft/yellowsoft_flipped.rsi/meta.json | 26 -- 100 files changed, 389 insertions(+), 528 deletions(-) rename Resources/Textures/Clothing/Head/Soft/{bizarresoft_flipped.rsi/equipped-HELMET.png => bizarresoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{bizarresoft_flipped.rsi/inhand-left.png => bizarresoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{bizarresoft_flipped.rsi/inhand-right.png => bizarresoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{bizarresoft_flipped.rsi/icon.png => bizarresoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/meta.json rename Resources/Textures/Clothing/Head/Soft/{blacksoft_flipped.rsi/equipped-HELMET.png => blacksoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{blacksoft_flipped.rsi/inhand-left.png => blacksoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{blacksoft_flipped.rsi/inhand-right.png => blacksoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{blacksoft_flipped.rsi/icon.png => blacksoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/blacksoft_flipped.rsi/meta.json rename Resources/Textures/Clothing/Head/Soft/{bluesoft_flipped.rsi/equipped-HELMET.png => bluesoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{bluesoft_flipped.rsi/inhand-left.png => bluesoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{bluesoft_flipped.rsi/inhand-right.png => bluesoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{bluesoft_flipped.rsi/icon.png => bluesoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/bluesoft_flipped.rsi/meta.json create mode 100644 Resources/Textures/Clothing/Head/Soft/cargosoft.rsi/flipped-equipped-HELMET-hamster.png rename Resources/Textures/Clothing/Head/Soft/{cargosoft_flipped.rsi/equipped-HELMET.png => cargosoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{cargosoft_flipped.rsi/inhand-left.png => cargosoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{cargosoft_flipped.rsi/inhand-right.png => cargosoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{cargosoft_flipped.rsi/icon.png => cargosoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/cargosoft_flipped.rsi/meta.json rename Resources/Textures/Clothing/Head/Soft/{corpsoft_flipped.rsi/equipped-HELMET.png => corpsoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{corpsoft_flipped.rsi/inhand-left.png => corpsoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{corpsoft_flipped.rsi/inhand-right.png => corpsoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{corpsoft_flipped.rsi/icon.png => corpsoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/corpsoft_flipped.rsi/meta.json rename Resources/Textures/Clothing/Head/Soft/{greensoft_flipped.rsi/equipped-HELMET.png => greensoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{greensoft_flipped.rsi/inhand-left.png => greensoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{greensoft_flipped.rsi/inhand-right.png => greensoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{greensoft_flipped.rsi/icon.png => greensoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/greensoft_flipped.rsi/meta.json rename Resources/Textures/Clothing/Head/Soft/{greysoft_flipped.rsi/equipped-HELMET.png => greysoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{greysoft_flipped.rsi/inhand-left.png => greysoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{greysoft_flipped.rsi/inhand-right.png => greysoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{greysoft_flipped.rsi/icon.png => greysoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/greysoft_flipped.rsi/meta.json rename Resources/Textures/Clothing/Head/Soft/{mimesoft_flipped.rsi/equipped-HELMET.png => mimesoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{mimesoft_flipped.rsi/inhand-left.png => mimesoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{mimesoft_flipped.rsi/inhand-right.png => mimesoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{mimesoft_flipped.rsi/icon.png => mimesoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/mimesoft_flipped.rsi/meta.json rename Resources/Textures/Clothing/Head/Soft/{orangesoft_flipped.rsi/equipped-HELMET.png => orangesoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{orangesoft_flipped.rsi/inhand-left.png => orangesoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{orangesoft_flipped.rsi/inhand-right.png => orangesoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{orangesoft_flipped.rsi/icon.png => orangesoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/orangesoft_flipped.rsi/meta.json create mode 100644 Resources/Textures/Clothing/Head/Soft/paramedicsoft.rsi/flipped-equipped-HELMET-hamster.png rename Resources/Textures/Clothing/Head/Soft/{paramedicsoft_flipped.rsi/equipped-HELMET.png => paramedicsoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{paramedicsoft_flipped.rsi/inhand-left.png => paramedicsoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{paramedicsoft_flipped.rsi/inhand-right.png => paramedicsoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{paramedicsoft_flipped.rsi/icon.png => paramedicsoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/paramedicsoft_flipped.rsi/meta.json create mode 100644 Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/flipped-equipped-HELMET-hamster.png rename Resources/Textures/Clothing/Head/Soft/{purplesoft_flipped.rsi/equipped-HELMET.png => purplesoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{purplesoft_flipped.rsi/inhand-left.png => purplesoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{purplesoft_flipped.rsi/inhand-right.png => purplesoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{purplesoft_flipped.rsi/icon.png => purplesoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/purplesoft_flipped.rsi/meta.json rename Resources/Textures/Clothing/Head/Soft/{qmsoft_flipped.rsi/equipped-HELMET.png => qmsoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{qmsoft_flipped.rsi/inhand-left.png => qmsoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{qmsoft_flipped.rsi/inhand-right.png => qmsoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{qmsoft_flipped.rsi/icon.png => qmsoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/qmsoft_flipped.rsi/meta.json rename Resources/Textures/Clothing/Head/Soft/{redsoft_flipped.rsi/equipped-HELMET.png => redsoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{redsoft_flipped.rsi/inhand-left.png => redsoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{redsoft_flipped.rsi/inhand-right.png => redsoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{redsoft_flipped.rsi/icon.png => redsoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/redsoft_flipped.rsi/meta.json rename Resources/Textures/Clothing/Head/Soft/{secsoft_flipped.rsi/equipped-HELMET.png => secsoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{secsoft_flipped.rsi/inhand-left.png => secsoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{secsoft_flipped.rsi/inhand-right.png => secsoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{secsoft_flipped.rsi/icon.png => secsoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/secsoft_flipped.rsi/meta.json rename Resources/Textures/Clothing/Head/Soft/{yellowsoft_flipped.rsi/equipped-HELMET.png => yellowsoft.rsi/flipped-equipped-HELMET.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{yellowsoft_flipped.rsi/inhand-left.png => yellowsoft.rsi/flipped-inhand-left.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{yellowsoft_flipped.rsi/inhand-right.png => yellowsoft.rsi/flipped-inhand-right.png} (100%) rename Resources/Textures/Clothing/Head/Soft/{yellowsoft_flipped.rsi/icon.png => yellowsoft.rsi/icon_flipped.png} (100%) delete mode 100644 Resources/Textures/Clothing/Head/Soft/yellowsoft_flipped.rsi/meta.json diff --git a/Content.Shared/Clothing/Components/FoldableClothingComponent.cs b/Content.Shared/Clothing/Components/FoldableClothingComponent.cs index 61237b22834..1a40d1dca12 100644 --- a/Content.Shared/Clothing/Components/FoldableClothingComponent.cs +++ b/Content.Shared/Clothing/Components/FoldableClothingComponent.cs @@ -17,4 +17,17 @@ public sealed partial class FoldableClothingComponent : Component /// [DataField] public SlotFlags? UnfoldedSlots; + + + /// + /// What equipped prefix does this have while in folded form? + /// + [DataField] + public string? FoldedEquippedPrefix; + + /// + /// What held prefix does this have while in folded form? + /// + [DataField] + public string? FoldedHeldPrefix; } diff --git a/Content.Shared/Clothing/EntitySystems/FoldableClothingSystem.cs b/Content.Shared/Clothing/EntitySystems/FoldableClothingSystem.cs index d0611c5851c..27ea1680188 100644 --- a/Content.Shared/Clothing/EntitySystems/FoldableClothingSystem.cs +++ b/Content.Shared/Clothing/EntitySystems/FoldableClothingSystem.cs @@ -1,6 +1,7 @@ using Content.Shared.Clothing.Components; using Content.Shared.Foldable; using Content.Shared.Inventory; +using Content.Shared.Item; namespace Content.Shared.Clothing.EntitySystems; @@ -8,6 +9,7 @@ public sealed class FoldableClothingSystem : EntitySystem { [Dependency] private readonly ClothingSystem _clothingSystem = default!; [Dependency] private readonly InventorySystem _inventorySystem = default!; + [Dependency] private readonly SharedItemSystem _itemSystem = default!; public override void Initialize() { @@ -31,12 +33,32 @@ private void OnFoldAttempt(Entity ent, ref FoldAttemp private void OnFolded(Entity ent, ref FoldedEvent args) { - if (TryComp(ent.Owner, out var clothingComp)) + if (TryComp(ent.Owner, out var clothingComp) && + TryComp(ent.Owner, out var itemComp)) { - if (args.IsFolded && ent.Comp.FoldedSlots.HasValue) - _clothingSystem.SetSlots(ent.Owner, ent.Comp.FoldedSlots.Value, clothingComp); - else if (!args.IsFolded && ent.Comp.UnfoldedSlots.HasValue) - _clothingSystem.SetSlots(ent.Owner, ent.Comp.UnfoldedSlots.Value, clothingComp); + if (args.IsFolded) + { + if (ent.Comp.FoldedSlots.HasValue) + _clothingSystem.SetSlots(ent.Owner, ent.Comp.FoldedSlots.Value, clothingComp); + + if (ent.Comp.FoldedEquippedPrefix != null) + _clothingSystem.SetEquippedPrefix(ent.Owner, ent.Comp.FoldedEquippedPrefix, clothingComp); + + if (ent.Comp.FoldedHeldPrefix != null) + _itemSystem.SetHeldPrefix(ent.Owner, ent.Comp.FoldedHeldPrefix, false, itemComp); + } + else + { + if (ent.Comp.UnfoldedSlots.HasValue) + _clothingSystem.SetSlots(ent.Owner, ent.Comp.UnfoldedSlots.Value, clothingComp); + + if (ent.Comp.FoldedEquippedPrefix != null) + _clothingSystem.SetEquippedPrefix(ent.Owner, null, clothingComp); + + if (ent.Comp.FoldedHeldPrefix != null) + _itemSystem.SetHeldPrefix(ent.Owner, null, false, itemComp); + + } } } } diff --git a/Content.Shared/Foldable/FoldableComponent.cs b/Content.Shared/Foldable/FoldableComponent.cs index c22095f3f29..74f6a209136 100644 --- a/Content.Shared/Foldable/FoldableComponent.cs +++ b/Content.Shared/Foldable/FoldableComponent.cs @@ -17,4 +17,10 @@ public sealed partial class FoldableComponent : Component [DataField] public bool CanFoldInsideContainer = false; + + [DataField] + public LocId UnfoldVerbText = "unfold-verb"; + + [DataField] + public LocId FoldVerbText = "fold-verb"; } diff --git a/Content.Shared/Foldable/FoldableSystem.cs b/Content.Shared/Foldable/FoldableSystem.cs index 374aba44c50..10baf8165b5 100644 --- a/Content.Shared/Foldable/FoldableSystem.cs +++ b/Content.Shared/Foldable/FoldableSystem.cs @@ -134,7 +134,7 @@ private void AddFoldVerb(EntityUid uid, FoldableComponent component, GetVerbsEve AlternativeVerb verb = new() { Act = () => TryToggleFold(uid, component), - Text = component.IsFolded ? Loc.GetString("unfold-verb") : Loc.GetString("fold-verb"), + Text = component.IsFolded ? Loc.GetString(component.UnfoldVerbText) : Loc.GetString(component.FoldVerbText), Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/fold.svg.192dpi.png")), // If the object is unfolded and they click it, they want to fold it, if it's folded, they want to pick it up diff --git a/Resources/Locale/en-US/foldable/components/foldable-component.ftl b/Resources/Locale/en-US/foldable/components/foldable-component.ftl index d3e4ecefb52..539b4fd9e71 100644 --- a/Resources/Locale/en-US/foldable/components/foldable-component.ftl +++ b/Resources/Locale/en-US/foldable/components/foldable-component.ftl @@ -3,3 +3,5 @@ foldable-deploy-fail = You can't deploy the {$object} here. fold-verb = Fold unfold-verb = Unfold + +fold-flip-verb = Flip \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Clothing/Head/soft.yml b/Resources/Prototypes/Entities/Clothing/Head/soft.yml index ea5e1c03919..163d9937f2e 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/soft.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/soft.yml @@ -1,5 +1,47 @@ - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadBaseButcherable, BaseFoldable] + id: ClothingHeadHeadHatBaseFlippable + abstract: true + components: + - type: Appearance + - type: Foldable + canFoldInsideContainer: true + unfoldVerbText: fold-flip-verb + foldVerbText: fold-flip-verb + - type: FoldableClothing + foldedEquippedPrefix: flipped + foldedHeldPrefix: flipped + - type: Sprite + layers: + - state: icon + map: [ "unfoldedLayer" ] + - state: icon_flipped + map: ["foldedLayer"] + visible: false + +- type: entity + parent: ClothingHeadHeadHatBaseFlippable + id: ClothingHeadHeadHatBaseFlipped + suffix: flipped + abstract: true + components: + - type: Foldable + folded: true + - type: Clothing + equippedPrefix: flipped + - type: Item + heldPrefix: flipped + - type: Sprite + layers: + - state: icon + map: [ "unfoldedLayer" ] + visible: false + - state: icon_flipped + map: ["foldedLayer"] + visible: true + +- type: entity + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatBluesoft name: blue cap description: "It's a baseball hat in a tasteless blue colour." @@ -10,18 +52,12 @@ sprite: Clothing/Head/Soft/bluesoft.rsi - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatBluesoft] id: ClothingHeadHatBluesoftFlipped - name: blue cap flipped - description: "It's a baseball hat in a tasteless blue colour. Flipped." - components: - - type: Sprite - sprite: Clothing/Head/Soft/bluesoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/bluesoft_flipped.rsi + name: blue cap - type: entity - parent: ClothingHeadBaseButcherable + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatCargosoft name: logistics cap # DeltaV - Logistics Department replacing Cargo description: "It's a baseball hat painted in Logistics colours." # DeltaV - Logistics Department replacing Cargo @@ -37,18 +73,19 @@ - WhitelistChameleon - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatCargosoft] id: ClothingHeadHatCargosoftFlipped - name: logistics cap flipped # DeltaV - Logistics Department replacing Cargo + name: logistics cap # DeltaV - Logistics Department replacing Cargo description: "It's a baseball hat painted in Logistics colours. Flipped." # DeltaV - Logistics Department replacing Cargo components: - - type: Sprite - sprite: Clothing/Head/Soft/cargosoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/cargosoft_flipped.rsi + - type: Tag + tags: + - ClothMade + - HamsterWearable + - WhitelistChameleon - type: entity - parent: ClothingHeadBaseButcherable + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatQMsoft name: logistics officer's cap # DeltaV - Logistics Department replacing Cargo description: "It's a baseball hat painted in the Logistics Officer's colors." @@ -59,18 +96,12 @@ sprite: Clothing/Head/Soft/qmsoft.rsi - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatQMsoft] id: ClothingHeadHatQMsoftFlipped - name: logistics officer's cap flipped # DeltaV - Logistics Department replacing Cargo - description: "It's a baseball hat painted in the Logistics Officer's colors. Flipped." - components: - - type: Sprite - sprite: Clothing/Head/Soft/qmsoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/qmsoft_flipped.rsi + name: logistics officer's cap - type: entity - parent: ClothingHeadBaseButcherable + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatCorpsoft name: corporate cap description: A baseball bat in corporation colors. @@ -81,18 +112,12 @@ sprite: Clothing/Head/Soft/corpsoft.rsi - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatCorpsoft] id: ClothingHeadHatCorpsoftFlipped - name: corporate cap flipped - description: A baseball bat in corporation colors. Flipped. - components: - - type: Sprite - sprite: Clothing/Head/Soft/corpsoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/corpsoft_flipped.rsi + name: corporate cap - type: entity - parent: ClothingHeadBaseButcherable + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatGreensoft name: green cap description: "It's a baseball hat in a tasteless green colour." @@ -103,18 +128,12 @@ sprite: Clothing/Head/Soft/greensoft.rsi - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatGreensoft] id: ClothingHeadHatGreensoftFlipped - name: green cap flipped - description: "It's a baseball hat in a tasteless green colour. Flipped." - components: - - type: Sprite - sprite: Clothing/Head/Soft/greensoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/greensoft_flipped.rsi + name: green cap - type: entity - parent: ClothingHeadBaseButcherable + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatBlacksoft name: black cap description: "It's a baseball hat in a tasteless black colour." @@ -125,18 +144,12 @@ sprite: Clothing/Head/Soft/blacksoft.rsi - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatBlacksoft] id: ClothingHeadHatBlacksoftFlipped - name: black cap flipped - description: "It's a baseball hat in a tasteless black colour. Flipped." - components: - - type: Sprite - sprite: Clothing/Head/Soft/blacksoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/blacksoft_flipped.rsi + name: black cap - type: entity - parent: ClothingHeadBaseButcherable + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatGreysoft name: grey cap description: "It's a baseball hat in a tasteless grey colour." @@ -147,18 +160,12 @@ sprite: Clothing/Head/Soft/greysoft.rsi - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatGreysoft] id: ClothingHeadHatGreysoftFlipped - name: grey cap flipped - description: "It's a baseball hat in a tasteless grey colour. Flipped." - components: - - type: Sprite - sprite: Clothing/Head/Soft/greysoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/greysoft_flipped.rsi + name: grey cap - type: entity - parent: ClothingHeadBaseButcherable + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatMimesoft name: mime cap description: "It's a baseball hat in a tasteless white colour." @@ -169,18 +176,12 @@ sprite: Clothing/Head/Soft/mimesoft.rsi - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatMimesoft] id: ClothingHeadHatMimesoftFlipped - name: mime cap flipped - description: It's a baseball hat in a tasteless white colour. Flipped. - components: - - type: Sprite - sprite: Clothing/Head/Soft/mimesoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/mimesoft_flipped.rsi + name: mime cap - type: entity - parent: ClothingHeadBaseButcherable + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatOrangesoft name: orange cap description: It's a baseball hat in a good-looking orange colour. @@ -191,18 +192,12 @@ sprite: Clothing/Head/Soft/orangesoft.rsi - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatOrangesoft] id: ClothingHeadHatOrangesoftFlipped - name: orange cap flipped - description: It's a baseball hat in a good-looking orange colour. Flipped. - components: - - type: Sprite - sprite: Clothing/Head/Soft/orangesoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/orangesoft_flipped.rsi + name: orange cap - type: entity - parent: ClothingHeadBaseButcherable + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatPurplesoft name: purple cap description: It's a baseball hat in a tasteless purple colour. @@ -218,18 +213,18 @@ - WhitelistChameleon - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatPurplesoft] id: ClothingHeadHatPurplesoftFlipped - name: purple cap flipped - description: It's a baseball hat in a tasteless purple colour. Flipped. + name: purple cap components: - - type: Sprite - sprite: Clothing/Head/Soft/purplesoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/purplesoft_flipped.rsi + - type: Tag + tags: + - ClothMade + - HamsterWearable + - WhitelistChameleon - type: entity - parent: ClothingHeadBaseButcherable + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatRedsoft name: red cap description: It's a baseball hat in a tasteless red colour. @@ -240,18 +235,12 @@ sprite: Clothing/Head/Soft/redsoft.rsi - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatRedsoft] id: ClothingHeadHatRedsoftFlipped - name: red cap flipped - description: It's a baseball hat in a tasteless purple colour. Flipped. - components: - - type: Sprite - sprite: Clothing/Head/Soft/redsoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/redsoft_flipped.rsi + name: red cap - type: entity - parent: ClothingHeadBaseButcherable + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatSecsoft name: security cap description: It's a robust baseball hat in tasteful red colour. @@ -262,18 +251,12 @@ sprite: Clothing/Head/Soft/secsoft.rsi - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatSecsoft] id: ClothingHeadHatSecsoftFlipped - name: security cap flipped - description: It's a robust baseball hat in tasteful red colour. Flipped. - components: - - type: Sprite - sprite: Clothing/Head/Soft/secsoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/secsoft_flipped.rsi + name: security cap - type: entity - parent: ClothingHeadBaseButcherable + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatYellowsoft name: yellow cap description: A yellow baseball hat. @@ -284,20 +267,14 @@ sprite: Clothing/Head/Soft/yellowsoft.rsi - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatYellowsoft] id: ClothingHeadHatYellowsoftFlipped - name: yellow cap flipped - description: A yellow flipped baseball hat. - components: - - type: Sprite - sprite: Clothing/Head/Soft/yellowsoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/yellowsoft_flipped.rsi + name: yellow cap - type: entity - parent: ClothingHeadBaseButcherable + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatBizarreSoft - name: troublemaker's soft + name: troublemaker's cap description: A truly.. bizarre accessory. components: - type: Sprite @@ -306,18 +283,12 @@ sprite: Clothing/Head/Soft/bizarresoft.rsi - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatBizarreSoft] id: ClothingHeadHatBizarreSoftFlipped - name: troublemaker's soft flipped - description: A truly.. bizarre accessory, flipped. - components: - - type: Sprite - sprite: Clothing/Head/Soft/bizarresoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/bizarresoft_flipped.rsi + name: troublemaker's cap - type: entity - parent: ClothingHeadBaseButcherable + parent: ClothingHeadHeadHatBaseFlippable id: ClothingHeadHatParamedicsoft name: paramedic cap description: "It's a paramedic's baseball hat with a medical logo." @@ -333,12 +304,12 @@ - WhitelistChameleon - type: entity - parent: ClothingHeadBaseButcherable + parent: [ClothingHeadHeadHatBaseFlipped, ClothingHeadHatParamedicsoft] id: ClothingHeadHatParamedicsoftFlipped - name: paramedic cap flipped - description: "It's a paramedic's baseball hat with a medical logo. Flipped." + name: paramedic cap components: - - type: Sprite - sprite: Clothing/Head/Soft/paramedicsoft_flipped.rsi - - type: Clothing - sprite: Clothing/Head/Soft/paramedicsoft_flipped.rsi + - type: Tag + tags: + - ClothMade + - HamsterWearable + - WhitelistChameleon diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/flipped-equipped-HELMET.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/equipped-HELMET.png rename to Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/flipped-equipped-HELMET.png diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/flipped-inhand-left.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/inhand-left.png rename to Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/flipped-inhand-left.png diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/flipped-inhand-right.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/inhand-right.png rename to Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/flipped-inhand-right.png diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/icon.png b/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/icon_flipped.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/icon.png rename to Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/icon_flipped.png diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/meta.json index b3513bb5cd0..adf7e7620a5 100644 --- a/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/meta.json +++ b/Resources/Textures/Clothing/Head/Soft/bizarresoft.rsi/meta.json @@ -10,6 +10,9 @@ { "name": "icon" }, + { + "name": "icon_flipped" + }, { "name": "equipped-HELMET", "directions": 4 @@ -21,6 +24,18 @@ { "name": "inhand-right", "directions": 4 + }, + { + "name": "flipped-equipped-HELMET", + "directions": 4 + }, + { + "name": "flipped-inhand-left", + "directions": 4 + }, + { + "name": "flipped-inhand-right", + "directions": 4 } ] } diff --git a/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/meta.json deleted file mode 100644 index b3513bb5cd0..00000000000 --- a/Resources/Textures/Clothing/Head/Soft/bizarresoft_flipped.rsi/meta.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "version": 1, - "license": "CC-BY-NC-SA-3.0", - "copyright": "Taken from civstation at commit https://github.com/Civ13/Civ13/commit/ec52cbb95d59b717d4d8c480b35ac133e5b58088#diff-fba188fb2db5d16e5d41985147336a8f96085f761b903e016fffd869b63e497d", - "size": { - "x": 32, - "y": 32 - }, - "states": [ - { - "name": "icon" - }, - { - "name": "equipped-HELMET", - "directions": 4 - }, - { - "name": "inhand-left", - "directions": 4 - }, - { - "name": "inhand-right", - "directions": 4 - } - ] -} diff --git a/Resources/Textures/Clothing/Head/Soft/blacksoft_flipped.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Soft/blacksoft.rsi/flipped-equipped-HELMET.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/blacksoft_flipped.rsi/equipped-HELMET.png rename to Resources/Textures/Clothing/Head/Soft/blacksoft.rsi/flipped-equipped-HELMET.png diff --git a/Resources/Textures/Clothing/Head/Soft/blacksoft_flipped.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Soft/blacksoft.rsi/flipped-inhand-left.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/blacksoft_flipped.rsi/inhand-left.png rename to Resources/Textures/Clothing/Head/Soft/blacksoft.rsi/flipped-inhand-left.png diff --git a/Resources/Textures/Clothing/Head/Soft/blacksoft_flipped.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Soft/blacksoft.rsi/flipped-inhand-right.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/blacksoft_flipped.rsi/inhand-right.png rename to Resources/Textures/Clothing/Head/Soft/blacksoft.rsi/flipped-inhand-right.png diff --git a/Resources/Textures/Clothing/Head/Soft/blacksoft_flipped.rsi/icon.png b/Resources/Textures/Clothing/Head/Soft/blacksoft.rsi/icon_flipped.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/blacksoft_flipped.rsi/icon.png rename to Resources/Textures/Clothing/Head/Soft/blacksoft.rsi/icon_flipped.png diff --git a/Resources/Textures/Clothing/Head/Soft/blacksoft.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/blacksoft.rsi/meta.json index a470e009443..a29360acd8b 100644 --- a/Resources/Textures/Clothing/Head/Soft/blacksoft.rsi/meta.json +++ b/Resources/Textures/Clothing/Head/Soft/blacksoft.rsi/meta.json @@ -10,6 +10,9 @@ { "name": "icon" }, + { + "name": "icon_flipped" + }, { "name": "equipped-HELMET", "directions": 4 @@ -21,6 +24,18 @@ { "name": "inhand-right", "directions": 4 + }, + { + "name": "flipped-equipped-HELMET", + "directions": 4 + }, + { + "name": "flipped-inhand-left", + "directions": 4 + }, + { + "name": "flipped-inhand-right", + "directions": 4 } ] } diff --git a/Resources/Textures/Clothing/Head/Soft/blacksoft_flipped.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/blacksoft_flipped.rsi/meta.json deleted file mode 100644 index a470e009443..00000000000 --- a/Resources/Textures/Clothing/Head/Soft/blacksoft_flipped.rsi/meta.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "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-HELMET", - "directions": 4 - }, - { - "name": "inhand-left", - "directions": 4 - }, - { - "name": "inhand-right", - "directions": 4 - } - ] -} diff --git a/Resources/Textures/Clothing/Head/Soft/bluesoft_flipped.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Soft/bluesoft.rsi/flipped-equipped-HELMET.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/bluesoft_flipped.rsi/equipped-HELMET.png rename to Resources/Textures/Clothing/Head/Soft/bluesoft.rsi/flipped-equipped-HELMET.png diff --git a/Resources/Textures/Clothing/Head/Soft/bluesoft_flipped.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Soft/bluesoft.rsi/flipped-inhand-left.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/bluesoft_flipped.rsi/inhand-left.png rename to Resources/Textures/Clothing/Head/Soft/bluesoft.rsi/flipped-inhand-left.png diff --git a/Resources/Textures/Clothing/Head/Soft/bluesoft_flipped.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Soft/bluesoft.rsi/flipped-inhand-right.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/bluesoft_flipped.rsi/inhand-right.png rename to Resources/Textures/Clothing/Head/Soft/bluesoft.rsi/flipped-inhand-right.png diff --git a/Resources/Textures/Clothing/Head/Soft/bluesoft_flipped.rsi/icon.png b/Resources/Textures/Clothing/Head/Soft/bluesoft.rsi/icon_flipped.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/bluesoft_flipped.rsi/icon.png rename to Resources/Textures/Clothing/Head/Soft/bluesoft.rsi/icon_flipped.png diff --git a/Resources/Textures/Clothing/Head/Soft/bluesoft.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/bluesoft.rsi/meta.json index a470e009443..a29360acd8b 100644 --- a/Resources/Textures/Clothing/Head/Soft/bluesoft.rsi/meta.json +++ b/Resources/Textures/Clothing/Head/Soft/bluesoft.rsi/meta.json @@ -10,6 +10,9 @@ { "name": "icon" }, + { + "name": "icon_flipped" + }, { "name": "equipped-HELMET", "directions": 4 @@ -21,6 +24,18 @@ { "name": "inhand-right", "directions": 4 + }, + { + "name": "flipped-equipped-HELMET", + "directions": 4 + }, + { + "name": "flipped-inhand-left", + "directions": 4 + }, + { + "name": "flipped-inhand-right", + "directions": 4 } ] } diff --git a/Resources/Textures/Clothing/Head/Soft/bluesoft_flipped.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/bluesoft_flipped.rsi/meta.json deleted file mode 100644 index a470e009443..00000000000 --- a/Resources/Textures/Clothing/Head/Soft/bluesoft_flipped.rsi/meta.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "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-HELMET", - "directions": 4 - }, - { - "name": "inhand-left", - "directions": 4 - }, - { - "name": "inhand-right", - "directions": 4 - } - ] -} diff --git a/Resources/Textures/Clothing/Head/Soft/cargosoft.rsi/flipped-equipped-HELMET-hamster.png b/Resources/Textures/Clothing/Head/Soft/cargosoft.rsi/flipped-equipped-HELMET-hamster.png new file mode 100644 index 0000000000000000000000000000000000000000..f5372ea5a3b66f97015499e4944ab8ec114c6ee3 GIT binary patch literal 375 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%z4Lw~PLn`LH zy=Cur*g)j?$9REkBllP>wpAQ?O_#D$PI4SSaf;zO$1C41B_o$erLb4bGgxnFT zpYY)K%th%p&sS~SW8=-h@L>O^7`0T-gxwo=AD^54R`E@xpEv)h_nX4rdqxV~cr&PH#F=lz+BE6nz6YVSH_i_iAE?jb5`Qyv2 zpYy#hcfPM$Z~n@1?rT1e$5Z!4$kaJqZP`^{HS;;2Md~^xpl6`qujTjk`(9u4epmbJ z{;AhjPx$K1oDDRCt{2+P!T8F&M`2=g>_6g=tuT zf?EI(6)j&QK*J2w%s`W@kYt7^3y^{dQs9V_7$A|;gad^TiI*Hv;Qy1ZIG^mte&wrd z2><|GtH{#H^@hPYr}=EEWIU1gUjF{pG?qo&?1pN!n!PU;3%!3mKA7^4?i4q>p;Rhq zd3TewmHQ*5X=GjnE(I)07*qo IM6N<$g8ihQ-2eap literal 20825 zcmeHPeT-aH6@RTomTD0wri6e@h9D*QcJ90H`!PFZKU&+ul-h2?wn*W=d+*zQurqI% zdE1>D)s2mMt^KS~s*J><<3xOON?}$;xCVCntL+SOf{N zvbE@ws#vU?T?c944DkvryCvWCim3pX*xrQSmre&AHDBSp3Z-U8#Y)H>u$ZZmQby`U znNCWKHg!r9zlneAk%)CwMX=3B2mg zpcXu-tJQp}Zt5(MW(}4(@xAh}=Z)v;?z*;Ni`3v?%{@~~FLjH|o2;Cd&9tku9H)iG zhltN}7=bTJNJMy8QY~4vB>j9OSqMcy>XL03d5^iy)&_)*}_s3BO=+3 z0Sl24pUes+DjUIJ)N;IXf%rMMKt_3{R2iWO8Uuq;KOX4UR82+w{icRj z7}-p))q*op%sD|atIeq1@jQvk+JAVHenbk93iDkXw|SKL&Heq zx}wbOsC6bY*_H@EQ#It813y$Zbb_%%WC?dUYLijUk%ob5uFvhLP0nP;22`7yb_mTS zNwjqabHTFdsNI^8N{Xr)8ifs04hbPxQ$(;X+m>5prA#+U#m$76kz_p`> z9zuwYMWS+r7|d`asoQwX9j>XSLPS|7VNf+q1Bs?VOcesI!3pcqLmVt&*#HkwG$6dT z6%gbAKMvxmEK{u8T|=uFBN@UI3@}{i@kc%CLMl_=ziMA0^bmt+nkcK9BPzC{i6$~+ z(U2G?6mvr{j=l*%uG7n4N3?BZQ|3q_akwcmRdGbqw1HR6MihX!A*n~@wE^a+5;GOZ zX|Qb&Q6;dEz=mgt8rCR7)S$X)&K`^ykY!Ox)Ibe}7r2$KNTMSn>`;V(0mwr-ZT|Jv zsYyjNV>wbv5@dS$ytS%W@d;!stA=vH8Sy!k0dMH)Jda@4lvWYTImL<-PWl&SS__% z&##%<+Dh$eMOulJD?BJc`qGUWq*>L~^SCgZtCcbqp+R|6 z8Dwf|oEWBvRfsyerXbOvOcgbV%BrH-lFsyonIl$gpJFhX2*FUF!Sa!U`YbqjP&PFn z-Vgd)W20lFILcWr(-=;pp?y04%N8?q14594MH`!ns3VAj27@%#;E3w7?NHNk8uRPI zV)8ITR$w$KF`D0ucV2M|FUN^^5LXGD*m0=0ow8R*HOu^z@1;noH11Logwo8GA`8#I zn#FO$dJ&BOqJuJCcH;z<$S7%prql;)&c_@^p=f8A%8m#p7pkZ_3Y4viq>E5LX@;qq z$U%^tbg`S&!)UT7YZ*nj#e_-7F&hobu+wRnh&p9Z{4+?G;j96Pnu2wzUu@3%a#QP0b}{acnx96r=^;*z(@bJ+K)k8cQOy=**-Y_tGUUS5RV6ra z(BR0WrqlkQqvFPy6eABp#rm>|++EiUQ*VWvak!MvG;if2Hml_$@6B6lM(+)N4K?W` z7P$#s30<)mh$WnOS3*}T24V>(-j&c5i-B0eiFYM*#bO|qaN=DFU9lL5C7gIyLRTyX zVhJbSmCzN7fmp(ccO`ViVjz}q;#~<{u^5OYoOoA4S1bl%2`Ao_&=re;Si*^SC3MAN zAeM0AT?t*W7>FgDcvnJKECyl;C*GCN6^nsb!ije!bj4yImT=--30<)mh$WnOS3*}T z24V>(-j&c5i-B0eNA#|Rt>3xhMfh>MN%$4Jw{CyzHTVU*6kWM4F9_St5rpf$Bnba} z7e45>{%fQ^PXEZ)IVI^_r|`*E}H+DGmbxeXz`f~AOG!5 zm79Auo#7WAeeR(R=k(nF$;;naa>~9pt|&eBP|po(_df9A>6;3r69#tv@bI%Az3Sz6 z)E9Q7Pn`Vy`A;7D*#6QpKYn%pp${GU^X|{B9y)Na=h=h(!u*r26BZn^^_1EK?^x)pF-`RKT>;3n=`NU~AUBBg< z*`F-O<}bf@YyZ;^_@^#=WY-rj+py`5>k7Zx&dQ7Ty#D1~#nFe|%jW;=r<7S>hs>&d-&}|2fVKc3sS)?rkumaz>|M0;LHxWVD zcl+b7%)i$@VdLh{-t}VU#^x%`SfyEpeNd4AC)!bvAzTFBn^wcX2}8O!F5 t|NeKk_nex!sB%{42^`q>kb?-@ga10|j4?92+&enNIa<2Jc$8K%j!136#vs4_e4f?jer#A7t{U~za<%e}Ow|PU`b60Uzo_n3hum8$ylBWw2@D*Mu<84(u zi}#cG%I$SneG8~WyUbFk$i`TCi*1%Ds&DQ%l%{pR+~8Hro8ze)eg68C%>H-B**J iFHc*?BnSh4E#>3xP2By>#lIXF!VI3SelF{r5}E+2%d8Cm literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Soft/paramedicsoft_flipped.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Soft/paramedicsoft.rsi/flipped-equipped-HELMET.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/paramedicsoft_flipped.rsi/equipped-HELMET.png rename to Resources/Textures/Clothing/Head/Soft/paramedicsoft.rsi/flipped-equipped-HELMET.png diff --git a/Resources/Textures/Clothing/Head/Soft/paramedicsoft_flipped.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Soft/paramedicsoft.rsi/flipped-inhand-left.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/paramedicsoft_flipped.rsi/inhand-left.png rename to Resources/Textures/Clothing/Head/Soft/paramedicsoft.rsi/flipped-inhand-left.png diff --git a/Resources/Textures/Clothing/Head/Soft/paramedicsoft_flipped.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Soft/paramedicsoft.rsi/flipped-inhand-right.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/paramedicsoft_flipped.rsi/inhand-right.png rename to Resources/Textures/Clothing/Head/Soft/paramedicsoft.rsi/flipped-inhand-right.png diff --git a/Resources/Textures/Clothing/Head/Soft/paramedicsoft_flipped.rsi/icon.png b/Resources/Textures/Clothing/Head/Soft/paramedicsoft.rsi/icon_flipped.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/paramedicsoft_flipped.rsi/icon.png rename to Resources/Textures/Clothing/Head/Soft/paramedicsoft.rsi/icon_flipped.png diff --git a/Resources/Textures/Clothing/Head/Soft/paramedicsoft.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/paramedicsoft.rsi/meta.json index 2b73b340e68..b60639b2654 100644 --- a/Resources/Textures/Clothing/Head/Soft/paramedicsoft.rsi/meta.json +++ b/Resources/Textures/Clothing/Head/Soft/paramedicsoft.rsi/meta.json @@ -10,21 +10,40 @@ { "name": "icon" }, + { + "name": "icon_flipped" + }, { "name": "equipped-HELMET", "directions": 4 }, + { + "name": "flipped-equipped-HELMET", + "directions": 4 + }, { "name": "equipped-HELMET-hamster", "directions": 4 }, + { + "name": "flipped-equipped-HELMET-hamster", + "directions": 4 + }, { "name": "inhand-left", "directions": 4 }, + { + "name": "flipped-inhand-left", + "directions": 4 + }, { "name": "inhand-right", "directions": 4 + }, + { + "name": "flipped-inhand-right", + "directions": 4 } ] } diff --git a/Resources/Textures/Clothing/Head/Soft/paramedicsoft_flipped.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/paramedicsoft_flipped.rsi/meta.json deleted file mode 100644 index 8089773135c..00000000000 --- a/Resources/Textures/Clothing/Head/Soft/paramedicsoft_flipped.rsi/meta.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "version": 1, - "license": "CC-BY-SA-3.0", - "copyright": "Made by MagnusCrowe (Github) for SS14", - "size": { - "x": 32, - "y": 32 - }, - "states": [ - { - "name": "icon" - }, - { - "name": "equipped-HELMET", - "directions": 4 - }, - { - "name": "inhand-left", - "directions": 4 - }, - { - "name": "inhand-right", - "directions": 4 - } - ] -} diff --git a/Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/flipped-equipped-HELMET-hamster.png b/Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/flipped-equipped-HELMET-hamster.png new file mode 100644 index 0000000000000000000000000000000000000000..140bf71b782a83bf8cc38024c82e74777fbe031d GIT binary patch literal 406 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%z13Xltui9SrsLMb8`xZ1-^A!|ND^_J-_z=%Jt^J+;yw~%S`{lPg#^$#-A29j4;K#I` zezo#5{KdYS%=y}P`iGPgqU0H$d>GAHIdIzDMj&`v$`N}a#YrE5=`l_uObT@W+< z?auBwJK1_>Jzd!KV1|z=(63P7e&WvlSFbO6f3y1=f7G^0#%2G#HqZEFq1YLJMhtDnm{r-UW|nzyg( literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Soft/purplesoft_flipped.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/flipped-equipped-HELMET.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/purplesoft_flipped.rsi/equipped-HELMET.png rename to Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/flipped-equipped-HELMET.png diff --git a/Resources/Textures/Clothing/Head/Soft/purplesoft_flipped.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/flipped-inhand-left.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/purplesoft_flipped.rsi/inhand-left.png rename to Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/flipped-inhand-left.png diff --git a/Resources/Textures/Clothing/Head/Soft/purplesoft_flipped.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/flipped-inhand-right.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/purplesoft_flipped.rsi/inhand-right.png rename to Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/flipped-inhand-right.png diff --git a/Resources/Textures/Clothing/Head/Soft/purplesoft_flipped.rsi/icon.png b/Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/icon_flipped.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/purplesoft_flipped.rsi/icon.png rename to Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/icon_flipped.png diff --git a/Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/meta.json index ade65863af2..3fb7add363e 100644 --- a/Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/meta.json +++ b/Resources/Textures/Clothing/Head/Soft/purplesoft.rsi/meta.json @@ -10,21 +10,40 @@ { "name": "icon" }, + { + "name": "icon_flipped" + }, { "name": "equipped-HELMET", "directions": 4 }, + { + "name": "flipped-equipped-HELMET", + "directions": 4 + }, { "name": "equipped-HELMET-hamster", "directions": 4 }, + { + "name": "flipped-equipped-HELMET-hamster", + "directions": 4 + }, { "name": "inhand-left", "directions": 4 }, + { + "name": "flipped-inhand-left", + "directions": 4 + }, { "name": "inhand-right", "directions": 4 + }, + { + "name": "flipped-inhand-right", + "directions": 4 } ] } diff --git a/Resources/Textures/Clothing/Head/Soft/purplesoft_flipped.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/purplesoft_flipped.rsi/meta.json deleted file mode 100644 index a470e009443..00000000000 --- a/Resources/Textures/Clothing/Head/Soft/purplesoft_flipped.rsi/meta.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "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-HELMET", - "directions": 4 - }, - { - "name": "inhand-left", - "directions": 4 - }, - { - "name": "inhand-right", - "directions": 4 - } - ] -} diff --git a/Resources/Textures/Clothing/Head/Soft/qmsoft_flipped.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Soft/qmsoft.rsi/flipped-equipped-HELMET.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/qmsoft_flipped.rsi/equipped-HELMET.png rename to Resources/Textures/Clothing/Head/Soft/qmsoft.rsi/flipped-equipped-HELMET.png diff --git a/Resources/Textures/Clothing/Head/Soft/qmsoft_flipped.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Soft/qmsoft.rsi/flipped-inhand-left.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/qmsoft_flipped.rsi/inhand-left.png rename to Resources/Textures/Clothing/Head/Soft/qmsoft.rsi/flipped-inhand-left.png diff --git a/Resources/Textures/Clothing/Head/Soft/qmsoft_flipped.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Soft/qmsoft.rsi/flipped-inhand-right.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/qmsoft_flipped.rsi/inhand-right.png rename to Resources/Textures/Clothing/Head/Soft/qmsoft.rsi/flipped-inhand-right.png diff --git a/Resources/Textures/Clothing/Head/Soft/qmsoft_flipped.rsi/icon.png b/Resources/Textures/Clothing/Head/Soft/qmsoft.rsi/icon_flipped.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/qmsoft_flipped.rsi/icon.png rename to Resources/Textures/Clothing/Head/Soft/qmsoft.rsi/icon_flipped.png diff --git a/Resources/Textures/Clothing/Head/Soft/qmsoft.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/qmsoft.rsi/meta.json index a470e009443..a29360acd8b 100644 --- a/Resources/Textures/Clothing/Head/Soft/qmsoft.rsi/meta.json +++ b/Resources/Textures/Clothing/Head/Soft/qmsoft.rsi/meta.json @@ -10,6 +10,9 @@ { "name": "icon" }, + { + "name": "icon_flipped" + }, { "name": "equipped-HELMET", "directions": 4 @@ -21,6 +24,18 @@ { "name": "inhand-right", "directions": 4 + }, + { + "name": "flipped-equipped-HELMET", + "directions": 4 + }, + { + "name": "flipped-inhand-left", + "directions": 4 + }, + { + "name": "flipped-inhand-right", + "directions": 4 } ] } diff --git a/Resources/Textures/Clothing/Head/Soft/qmsoft_flipped.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/qmsoft_flipped.rsi/meta.json deleted file mode 100644 index a470e009443..00000000000 --- a/Resources/Textures/Clothing/Head/Soft/qmsoft_flipped.rsi/meta.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "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-HELMET", - "directions": 4 - }, - { - "name": "inhand-left", - "directions": 4 - }, - { - "name": "inhand-right", - "directions": 4 - } - ] -} diff --git a/Resources/Textures/Clothing/Head/Soft/redsoft_flipped.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Soft/redsoft.rsi/flipped-equipped-HELMET.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/redsoft_flipped.rsi/equipped-HELMET.png rename to Resources/Textures/Clothing/Head/Soft/redsoft.rsi/flipped-equipped-HELMET.png diff --git a/Resources/Textures/Clothing/Head/Soft/redsoft_flipped.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Soft/redsoft.rsi/flipped-inhand-left.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/redsoft_flipped.rsi/inhand-left.png rename to Resources/Textures/Clothing/Head/Soft/redsoft.rsi/flipped-inhand-left.png diff --git a/Resources/Textures/Clothing/Head/Soft/redsoft_flipped.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Soft/redsoft.rsi/flipped-inhand-right.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/redsoft_flipped.rsi/inhand-right.png rename to Resources/Textures/Clothing/Head/Soft/redsoft.rsi/flipped-inhand-right.png diff --git a/Resources/Textures/Clothing/Head/Soft/redsoft_flipped.rsi/icon.png b/Resources/Textures/Clothing/Head/Soft/redsoft.rsi/icon_flipped.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/redsoft_flipped.rsi/icon.png rename to Resources/Textures/Clothing/Head/Soft/redsoft.rsi/icon_flipped.png diff --git a/Resources/Textures/Clothing/Head/Soft/redsoft.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/redsoft.rsi/meta.json index a470e009443..a29360acd8b 100644 --- a/Resources/Textures/Clothing/Head/Soft/redsoft.rsi/meta.json +++ b/Resources/Textures/Clothing/Head/Soft/redsoft.rsi/meta.json @@ -10,6 +10,9 @@ { "name": "icon" }, + { + "name": "icon_flipped" + }, { "name": "equipped-HELMET", "directions": 4 @@ -21,6 +24,18 @@ { "name": "inhand-right", "directions": 4 + }, + { + "name": "flipped-equipped-HELMET", + "directions": 4 + }, + { + "name": "flipped-inhand-left", + "directions": 4 + }, + { + "name": "flipped-inhand-right", + "directions": 4 } ] } diff --git a/Resources/Textures/Clothing/Head/Soft/redsoft_flipped.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/redsoft_flipped.rsi/meta.json deleted file mode 100644 index a470e009443..00000000000 --- a/Resources/Textures/Clothing/Head/Soft/redsoft_flipped.rsi/meta.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "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-HELMET", - "directions": 4 - }, - { - "name": "inhand-left", - "directions": 4 - }, - { - "name": "inhand-right", - "directions": 4 - } - ] -} diff --git a/Resources/Textures/Clothing/Head/Soft/secsoft_flipped.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Soft/secsoft.rsi/flipped-equipped-HELMET.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/secsoft_flipped.rsi/equipped-HELMET.png rename to Resources/Textures/Clothing/Head/Soft/secsoft.rsi/flipped-equipped-HELMET.png diff --git a/Resources/Textures/Clothing/Head/Soft/secsoft_flipped.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Soft/secsoft.rsi/flipped-inhand-left.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/secsoft_flipped.rsi/inhand-left.png rename to Resources/Textures/Clothing/Head/Soft/secsoft.rsi/flipped-inhand-left.png diff --git a/Resources/Textures/Clothing/Head/Soft/secsoft_flipped.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Soft/secsoft.rsi/flipped-inhand-right.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/secsoft_flipped.rsi/inhand-right.png rename to Resources/Textures/Clothing/Head/Soft/secsoft.rsi/flipped-inhand-right.png diff --git a/Resources/Textures/Clothing/Head/Soft/secsoft_flipped.rsi/icon.png b/Resources/Textures/Clothing/Head/Soft/secsoft.rsi/icon_flipped.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/secsoft_flipped.rsi/icon.png rename to Resources/Textures/Clothing/Head/Soft/secsoft.rsi/icon_flipped.png diff --git a/Resources/Textures/Clothing/Head/Soft/secsoft.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/secsoft.rsi/meta.json index a470e009443..a29360acd8b 100644 --- a/Resources/Textures/Clothing/Head/Soft/secsoft.rsi/meta.json +++ b/Resources/Textures/Clothing/Head/Soft/secsoft.rsi/meta.json @@ -10,6 +10,9 @@ { "name": "icon" }, + { + "name": "icon_flipped" + }, { "name": "equipped-HELMET", "directions": 4 @@ -21,6 +24,18 @@ { "name": "inhand-right", "directions": 4 + }, + { + "name": "flipped-equipped-HELMET", + "directions": 4 + }, + { + "name": "flipped-inhand-left", + "directions": 4 + }, + { + "name": "flipped-inhand-right", + "directions": 4 } ] } diff --git a/Resources/Textures/Clothing/Head/Soft/secsoft_flipped.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/secsoft_flipped.rsi/meta.json deleted file mode 100644 index a470e009443..00000000000 --- a/Resources/Textures/Clothing/Head/Soft/secsoft_flipped.rsi/meta.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "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-HELMET", - "directions": 4 - }, - { - "name": "inhand-left", - "directions": 4 - }, - { - "name": "inhand-right", - "directions": 4 - } - ] -} diff --git a/Resources/Textures/Clothing/Head/Soft/yellowsoft_flipped.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Soft/yellowsoft.rsi/flipped-equipped-HELMET.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/yellowsoft_flipped.rsi/equipped-HELMET.png rename to Resources/Textures/Clothing/Head/Soft/yellowsoft.rsi/flipped-equipped-HELMET.png diff --git a/Resources/Textures/Clothing/Head/Soft/yellowsoft_flipped.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Soft/yellowsoft.rsi/flipped-inhand-left.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/yellowsoft_flipped.rsi/inhand-left.png rename to Resources/Textures/Clothing/Head/Soft/yellowsoft.rsi/flipped-inhand-left.png diff --git a/Resources/Textures/Clothing/Head/Soft/yellowsoft_flipped.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Soft/yellowsoft.rsi/flipped-inhand-right.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/yellowsoft_flipped.rsi/inhand-right.png rename to Resources/Textures/Clothing/Head/Soft/yellowsoft.rsi/flipped-inhand-right.png diff --git a/Resources/Textures/Clothing/Head/Soft/yellowsoft_flipped.rsi/icon.png b/Resources/Textures/Clothing/Head/Soft/yellowsoft.rsi/icon_flipped.png similarity index 100% rename from Resources/Textures/Clothing/Head/Soft/yellowsoft_flipped.rsi/icon.png rename to Resources/Textures/Clothing/Head/Soft/yellowsoft.rsi/icon_flipped.png diff --git a/Resources/Textures/Clothing/Head/Soft/yellowsoft.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/yellowsoft.rsi/meta.json index a470e009443..a29360acd8b 100644 --- a/Resources/Textures/Clothing/Head/Soft/yellowsoft.rsi/meta.json +++ b/Resources/Textures/Clothing/Head/Soft/yellowsoft.rsi/meta.json @@ -10,6 +10,9 @@ { "name": "icon" }, + { + "name": "icon_flipped" + }, { "name": "equipped-HELMET", "directions": 4 @@ -21,6 +24,18 @@ { "name": "inhand-right", "directions": 4 + }, + { + "name": "flipped-equipped-HELMET", + "directions": 4 + }, + { + "name": "flipped-inhand-left", + "directions": 4 + }, + { + "name": "flipped-inhand-right", + "directions": 4 } ] } diff --git a/Resources/Textures/Clothing/Head/Soft/yellowsoft_flipped.rsi/meta.json b/Resources/Textures/Clothing/Head/Soft/yellowsoft_flipped.rsi/meta.json deleted file mode 100644 index a470e009443..00000000000 --- a/Resources/Textures/Clothing/Head/Soft/yellowsoft_flipped.rsi/meta.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "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-HELMET", - "directions": 4 - }, - { - "name": "inhand-left", - "directions": 4 - }, - { - "name": "inhand-right", - "directions": 4 - } - ] -} From fc32b7d4a8ce8761832f188bc6e51b888530f766 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 10 Feb 2024 08:45:24 +0000 Subject: [PATCH 029/200] Automatic changelog update (cherry picked from commit 1be78656613dd1dceaf57637ad15daba8fa69b05) --- 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 55cb9d072e5..c2bcd93bf6b 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: yathxyz - changes: - - message: Fixed nix devShell - type: Fix - id: 5408 - time: '2023-12-17T16:55:37.0000000+00:00' - url: null - author: Ubaser changes: - message: HoS parade uniforms are available at the uniform printer. @@ -3885,3 +3878,10 @@ Order: 1 id: 5907 time: '2024-02-10T08:21:44.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25089 +- author: themias + changes: + - message: Soft caps can be flipped backwards with an alt-verb (Flip) + type: Tweak + id: 5908 + time: '2024-02-10T08:44:19.0000000+00:00' + url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24961 From 6faa6f4c6e6c7c41832888387708fa29e1b7f1f3 Mon Sep 17 00:00:00 2001 From: Alzore <140123969+Blackern5000@users.noreply.github.com> Date: Sat, 10 Feb 2024 02:49:24 -0600 Subject: [PATCH 030/200] Nerf Beanbags (#24653) Lowers beanbag damage from 55 stam to 30 stam (cherry picked from commit cc5f45bb166375fe847ea2d0138ea80aa88a407c) --- .../Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml index 36b1b2a99f1..e62fb9115e3 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity id: PelletShotgunSlug name: pellet (.50 slug) noSpawn: true @@ -26,7 +26,7 @@ types: Blunt: 10 - type: StaminaDamageOnCollide - damage: 55 # 2 hits to stun + damage: 40 # 3 hits to stun - type: entity id: PelletShotgun From 8e7b7823a3326ad5f8730f7fd6ce5beda95b0596 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 10 Feb 2024 08:50:30 +0000 Subject: [PATCH 031/200] Automatic changelog update (cherry picked from commit 98015a45230af1e13e21435d6b3c3f22aa88e3e4) --- 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 c2bcd93bf6b..7adeea366ef 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Ubaser - changes: - - message: HoS parade uniforms are available at the uniform printer. - type: Add - id: 5409 - time: '2023-12-17T23:20:04.0000000+00:00' - url: null - author: Alzore changes: - message: Security zipties are now tiny and easier to store. @@ -3885,3 +3878,10 @@ Order: 1 id: 5908 time: '2024-02-10T08:44:19.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24961 +- author: Blackern5000 + changes: + - message: Shotgun beanbag rounds now deal 40 stamina damage and stun in 3 hits. + type: Tweak + id: 5909 + time: '2024-02-10T08:49:24.0000000+00:00' + url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24653 From 464e4d4b608cb6a61147ad9f03fc242d9786a389 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sat, 10 Feb 2024 19:51:11 +1100 Subject: [PATCH 032/200] Fix screenspace popups (#24987) * Fix screenspace popups Never got around to it earlier but need to draw it above UI controls. * Minor null change (cherry picked from commit 560ea9775a561b9d516a838687733e8983bbe9a0) --- Content.Client/Popups/PopupOverlay.cs | 77 ++----------- Content.Client/Popups/PopupSystem.cs | 10 +- Content.Client/Popups/PopupUIController.cs | 121 +++++++++++++++++++++ 3 files changed, 137 insertions(+), 71 deletions(-) create mode 100644 Content.Client/Popups/PopupUIController.cs diff --git a/Content.Client/Popups/PopupOverlay.cs b/Content.Client/Popups/PopupOverlay.cs index 5adc2e1ff0c..1305d8bb947 100644 --- a/Content.Client/Popups/PopupOverlay.cs +++ b/Content.Client/Popups/PopupOverlay.cs @@ -1,12 +1,6 @@ -using System.Numerics; -using Content.Client.Examine; -using Content.Shared.CCVar; using Content.Shared.Examine; -using Content.Shared.Interaction; -using Content.Shared.Popups; using Robust.Client.Graphics; using Robust.Client.Player; -using Robust.Client.ResourceManagement; using Robust.Client.UserInterface; using Robust.Shared; using Robust.Shared.Configuration; @@ -26,11 +20,9 @@ public sealed class PopupOverlay : Overlay private readonly IPlayerManager _playerMgr; private readonly IUserInterfaceManager _uiManager; private readonly PopupSystem _popup; + private readonly PopupUIController _controller; private readonly ShaderInstance _shader; - private readonly Font _smallFont; - private readonly Font _mediumFont; - private readonly Font _largeFont; public override OverlaySpace Space => OverlaySpace.ScreenSpace; @@ -39,8 +31,8 @@ public PopupOverlay( IEntityManager entManager, IPlayerManager playerMgr, IPrototypeManager protoManager, - IResourceCache cache, IUserInterfaceManager uiManager, + PopupUIController controller, PopupSystem popup) { _configManager = configManager; @@ -48,11 +40,9 @@ public PopupOverlay( _playerMgr = playerMgr; _uiManager = uiManager; _popup = popup; + _controller = controller; _shader = protoManager.Index("unshaded").Instance(); - _smallFont = new VectorFont(cache.GetResource("/Fonts/NotoSans/NotoSans-Italic.ttf"), 10); - _mediumFont = new VectorFont(cache.GetResource("/Fonts/NotoSans/NotoSans-Italic.ttf"), 12); - _largeFont = new VectorFont(cache.GetResource("/Fonts/NotoSans/NotoSans-BoldItalic.ttf"), 14); } protected override void Draw(in OverlayDrawArgs args) @@ -68,19 +58,18 @@ protected override void Draw(in OverlayDrawArgs args) scale = _uiManager.DefaultUIScale; DrawWorld(args.ScreenHandle, args, scale); - DrawScreen(args.ScreenHandle, args, scale); args.DrawingHandle.UseShader(null); } private void DrawWorld(DrawingHandleScreen worldHandle, OverlayDrawArgs args, float scale) { - if (_popup.WorldLabels.Count == 0) + if (_popup.WorldLabels.Count == 0 || args.ViewportControl == null) return; - var matrix = args.ViewportControl!.GetWorldToScreenMatrix(); + var matrix = args.ViewportControl.GetWorldToScreenMatrix(); var viewPos = new MapCoordinates(args.WorldAABB.Center, args.MapId); - var ourEntity = _playerMgr.LocalPlayer?.ControlledEntity; + var ourEntity = _playerMgr.LocalEntity; foreach (var popup in _popup.WorldLabels) { @@ -92,62 +81,12 @@ private void DrawWorld(DrawingHandleScreen worldHandle, OverlayDrawArgs args, fl var distance = (mapPos.Position - args.WorldBounds.Center).Length(); // Should handle fade here too wyci. - if (!args.WorldAABB.Contains(mapPos.Position) || !ExamineSystemShared.InRangeUnOccluded(viewPos, mapPos, distance, + if (!args.WorldBounds.Contains(mapPos.Position) || !ExamineSystemShared.InRangeUnOccluded(viewPos, mapPos, distance, e => e == popup.InitialPos.EntityId || e == ourEntity, entMan: _entManager)) continue; var pos = matrix.Transform(mapPos.Position); - DrawPopup(popup, worldHandle, pos, scale); + _controller.DrawPopup(popup, worldHandle, pos, scale); } } - - private void DrawScreen(DrawingHandleScreen screenHandle, OverlayDrawArgs args, float scale) - { - foreach (var popup in _popup.CursorLabels) - { - // Different window - if (popup.InitialPos.Window != args.ViewportControl?.Window?.Id) - continue; - - DrawPopup(popup, screenHandle, popup.InitialPos.Position, scale); - } - } - - private void DrawPopup(PopupSystem.PopupLabel popup, DrawingHandleScreen handle, Vector2 position, float scale) - { - var lifetime = PopupSystem.GetPopupLifetime(popup); - - // Keep alpha at 1 until TotalTime passes half its lifetime, then gradually decrease to 0. - var alpha = MathF.Min(1f, 1f - MathF.Max(0f, popup.TotalTime - lifetime / 2) * 2 / lifetime); - - var updatedPosition = position - new Vector2(0f, MathF.Min(8f, 12f * (popup.TotalTime * popup.TotalTime + popup.TotalTime))); - var font = _smallFont; - var color = Color.White.WithAlpha(alpha); - - switch (popup.Type) - { - case PopupType.SmallCaution: - color = Color.Red; - break; - case PopupType.Medium: - font = _mediumFont; - color = Color.LightGray; - break; - case PopupType.MediumCaution: - font = _mediumFont; - color = Color.Red; - break; - case PopupType.Large: - font = _largeFont; - color = Color.LightGray; - break; - case PopupType.LargeCaution: - font = _largeFont; - color = Color.Red; - break; - } - - var dimensions = handle.GetDimensions(font, popup.Text, scale); - handle.DrawString(font, updatedPosition - dimensions / 2f, popup.Text, scale, color.WithAlpha(alpha)); - } } diff --git a/Content.Client/Popups/PopupSystem.cs b/Content.Client/Popups/PopupSystem.cs index d9e66c79fa9..2c923ae3a71 100644 --- a/Content.Client/Popups/PopupSystem.cs +++ b/Content.Client/Popups/PopupSystem.cs @@ -23,7 +23,6 @@ public sealed class PopupSystem : SharedPopupSystem [Dependency] private readonly IOverlayManager _overlay = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; - [Dependency] private readonly IResourceCache _resource = default!; [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IUserInterfaceManager _uiManager = default!; [Dependency] private readonly IReplayRecordingManager _replayRecording = default!; @@ -45,7 +44,14 @@ public override void Initialize() SubscribeNetworkEvent(OnPopupEntityEvent); SubscribeNetworkEvent(OnRoundRestart); _overlay - .AddOverlay(new PopupOverlay(_configManager, EntityManager, _playerManager, _prototype, _resource, _uiManager, this)); + .AddOverlay(new PopupOverlay( + _configManager, + EntityManager, + _playerManager, + _prototype, + _uiManager, + _uiManager.GetUIController(), + this)); } public override void Shutdown() diff --git a/Content.Client/Popups/PopupUIController.cs b/Content.Client/Popups/PopupUIController.cs new file mode 100644 index 00000000000..8ce8ae21e19 --- /dev/null +++ b/Content.Client/Popups/PopupUIController.cs @@ -0,0 +1,121 @@ +using System.Numerics; +using Content.Client.Gameplay; +using Content.Shared.Popups; +using Robust.Client.Graphics; +using Robust.Client.ResourceManagement; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controllers; + +namespace Content.Client.Popups; + +/// +/// Handles screens-space popups. World popups are handled via PopupOverlay. +/// +public sealed class PopupUIController : UIController, IOnStateEntered, IOnStateExited +{ + [UISystemDependency] private readonly PopupSystem? _popup = default!; + + private Font _smallFont = default!; + private Font _mediumFont = default!; + private Font _largeFont = default!; + + private PopupRootControl? _popupControl; + + public override void Initialize() + { + base.Initialize(); + var cache = IoCManager.Resolve(); + + _smallFont = new VectorFont(cache.GetResource("/Fonts/NotoSans/NotoSans-Italic.ttf"), 10); + _mediumFont = new VectorFont(cache.GetResource("/Fonts/NotoSans/NotoSans-Italic.ttf"), 12); + _largeFont = new VectorFont(cache.GetResource("/Fonts/NotoSans/NotoSans-BoldItalic.ttf"), 14); + } + + public void OnStateEntered(GameplayState state) + { + _popupControl = new PopupRootControl(_popup, this); + + UIManager.RootControl.AddChild(_popupControl); + } + + public void OnStateExited(GameplayState state) + { + if (_popupControl == null) + return; + + UIManager.RootControl.RemoveChild(_popupControl); + _popupControl = null; + } + + public void DrawPopup(PopupSystem.PopupLabel popup, DrawingHandleScreen handle, Vector2 position, float scale) + { + var lifetime = PopupSystem.GetPopupLifetime(popup); + + // Keep alpha at 1 until TotalTime passes half its lifetime, then gradually decrease to 0. + var alpha = MathF.Min(1f, 1f - MathF.Max(0f, popup.TotalTime - lifetime / 2) * 2 / lifetime); + + var updatedPosition = position - new Vector2(0f, MathF.Min(8f, 12f * (popup.TotalTime * popup.TotalTime + popup.TotalTime))); + var font = _smallFont; + var color = Color.White.WithAlpha(alpha); + + switch (popup.Type) + { + case PopupType.SmallCaution: + color = Color.Red; + break; + case PopupType.Medium: + font = _mediumFont; + color = Color.LightGray; + break; + case PopupType.MediumCaution: + font = _mediumFont; + color = Color.Red; + break; + case PopupType.Large: + font = _largeFont; + color = Color.LightGray; + break; + case PopupType.LargeCaution: + font = _largeFont; + color = Color.Red; + break; + } + + var dimensions = handle.GetDimensions(font, popup.Text, scale); + handle.DrawString(font, updatedPosition - dimensions / 2f, popup.Text, scale, color.WithAlpha(alpha)); + } + + /// + /// Handles drawing all screen popups. + /// + private sealed class PopupRootControl : Control + { + private readonly PopupSystem? _popup; + private readonly PopupUIController _controller; + + public PopupRootControl(PopupSystem? system, PopupUIController controller) + { + _popup = system; + _controller = controller; + } + + protected override void Draw(DrawingHandleScreen handle) + { + base.Draw(handle); + + if (_popup == null) + return; + + // Different window + var windowId = UserInterfaceManager.RootControl.Window.Id; + + foreach (var popup in _popup.CursorLabels) + { + if (popup.InitialPos.Window != windowId) + continue; + + _controller.DrawPopup(popup, handle, popup.InitialPos.Position, UIScale); + } + } + } +} From 244658a3114aff8672e3edd33b307a3476c35830 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 10 Feb 2024 08:52:16 +0000 Subject: [PATCH 033/200] Automatic changelog update (cherry picked from commit 21e2289d2b63708e9a521eb152569503cf4e028c) --- 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 7adeea366ef..ca973ef28f2 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Alzore - changes: - - message: Security zipties are now tiny and easier to store. - type: Tweak - id: 5410 - time: '2023-12-17T23:27:01.0000000+00:00' - url: null - author: Aexxie changes: - message: Added RCDs to all engineering lockers. @@ -3885,3 +3878,11 @@ Order: 1 id: 5909 time: '2024-02-10T08:49:24.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24653 +- author: metalgearsloth + changes: + - message: Fix screenspace popups e.g. inventory / access popups drawing below the + UI. + type: Fix + id: 5910 + time: '2024-02-10T08:51:11.0000000+00:00' + url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24987 From d899831a239910ab97382f85dfdbf43c14cf9bb5 Mon Sep 17 00:00:00 2001 From: themias <89101928+themias@users.noreply.github.com> Date: Sat, 10 Feb 2024 04:17:25 -0500 Subject: [PATCH 034/200] Fix crew manifest department bugs (#24975) (cherry picked from commit 543cd6a2368cb379618f0c56cfaf3414044ba012) --- .../Access/Systems/AgentIDCardSystem.cs | 20 +++++++++++++++++++ .../Access/Systems/IdCardConsoleSystem.cs | 1 + Content.Server/Access/Systems/IdCardSystem.cs | 1 + 3 files changed, 22 insertions(+) diff --git a/Content.Server/Access/Systems/AgentIDCardSystem.cs b/Content.Server/Access/Systems/AgentIDCardSystem.cs index 4d242e8f81d..29657b509a9 100644 --- a/Content.Server/Access/Systems/AgentIDCardSystem.cs +++ b/Content.Server/Access/Systems/AgentIDCardSystem.cs @@ -7,6 +7,8 @@ using Content.Shared.StatusIcon; using Robust.Server.GameObjects; using Robust.Shared.Prototypes; +using Content.Shared.Roles; +using System.Diagnostics.CodeAnalysis; namespace Content.Server.Access.Systems { @@ -98,6 +100,24 @@ private void OnJobIconChanged(EntityUid uid, AgentIDCardComponent comp, AgentIDC } _cardSystem.TryChangeJobIcon(uid, jobIcon, idCard); + + if (TryFindJobProtoFromIcon(jobIcon, out var job)) + _cardSystem.TryChangeJobDepartment(uid, job, idCard); + } + + private bool TryFindJobProtoFromIcon(StatusIconPrototype jobIcon, [NotNullWhen(true)] out JobPrototype? job) + { + foreach (var jobPrototype in _prototypeManager.EnumeratePrototypes()) + { + if(jobPrototype.Icon == jobIcon.ID) + { + job = jobPrototype; + return true; + } + } + + job = null; + return false; } } } diff --git a/Content.Server/Access/Systems/IdCardConsoleSystem.cs b/Content.Server/Access/Systems/IdCardConsoleSystem.cs index b3b2baf28e7..791159f972b 100644 --- a/Content.Server/Access/Systems/IdCardConsoleSystem.cs +++ b/Content.Server/Access/Systems/IdCardConsoleSystem.cs @@ -131,6 +131,7 @@ private void TryWriteToTargetId(EntityUid uid, && _prototype.TryIndex(job.Icon, out var jobIcon)) { _idCard.TryChangeJobIcon(targetId, jobIcon, player: player); + _idCard.TryChangeJobDepartment(targetId, job); } if (!newAccessList.TrueForAll(x => component.AccessLevels.Contains(x))) diff --git a/Content.Server/Access/Systems/IdCardSystem.cs b/Content.Server/Access/Systems/IdCardSystem.cs index 1c1e6874172..def5e950d2c 100644 --- a/Content.Server/Access/Systems/IdCardSystem.cs +++ b/Content.Server/Access/Systems/IdCardSystem.cs @@ -149,6 +149,7 @@ public bool TryChangeJobDepartment(EntityUid uid, JobPrototype job, IdCardCompon if (!Resolve(uid, ref id)) return false; + id.JobDepartments.Clear(); foreach (var department in _prototypeManager.EnumeratePrototypes()) { if (department.Roles.Contains(job.ID)) From 8a51130584c9409ab4deae5b4ee12ce1063691cc Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 10 Feb 2024 09:18:31 +0000 Subject: [PATCH 035/200] Automatic changelog update (cherry picked from commit b59dc2911ca4ffb46e187a31a59cb930b3f1654e) --- Resources/Changelog/Changelog.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index ca973ef28f2..78e7a6942c2 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Aexxie - changes: - - message: Added RCDs to all engineering lockers. - type: Add - id: 5411 - time: '2023-12-18T02:38:37.0000000+00:00' - url: null - author: Ubaser changes: - message: Traitors and Nukies can now purchase a Chemical Synthesis Kit for 4TC @@ -3886,3 +3879,13 @@ Order: 1 id: 5910 time: '2024-02-10T08:51:11.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24987 +- author: themias + changes: + - message: The ID card console now correctly updates the ID's department when you + update its job + type: Fix + - message: The Agent ID will update its department depending on the selected icon + type: Fix + id: 5911 + time: '2024-02-10T09:17:26.0000000+00:00' + url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24975 From 9d9d86dda488c7642b0b84ccaad7c45359f56b3d Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Sat, 10 Feb 2024 02:22:19 -0800 Subject: [PATCH 036/200] Changed door remote to trigger based on vision occlusion(#25093) Changed door remote to trigger based on vision occlusion rather than opaque collision targeting check. Ian's butt will no longer absorb your 5G signals. Co-authored-by: Plykiya (cherry picked from commit 7a04acc8511f477dbb0fdb8852dcc72ab4b0677f) --- Content.Server/Remotes/DoorRemoteSystem.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Content.Server/Remotes/DoorRemoteSystem.cs b/Content.Server/Remotes/DoorRemoteSystem.cs index c63b2295c16..a88508ce53d 100644 --- a/Content.Server/Remotes/DoorRemoteSystem.cs +++ b/Content.Server/Remotes/DoorRemoteSystem.cs @@ -10,6 +10,7 @@ using Content.Server.Power.EntitySystems; using Content.Shared.Database; using Content.Shared.Interaction.Events; +using Content.Shared.Examine; using static Content.Server.Remotes.DoorRemoteComponent; namespace Content.Server.Remotes @@ -65,10 +66,9 @@ private void OnBeforeInteract(EntityUid uid, DoorRemoteComponent component, Befo if (args.Handled || args.Target == null || !TryComp(args.Target, out var doorComp) // If it isn't a door we don't use it - // The remote can be used anywhere the user can see the door. - // This doesn't work that well, but I don't know of an alternative - || !_interactionSystem.InRangeUnobstructed(args.User, args.Target.Value, - SharedInteractionSystem.MaxRaycastRange, CollisionGroup.Opaque)) + // Only able to control doors if they are within your vision and within your max range. + // Not affected by mobs or machines anymore. + || !ExamineSystemShared.InRangeUnOccluded(args.User, args.Target.Value, SharedInteractionSystem.MaxRaycastRange, null)) { return; } From 4e452bf090fe2690ad6e6c89a6697bd873f8f94c Mon Sep 17 00:00:00 2001 From: PoorMansDreams <150595537+poormansdreams@users.noreply.github.com> Date: Sat, 10 Feb 2024 15:35:07 +0100 Subject: [PATCH 037/200] GPS In Paramed Locker (#25096) GPS in paramed locker (cherry picked from commit 7e91ffec4fcfe4d074e1186ea6da5f7d51383c5d) --- Resources/Prototypes/Catalog/Fills/Lockers/medical.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/medical.yml b/Resources/Prototypes/Catalog/Fills/Lockers/medical.yml index 8bc391fab62..3dff55b9682 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/medical.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/medical.yml @@ -201,5 +201,6 @@ - id: ClothingHeadsetMedical - id: ClothingMaskSterile - id: ClothingShoesBootsWinterParamedic #Delta V: Add departmental winter boots + - id: HandheldGPSBasic - id: MedkitFilled prob: 0.3 From a9dd7af05f81dd60ac9806302b12a24a98b2eba8 Mon Sep 17 00:00:00 2001 From: YuNii Date: Sat, 10 Feb 2024 18:25:14 +0100 Subject: [PATCH 038/200] Remove 'travis scott day' from the game (#25106) * remove travis scott from the game * KILL TRAVIS EVEN MORE (cherry picked from commit 148e10207b5eab7ca7d85b9052e23a605795c745) --- Resources/Locale/en-US/holiday/greet/holiday-greet.ftl | 1 - Resources/Prototypes/holidays.yml | 6 ------ 2 files changed, 7 deletions(-) diff --git a/Resources/Locale/en-US/holiday/greet/holiday-greet.ftl b/Resources/Locale/en-US/holiday/greet/holiday-greet.ftl index 825f4a803fa..fde896df39b 100644 --- a/Resources/Locale/en-US/holiday/greet/holiday-greet.ftl +++ b/Resources/Locale/en-US/holiday/greet/holiday-greet.ftl @@ -8,7 +8,6 @@ holiday-name-new-year = New Year holiday-name-mister-lizard = Mister Lizard's Birthday holiday-name-chinese-new-year = Chinese New Year holiday-name-groundhog-day = Groundhog Day -holiday-name-travis-scott-day = Travis Scott Day holiday-name-valentines-day = Valentine's Day holiday-name-birthday13 = Birthday of Space Station 13 holiday-name-random-kindness = Random Acts of Kindness Day diff --git a/Resources/Prototypes/holidays.yml b/Resources/Prototypes/holidays.yml index 207378f71e0..235584dd636 100644 --- a/Resources/Prototypes/holidays.yml +++ b/Resources/Prototypes/holidays.yml @@ -24,12 +24,6 @@ beginDay: 2 beginMonth: February -- type: holiday - id: TravisScottDay - name: holiday-name-travis-scott-day - beginDay: 10 - beginMonth: February - - type: holiday id: ValentinesDay name: holiday-name-valentines-day From 7f905dc03d244f5fcd4c79aaeab89203ceb9ec36 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 10 Feb 2024 17:26:20 +0000 Subject: [PATCH 039/200] Automatic changelog update (cherry picked from commit 04ca43c6418f6d51ce8364ac01dce1ab842381ee) --- Resources/Changelog/Changelog.yml | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 78e7a6942c2..bcc8a92b6e9 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,20 +1,5 @@ Order: 1 Entries: -- author: Ubaser - changes: - - message: Traitors and Nukies can now purchase a Chemical Synthesis Kit for 4TC - which contains Vestine. - type: Add - - message: Nocturine, Tazinide, Stimulants, Lexorin and Mute Toxin are now locked - behind Vestine. - type: Tweak - - message: Lexorin and Heartbreaker toxin are buffed, while Licoxide is nerfed. - type: Tweak - - message: You can no longer purchase Nocturine through the uplink. - type: Remove - id: 5412 - time: '2023-12-18T02:40:28.0000000+00:00' - url: null - author: Ubaser changes: - message: Janitors now get rubber gloves for cleaning. @@ -3889,3 +3874,16 @@ Order: 1 id: 5911 time: '2024-02-10T09:17:26.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24975 +- author: bhenrich + changes: + - message: Added fun! + type: Add + - message: Removed fun! + type: Remove + - message: Changed fun! + type: Tweak + - message: Fixed fun! + type: Fix + id: 5912 + time: '2024-02-10T17:25:14.0000000+00:00' + url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25106 From 73b2b6848b82aa611eef30c24ac9857060dc373f Mon Sep 17 00:00:00 2001 From: Kara Date: Sat, 10 Feb 2024 10:39:37 -0700 Subject: [PATCH 040/200] Remove erroneous changelog (#25107) (cherry picked from commit 64d2733b235689b7c7d0497af7356e717a529961) --- Resources/Changelog/Changelog.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index bcc8a92b6e9..16089dcf62b 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -3874,16 +3874,3 @@ Order: 1 id: 5911 time: '2024-02-10T09:17:26.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24975 -- author: bhenrich - changes: - - message: Added fun! - type: Add - - message: Removed fun! - type: Remove - - message: Changed fun! - type: Tweak - - message: Fixed fun! - type: Fix - id: 5912 - time: '2024-02-10T17:25:14.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/25106 From e3ed747015a6f53a262a584821d75c13f4d21c1e Mon Sep 17 00:00:00 2001 From: Nim <128169402+Nimfar11@users.noreply.github.com> Date: Sun, 11 Feb 2024 01:36:18 +0200 Subject: [PATCH 041/200] Glass box for antique laser pistol (#25104) * glassbox * fix (cherry picked from commit 2a9fa67a7fef8c6f8f54d507c88fc4e399d1fd4f) --- .../Catalog/Fills/Lockers/heads.yml | 27 +++- .../Entities/Structures/Storage/glass_box.yml | 139 ++++++++++++++++++ Resources/Prototypes/tags.yml | 3 + .../Storage/glassbox.rsi/DamageOverlay_12.png | Bin 0 -> 578 bytes .../Storage/glassbox.rsi/DamageOverlay_4.png | Bin 0 -> 332 bytes .../Storage/glassbox.rsi/DamageOverlay_8.png | Bin 0 -> 413 bytes .../Storage/glassbox.rsi/caplaser.png | Bin 0 -> 557 bytes .../Storage/glassbox.rsi/glass-4.png | Bin 0 -> 377 bytes .../Storage/glassbox.rsi/glass-up.png | Bin 0 -> 158 bytes .../Structures/Storage/glassbox.rsi/glass.png | Bin 0 -> 238 bytes .../glassbox.rsi/glassbox-empty-open.png | Bin 0 -> 313 bytes .../glassbox.rsi/glassbox-filled-closed.png | Bin 0 -> 901 bytes .../glassbox.rsi/glassbox-filled-open.png | Bin 0 -> 796 bytes .../Storage/glassbox.rsi/glassbox.png | Bin 0 -> 313 bytes .../Storage/glassbox.rsi/locked.png | Bin 0 -> 116 bytes .../Structures/Storage/glassbox.rsi/meta.json | 50 +++++++ .../Storage/glassbox.rsi/unlocked.png | Bin 0 -> 119 bytes 17 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 Resources/Prototypes/Entities/Structures/Storage/glass_box.yml create mode 100644 Resources/Textures/Structures/Storage/glassbox.rsi/DamageOverlay_12.png create mode 100644 Resources/Textures/Structures/Storage/glassbox.rsi/DamageOverlay_4.png create mode 100644 Resources/Textures/Structures/Storage/glassbox.rsi/DamageOverlay_8.png create mode 100644 Resources/Textures/Structures/Storage/glassbox.rsi/caplaser.png create mode 100644 Resources/Textures/Structures/Storage/glassbox.rsi/glass-4.png create mode 100644 Resources/Textures/Structures/Storage/glassbox.rsi/glass-up.png create mode 100644 Resources/Textures/Structures/Storage/glassbox.rsi/glass.png create mode 100644 Resources/Textures/Structures/Storage/glassbox.rsi/glassbox-empty-open.png create mode 100644 Resources/Textures/Structures/Storage/glassbox.rsi/glassbox-filled-closed.png create mode 100644 Resources/Textures/Structures/Storage/glassbox.rsi/glassbox-filled-open.png create mode 100644 Resources/Textures/Structures/Storage/glassbox.rsi/glassbox.png create mode 100644 Resources/Textures/Structures/Storage/glassbox.rsi/locked.png create mode 100644 Resources/Textures/Structures/Storage/glassbox.rsi/meta.json create mode 100644 Resources/Textures/Structures/Storage/glassbox.rsi/unlocked.png diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml index 966be72c49a..7e19b1a4bbd 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml @@ -56,7 +56,7 @@ - type: entity id: LockerCaptainFilled - suffix: Filled + suffix: Filled, AntiqueLaser parent: LockerCaptain components: - type: StorageFill @@ -84,6 +84,31 @@ - id: ClothingShoesMiscWhite # DeltaV - add fancy shoes for HoP and cap - id: ClothingShoesBootsWinterCap #Delta V: Add departmental winter boots +- type: entity + id: LockerCaptainFilledNoLaser + suffix: Filled + parent: LockerCaptain + components: + - type: StorageFill + contents: + - id: ClothingOuterArmorCaptainCarapace + - id: NukeDisk + - id: PinpointerNuclear + - id: CaptainIDCard + - id: WeaponDisabler + - id: CommsComputerCircuitboard + - id: ClothingHeadsetAltCommand + - id: SpaceCash1000 + - id: PlushieNuke + prob: 0.1 + - id: CigarGoldCase + prob: 0.25 + - id: ClothingBeltSheathFilled + - id: DoorRemoteCommand + - id: RubberStampCaptain + - id: JetpackCaptainFilled + - id: MedalCase + - type: entity id: LockerHeadOfPersonnelFilled suffix: Filled diff --git a/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml b/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml new file mode 100644 index 00000000000..bdb02d2bc35 --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml @@ -0,0 +1,139 @@ +- type: entity + id: GlassBoxLaser + name: glass box + description: A sturdy showcase for an expensive exhibit. + parent: BaseStructureDynamic + placement: + mode: SnapgridCenter + components: + - type: Anchorable + delay: 4 + - type: Transform + anchored: true + - type: Damageable + damageContainer: Inorganic + damageModifierSet: Glass + - type: MeleeSound + soundGroups: + Brute: + collection: GlassSmash + - type: Physics + bodyType: Static + - type: Clickable + - type: InteractionOutline + - type: Sprite + sprite: Structures/Storage/glassbox.rsi + layers: + - state: glassbox + - state: caplaser + map: ["enum.ItemCabinetVisualLayers.ContainsItem"] + visible: true + - state: glass + map: ["enum.ItemCabinetVisualLayers.Door"] + - type: ItemCabinet + cabinetSlot: + ejectOnInteract: true + whitelist: + tags: + - WeaponAntiqueLaser + doorSound: + path: /Audio/Machines/machine_switch.ogg + openState: glass-up + closedState: glass + - type: Lock + - type: AccessReader + access: [["Captain"]] + - type: ItemSlots + - type: ContainerContainer + containers: + ItemCabinet: !type:ContainerSlot + - type: Repairable + - type: Appearance + - type: DamageVisuals + thresholds: [4, 8, 12] + damageDivisor: 7.555 + trackAllDamage: true + damageOverlay: + sprite: Structures/Storage/glassbox.rsi + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 150 + behaviors: + - !type:EmptyAllContainersBehaviour + - !type:PlaySoundBehavior + sound: + collection: WindowShatter + - !type:SpawnEntitiesBehavior + spawn: + ShardGlassReinforced: + min: 1 + max: 1 + GlassBoxLaserBroken: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + +- type: entity + id: GlassBoxLaserOpen + parent: GlassBoxLaser + suffix: Open + components: + - type: ItemCabinet + opened: true + doorSound: + path: /Audio/Machines/machine_switch.ogg + openState: glass-up + closedState: glass + +- type: entity + id: GlassBoxLaserFilled + parent: GlassBoxLaser + suffix: Filled + components: + - type: ItemCabinet + cabinetSlot: + startingItem: WeaponAntiqueLaser + ejectOnInteract: true + whitelist: + tags: + - WeaponAntiqueLaser + doorSound: + path: /Audio/Machines/machine_switch.ogg + openState: glass-up + closedState: glass + +- type: entity + id: GlassBoxLaserFilledOpen + parent: GlassBoxLaserFilled + suffix: Filled, Open + components: + - type: ItemCabinet + opened: true + doorSound: + path: /Audio/Machines/machine_switch.ogg + openState: glass-up + closedState: glass + +- type: entity + id: GlassBoxLaserBroken + name: broken glass box + description: A broken showcase for a stolen expensive exhibit. + parent: BaseStructureDynamic + suffix: Broken + placement: + mode: SnapgridCenter + components: + - type: Transform + anchored: true + - type: Physics + bodyType: Static + - type: Sprite + sprite: Structures/Storage/glassbox.rsi + layers: + - state: glassbox + - state: glass-4 + - type: Clickable + - type: InteractionOutline diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index 4d85f488a14..8e94128ce66 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -1160,6 +1160,9 @@ - type: Tag id: WallmountSubstationElectronics +- type: Tag + id: WeaponAntiqueLaser + - type: Tag id: WeaponPistolCHIMPUpgradeKit diff --git a/Resources/Textures/Structures/Storage/glassbox.rsi/DamageOverlay_12.png b/Resources/Textures/Structures/Storage/glassbox.rsi/DamageOverlay_12.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed908b6826c8a41841b0c2aed44360e134cae69 GIT binary patch literal 578 zcmV-I0=@l-P)Px${7FPXR9J=WmN7^IQ5eVn#YK&wMTIwb(BMH3E^Sgn6zw%RG~D9g6f`w-4ME`+ zH?%ZF*iu2Xm=Pk>q=ZYTL*PM0iCIBQ(9)m}UiR+ZdzRPIA4KrJ@B9Dmd*A!8YjN{r z4Sy&F02b!-fu8=sVK0q8UTcpBsnU}I03$>GsfTJUO9zBQ!DyjuCp!f&GUT5EaM;ay z*lBZGOn^e!PKHCl=uZmknrevr#sttc)hLwhBr8G0OxIMSRJq$}jVo2|c3NYZ03?}} z;1sWGszE-j=A?$MsYYL~@=iZfM2hobcyR=f#Dqh^=;O=VJ>bxRPKXAi2fQtSpAIOk zwg7(PmPiB8hHiU8^yUz8hmeSVYqurUI&eHm9YLXNCwc9cF$bC*c&OI16Jw(@5-c^B z_*;=$x$B!V08s3FF_H=RE)G(qeF=asGUKyx(@I-1IsSkTcD@*49>Gd%dYNY^YwlF@ z8^B6zdU<{OJmCspr7bf)8z<&8kdxN8&l4<&Z?}MFP9RMy&5aY0^de$)NTv&}0KBs& zMObmBm9|9kT>+emi%4X4Tmi^X@rpPZiOvrF4FFw}^BbAny`}Nhty8Ic+^)zA_yay% z9bY!~z}8XD6LX-^DSBW%`$IyDUR>P(P``in9D;Z%0AS~f5zh(!^{=Kr0a26v9nrov QWB>pF07*qoM6N<$f~XV#od5s; literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/glassbox.rsi/DamageOverlay_4.png b/Resources/Textures/Structures/Storage/glassbox.rsi/DamageOverlay_4.png new file mode 100644 index 0000000000000000000000000000000000000000..e6a50bde32ea637d4d66e76cd6f994ce09cc5df4 GIT binary patch literal 332 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^TBT9ewro`uzIF`q=~feR%K3)`H&G*~_O)64F?@+rq6*@m2jAfcbq{L_LCGwK}C za`|SuRVO_`!I10R{fZ4!W*t0#fPuI1x&D1QgUf-1%8vK5g{~$y1c$$Slav4il?A_M zy|v3+czE^p_;|N={1jdLH*66&+_iH$On0Z$laJOxQJKW5;n z@e^fNux_~%uplbdAuogH?5T_^jEB!N=Fi`^c=u5Q>qrS8kejnF&AVK@rzwzul|erz Wa)sxCKg)r^!{F)a=d#Wzp$P!S{fI>X literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/glassbox.rsi/DamageOverlay_8.png b/Resources/Textures/Structures/Storage/glassbox.rsi/DamageOverlay_8.png new file mode 100644 index 0000000000000000000000000000000000000000..f1b8f6f516324f9ff4758dd57f4e04d6b64e2fab GIT binary patch literal 413 zcmV;O0b>4%P)Px$S4l)cR9J=Wl_5{VKorOSG>0cEWGpiih>>7s=9)~=pb2V%FL2pcpp)38U!jPHC+$^vNA?H+)8E9+y~=AtqIqJ#yVcB@|* z0Eeg)pe$`y);PfS^%@7@5QPAAHmDMS&MC!UEk(iU7cJ zwVrj)PR=FrQpxy#n!mk20{~%R?7TEe3?S zqSOHVsqayja&r+#R=KAj3qmzll$KRoqzc;J0@aFC@)%_T@TM{iKmcHH*`+t5CoN4S zD+>Td4|AjDVx=qT0kL5%09b!~8;9VY1OQkVJH`oi+UZXl0bqm@oNnGV00000NkvXX Hu0mjfME0?l literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/glassbox.rsi/caplaser.png b/Resources/Textures/Structures/Storage/glassbox.rsi/caplaser.png new file mode 100644 index 0000000000000000000000000000000000000000..4af9023cd0c9e802f602ee551d0e7ec7dfcc2a4d GIT binary patch literal 557 zcmV+|0@D47P)Px$=Sf6CR9J=WlTT|CK^Vq=>29+5BPb+`7&bzWOAnp`dyYb}x#=PViv=NIzeFxl zsP+TYFX2H$D_&cuduTmbHyR?ihDJ#sm;|$%C60%h;Kl96iaCf`XUF3%U23whpu_)04MljTC5dv|ZrY&1~PNdQ{S7LT{KE;J7{f)~$C z?00!u%_fbHO*HKqqrnhG9s%(3)oau%zZ<)*v7{&{sq;iMO%v^Q`>!d48G+c_+XuiK z|KN^kVi*PhmSv%;D&1}ufZg3^bUJ6OtmtfSKSh>hI-L$d4TMP`RxYp2A6>Cn#Pd8{ z*PUHJ%r3II`AF1iHR4hnS(ZsEN?`Gs!9wV|E_%HlqtS@*csxJ9zJ6aE92^3W&1P|3 z7u&Wk^bh?F!{Rtj%yFF1`lSW^g>Bp9aye90h4c8ut+fqta`Ki;CbOX3;t9lbT^9g5 vJ5M-0wE;Lf{)}zg@DC%6h=_=Y`0xAz<}t3-?nQhm00000NkvXXu0mjfwPNxI literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/glassbox.rsi/glass-4.png b/Resources/Textures/Structures/Storage/glassbox.rsi/glass-4.png new file mode 100644 index 0000000000000000000000000000000000000000..acb2054a66f01a43ae5e547c98db81943bd24f8b GIT binary patch literal 377 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?4jBOuH;Rhv(mfq_xm z)5S5QVoq|RM1sMqhCucntAr1h38$Cd4zB$YvUz1Dr=9V~HU`Z;#+9rWcU*aF)Xf?z zxN+J-X|_krM?9w{cfP-KWybUb;ZJ{_-ex`$!B(uIR~Yofp-gxxM+%7aVG)2^UG2F>Dro!w_I{qrKz}^Q8jT7d26g)0(rj=18y!^z120xM0b^u!#2~ V%dd&MyMSTI;OXk;vd$@?2>^e4l6e3C literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/glassbox.rsi/glass-up.png b/Resources/Textures/Structures/Storage/glassbox.rsi/glass-up.png new file mode 100644 index 0000000000000000000000000000000000000000..39a32dfef5c218fd9da5b79920a2ef6796327419 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}5uPrNArY;~ zIv+0nJa5p@(AwD8=olJU;h?j>_P_2CMjjxzIho(+(&bMpcYgaXDIp;-<3*;XnZc`u zK=vN1ge#29?--6XuIq6-s3F0+I6sxELj2-n54gZZ9at$TTQVp)?cgVtn8HjWK4F~JXy7&IglENK*c b%fL|eMf;1%zv9C{w=#IT`njxgN@xNA3sG5> literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/glassbox.rsi/glassbox-empty-open.png b/Resources/Textures/Structures/Storage/glassbox.rsi/glassbox-empty-open.png new file mode 100644 index 0000000000000000000000000000000000000000..3a3bf591ca5d62d6434a459175a4a8783e9af0d0 GIT binary patch literal 313 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?4jBOuH;Rhv&5DEQjb z#WAE}PI96|g2AhXK=vN1ge#1T`6Nmiyr*paRG-3V=;+rL{(k@EBStxCn;Td{MOz;- zZGXQ%b%WWYg`Lb7&a!7!?>LYJb}?A6|5JdPdUD zrF|xCvCQ*1+-1R*@Nlv7WO#C{V)yagd0^5`J070p{`E^%G8fhUcu-bbarn>yrd0wG z4m127e0h0XqozX2VV&T_n_E~u+!6?K7Z&H*@Jl9advit+qldkhp2f#W@-qxREN4vN zKDkxqrkvP}euphWx69iehu<^2Af(~V-T1chtK1=WhIdPn{HDIU#R>E_gQu&X%Q~lo FCIE({b}#?{ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/glassbox.rsi/glassbox-filled-closed.png b/Resources/Textures/Structures/Storage/glassbox.rsi/glassbox-filled-closed.png new file mode 100644 index 0000000000000000000000000000000000000000..b558cf5212c681f9d39908c8262d0aea5cc40aa1 GIT binary patch literal 901 zcmV;01A6?4P)Px&KS@MER9J=Wl}m3MRTze!86RI}V$;}hF14FpNL&>VAR(a?K|>dSgu((AWswbg zulNO(y5tY=3s^wgRgqd%iquj<)0Ctnuz)61r8KUo?f4QWGxl7LyKpw5`s zaIo(*a8cb$)4z*-fPH{{fE@wc|M^aOX?`}nmFBk}XVMGP*SFNPhUipyZ(+_Ws(<~J zH?HUr01TrFfHIoGwk+nZO{Fz0#49J?`SKqF{BrX~+LaO-4SYTy^DmA7Af=0{`jFB^ zh~`aRuh&r&l}1Binze0f3-|8Tv#SpiEX~|_89)mP%(~+Vma`S!c=HslwD73`Z$1+4 zp;R^yqCq6wLuz!GO0kGfG}lzFRG6EeXX(3dy|2|;JMh*x?%k_rMK~l_{rwIfe|iQ0 z%a#QEn_DASsSyYq#j^h3=#j%%mW>bsDJ8aT1F&J#h=g_GeFyLh0g8g-I2=Bbz;#_> zJ^trv&tAJiI3!R$`sDM5cBq%s3w0J(B*Q&5Vo}`#xP1EolarGGxQ@*?=P!^jHQF{u2)Um# literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/glassbox.rsi/glassbox-filled-open.png b/Resources/Textures/Structures/Storage/glassbox.rsi/glassbox-filled-open.png new file mode 100644 index 0000000000000000000000000000000000000000..48db8e88e598cda3e7e3d2d168f4efbe85d3e362 GIT binary patch literal 796 zcmV+%1LOROP)Px%)=5M`R9J=WmS0FyQ5?rVZr9Dbg}Q8-|3VWVM6n2lR}2CRB`@Gz9&i$R= z_sj3xbIye{Y0{)gvkltX+LV@-79~-P)oN858ygeGL?R>`c)9hGvL09iU>H<^>4H)K zzAnuJFrd}q@pzCVNimzv^!N8?B+8rce8+%TdS6ON)5_ zVG+@=L3wEr=g%F-J~f5jkOhFl?%-xe2a)+>a{~zZCXveWJaxc6cy3E0QDuAj>jlvze8Z6`nkLKu^zoM#smguCAi9^EQGI z|B1zFWn4R5qr_HVU}7O^(%`I1ZCflBLZJ|Tzn^U1BGbPF4jMyhTzh*vhihxO)zw9o zUQgi5q&m00rZ}$JN$rBVGLzbNd%di#uHyB2sV&G-#Ve0C^KIiby}iBU<>le``_Zg? z`fu)}w_&mrYCPcbpi44-TL!{Q;i9Ul3Q-gpoc#>IiRM;DM&4mG8o}q;mf>v~s4Fw! z7WV_t-QC6Hqz!<#!*kedwy34r6$1d-zC{4;UcVA&E)_H>&DufI1~d>pog$yRNvu}J zy{pHR+T8OzSW4CYkJaA@_8BM4ICn*GD~5*Vqx$MLj69a{d*ol5Y}K(Nx7FbuwcAh#U*wQ%agF6~%j_ a`hNfqy%slc>Gk{o00007!?>LYJb}?A6|5JdPdUD zrF|xCvCQ*1+-1R*@Nlv7WO#C{V)yagd0^5`J070p{`E^%G8fhUcu-bbarn>yrd0wG z4m127e0h0XqozX2VV&T_n_E~u+!6?K7Z&H*@Jl9advit+qldkhp2f#W@-qxREN4vN zKDkxqrkvP}euphWx69iehu<^2Af(~V-T1chtK1=WhIdPn{HDIU#R>E_gQu&X%Q~lo FCIE({b}#?{ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Storage/glassbox.rsi/locked.png b/Resources/Textures/Structures/Storage/glassbox.rsi/locked.png new file mode 100644 index 0000000000000000000000000000000000000000..f5739c805870a0a1fc99f4fee29dcd5904470eaa GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}dY&$hArY-_ z&n#qQP~c(Ncqne}zG_CX*k*-7^?%Ah1rIh}lwEhG_WPQw`oC`(q~lna?#VZY~6>gNOPvQWosaTWJUc0sS`wHW~U$-+W%CRsl>O8*$ PD8bgTe~DWM4f6x<{x literal 0 HcmV?d00001 From 6737912059efe710192d3b48b57c432355bf1d40 Mon Sep 17 00:00:00 2001 From: Jezithyr Date: Sat, 10 Feb 2024 15:37:06 -0800 Subject: [PATCH 042/200] Gibbing refactor (Per-part gibbing and giblet throwing!) (#24989) * Moving Gibbing rework out from medrefactor into it's own PR * Re-enabled warning for missing gibbable on TryGibEntity * Implemented better logic for gibbing failover and better logging * Allowing audio params and drop scattering customization per component. Created UnGibbable organ base types and made brains ungibbable. Removed delete brain from gibBody function. Artifact crusher does not destroy brains anymore. It only destroyed brains before not other organs which was wierd. * Update Content.Shared/Body/Systems/SharedBodySystem.Body.cs Fixing space for multiplication Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> * Added event raised when attempting to gib contained entities to allow modification of allowed and excluded container ids * removing audioParams var from component (sound specifier includes it) * Fixing signature --------- Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> (cherry picked from commit 541d8f8715e4e74a77501863c2573aaa1eb33add) --- Content.Server/Body/Systems/BodySystem.cs | 37 +- .../Systems/ArtifactCrusherSystem.cs | 2 +- .../Body/Systems/SharedBodySystem.Body.cs | 41 ++- .../Gibbing/Components/GibbableComponent.cs | 34 ++ .../Gibbing/Events/GibbingEvents.cs | 50 +++ .../Gibbing/Systems/GibbingSystem.cs | 341 ++++++++++++++++++ .../Prototypes/Body/Organs/Animal/animal.yml | 8 +- Resources/Prototypes/Body/Organs/human.yml | 11 +- Resources/Prototypes/Body/Parts/animal.yml | 1 + Resources/Prototypes/Body/Parts/base.yml | 1 + Resources/Prototypes/Body/Parts/skeleton.yml | 1 + .../Prototypes/Body/Parts/terminator.yml | 1 + 12 files changed, 493 insertions(+), 35 deletions(-) create mode 100644 Content.Shared/Gibbing/Components/GibbableComponent.cs create mode 100644 Content.Shared/Gibbing/Events/GibbingEvents.cs create mode 100644 Content.Shared/Gibbing/Systems/GibbingSystem.cs diff --git a/Content.Server/Body/Systems/BodySystem.cs b/Content.Server/Body/Systems/BodySystem.cs index 1630d4cb10d..0e9b295f718 100644 --- a/Content.Server/Body/Systems/BodySystem.cs +++ b/Content.Server/Body/Systems/BodySystem.cs @@ -15,6 +15,7 @@ using Robust.Shared.Random; using Robust.Shared.Timing; using System.Numerics; +using Content.Shared.Gibbing.Components; using Content.Shared.Movement.Systems; using Robust.Shared.Audio.Systems; @@ -106,7 +107,17 @@ protected override void RemovePart( _humanoidSystem.SetLayersVisibility(bodyUid, layers, false, true, humanoid); } - public override HashSet GibBody(EntityUid bodyId, bool gibOrgans = false, BodyComponent? body = null, bool deleteItems = false, bool deleteBrain = false) + public override HashSet GibBody( + EntityUid bodyId, + bool gibOrgans = false, + BodyComponent? body = null , + bool deleteItems = false, + bool launchGibs = true, + Vector2? splatDirection = null, + float splatModifier = 1, + Angle splatCone = default, + SoundSpecifier? gibSoundOverride = null + ) { if (!Resolve(bodyId, ref body, false)) return new HashSet(); @@ -118,28 +129,8 @@ public override HashSet GibBody(EntityUid bodyId, bool gibOrgans = fa if (xform.MapUid == null) return new HashSet(); - var gibs = base.GibBody(bodyId, gibOrgans, body, deleteItems, deleteBrain); - - var coordinates = xform.Coordinates; - var filter = Filter.Pvs(bodyId, entityManager: EntityManager); - var audio = AudioParams.Default.WithVariation(0.025f); - - _audio.PlayStatic(body.GibSound, filter, coordinates, true, audio); - - foreach (var entity in gibs) - { - if (deleteItems) - { - if (!HasComp(entity) || deleteBrain) - { - QueueDel(entity); - } - } - else - { - SharedTransform.SetCoordinates(entity, coordinates.Offset(_random.NextVector2(.3f))); - } - } + var gibs = base.GibBody(bodyId, gibOrgans, body, deleteItems, launchGibs: launchGibs, + splatDirection: splatDirection, splatModifier: splatModifier, splatCone:splatCone); RaiseLocalEvent(bodyId, new BeingGibbedEvent(gibs)); QueueDel(bodyId); diff --git a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactCrusherSystem.cs b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactCrusherSystem.cs index 09fdc260d7c..6606f284327 100644 --- a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactCrusherSystem.cs +++ b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactCrusherSystem.cs @@ -106,7 +106,7 @@ public void FinishCrushing(Entity(contained, out var body)) Del(contained); - var gibs = _body.GibBody(contained, body: body, gibOrgans: true, deleteBrain: true); + var gibs = _body.GibBody(contained, body: body, gibOrgans: true); foreach (var gib in gibs) { ContainerSystem.Insert((gib, null, null, null), crusher.OutputContainer); diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Body.cs b/Content.Shared/Body/Systems/SharedBodySystem.Body.cs index e5e4edddb07..85b6758d78a 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Body.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Body.cs @@ -5,8 +5,13 @@ using Content.Shared.Body.Part; using Content.Shared.Body.Prototypes; using Content.Shared.DragDrop; +using Content.Shared.Gibbing.Components; +using Content.Shared.Gibbing.Events; +using Content.Shared.Gibbing.Systems; using Content.Shared.Inventory; using Content.Shared.Inventory.Events; +using Robust.Shared.Audio; +using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Utility; @@ -23,7 +28,10 @@ public partial class SharedBodySystem */ [Dependency] private readonly InventorySystem _inventory = default!; - + [Dependency] private readonly GibbingSystem _gibbingSystem = default!; + [Dependency] private readonly SharedAudioSystem _audioSystem = default!; + private const float GibletLaunchImpulse = 8; + private const float GibletLaunchImpulseVariance = 3; private void InitializeBody() { // Body here to handle root body parts. @@ -263,29 +271,45 @@ public IEnumerable GetBodyAllSlots(EntityUid bodyId, BodyComponent } } - public virtual HashSet GibBody(EntityUid bodyId, bool gibOrgans = false, - BodyComponent? body = null, bool deleteItems = false, bool deleteBrain = false) + public virtual HashSet GibBody( + EntityUid bodyId, + bool gibOrgans = false, + BodyComponent? body = null , + bool deleteItems = false, + bool launchGibs = true, + Vector2? splatDirection = null, + float splatModifier = 1, + Angle splatCone = default, + SoundSpecifier? gibSoundOverride = null + ) { var gibs = new HashSet(); if (!Resolve(bodyId, ref body, false)) return gibs; + var root = GetRootPartOrNull(bodyId, body); + if (root != null && TryComp(root.Value.Entity, out GibbableComponent? gibbable)) + { + gibSoundOverride ??= gibbable.GibSound; + } var parts = GetBodyChildren(bodyId, body).ToArray(); gibs.EnsureCapacity(parts.Length); - foreach (var part in parts) { - SharedTransform.AttachToGridOrMap(part.Id); - gibs.Add(part.Id); + + _gibbingSystem.TryGibEntityWithRef(bodyId, part.Id, GibType.Gib, GibContentsOption.Skip, ref gibs, + playAudio: false, launchGibs:true, launchDirection:splatDirection, launchImpulse: GibletLaunchImpulse * splatModifier, + launchImpulseVariance:GibletLaunchImpulseVariance, launchCone: splatCone); if (!gibOrgans) continue; foreach (var organ in GetPartOrgans(part.Id, part.Component)) { - SharedTransform.AttachToGridOrMap(organ.Id); - gibs.Add(organ.Id); + _gibbingSystem.TryGibEntityWithRef(bodyId, organ.Id, GibType.Drop, GibContentsOption.Skip, + ref gibs, playAudio: false, launchImpulse: GibletLaunchImpulse * splatModifier, + launchImpulseVariance:GibletLaunchImpulseVariance, launchCone: splatCone); } } if(TryComp(bodyId, out var inventory)) @@ -296,6 +320,7 @@ public virtual HashSet GibBody(EntityUid bodyId, bool gibOrgans = fal gibs.Add(item); } } + _audioSystem.PlayPredicted(gibSoundOverride, Transform(bodyId).Coordinates, null); return gibs; } } diff --git a/Content.Shared/Gibbing/Components/GibbableComponent.cs b/Content.Shared/Gibbing/Components/GibbableComponent.cs new file mode 100644 index 00000000000..9c7501f0282 --- /dev/null +++ b/Content.Shared/Gibbing/Components/GibbableComponent.cs @@ -0,0 +1,34 @@ +using Content.Shared.Gibbing.Systems; +using Robust.Shared.Audio; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Gibbing.Components; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(GibbingSystem))] +public sealed partial class GibbableComponent : Component +{ + /// + /// Giblet entity prototypes to randomly select from when spawning additional giblets + /// + [DataField, AutoNetworkedField] + public List GibPrototypes = new(); + + /// + /// Number of giblet entities to spawn in addition to entity contents + /// + [DataField, AutoNetworkedField] + public int GibCount; + + /// + /// Sound to be played when this entity is gibbed, only played when playsound is true on the gibbing function + /// + [DataField, AutoNetworkedField] + public SoundSpecifier? GibSound = new SoundCollectionSpecifier("gib", AudioParams.Default.WithVariation(0.025f)); + + /// + /// Max distance giblets can be dropped from an entity when NOT using physics-based scattering + /// + [DataField, AutoNetworkedField] + public float GibScatterRange = 0.3f; +} diff --git a/Content.Shared/Gibbing/Events/GibbingEvents.cs b/Content.Shared/Gibbing/Events/GibbingEvents.cs new file mode 100644 index 00000000000..949b10eab9a --- /dev/null +++ b/Content.Shared/Gibbing/Events/GibbingEvents.cs @@ -0,0 +1,50 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.Gibbing.Events; + + + +/// +/// Called just before we actually gib the target entity +/// +/// The entity being gibed +/// What type of gibbing is occuring +/// Containers we are allow to gib +/// Containers we are allow not allowed to gib +[ByRefEvent] public record struct AttemptEntityContentsGibEvent( + EntityUid Target, + GibContentsOption GibType, + List? AllowedContainers, + List? ExcludedContainers + ); + + +/// +/// Called just before we actually gib the target entity +/// +/// The entity being gibed +/// how many giblets to spawn +/// What type of gibbing is occuring +[ByRefEvent] public record struct AttemptEntityGibEvent(EntityUid Target, int GibletCount, GibType GibType); + +/// +/// Called immediately after we gib the target entity +/// +/// The entity being gibbed +/// Any entities that are spilled out (if any) +[ByRefEvent] public record struct EntityGibbedEvent(EntityUid Target, List DroppedEntities); + +[Serializable, NetSerializable] +public enum GibType : byte +{ + Skip, + Drop, + Gib, +} + +public enum GibContentsOption : byte +{ + Skip, + Drop, + Gib +} diff --git a/Content.Shared/Gibbing/Systems/GibbingSystem.cs b/Content.Shared/Gibbing/Systems/GibbingSystem.cs new file mode 100644 index 00000000000..5d00b2a4912 --- /dev/null +++ b/Content.Shared/Gibbing/Systems/GibbingSystem.cs @@ -0,0 +1,341 @@ +using System.Diagnostics.CodeAnalysis; +using System.Numerics; +using Content.Shared.Gibbing.Components; +using Content.Shared.Gibbing.Events; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Containers; +using Robust.Shared.Map; +using Robust.Shared.Physics.Systems; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; + +namespace Content.Shared.Gibbing.Systems; + +public sealed class GibbingSystem : EntitySystem +{ + [Dependency] private readonly SharedContainerSystem _containerSystem = default!; + [Dependency] private readonly SharedTransformSystem _transformSystem = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly SharedAudioSystem _audioSystem = default!; + [Dependency] private readonly SharedPhysicsSystem _physicsSystem = default!; + [Dependency] private readonly IRobustRandom _random = default!; + + //TODO: (future optimization) implement a system that "caps" giblet entities by deleting the oldest ones once we reach a certain limit, customizable via CVAR + + /// + /// Attempt to gib a specified entity. That entity must have a gibable components. This method is NOT recursive will only + /// work on the target and any entities it contains (depending on gibContentsOption) + /// + /// The outermost entity we care about, used to place the dropped items + /// Target entity/comp we wish to gib + /// What type of gibing are we performing + /// What type of gibing do we perform on any container contents? + /// a hashset containing all the entities that have been dropped/created + /// How much to multiply the random spread on dropped giblets(if we are dropping them!) + /// Should we play audio + /// A list of containerIds on the target that permit gibing + /// A list of containerIds on the target that DO NOT permit gibing + /// The cone we are launching giblets in (if we are launching them!) + /// Should we launch giblets or just drop them + /// The direction to launch giblets (if we are launching them!) + /// The impluse to launch giblets at(if we are launching them!) + /// /// Should we log if we are missing a gibbableComp when we call this function + /// The variation in giblet launch impulse (if we are launching them!) + /// True if successful, false if not + public bool TryGibEntity(EntityUid outerEntity, Entity gibbable, GibType gibType, + GibContentsOption gibContentsOption, + out HashSet droppedEntities, bool launchGibs = true, + Vector2 launchDirection = default, float launchImpulse = 0f, float launchImpulseVariance = 0f, + Angle launchCone = default, + float randomSpreadMod = 1.0f, bool playAudio = true, List? allowedContainers = null, + List? excludedContainers = null, bool logMissingGibable = false) + { + droppedEntities = new(); + return TryGibEntityWithRef(outerEntity, gibbable, gibType, gibContentsOption, ref droppedEntities, + launchGibs, launchDirection, launchImpulse, launchImpulseVariance, launchCone, randomSpreadMod, playAudio, + allowedContainers, excludedContainers, logMissingGibable); + } + + + /// + /// Attempt to gib a specified entity. That entity must have a gibable components. This method is NOT recursive will only + /// work on the target and any entities it contains (depending on gibContentsOption) + /// + /// The outermost entity we care about, used to place the dropped items + /// Target entity/comp we wish to gib + /// What type of gibing are we performing + /// What type of gibing do we perform on any container contents? + /// a hashset containing all the entities that have been dropped/created + /// How much to multiply the random spread on dropped giblets(if we are dropping them!) + /// Should we play audio + /// A list of containerIds on the target that permit gibing + /// A list of containerIds on the target that DO NOT permit gibing + /// The cone we are launching giblets in (if we are launching them!) + /// Should we launch giblets or just drop them + /// The direction to launch giblets (if we are launching them!) + /// The impluse to launch giblets at(if we are launching them!) + /// The variation in giblet launch impulse (if we are launching them!) + /// Should we log if we are missing a gibbableComp when we call this function + /// True if successful, false if not + public bool TryGibEntityWithRef( + EntityUid outerEntity, + Entity gibbable, + GibType gibType, + GibContentsOption gibContentsOption, + ref HashSet droppedEntities, + bool launchGibs = true, + Vector2? launchDirection = null, + float launchImpulse = 0f, + float launchImpulseVariance = 0f, + Angle launchCone = default, + float randomSpreadMod = 1.0f, + bool playAudio = true, + List? allowedContainers = null, + List? excludedContainers = null, + bool logMissingGibable = false) + { + if (!Resolve(gibbable, ref gibbable.Comp, logMissing: false)) + { + DropEntity(gibbable, Transform(outerEntity), randomSpreadMod, ref droppedEntities, + launchGibs, launchDirection, launchImpulse, launchImpulseVariance, launchCone); + if (logMissingGibable) + { + Log.Warning($"{ToPrettyString(gibbable)} does not have a GibbableComponent! " + + $"This is not required but may cause issues contained items to not be dropped."); + } + + return false; + } + + if (gibType == GibType.Skip && gibContentsOption == GibContentsOption.Skip) + return true; + if (launchGibs) + { + randomSpreadMod = 0; + } + + var parentXform = Transform(outerEntity); + HashSet validContainers = new(); + var gibContentsAttempt = + new AttemptEntityContentsGibEvent(gibbable, gibContentsOption, allowedContainers, excludedContainers); + RaiseLocalEvent(gibbable, ref gibContentsAttempt); + + foreach (var container in _containerSystem.GetAllContainers(gibbable)) + { + var valid = true; + if (allowedContainers != null) + valid = allowedContainers.Contains(container.ID); + if (excludedContainers != null) + valid = valid && !excludedContainers.Contains(container.ID); + if (valid) + validContainers.Add(container); + } + + switch (gibContentsOption) + { + case GibContentsOption.Skip: + break; + case GibContentsOption.Drop: + { + foreach (var container in validContainers) + { + foreach (var ent in container.ContainedEntities) + { + DropEntity(new Entity(ent, null), parentXform, randomSpreadMod, + ref droppedEntities, launchGibs, + launchDirection, launchImpulse, launchImpulseVariance, launchCone); + } + } + + break; + } + case GibContentsOption.Gib: + { + foreach (var container in _containerSystem.GetAllContainers(gibbable)) + { + foreach (var ent in container.ContainedEntities) + { + GibEntity(new Entity(ent, null), parentXform, randomSpreadMod, + ref droppedEntities, launchGibs, + launchDirection, launchImpulse, launchImpulseVariance, launchCone); + } + } + + break; + } + } + + switch (gibType) + { + case GibType.Skip: + break; + case GibType.Drop: + { + DropEntity(gibbable, parentXform, randomSpreadMod, ref droppedEntities, launchGibs, + launchDirection, launchImpulse, launchImpulseVariance, launchCone); + break; + } + case GibType.Gib: + { + GibEntity(gibbable, parentXform, randomSpreadMod, ref droppedEntities, launchGibs, + launchDirection, launchImpulse, launchImpulseVariance, launchCone); + break; + } + } + + if (playAudio) + { + _audioSystem.PlayPredicted(gibbable.Comp.GibSound, parentXform.Coordinates, null); + } + + if (gibType == GibType.Gib) + QueueDel(gibbable); + return true; + } + + private void DropEntity(Entity gibbable, TransformComponent parentXform, float randomSpreadMod, + ref HashSet droppedEntities, bool flingEntity, Vector2? scatterDirection, float scatterImpulse, + float scatterImpulseVariance, Angle scatterCone) + { + var gibCount = 0; + if (Resolve(gibbable, ref gibbable.Comp, logMissing: false)) + { + gibCount = gibbable.Comp.GibCount; + } + + var gibAttemptEvent = new AttemptEntityGibEvent(gibbable, gibCount, GibType.Drop); + RaiseLocalEvent(gibbable, ref gibAttemptEvent); + switch (gibAttemptEvent.GibType) + { + case GibType.Skip: + return; + case GibType.Gib: + GibEntity(gibbable, parentXform, randomSpreadMod, ref droppedEntities, flingEntity, scatterDirection, + scatterImpulse, scatterImpulseVariance, scatterCone, deleteTarget: false); + return; + } + + _transformSystem.AttachToGridOrMap(gibbable); + _transformSystem.SetCoordinates(gibbable, parentXform.Coordinates); + _transformSystem.SetWorldRotation(gibbable, _random.NextAngle()); + droppedEntities.Add(gibbable); + if (flingEntity) + { + FlingDroppedEntity(gibbable, scatterDirection, scatterImpulse, scatterImpulseVariance, scatterCone); + } + + var gibbedEvent = new EntityGibbedEvent(gibbable, new List {gibbable}); + RaiseLocalEvent(gibbable, ref gibbedEvent); + } + + private List GibEntity(Entity gibbable, TransformComponent parentXform, + float randomSpreadMod, + ref HashSet droppedEntities, bool flingEntity, Vector2? scatterDirection, float scatterImpulse, + float scatterImpulseVariance, Angle scatterCone, bool deleteTarget = true) + { + var localGibs = new List(); + var gibCount = 0; + var gibProtoCount = 0; + if (Resolve(gibbable, ref gibbable.Comp, logMissing: false)) + { + gibCount = gibbable.Comp.GibCount; + gibProtoCount = gibbable.Comp.GibPrototypes.Count; + } + + var gibAttemptEvent = new AttemptEntityGibEvent(gibbable, gibCount, GibType.Drop); + RaiseLocalEvent(gibbable, ref gibAttemptEvent); + switch (gibAttemptEvent.GibType) + { + case GibType.Skip: + return localGibs; + case GibType.Drop: + DropEntity(gibbable, parentXform, randomSpreadMod, ref droppedEntities, flingEntity, + scatterDirection, scatterImpulse, scatterImpulseVariance, scatterCone); + localGibs.Add(gibbable); + return localGibs; + } + + if (gibbable.Comp != null && gibProtoCount > 0) + { + if (flingEntity) + { + for (var i = 0; i < gibAttemptEvent.GibletCount; i++) + { + if (!TryCreateRandomGiblet(gibbable.Comp, parentXform.Coordinates, false, out var giblet, + randomSpreadMod)) + continue; + FlingDroppedEntity(giblet.Value, scatterDirection, scatterImpulse, scatterImpulseVariance, + scatterCone); + droppedEntities.Add(giblet.Value); + } + } + else + { + for (var i = 0; i < gibAttemptEvent.GibletCount; i++) + { + if (TryCreateRandomGiblet(gibbable.Comp, parentXform.Coordinates, false, out var giblet, + randomSpreadMod)) + droppedEntities.Add(giblet.Value); + } + } + } + + _transformSystem.AttachToGridOrMap(gibbable, Transform(gibbable)); + if (flingEntity) + { + FlingDroppedEntity(gibbable, scatterDirection, scatterImpulse, scatterImpulseVariance, scatterCone); + } + + var gibbedEvent = new EntityGibbedEvent(gibbable, localGibs); + RaiseLocalEvent(gibbable, ref gibbedEvent); + if (deleteTarget) + QueueDel(gibbable); + return localGibs; + } + + + public bool TryCreateRandomGiblet(Entity gibbable, [NotNullWhen(true)] out EntityUid? gibletEntity, + float randomSpreadModifier = 1.0f, bool playSound = true) + { + gibletEntity = null; + return Resolve(gibbable, ref gibbable.Comp) && TryCreateRandomGiblet(gibbable.Comp, Transform(gibbable).Coordinates, + playSound, out gibletEntity, randomSpreadModifier); + } + + public bool TryCreateAndFlingRandomGiblet(Entity gibbable, [NotNullWhen(true)] out EntityUid? gibletEntity, + Vector2 scatterDirection, float force, float scatterImpulseVariance, Angle scatterCone = default, + bool playSound = true) + { + gibletEntity = null; + if (!Resolve(gibbable, ref gibbable.Comp) || + !TryCreateRandomGiblet(gibbable.Comp, Transform(gibbable).Coordinates, playSound, out gibletEntity)) + return false; + FlingDroppedEntity(gibletEntity.Value, scatterDirection, force, scatterImpulseVariance, scatterCone); + return true; + } + + private void FlingDroppedEntity(EntityUid target, Vector2? direction, float impulse, float impulseVariance, + Angle scatterConeAngle) + { + var scatterAngle = direction?.ToAngle() ?? _random.NextAngle(); + var scatterVector = _random.NextAngle(scatterAngle - scatterConeAngle / 2, scatterAngle + scatterConeAngle / 2) + .ToVec() * (impulse + _random.NextFloat(impulseVariance)); + _physicsSystem.ApplyLinearImpulse(target, scatterVector); + } + + private bool TryCreateRandomGiblet(GibbableComponent gibbable, EntityCoordinates coords, + bool playSound, [NotNullWhen(true)] out EntityUid? gibletEntity, float? randomSpreadModifier = null) + { + gibletEntity = null; + if (gibbable.GibPrototypes.Count == 0) + return false; + gibletEntity = Spawn(gibbable.GibPrototypes[_random.Next(0, gibbable.GibPrototypes.Count)], + randomSpreadModifier == null + ? coords + : coords.Offset(_random.NextVector2(gibbable.GibScatterRange * randomSpreadModifier.Value))); + if (playSound) + _audioSystem.PlayPredicted(gibbable.GibSound, coords, null); + _transformSystem.SetWorldRotation(gibletEntity.Value, _random.NextAngle()); + return true; + } +} diff --git a/Resources/Prototypes/Body/Organs/Animal/animal.yml b/Resources/Prototypes/Body/Organs/Animal/animal.yml index 358fc74bca6..2f50821df35 100644 --- a/Resources/Prototypes/Body/Organs/Animal/animal.yml +++ b/Resources/Prototypes/Body/Organs/Animal/animal.yml @@ -1,5 +1,5 @@ - type: entity - id: BaseAnimalOrgan + id: BaseAnimalOrganUnGibbable parent: BaseItem abstract: true components: @@ -23,6 +23,12 @@ tags: - Meat +- type: entity + id: BaseAnimalOrgan + parent: BaseAnimalOrganUnGibbable + abstract: true + components: + - type: Gibbable - type: entity id: OrganAnimalLungs diff --git a/Resources/Prototypes/Body/Organs/human.yml b/Resources/Prototypes/Body/Organs/human.yml index 6abf168a9e7..fe33c11029f 100644 --- a/Resources/Prototypes/Body/Organs/human.yml +++ b/Resources/Prototypes/Body/Organs/human.yml @@ -1,5 +1,5 @@ - type: entity - id: BaseHumanOrgan + id: BaseHumanOrganUnGibbable parent: BaseItem abstract: true components: @@ -27,9 +27,16 @@ tags: - Meat +- type: entity + id: BaseHumanOrgan + parent: BaseHumanOrganUnGibbable + abstract: true + components: + - type: Gibbable + - type: entity id: OrganHumanBrain - parent: BaseHumanOrgan + parent: BaseHumanOrganUnGibbable name: brain description: "The source of incredible, unending intelligence. Honk." components: diff --git a/Resources/Prototypes/Body/Parts/animal.yml b/Resources/Prototypes/Body/Parts/animal.yml index cf65fd21360..4db026b40fb 100644 --- a/Resources/Prototypes/Body/Parts/animal.yml +++ b/Resources/Prototypes/Body/Parts/animal.yml @@ -23,6 +23,7 @@ - type: Tag tags: - Trash + - type: Gibbable - type: Extractable juiceSolution: reagents: diff --git a/Resources/Prototypes/Body/Parts/base.yml b/Resources/Prototypes/Body/Parts/base.yml index a27059f59f3..836d0f140af 100644 --- a/Resources/Prototypes/Body/Parts/base.yml +++ b/Resources/Prototypes/Body/Parts/base.yml @@ -9,6 +9,7 @@ - type: Damageable damageContainer: Biological - type: BodyPart + - type: Gibbable - type: ContainerContainer containers: bodypart: !type:Container diff --git a/Resources/Prototypes/Body/Parts/skeleton.yml b/Resources/Prototypes/Body/Parts/skeleton.yml index 38656ce5cee..ffba0c7c44a 100644 --- a/Resources/Prototypes/Body/Parts/skeleton.yml +++ b/Resources/Prototypes/Body/Parts/skeleton.yml @@ -14,6 +14,7 @@ ents: [] - type: StaticPrice price: 20 + - type: Gibbable - type: Tag tags: - Trash diff --git a/Resources/Prototypes/Body/Parts/terminator.yml b/Resources/Prototypes/Body/Parts/terminator.yml index dec0c99f7c2..58530da959c 100644 --- a/Resources/Prototypes/Body/Parts/terminator.yml +++ b/Resources/Prototypes/Body/Parts/terminator.yml @@ -16,6 +16,7 @@ containers: bodypart: !type:Container ents: [] + - type: Gibbable - type: StaticPrice price: 200 From 81f26efd3e6a35d5bbe775c4e2b079d45b6046b7 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 10 Feb 2024 23:38:12 +0000 Subject: [PATCH 043/200] Automatic changelog update (cherry picked from commit 0495b1770b1b78426d276012ea6bc15442741500) --- Resources/Changelog/Changelog.yml | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 16089dcf62b..3691d31d4e5 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Ubaser - changes: - - message: Janitors now get rubber gloves for cleaning. - type: Add - id: 5413 - time: '2023-12-18T03:11:19.0000000+00:00' - url: null - author: Velcroboy changes: - message: Added coal. Coal has been added to the steel recipe in the Ore Processor. @@ -3874,3 +3867,20 @@ Order: 1 id: 5911 time: '2024-02-10T09:17:26.0000000+00:00' url: https://api.github.com/repos/space-wizards/space-station-14/pulls/24975 +- author: Nimfar11 + changes: + - message: Adds a glass showcase for an antique laser pistol. + type: Add + id: 5912 + time: '2024-02-10T23:36:19.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25104 +- author: Jezithyr + changes: + - message: Changed gibbing to now rotate giblets randomly when they are spawned. + type: Tweak + - message: Giblets are now thrown around the body instead of spawning in a rough + pile. + type: Tweak + id: 5913 + time: '2024-02-10T23:37:06.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/24989 From 9c6a9e23f005716e453c201666fb5043803fec29 Mon Sep 17 00:00:00 2001 From: Jezithyr Date: Sat, 10 Feb 2024 16:37:32 -0800 Subject: [PATCH 044/200] Gibbing contents hotfix (#25114) Fixing gibbing contents not respecting Include/Exclude container lists. This is currently unused (cherry picked from commit 8e59b4f50546c9ba53981ab4b22bcd1595d775d6) --- Content.Shared/Gibbing/Systems/GibbingSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Shared/Gibbing/Systems/GibbingSystem.cs b/Content.Shared/Gibbing/Systems/GibbingSystem.cs index 5d00b2a4912..2f5a9cb61c0 100644 --- a/Content.Shared/Gibbing/Systems/GibbingSystem.cs +++ b/Content.Shared/Gibbing/Systems/GibbingSystem.cs @@ -151,7 +151,7 @@ public bool TryGibEntityWithRef( } case GibContentsOption.Gib: { - foreach (var container in _containerSystem.GetAllContainers(gibbable)) + foreach (var container in validContainers) { foreach (var ent in container.ContainedEntities) { From 9e366f3119768265274e8c1edb683b0a7ca168a4 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sun, 11 Feb 2024 14:19:45 +1100 Subject: [PATCH 045/200] Predict two-way levers (#25043) * Predict two-way levers Annoys me the rare occasions I touch cargo. Doesn't predict the signal but at least the lever responds immediately. * space * a (cherry picked from commit 05a2ddff1cc415c3bdf1e15ef3a2c953bcb5384b) --- .../DeviceNetworkingBenchmark.cs | 2 +- .../DeviceLinking/DeviceLinkSystem.cs | 8 ++++++ .../Tests/DeviceNetwork/DeviceNetworkTest.cs | 1 + .../DeviceNetwork/DeviceNetworkTestSystem.cs | 3 +-- .../Atmos/Monitor/Systems/AirAlarmSystem.cs | 1 + .../Monitor/Systems/AtmosAlarmableSystem.cs | 1 + .../Monitor/Systems/AtmosDeviceNetwork.cs | 1 + .../Monitor/Systems/AtmosMonitoringSystem.cs | 1 + .../EntitySystems/GasVolumePumpSystem.cs | 1 + .../EntitySystems/GasThermoMachineSystem.cs | 1 + .../Unary/EntitySystems/GasVentPumpSystem.cs | 1 + .../EntitySystems/GasVentScrubberSystem.cs | 1 + .../CommunicationsConsoleSystem.cs | 1 + .../Components/TwoWayLeverComponent.cs | 24 ----------------- .../Events/SignalReceivedEvent.cs | 1 + .../DeviceLinking/Systems/DeviceLinkSystem.cs | 11 ++------ .../Systems/DoorSignalControlSystem.cs | 1 + .../DeviceNetwork/NetworkPayload.cs | 26 ------------------- .../Systems/Devices/ApcNetSwitchSystem.cs | 1 + .../Disposal/Mailing/MailingUnitSystem.cs | 1 + Content.Server/Fax/FaxSystem.cs | 1 + .../CrewMonitoringServerSystem.cs | 1 + .../Medical/SuitSensors/SuitSensorSystem.cs | 1 + .../Power/Generation/Teg/TegSystem.cs | 1 + Content.Server/RoundEnd/RoundEndSystem.cs | 1 + .../SensorMonitoring/BatterySensorSystem.cs | 1 + .../SensorMonitoringConsoleSystem.cs | 2 +- .../Shuttles/Systems/ArrivalsSystem.cs | 1 + .../Systems/EmergencyShuttleSystem.Console.cs | 1 + .../Systems/EmergencyShuttleSystem.cs | 2 +- .../SurveillanceCameraMonitorSystem.cs | 1 + .../Components/TwoWayLeverComponent.cs | 26 +++++++++++++++++++ .../DeviceLinking/SharedDeviceLinkSystem.cs | 23 ++++++++++++++++ .../Systems/TwoWayLeverSystem.cs | 8 +++--- .../DeviceNetwork/NetworkPayload.cs | 24 +++++++++++++++++ 35 files changed, 114 insertions(+), 68 deletions(-) create mode 100644 Content.Client/DeviceLinking/DeviceLinkSystem.cs delete mode 100644 Content.Server/DeviceLinking/Components/TwoWayLeverComponent.cs delete mode 100644 Content.Server/DeviceNetwork/NetworkPayload.cs create mode 100644 Content.Shared/DeviceLinking/Components/TwoWayLeverComponent.cs rename {Content.Server => Content.Shared}/DeviceLinking/Systems/TwoWayLeverSystem.cs (95%) create mode 100644 Content.Shared/DeviceNetwork/NetworkPayload.cs diff --git a/Content.Benchmarks/DeviceNetworkingBenchmark.cs b/Content.Benchmarks/DeviceNetworkingBenchmark.cs index 16805c2684f..bb2a22312ea 100644 --- a/Content.Benchmarks/DeviceNetworkingBenchmark.cs +++ b/Content.Benchmarks/DeviceNetworkingBenchmark.cs @@ -4,8 +4,8 @@ using Content.IntegrationTests; using Content.IntegrationTests.Pair; using Content.IntegrationTests.Tests.DeviceNetwork; -using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork.Systems; +using Content.Shared.DeviceNetwork; using Robust.Shared; using Robust.Shared.Analyzers; using Robust.Shared.GameObjects; diff --git a/Content.Client/DeviceLinking/DeviceLinkSystem.cs b/Content.Client/DeviceLinking/DeviceLinkSystem.cs new file mode 100644 index 00000000000..3356e346f6a --- /dev/null +++ b/Content.Client/DeviceLinking/DeviceLinkSystem.cs @@ -0,0 +1,8 @@ +using Content.Shared.DeviceLinking; + +namespace Content.Client.DeviceLinking; + +public sealed class DeviceLinkSystem : SharedDeviceLinkSystem +{ + +} diff --git a/Content.IntegrationTests/Tests/DeviceNetwork/DeviceNetworkTest.cs b/Content.IntegrationTests/Tests/DeviceNetwork/DeviceNetworkTest.cs index 1d994624a6d..26ea726211b 100644 --- a/Content.IntegrationTests/Tests/DeviceNetwork/DeviceNetworkTest.cs +++ b/Content.IntegrationTests/Tests/DeviceNetwork/DeviceNetworkTest.cs @@ -2,6 +2,7 @@ using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork.Components; using Content.Server.DeviceNetwork.Systems; +using Content.Shared.DeviceNetwork; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; diff --git a/Content.IntegrationTests/Tests/DeviceNetwork/DeviceNetworkTestSystem.cs b/Content.IntegrationTests/Tests/DeviceNetwork/DeviceNetworkTestSystem.cs index 6e3db254047..400d85f2ccb 100644 --- a/Content.IntegrationTests/Tests/DeviceNetwork/DeviceNetworkTestSystem.cs +++ b/Content.IntegrationTests/Tests/DeviceNetwork/DeviceNetworkTestSystem.cs @@ -1,7 +1,6 @@ - -using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork.Components; using Content.Server.DeviceNetwork.Systems; +using Content.Shared.DeviceNetwork; using Robust.Shared.GameObjects; using Robust.Shared.Reflection; diff --git a/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs b/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs index b346fd63b0d..2922d0796a9 100644 --- a/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs +++ b/Content.Server/Atmos/Monitor/Systems/AirAlarmSystem.cs @@ -15,6 +15,7 @@ using Content.Shared.Atmos.Monitor.Components; using Content.Shared.Atmos.Piping.Unary.Components; using Content.Shared.DeviceLinking; +using Content.Shared.DeviceNetwork; using Content.Shared.DeviceNetwork.Systems; using Content.Shared.Interaction; using Content.Shared.Wires; diff --git a/Content.Server/Atmos/Monitor/Systems/AtmosAlarmableSystem.cs b/Content.Server/Atmos/Monitor/Systems/AtmosAlarmableSystem.cs index 27e64a9956d..2875d4a3d5d 100644 --- a/Content.Server/Atmos/Monitor/Systems/AtmosAlarmableSystem.cs +++ b/Content.Server/Atmos/Monitor/Systems/AtmosAlarmableSystem.cs @@ -6,6 +6,7 @@ using Content.Server.DeviceNetwork.Systems; using Content.Server.Power.Components; using Content.Shared.Atmos.Monitor; +using Content.Shared.DeviceNetwork; using Content.Shared.Tag; using Robust.Server.Audio; using Robust.Server.GameObjects; diff --git a/Content.Server/Atmos/Monitor/Systems/AtmosDeviceNetwork.cs b/Content.Server/Atmos/Monitor/Systems/AtmosDeviceNetwork.cs index 0b73ea5f351..33e4eafc741 100644 --- a/Content.Server/Atmos/Monitor/Systems/AtmosDeviceNetwork.cs +++ b/Content.Server/Atmos/Monitor/Systems/AtmosDeviceNetwork.cs @@ -1,6 +1,7 @@ using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork.Systems; using Content.Shared.Atmos.Monitor.Components; +using Content.Shared.DeviceNetwork; namespace Content.Server.Atmos.Monitor.Systems; diff --git a/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs b/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs index 1fcb7734d8b..28a0a01c99a 100644 --- a/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs +++ b/Content.Server/Atmos/Monitor/Systems/AtmosMonitoringSystem.cs @@ -8,6 +8,7 @@ using Content.Server.Power.EntitySystems; using Content.Shared.Atmos; using Content.Shared.Atmos.Monitor; +using Content.Shared.DeviceNetwork; using Content.Shared.Tag; using Robust.Shared.Prototypes; diff --git a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs index 4ae0d70f5e7..10b9cccc099 100644 --- a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs +++ b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs @@ -13,6 +13,7 @@ using Content.Shared.Atmos.Visuals; using Content.Shared.Audio; using Content.Shared.Database; +using Content.Shared.DeviceNetwork; using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.Popups; diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs index ee0dca0fb0a..645b2ecc459 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs @@ -17,6 +17,7 @@ using Content.Shared.UserInterface; using Content.Shared.Administration.Logs; using Content.Shared.Database; +using Content.Shared.DeviceNetwork; using Content.Shared.Examine; namespace Content.Server.Atmos.Piping.Unary.EntitySystems diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs index a35c6b1aa6e..3a3ccf75234 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentPumpSystem.cs @@ -16,6 +16,7 @@ using Content.Shared.Atmos.Piping.Unary.Components; using Content.Shared.Atmos.Visuals; using Content.Shared.Audio; +using Content.Shared.DeviceNetwork; using Content.Shared.Examine; using Content.Shared.Tools.Systems; using JetBrains.Annotations; diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentScrubberSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentScrubberSystem.cs index ecf7d1d0b45..32591e9c540 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentScrubberSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasVentScrubberSystem.cs @@ -15,6 +15,7 @@ using Content.Shared.Atmos.Monitor; using Content.Shared.Atmos.Piping.Unary.Components; using Content.Shared.Audio; +using Content.Shared.DeviceNetwork; using Content.Shared.Tools.Systems; using JetBrains.Annotations; using Robust.Server.GameObjects; diff --git a/Content.Server/Communications/CommunicationsConsoleSystem.cs b/Content.Server/Communications/CommunicationsConsoleSystem.cs index 4fa60563bdd..6b0b13c410e 100644 --- a/Content.Server/Communications/CommunicationsConsoleSystem.cs +++ b/Content.Server/Communications/CommunicationsConsoleSystem.cs @@ -19,6 +19,7 @@ using Content.Shared.Chat; using Content.Shared.Communications; using Content.Shared.Database; +using Content.Shared.DeviceNetwork; using Content.Shared.Emag.Components; using Content.Shared.Popups; using Robust.Server.GameObjects; diff --git a/Content.Server/DeviceLinking/Components/TwoWayLeverComponent.cs b/Content.Server/DeviceLinking/Components/TwoWayLeverComponent.cs deleted file mode 100644 index bbf78b6876b..00000000000 --- a/Content.Server/DeviceLinking/Components/TwoWayLeverComponent.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Content.Shared.DeviceLinking; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; - -namespace Content.Server.DeviceLinking.Components -{ - [RegisterComponent] - public sealed partial class TwoWayLeverComponent : Component - { - [DataField("state")] - public TwoWayLeverState State; - - [DataField("nextSignalLeft")] - public bool NextSignalLeft; - - [DataField("leftPort", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string LeftPort = "Left"; - - [DataField("rightPort", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string RightPort = "Right"; - - [DataField("middlePort", customTypeSerializer: typeof(PrototypeIdSerializer))] - public string MiddlePort = "Middle"; - } -} diff --git a/Content.Server/DeviceLinking/Events/SignalReceivedEvent.cs b/Content.Server/DeviceLinking/Events/SignalReceivedEvent.cs index c1928575feb..c8c611103d9 100644 --- a/Content.Server/DeviceLinking/Events/SignalReceivedEvent.cs +++ b/Content.Server/DeviceLinking/Events/SignalReceivedEvent.cs @@ -1,4 +1,5 @@ using Content.Server.DeviceNetwork; +using Content.Shared.DeviceNetwork; namespace Content.Server.DeviceLinking.Events; diff --git a/Content.Server/DeviceLinking/Systems/DeviceLinkSystem.cs b/Content.Server/DeviceLinking/Systems/DeviceLinkSystem.cs index 47f632843d3..e54e21316f2 100644 --- a/Content.Server/DeviceLinking/Systems/DeviceLinkSystem.cs +++ b/Content.Server/DeviceLinking/Systems/DeviceLinkSystem.cs @@ -4,6 +4,7 @@ using Content.Server.DeviceNetwork.Components; using Content.Server.DeviceNetwork.Systems; using Content.Shared.DeviceLinking; +using Content.Shared.DeviceNetwork; namespace Content.Server.DeviceLinking.Systems; @@ -35,15 +36,7 @@ public override void Update(float frameTime) } #region Sending & Receiving - /// - /// Sends a network payload directed at the sink entity. - /// Just raises a without data if the source or the sink doesn't have a - /// - /// The source uid that invokes the port - /// The port to invoke - /// Optional data to send along - /// - public void InvokePort(EntityUid uid, string port, NetworkPayload? data = null, DeviceLinkSourceComponent? sourceComponent = null) + public override void InvokePort(EntityUid uid, string port, NetworkPayload? data = null, DeviceLinkSourceComponent? sourceComponent = null) { if (!Resolve(uid, ref sourceComponent) || !sourceComponent.Outputs.TryGetValue(port, out var sinks)) return; diff --git a/Content.Server/DeviceLinking/Systems/DoorSignalControlSystem.cs b/Content.Server/DeviceLinking/Systems/DoorSignalControlSystem.cs index 90623dbae37..40feda32f2b 100644 --- a/Content.Server/DeviceLinking/Systems/DoorSignalControlSystem.cs +++ b/Content.Server/DeviceLinking/Systems/DoorSignalControlSystem.cs @@ -1,6 +1,7 @@ using Content.Server.DeviceLinking.Components; using Content.Server.DeviceNetwork; using Content.Server.Doors.Systems; +using Content.Shared.DeviceNetwork; using Content.Shared.Doors.Components; using Content.Shared.Doors; using JetBrains.Annotations; diff --git a/Content.Server/DeviceNetwork/NetworkPayload.cs b/Content.Server/DeviceNetwork/NetworkPayload.cs deleted file mode 100644 index eefbaa6eea5..00000000000 --- a/Content.Server/DeviceNetwork/NetworkPayload.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Robust.Shared.Utility; -using System.Diagnostics.CodeAnalysis; - -namespace Content.Server.DeviceNetwork -{ - public sealed class NetworkPayload : Dictionary - { - /// - /// Tries to get a value from the payload and checks if that value is of type T. - /// - /// The type that should be casted to - /// Whether the value was present in the payload and of the required type - public bool TryGetValue(string key, [NotNullWhen(true)] out T? value) - { - if (this.TryCastValue(key, out T? result)) - { - value = result; - return true; - } - - value = default; - return false; - } - } - -} diff --git a/Content.Server/DeviceNetwork/Systems/Devices/ApcNetSwitchSystem.cs b/Content.Server/DeviceNetwork/Systems/Devices/ApcNetSwitchSystem.cs index 11dc628df1c..9a4a81a4c0a 100644 --- a/Content.Server/DeviceNetwork/Systems/Devices/ApcNetSwitchSystem.cs +++ b/Content.Server/DeviceNetwork/Systems/Devices/ApcNetSwitchSystem.cs @@ -1,5 +1,6 @@ using Content.Server.DeviceNetwork.Components; using Content.Server.DeviceNetwork.Components.Devices; +using Content.Shared.DeviceNetwork; using Content.Shared.Interaction; namespace Content.Server.DeviceNetwork.Systems.Devices diff --git a/Content.Server/Disposal/Mailing/MailingUnitSystem.cs b/Content.Server/Disposal/Mailing/MailingUnitSystem.cs index 1a819ab0fb1..001abad3dcd 100644 --- a/Content.Server/Disposal/Mailing/MailingUnitSystem.cs +++ b/Content.Server/Disposal/Mailing/MailingUnitSystem.cs @@ -4,6 +4,7 @@ using Content.Server.DeviceNetwork.Systems; using Content.Server.Disposal.Unit.EntitySystems; using Content.Server.Power.Components; +using Content.Shared.DeviceNetwork; using Content.Shared.Disposal; using Content.Shared.Interaction; using Robust.Server.GameObjects; diff --git a/Content.Server/Fax/FaxSystem.cs b/Content.Server/Fax/FaxSystem.cs index f25fb625425..5fee750c1d9 100644 --- a/Content.Server/Fax/FaxSystem.cs +++ b/Content.Server/Fax/FaxSystem.cs @@ -12,6 +12,7 @@ using Content.Shared.Administration.Logs; using Content.Shared.Containers.ItemSlots; using Content.Shared.Database; +using Content.Shared.DeviceNetwork; using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; using Content.Shared.Fax; diff --git a/Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs b/Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs index 785ef60af90..bff7f1565a1 100644 --- a/Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs +++ b/Content.Server/Medical/CrewMonitoring/CrewMonitoringServerSystem.cs @@ -4,6 +4,7 @@ using Content.Server.Medical.SuitSensors; using Content.Server.Power.Components; using Content.Server.Station.Systems; +using Content.Shared.DeviceNetwork; using Content.Shared.Medical.SuitSensor; using Robust.Shared.Timing; diff --git a/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs b/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs index aa6dca718d5..38a7b0a4517 100644 --- a/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs +++ b/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs @@ -8,6 +8,7 @@ using Content.Server.Popups; using Content.Server.Station.Systems; using Content.Shared.Damage; +using Content.Shared.DeviceNetwork; using Content.Shared.Emp; using Content.Shared.Examine; using Content.Shared.Inventory.Events; diff --git a/Content.Server/Power/Generation/Teg/TegSystem.cs b/Content.Server/Power/Generation/Teg/TegSystem.cs index 54f40a1bf34..3510a3da45d 100644 --- a/Content.Server/Power/Generation/Teg/TegSystem.cs +++ b/Content.Server/Power/Generation/Teg/TegSystem.cs @@ -7,6 +7,7 @@ using Content.Server.NodeContainer; using Content.Server.NodeContainer.Nodes; using Content.Server.Power.Components; +using Content.Shared.DeviceNetwork; using Content.Shared.Examine; using Content.Shared.Power.Generation.Teg; using Content.Shared.Rounding; diff --git a/Content.Server/RoundEnd/RoundEndSystem.cs b/Content.Server/RoundEnd/RoundEndSystem.cs index 10d4bea8b54..3a8331f3f7a 100644 --- a/Content.Server/RoundEnd/RoundEndSystem.cs +++ b/Content.Server/RoundEnd/RoundEndSystem.cs @@ -14,6 +14,7 @@ using Content.Server.Station.Components; using Content.Server.Station.Systems; using Content.Shared.Database; +using Content.Shared.DeviceNetwork; using Content.Shared.GameTicking; using Robust.Shared.Audio.Systems; using Robust.Shared.Configuration; diff --git a/Content.Server/SensorMonitoring/BatterySensorSystem.cs b/Content.Server/SensorMonitoring/BatterySensorSystem.cs index 20e990b14c3..eb2ab21075c 100644 --- a/Content.Server/SensorMonitoring/BatterySensorSystem.cs +++ b/Content.Server/SensorMonitoring/BatterySensorSystem.cs @@ -1,6 +1,7 @@ using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork.Systems; using Content.Server.Power.Components; +using Content.Shared.DeviceNetwork; namespace Content.Server.SensorMonitoring; diff --git a/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.cs b/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.cs index fdd340ba0ae..ddd7812394e 100644 --- a/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.cs +++ b/Content.Server/SensorMonitoring/SensorMonitoringConsoleSystem.cs @@ -10,13 +10,13 @@ using Content.Shared.Atmos.Monitor; using Content.Shared.Atmos.Piping.Binary.Components; using Content.Shared.Atmos.Piping.Unary.Components; +using Content.Shared.DeviceNetwork; using Content.Shared.DeviceNetwork.Components; using Content.Shared.DeviceNetwork.Systems; using Content.Shared.SensorMonitoring; using Robust.Server.GameObjects; using Robust.Shared.Timing; using Robust.Shared.Utility; -using ConsoleUIState = Content.Shared.SensorMonitoring.SensorMonitoringConsoleBoundInterfaceState; namespace Content.Server.SensorMonitoring; diff --git a/Content.Server/Shuttles/Systems/ArrivalsSystem.cs b/Content.Server/Shuttles/Systems/ArrivalsSystem.cs index 6503e4bf517..08f3481cd72 100644 --- a/Content.Server/Shuttles/Systems/ArrivalsSystem.cs +++ b/Content.Server/Shuttles/Systems/ArrivalsSystem.cs @@ -16,6 +16,7 @@ using Content.Server.Station.Systems; using Content.Shared.Administration; using Content.Shared.CCVar; +using Content.Shared.DeviceNetwork; using Content.Shared.Mobs.Components; using Content.Shared.Movement.Components; using Content.Shared.Parallax.Biomes; diff --git a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.Console.cs b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.Console.cs index 37c70c4e486..b589a526403 100644 --- a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.Console.cs +++ b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.Console.cs @@ -8,6 +8,7 @@ using Content.Shared.Access; using Content.Shared.CCVar; using Content.Shared.Database; +using Content.Shared.DeviceNetwork; using Content.Shared.Popups; using Content.Shared.Shuttles.BUIStates; using Content.Shared.Shuttles.Events; diff --git a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs index d984c727376..d9ba2de3e59 100644 --- a/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs +++ b/Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs @@ -5,7 +5,6 @@ using Content.Server.Administration.Managers; using Content.Server.Chat.Systems; using Content.Server.Communications; -using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork.Components; using Content.Server.DeviceNetwork.Systems; using Content.Server.GameTicking.Events; @@ -19,6 +18,7 @@ using Content.Shared.Access.Systems; using Content.Shared.CCVar; using Content.Shared.Database; +using Content.Shared.DeviceNetwork; using Content.Shared.Shuttles.Components; using Content.Shared.Shuttles.Events; using Content.Shared.Tag; diff --git a/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraMonitorSystem.cs b/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraMonitorSystem.cs index cbc2f6d31ec..f258fbe89cf 100644 --- a/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraMonitorSystem.cs +++ b/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraMonitorSystem.cs @@ -2,6 +2,7 @@ using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork.Systems; using Content.Server.Power.Components; +using Content.Shared.DeviceNetwork; using Content.Shared.UserInterface; using Content.Shared.SurveillanceCamera; using Robust.Server.GameObjects; diff --git a/Content.Shared/DeviceLinking/Components/TwoWayLeverComponent.cs b/Content.Shared/DeviceLinking/Components/TwoWayLeverComponent.cs new file mode 100644 index 00000000000..6dfc25582a3 --- /dev/null +++ b/Content.Shared/DeviceLinking/Components/TwoWayLeverComponent.cs @@ -0,0 +1,26 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.DeviceLinking.Components; + +/// +/// Simple ternary state for device linking. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class TwoWayLeverComponent : Component +{ + [DataField, AutoNetworkedField] + public TwoWayLeverState State; + + [DataField, AutoNetworkedField] + public bool NextSignalLeft; + + [DataField] + public ProtoId LeftPort = "Left"; + + [DataField] + public ProtoId RightPort = "Right"; + + [DataField] + public ProtoId MiddlePort = "Middle"; +} diff --git a/Content.Shared/DeviceLinking/SharedDeviceLinkSystem.cs b/Content.Shared/DeviceLinking/SharedDeviceLinkSystem.cs index 02c0f608532..9610e2e6065 100644 --- a/Content.Shared/DeviceLinking/SharedDeviceLinkSystem.cs +++ b/Content.Shared/DeviceLinking/SharedDeviceLinkSystem.cs @@ -1,6 +1,7 @@ using Content.Shared.Administration.Logs; using Content.Shared.Database; using Content.Shared.DeviceLinking.Events; +using Content.Shared.DeviceNetwork; using Content.Shared.Popups; using Robust.Shared.Prototypes; using Robust.Shared.Utility; @@ -148,6 +149,9 @@ private void OnSinkRemoved(EntityUid sinkUid, DeviceLinkSinkComponent sinkCompon /// public void EnsureSourcePorts(EntityUid uid, params string[] ports) { + if (ports.Length == 0) + return; + var comp = EnsureComp(uid); comp.Ports ??= new HashSet(); @@ -163,6 +167,9 @@ public void EnsureSourcePorts(EntityUid uid, params string[] ports) /// public void EnsureSinkPorts(EntityUid uid, params string[] ports) { + if (ports.Length == 0) + return; + var comp = EnsureComp(uid); comp.Ports ??= new HashSet(); @@ -550,4 +557,20 @@ private void CreateLinkPopup(EntityUid? userId, EntityUid sourceUid, string sour ("machine2", sinkUid), ("port2", PortName(sink))), userId.Value, PopupType.Medium); } #endregion + + #region Sending & Receiving + /// + /// Sends a network payload directed at the sink entity. + /// Just raises a without data if the source or the sink doesn't have a + /// + /// The source uid that invokes the port + /// The port to invoke + /// Optional data to send along + /// + public virtual void InvokePort(EntityUid uid, string port, NetworkPayload? data = null, + DeviceLinkSourceComponent? sourceComponent = null) + { + // NOOP on client for the moment. + } + #endregion } diff --git a/Content.Server/DeviceLinking/Systems/TwoWayLeverSystem.cs b/Content.Shared/DeviceLinking/Systems/TwoWayLeverSystem.cs similarity index 95% rename from Content.Server/DeviceLinking/Systems/TwoWayLeverSystem.cs rename to Content.Shared/DeviceLinking/Systems/TwoWayLeverSystem.cs index 7d351dcac56..c8783b05fc7 100644 --- a/Content.Server/DeviceLinking/Systems/TwoWayLeverSystem.cs +++ b/Content.Shared/DeviceLinking/Systems/TwoWayLeverSystem.cs @@ -1,14 +1,13 @@ -using Content.Server.DeviceLinking.Components; -using Content.Shared.DeviceLinking; +using Content.Shared.DeviceLinking.Components; using Content.Shared.Interaction; using Content.Shared.Verbs; using Robust.Shared.Utility; -namespace Content.Server.DeviceLinking.Systems +namespace Content.Shared.DeviceLinking.Systems { public sealed class TwoWayLeverSystem : EntitySystem { - [Dependency] private readonly DeviceLinkSystem _signalSystem = default!; + [Dependency] private readonly SharedDeviceLinkSystem _signalSystem = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; const string _leftToggleImage = "rotate_ccw.svg.192dpi.png"; @@ -111,6 +110,7 @@ private void StateChanged(EntityUid uid, TwoWayLeverComponent component) _ => throw new ArgumentOutOfRangeException() }; + Dirty(uid, component); _signalSystem.InvokePort(uid, port); } } diff --git a/Content.Shared/DeviceNetwork/NetworkPayload.cs b/Content.Shared/DeviceNetwork/NetworkPayload.cs new file mode 100644 index 00000000000..32393740213 --- /dev/null +++ b/Content.Shared/DeviceNetwork/NetworkPayload.cs @@ -0,0 +1,24 @@ +using System.Diagnostics.CodeAnalysis; +using Robust.Shared.Utility; + +namespace Content.Shared.DeviceNetwork; + +public sealed class NetworkPayload : Dictionary +{ + /// + /// Tries to get a value from the payload and checks if that value is of type T. + /// + /// The type that should be casted to + /// Whether the value was present in the payload and of the required type + public bool TryGetValue(string key, [NotNullWhen(true)] out T? value) + { + if (this.TryCastValue(key, out T? result)) + { + value = result; + return true; + } + + value = default; + return false; + } +} From eb397058c4a10d43baf27c4881b6e93b4d9cbd92 Mon Sep 17 00:00:00 2001 From: Fluffiest Floofers Date: Sun, 11 Feb 2024 06:53:26 +0100 Subject: [PATCH 046/200] Replace Romerol with Ambuzol in chemist guidebook (#25108) replace romerol with ambuzol (cherry picked from commit b2d0dd9c3077f7a9ffa7a8512fc811576bc189ed) --- Resources/ServerInfo/Guidebook/Medical/Medicine.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/ServerInfo/Guidebook/Medical/Medicine.xml b/Resources/ServerInfo/Guidebook/Medical/Medicine.xml index d56da3813db..7a09a1647d2 100644 --- a/Resources/ServerInfo/Guidebook/Medical/Medicine.xml +++ b/Resources/ServerInfo/Guidebook/Medical/Medicine.xml @@ -24,7 +24,7 @@ These medications tend to have specific use cases. - + # All Medications From c4b8f141e90c0c6b942bc65a0e8d219b849f4a38 Mon Sep 17 00:00:00 2001 From: Jajsha <101492056+Zap527@users.noreply.github.com> Date: Sun, 11 Feb 2024 01:23:32 -0500 Subject: [PATCH 047/200] Fix borgs being able to emag themselves (#24748) * Fix self emagging borgs * Add popup on self emag failure. (cherry picked from commit 402051c670a66d08726e0ec16f8fa5735bb0f60f) --- Content.Shared/Silicons/Laws/SharedSiliconLawSystem.cs | 8 ++++++++ Resources/Locale/en-US/station-laws/laws.ftl | 1 + 2 files changed, 9 insertions(+) diff --git a/Content.Shared/Silicons/Laws/SharedSiliconLawSystem.cs b/Content.Shared/Silicons/Laws/SharedSiliconLawSystem.cs index 9aa0aa9a381..c0619e6e43d 100644 --- a/Content.Shared/Silicons/Laws/SharedSiliconLawSystem.cs +++ b/Content.Shared/Silicons/Laws/SharedSiliconLawSystem.cs @@ -21,6 +21,14 @@ public override void Initialize() protected virtual void OnAttemptEmag(EntityUid uid, EmagSiliconLawComponent component, ref OnAttemptEmagEvent args) { + //prevent self emagging + if (uid == args.UserUid) + { + _popup.PopupClient(Loc.GetString("law-emag-cannot-emag-self"), uid, args.UserUid); + args.Handled = true; + return; + } + if (component.RequireOpenPanel && TryComp(uid, out var panel) && !panel.Open) diff --git a/Resources/Locale/en-US/station-laws/laws.ftl b/Resources/Locale/en-US/station-laws/laws.ftl index 1823d0782e5..f73755a359c 100644 --- a/Resources/Locale/en-US/station-laws/laws.ftl +++ b/Resources/Locale/en-US/station-laws/laws.ftl @@ -34,6 +34,7 @@ laws-owner-spider-clan = Spider Clan members law-emag-custom = Only {$name} and people they designate as such are {$title}. law-emag-secrecy = You must maintain the secrecy of any orders given by {$faction} except when doing so would conflict with any previous law. law-emag-require-panel = The panel must be open to use the EMAG. +law-emag-cannot-emag-self = You cannot use the EMAG on yourself. laws-ui-menu-title = Laws laws-ui-law-header = Law {$id} From 2fe88b33a1c0354e249ce86a33b7bf3ef2fd9296 Mon Sep 17 00:00:00 2001 From: Ubaser <134914314+ubaserb@users.noreply.github.com> Date: Sun, 11 Feb 2024 07:24:35 +0100 Subject: [PATCH 048/200] Ectoplasm is grindable into Necrosol (#25053) add (cherry picked from commit 82046aef3a69e96628d7b362fc8133d9ed29cc53) --- .../Prototypes/Entities/Objects/Specific/Medical/morgue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml index 1ce3cc26982..c4928dca53a 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml @@ -141,7 +141,7 @@ reagents: - ReagentId: Ash Quantity: 5 - - ReagentId: SpaceLube + - ReagentId: Necrosol Quantity: 5 - ReagentId: Ectoplasm # DeltaV - for normality crystals Quantity: 30 # DeltaV From e5e465d971244deac1245507ecf49bf23857f022 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 11 Feb 2024 06:24:38 +0000 Subject: [PATCH 049/200] Automatic changelog update (cherry picked from commit d804e47f60b5908d68c7221c2270190c7055cbd3) --- 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 3691d31d4e5..df5d9b1ee86 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,14 +1,5 @@ Order: 1 Entries: -- author: Velcroboy - changes: - - message: Added coal. Coal has been added to the steel recipe in the Ore Processor. - Coal can be ground up for Carbon and other elements. Coal can be mined or received - as a gift if you've been naughty. - type: Add - id: 5414 - time: '2023-12-18T19:38:12.0000000+00:00' - url: null - author: Flareguy changes: - message: You can now walk into external and shuttle airlocks to open them, like @@ -3884,3 +3875,10 @@ Order: 1 id: 5913 time: '2024-02-10T23:37:06.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/24989 +- author: Jajsha + changes: + - message: Cyborgs can no longer Emag themselves. + type: Fix + id: 5914 + time: '2024-02-11T06:23:32.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/24748 From 6d5fcd4f8613370690788e90f8ea05fcd2402f7d Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 11 Feb 2024 06:25:47 +0000 Subject: [PATCH 050/200] Automatic changelog update (cherry picked from commit 5e63b0c1f2810bf54939dfc00a7b9321e99ee010) --- 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 df5d9b1ee86..2b521e6a986 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,5 @@ Order: 1 Entries: -- author: Flareguy - changes: - - message: You can now walk into external and shuttle airlocks to open them, like - all other airlocks. - type: Tweak - id: 5415 - time: '2023-12-18T19:44:50.0000000+00:00' - url: null - author: iacore changes: - message: normal closets can now be constructed and deconstructed @@ -3882,3 +3874,10 @@ Order: 1 id: 5914 time: '2024-02-11T06:23:32.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/24748 +- author: Ubaser + changes: + - message: Grinding ectoplasm now gives Necrosol. + type: Tweak + id: 5915 + time: '2024-02-11T06:24:35.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25053 From d364ed9a3186ac46af2eecdd150dd3ecf45c070e Mon Sep 17 00:00:00 2001 From: Ubaser <134914314+ubaserb@users.noreply.github.com> Date: Sun, 11 Feb 2024 07:37:11 +0100 Subject: [PATCH 051/200] Roundstart Food Service research (#25046) add (cherry picked from commit 93d225d109904f89838fa0f07610f93ce1034e14) --- .../Entities/Structures/Machines/lathe.yml | 12 ++++++------ .../Prototypes/Research/civilianservices.yml | 17 ----------------- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 1b17954f3d8..5155fe98845 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -383,6 +383,12 @@ - UniformPrinterMachineCircuitboard - FloorGreenCircuit - FloorBlueCircuit + - MicrowaveMachineCircuitboard + - ReagentGrinderMachineCircuitboard + - ElectricGrillMachineCircuitboard + - BoozeDispenserMachineCircuitboard + - SodaDispenserMachineCircuitboard + - DeepFryerMachineCircuitboard #Nyano - Summary: adds deep fryer circuit board dynamicRecipes: - ThermomachineFreezerMachineCircuitBoard - HellfireFreezerMachineCircuitBoard @@ -408,9 +414,6 @@ - PowerComputerCircuitboard - AutolatheHyperConvectionMachineCircuitboard - ProtolatheHyperConvectionMachineCircuitboard - - ReagentGrinderMachineCircuitboard - - MicrowaveMachineCircuitboard - - ElectricGrillMachineCircuitboard - FatExtractorMachineCircuitboard - FlatpackerMachineCircuitboard - SheetifierMachineCircuitboard @@ -452,8 +455,6 @@ - ArtifactAnalyzerMachineCircuitboard - TraversalDistorterMachineCircuitboard - ArtifactCrusherMachineCircuitboard - - BoozeDispenserMachineCircuitboard - - SodaDispenserMachineCircuitboard - TelecomServerCircuitboard - MassMediaCircuitboard # Begin Nyano additions @@ -467,7 +468,6 @@ - SalvageMagnetMachineCircuitboard - StationMapElectronics - MetempsychoticMachineCircuitboard - - DeepFryerMachineCircuitboard # End Nyano additions - SalvageExpeditionsComputerCircuitboard # DeltaV - type: MaterialStorage diff --git a/Resources/Prototypes/Research/civilianservices.yml b/Resources/Prototypes/Research/civilianservices.yml index 13eccb316ca..0ba629c8c5c 100644 --- a/Resources/Prototypes/Research/civilianservices.yml +++ b/Resources/Prototypes/Research/civilianservices.yml @@ -35,23 +35,6 @@ - MechEquipmentGrabberSmall - VimHarness -- type: technology - id: FoodService - name: research-technology-food-service - icon: - sprite: Structures/Machines/juicer.rsi - state: juicer1 - discipline: CivilianServices - tier: 1 - cost: 7500 - recipeUnlocks: #remove all of these once we have more kitchen equipment - - MicrowaveMachineCircuitboard - - ReagentGrinderMachineCircuitboard - - ElectricGrillMachineCircuitboard - - BoozeDispenserMachineCircuitboard - - SodaDispenserMachineCircuitboard - - DeepFryerMachineCircuitboard #Nyano - Summary: adds deep fryer circuit board to service research. - - type: technology id: AudioVisualCommunication name: research-technology-audio-visual-communication From 8dff5e59be23ce071bcb075bbe97ecfec81fbe06 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 11 Feb 2024 06:38:17 +0000 Subject: [PATCH 052/200] Automatic changelog update (cherry picked from commit fabcc2b0d121094e43a2df3480e082cf7559c1e1) --- 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 2b521e6a986..702b0566868 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: iacore - changes: - - message: normal closets can now be constructed and deconstructed - type: Add - id: 5416 - time: '2023-12-18T19:46:16.0000000+00:00' - url: null - author: Emisse changes: - message: Walls are stronger and windows are weaker. @@ -3881,3 +3874,10 @@ Order: 1 id: 5915 time: '2024-02-11T06:24:35.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25053 +- author: Ubaser + changes: + - message: Food Service research is now roundstart. + type: Tweak + id: 5916 + time: '2024-02-11T06:37:12.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25046 From 6991618a45e4feca933c17c461dfc4f44845a837 Mon Sep 17 00:00:00 2001 From: SlamBamActionman <83650252+slambamactionman@users.noreply.github.com> Date: Sun, 11 Feb 2024 07:38:55 +0100 Subject: [PATCH 053/200] Add option for character name colors in chat & move coloration to clientside (#24625) * Adds option to disable character names in chat/speechbubbles * Moved the coloring of names to clientside * Move string functions to SharedChatSystem to avoid duplicate code in SpeechBubble.cs * Changed to be put under Accessibility section * Cache CVar (cherry picked from commit 247be5b5c770261544f4e468ea09422efb0f7028) --- Content.Client/Chat/UI/SpeechBubble.cs | 13 +------ Content.Client/Options/UI/Tabs/MiscTab.xaml | 1 + .../Options/UI/Tabs/MiscTab.xaml.cs | 5 +++ .../Systems/Chat/ChatUIController.cs | 39 +++++++++++++++++++ Content.Server/Chat/Systems/ChatSystem.cs | 35 +---------------- Content.Shared/CCVar/CCVars.cs | 3 ++ Content.Shared/Chat/SharedChatSystem.cs | 27 +++++++++++++ .../en-US/chat/managers/chat-manager.ftl | 6 +-- .../en-US/escape-menu/ui/options-menu.ftl | 1 + 9 files changed, 81 insertions(+), 49 deletions(-) diff --git a/Content.Client/Chat/UI/SpeechBubble.cs b/Content.Client/Chat/UI/SpeechBubble.cs index 91e8e5a90f0..82eccbcec84 100644 --- a/Content.Client/Chat/UI/SpeechBubble.cs +++ b/Content.Client/Chat/UI/SpeechBubble.cs @@ -182,20 +182,9 @@ protected FormattedMessage FormatSpeech(string message, Color? fontColor = null) return msg; } - protected string ExtractSpeechSubstring(ChatMessage message, string tag) - { - var rawmsg = message.WrappedMessage; - var tagStart = rawmsg.IndexOf($"[{tag}]"); - var tagEnd = rawmsg.IndexOf($"[/{tag}]"); - if (tagStart < 0 || tagEnd < 0) //the above return -1 if the tag's not found, which in turn will cause the below to throw an exception. a blank speech bubble is far more noticeably broken than the bubble not appearing at all -bhijn - return ""; - tagStart += tag.Length + 2; - return rawmsg.Substring(tagStart, tagEnd - tagStart); - } - protected FormattedMessage ExtractAndFormatSpeechSubstring(ChatMessage message, string tag, Color? fontColor = null) { - return FormatSpeech(ExtractSpeechSubstring(message, tag), fontColor); + return FormatSpeech(SharedChatSystem.GetStringInsideTag(message, tag), fontColor); } } diff --git a/Content.Client/Options/UI/Tabs/MiscTab.xaml b/Content.Client/Options/UI/Tabs/MiscTab.xaml index db176db456c..fc94ab7b0a6 100644 --- a/Content.Client/Options/UI/Tabs/MiscTab.xaml +++ b/Content.Client/Options/UI/Tabs/MiscTab.xaml @@ -22,6 +22,7 @@ FontColorOverride="{xNamespace:Static s:StyleNano.NanoGold}" StyleClasses="LabelKeyText"/> + diff --git a/Content.Client/Atmos/Monitor/UI/Widgets/ThresholdBoundControl.xaml.cs b/Content.Client/Atmos/Monitor/UI/Widgets/ThresholdBoundControl.xaml.cs index da63db77d34..3612d84de4c 100644 --- a/Content.Client/Atmos/Monitor/UI/Widgets/ThresholdBoundControl.xaml.cs +++ b/Content.Client/Atmos/Monitor/UI/Widgets/ThresholdBoundControl.xaml.cs @@ -72,7 +72,6 @@ public ThresholdBoundControl(string controlLabel, float value, float uiValueScal CBoundLabel.Text = controlLabel; CSpinner.Value = ScaledValue; - CBoundEnabled.Pressed = _value != null; CSpinner.OnValueChanged += SpinnerValueChanged; CBoundEnabled.OnToggled += CheckboxToggled; diff --git a/Content.Client/Audio/AmbientSoundSystem.cs b/Content.Client/Audio/AmbientSoundSystem.cs index d39073fa330..9d30cabb1ec 100644 --- a/Content.Client/Audio/AmbientSoundSystem.cs +++ b/Content.Client/Audio/AmbientSoundSystem.cs @@ -99,10 +99,10 @@ public override void Initialize() UpdatesOutsidePrediction = true; UpdatesAfter.Add(typeof(AmbientSoundTreeSystem)); - _cfg.OnValueChanged(CCVars.AmbientCooldown, SetCooldown, true); - _cfg.OnValueChanged(CCVars.MaxAmbientSources, SetAmbientCount, true); - _cfg.OnValueChanged(CCVars.AmbientRange, SetAmbientRange, true); - _cfg.OnValueChanged(CCVars.AmbienceVolume, SetAmbienceGain, true); + Subs.CVar(_cfg, CCVars.AmbientCooldown, SetCooldown, true); + Subs.CVar(_cfg, CCVars.MaxAmbientSources, SetAmbientCount, true); + Subs.CVar(_cfg, CCVars.AmbientRange, SetAmbientRange, true); + Subs.CVar(_cfg, CCVars.AmbienceVolume, SetAmbienceGain, true); SubscribeLocalEvent(OnShutdown); } @@ -138,11 +138,6 @@ public override void Shutdown() { base.Shutdown(); ClearSounds(); - - _cfg.UnsubValueChanged(CCVars.AmbientCooldown, SetCooldown); - _cfg.UnsubValueChanged(CCVars.MaxAmbientSources, SetAmbientCount); - _cfg.UnsubValueChanged(CCVars.AmbientRange, SetAmbientRange); - _cfg.UnsubValueChanged(CCVars.AmbienceVolume, SetAmbienceGain); } private int PlayingCount(string countSound) diff --git a/Content.Client/Audio/BackgroundAudioSystem.cs b/Content.Client/Audio/BackgroundAudioSystem.cs index 29279830627..702f810e27c 100644 --- a/Content.Client/Audio/BackgroundAudioSystem.cs +++ b/Content.Client/Audio/BackgroundAudioSystem.cs @@ -34,8 +34,8 @@ public override void Initialize() { base.Initialize(); - _configManager.OnValueChanged(CCVars.LobbyMusicEnabled, LobbyMusicCVarChanged); - _configManager.OnValueChanged(CCVars.LobbyMusicVolume, LobbyMusicVolumeCVarChanged); + Subs.CVar(_configManager, CCVars.LobbyMusicEnabled, LobbyMusicCVarChanged); + Subs.CVar(_configManager, CCVars.LobbyMusicVolume, LobbyMusicVolumeCVarChanged); _stateManager.OnStateChanged += StateManagerOnStateChanged; @@ -50,9 +50,6 @@ public override void Shutdown() { base.Shutdown(); - _configManager.UnsubValueChanged(CCVars.LobbyMusicEnabled, LobbyMusicCVarChanged); - _configManager.UnsubValueChanged(CCVars.LobbyMusicVolume, LobbyMusicVolumeCVarChanged); - _stateManager.OnStateChanged -= StateManagerOnStateChanged; _client.PlayerLeaveServer -= OnLeave; diff --git a/Content.Client/Audio/ClientGlobalSoundSystem.cs b/Content.Client/Audio/ClientGlobalSoundSystem.cs index 1d98564090a..7c77865f741 100644 --- a/Content.Client/Audio/ClientGlobalSoundSystem.cs +++ b/Content.Client/Audio/ClientGlobalSoundSystem.cs @@ -26,11 +26,11 @@ public override void Initialize() base.Initialize(); SubscribeLocalEvent(OnRoundRestart); SubscribeNetworkEvent(PlayAdminSound); - _cfg.OnValueChanged(CCVars.AdminSoundsEnabled, ToggleAdminSound, true); + Subs.CVar(_cfg, CCVars.AdminSoundsEnabled, ToggleAdminSound, true); SubscribeNetworkEvent(PlayStationEventMusic); SubscribeNetworkEvent(StopStationEventMusic); - _cfg.OnValueChanged(CCVars.EventMusicEnabled, ToggleStationEventMusic, true); + Subs.CVar(_cfg, CCVars.EventMusicEnabled, ToggleStationEventMusic, true); SubscribeNetworkEvent(PlayGameSound); } diff --git a/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs b/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs index 89324f22252..84b787a4ec9 100644 --- a/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs +++ b/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs @@ -59,7 +59,7 @@ public sealed partial class ContentAudioSystem private void InitializeAmbientMusic() { - _configManager.OnValueChanged(CCVars.AmbientMusicVolume, AmbienceCVarChanged, true); + Subs.CVar(_configManager, CCVars.AmbientMusicVolume, AmbienceCVarChanged, true); _sawmill = IoCManager.Resolve().GetSawmill("audio.ambience"); // Reset audio @@ -84,7 +84,6 @@ private void AmbienceCVarChanged(float obj) private void ShutdownAmbientMusic() { - _configManager.UnsubValueChanged(CCVars.AmbientMusicVolume, AmbienceCVarChanged); _state.OnStateChanged -= OnStateChange; _ambientMusicStream = _audio.Stop(_ambientMusicStream); } @@ -229,7 +228,7 @@ private void UpdateAmbientMusic() private AmbientMusicPrototype? GetAmbience() { - var player = _player.LocalPlayer?.ControlledEntity; + var player = _player.LocalEntity; if (player == null) return null; diff --git a/Content.Client/Audio/ContentAudioSystem.cs b/Content.Client/Audio/ContentAudioSystem.cs index c81e0a44f10..56921ee4301 100644 --- a/Content.Client/Audio/ContentAudioSystem.cs +++ b/Content.Client/Audio/ContentAudioSystem.cs @@ -1,18 +1,11 @@ using Content.Shared.Audio; using Content.Shared.GameTicking; -using Robust.Client.Audio; -using Robust.Client.ResourceManagement; -using Robust.Client.UserInterface; using AudioComponent = Robust.Shared.Audio.Components.AudioComponent; namespace Content.Client.Audio; public sealed partial class ContentAudioSystem : SharedContentAudioSystem { - [Dependency] private readonly IAudioManager _audioManager = default!; - [Dependency] private readonly IResourceCache _cache = default!; - [Dependency] private readonly IUserInterfaceManager _uiManager = default!; - // Need how much volume to change per tick and just remove it when it drops below "0" private readonly Dictionary _fadingOut = new(); diff --git a/Content.Client/Camera/CameraRecoilSystem.cs b/Content.Client/Camera/CameraRecoilSystem.cs index bb419b465d3..3e04cd5bf19 100644 --- a/Content.Client/Camera/CameraRecoilSystem.cs +++ b/Content.Client/Camera/CameraRecoilSystem.cs @@ -9,26 +9,19 @@ public sealed class CameraRecoilSystem : SharedCameraRecoilSystem { [Dependency] private readonly IConfigurationManager _configManager = default!; - protected float Intensity; + private float _intensity; public override void Initialize() { base.Initialize(); SubscribeNetworkEvent(OnCameraKick); - _configManager.OnValueChanged(CCVars.ScreenShakeIntensity, OnCvarChanged, true); - } - - public override void Shutdown() - { - base.Shutdown(); - - _configManager.UnsubValueChanged(CCVars.ScreenShakeIntensity, OnCvarChanged); + Subs.CVar(_configManager, CCVars.ScreenShakeIntensity, OnCvarChanged, true); } private void OnCvarChanged(float value) { - Intensity = value; + _intensity = value; } private void OnCameraKick(CameraKickEvent ev) @@ -38,13 +31,13 @@ private void OnCameraKick(CameraKickEvent ev) public override void KickCamera(EntityUid uid, Vector2 recoil, CameraRecoilComponent? component = null) { - if (Intensity == 0) + if (_intensity == 0) return; if (!Resolve(uid, ref component, false)) return; - recoil *= Intensity; + recoil *= _intensity; // Use really bad math to "dampen" kicks when we're already kicked. var existing = component.CurrentKick.Length(); diff --git a/Content.Client/CardboardBox/CardboardBoxSystem.cs b/Content.Client/CardboardBox/CardboardBoxSystem.cs index 5e479409cf9..50f9de239d5 100644 --- a/Content.Client/CardboardBox/CardboardBoxSystem.cs +++ b/Content.Client/CardboardBox/CardboardBoxSystem.cs @@ -10,6 +10,7 @@ namespace Content.Client.CardboardBox; public sealed class CardboardBoxSystem : SharedCardboardBoxSystem { [Dependency] private readonly EntityLookupSystem _entityLookup = default!; + [Dependency] private readonly TransformSystem _transform = default!; public override void Initialize() { @@ -29,7 +30,7 @@ private void OnBoxEffect(PlayBoxEffectMessage msg) if (!xformQuery.TryGetComponent(source, out var xform)) return; - var sourcePos = xform.MapPosition; + var sourcePos = _transform.GetMapCoordinates(source, xform); //Any mob that can move should be surprised? //God mind rework needs to come faster so it can just check for mind @@ -53,16 +54,17 @@ private void OnBoxEffect(PlayBoxEffectMessage msg) //Play the effect for the mobs as long as they can see the box and are in range. foreach (var mob in mobMoverEntities) { - if (!xformQuery.TryGetComponent(mob, out var moverTransform) || !ExamineSystemShared.InRangeUnOccluded(sourcePos, moverTransform.MapPosition, box.Distance, null)) + var mapPos = _transform.GetMapCoordinates(mob); + if (!ExamineSystemShared.InRangeUnOccluded(sourcePos, mapPos, box.Distance, null)) continue; - var ent = Spawn(box.Effect, moverTransform.MapPosition); + var ent = Spawn(box.Effect, mapPos); if (!xformQuery.TryGetComponent(ent, out var entTransform) || !TryComp(ent, out var sprite)) continue; sprite.Offset = new Vector2(0, 1); - entTransform.AttachParent(mob); + _transform.SetParent(ent, entTransform, mob); } } diff --git a/Content.Client/Cargo/UI/BountyEntry.xaml.cs b/Content.Client/Cargo/UI/BountyEntry.xaml.cs index 05c5673dddf..1fc8a4986a2 100644 --- a/Content.Client/Cargo/UI/BountyEntry.xaml.cs +++ b/Content.Client/Cargo/UI/BountyEntry.xaml.cs @@ -12,7 +12,6 @@ namespace Content.Client.Cargo.UI; [GenerateTypedNameReferences] public sealed partial class BountyEntry : BoxContainer { - [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; public Action? OnButtonPressed; diff --git a/Content.Client/Changelog/ChangelogManager.cs b/Content.Client/Changelog/ChangelogManager.cs index d62ce17f0e9..4cbd23ec3f9 100644 --- a/Content.Client/Changelog/ChangelogManager.cs +++ b/Content.Client/Changelog/ChangelogManager.cs @@ -1,11 +1,9 @@ -using System.Globalization; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; using Content.Shared.CCVar; using Robust.Shared.Configuration; using Robust.Shared.ContentPack; -using Robust.Shared.Serialization; using Robust.Shared.Serialization.Manager; using Robust.Shared.Serialization.Markdown; using Robust.Shared.Serialization.Markdown.Mapping; @@ -169,7 +167,7 @@ public sealed partial class Changelog } [DataDefinition] - public sealed partial class ChangelogEntry : ISerializationHooks + public sealed partial class ChangelogEntry { [DataField("id")] public int Id { get; private set; } @@ -177,17 +175,11 @@ public sealed partial class ChangelogEntry : ISerializationHooks [DataField("author")] public string Author { get; private set; } = ""; - [DataField("time")] private string _time = default!; - + [DataField] public DateTime Time { get; private set; } [DataField("changes")] public List Changes { get; private set; } = default!; - - void ISerializationHooks.AfterDeserialization() - { - Time = DateTime.Parse(_time, null, DateTimeStyles.RoundtripKind); - } } [DataDefinition] diff --git a/Content.Client/CharacterInfo/CharacterInfoSystem.cs b/Content.Client/CharacterInfo/CharacterInfoSystem.cs index 844a352a184..aeaa48c6f2d 100644 --- a/Content.Client/CharacterInfo/CharacterInfoSystem.cs +++ b/Content.Client/CharacterInfo/CharacterInfoSystem.cs @@ -20,7 +20,7 @@ public override void Initialize() public void RequestCharacterInfo() { - var entity = _players.LocalPlayer?.ControlledEntity; + var entity = _players.LocalEntity; if (entity == null) { return; diff --git a/Content.Client/Chat/TypingIndicator/TypingIndicatorSystem.cs b/Content.Client/Chat/TypingIndicator/TypingIndicatorSystem.cs index 0eea36aa573..844f793fc49 100644 --- a/Content.Client/Chat/TypingIndicator/TypingIndicatorSystem.cs +++ b/Content.Client/Chat/TypingIndicator/TypingIndicatorSystem.cs @@ -20,7 +20,8 @@ public sealed class TypingIndicatorSystem : SharedTypingIndicatorSystem public override void Initialize() { base.Initialize(); - _cfg.OnValueChanged(CCVars.ChatShowTypingIndicator, OnShowTypingChanged); + + Subs.CVar(_cfg, CCVars.ChatShowTypingIndicator, OnShowTypingChanged); } public void ClientChangedChatText() @@ -67,7 +68,7 @@ private void ClientUpdateTyping(bool isClientTyping) _isClientTyping = isClientTyping; // check if player controls any pawn - if (_playerManager.LocalPlayer?.ControlledEntity == null) + if (_playerManager.LocalEntity == null) return; // send a networked event to server diff --git a/Content.Client/CloningConsole/UI/CloningConsoleWindow.xaml.cs b/Content.Client/CloningConsole/UI/CloningConsoleWindow.xaml.cs index b71f1a282f2..a14ce138743 100644 --- a/Content.Client/CloningConsole/UI/CloningConsoleWindow.xaml.cs +++ b/Content.Client/CloningConsole/UI/CloningConsoleWindow.xaml.cs @@ -7,7 +7,7 @@ namespace Content.Client.CloningConsole.UI { [GenerateTypedNameReferences] - public partial class CloningConsoleWindow : DefaultWindow + public sealed partial class CloningConsoleWindow : DefaultWindow { public CloningConsoleWindow() { diff --git a/Content.Client/CombatMode/CombatModeSystem.cs b/Content.Client/CombatMode/CombatModeSystem.cs index 34ae0b1338b..2c938b1b937 100644 --- a/Content.Client/CombatMode/CombatModeSystem.cs +++ b/Content.Client/CombatMode/CombatModeSystem.cs @@ -28,7 +28,7 @@ public override void Initialize() SubscribeLocalEvent(OnHandleState); - _cfg.OnValueChanged(CCVars.CombatModeIndicatorsPointShow, OnShowCombatIndicatorsChanged, true); + Subs.CVar(_cfg, CCVars.CombatModeIndicatorsPointShow, OnShowCombatIndicatorsChanged, true); } private void OnHandleState(EntityUid uid, CombatModeComponent component, ref AfterAutoHandleStateEvent args) @@ -38,7 +38,6 @@ private void OnHandleState(EntityUid uid, CombatModeComponent component, ref Aft public override void Shutdown() { - _cfg.UnsubValueChanged(CCVars.CombatModeIndicatorsPointShow, OnShowCombatIndicatorsChanged); _overlayManager.RemoveOverlay(); base.Shutdown(); @@ -46,7 +45,7 @@ public override void Shutdown() public bool IsInCombatMode() { - var entity = _playerManager.LocalPlayer?.ControlledEntity; + var entity = _playerManager.LocalEntity; if (entity == null) return false; @@ -67,7 +66,7 @@ protected override bool IsNpc(EntityUid uid) private void UpdateHud(EntityUid entity) { - if (entity != _playerManager.LocalPlayer?.ControlledEntity || !Timing.IsFirstTimePredicted) + if (entity != _playerManager.LocalEntity || !Timing.IsFirstTimePredicted) { return; } diff --git a/Content.Client/Commands/DebugPathfindingCommand.cs b/Content.Client/Commands/DebugPathfindingCommand.cs index e02b6dcbbda..b920ccc5edf 100644 --- a/Content.Client/Commands/DebugPathfindingCommand.cs +++ b/Content.Client/Commands/DebugPathfindingCommand.cs @@ -38,7 +38,7 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args) } } - public CompletionResult GetCompletion(IConsoleShell shell, string[] args) + public override CompletionResult GetCompletion(IConsoleShell shell, string[] args) { if (args.Length > 1) { diff --git a/Content.Client/Construction/ConstructionSystem.cs b/Content.Client/Construction/ConstructionSystem.cs index 940538670c0..ae1724c3bf6 100644 --- a/Content.Client/Construction/ConstructionSystem.cs +++ b/Content.Client/Construction/ConstructionSystem.cs @@ -185,7 +185,7 @@ public bool TrySpawnGhost( [NotNullWhen(true)] out EntityUid? ghost) { ghost = null; - if (_playerManager.LocalPlayer?.ControlledEntity is not { } user || + if (_playerManager.LocalEntity is not { } user || !user.IsValid()) { return false; diff --git a/Content.Client/ContextMenu/UI/EntityMenuUIController.cs b/Content.Client/ContextMenu/UI/EntityMenuUIController.cs index 039c03601ad..ae1b3ec3bf0 100644 --- a/Content.Client/ContextMenu/UI/EntityMenuUIController.cs +++ b/Content.Client/ContextMenu/UI/EntityMenuUIController.cs @@ -148,7 +148,7 @@ public void OnKeyBindDown(ContextMenuElement element, GUIBoundKeyEventArgs args) Uid = entity.Value, }; - var session = _playerManager.LocalPlayer?.Session; + var session = _playerManager.LocalSession; if (session != null) { inputSys.HandleInputCommand(session, func, message); @@ -189,7 +189,7 @@ public override void FrameUpdate(FrameEventArgs args) if (!_context.RootMenu.Visible) return; - if (_playerManager.LocalPlayer?.ControlledEntity is not { } player || + if (_playerManager.LocalEntity is not { } player || !player.IsValid()) return; diff --git a/Content.Client/Damage/DamageVisualsSystem.cs b/Content.Client/Damage/DamageVisualsSystem.cs index 718d4731823..e275f13f935 100644 --- a/Content.Client/Damage/DamageVisualsSystem.cs +++ b/Content.Client/Damage/DamageVisualsSystem.cs @@ -28,8 +28,6 @@ public sealed class DamageVisualsSystem : VisualizerSystem( out float progress) where T : DoAfterEvent { - var playerEntity = _player.LocalPlayer?.ControlledEntity; + var playerEntity = _player.LocalEntity; doAfter = null; @event = null; diff --git a/Content.Client/Doors/FirelockSystem.cs b/Content.Client/Doors/FirelockSystem.cs index d4331fd15dc..cfd84a47133 100644 --- a/Content.Client/Doors/FirelockSystem.cs +++ b/Content.Client/Doors/FirelockSystem.cs @@ -5,7 +5,7 @@ namespace Content.Client.Doors; public sealed class FirelockSystem : EntitySystem { - [Dependency] protected readonly SharedAppearanceSystem _appearanceSystem = default!; + [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; public override void Initialize() { diff --git a/Content.Client/Drugs/DrugOverlaySystem.cs b/Content.Client/Drugs/DrugOverlaySystem.cs index 3c42033be6c..9bfa4fdf827 100644 --- a/Content.Client/Drugs/DrugOverlaySystem.cs +++ b/Content.Client/Drugs/DrugOverlaySystem.cs @@ -43,13 +43,13 @@ private void OnPlayerDetached(EntityUid uid, SeeingRainbowsComponent component, private void OnInit(EntityUid uid, SeeingRainbowsComponent component, ComponentInit args) { - if (_player.LocalPlayer?.ControlledEntity == uid) + if (_player.LocalEntity == uid) _overlayMan.AddOverlay(_overlay); } private void OnShutdown(EntityUid uid, SeeingRainbowsComponent component, ComponentShutdown args) { - if (_player.LocalPlayer?.ControlledEntity == uid) + if (_player.LocalEntity == uid) { _overlay.Intoxication = 0; _overlayMan.RemoveOverlay(_overlay); diff --git a/Content.Client/Drugs/RainbowOverlay.cs b/Content.Client/Drugs/RainbowOverlay.cs index 8372f7ea600..6ef5d0f65ce 100644 --- a/Content.Client/Drugs/RainbowOverlay.cs +++ b/Content.Client/Drugs/RainbowOverlay.cs @@ -34,7 +34,7 @@ public RainbowOverlay() protected override void FrameUpdate(FrameEventArgs args) { - var playerEntity = _playerManager.LocalPlayer?.ControlledEntity; + var playerEntity = _playerManager.LocalEntity; if (playerEntity == null) return; @@ -53,7 +53,7 @@ protected override void FrameUpdate(FrameEventArgs args) protected override bool BeforeDraw(in OverlayDrawArgs args) { - if (!_entityManager.TryGetComponent(_playerManager.LocalPlayer?.ControlledEntity, out EyeComponent? eyeComp)) + if (!_entityManager.TryGetComponent(_playerManager.LocalEntity, out EyeComponent? eyeComp)) return false; if (args.Viewport.Eye != eyeComp.Eye) diff --git a/Content.Client/Drunk/DrunkOverlay.cs b/Content.Client/Drunk/DrunkOverlay.cs index 96a3beb7022..e01719e62cb 100644 --- a/Content.Client/Drunk/DrunkOverlay.cs +++ b/Content.Client/Drunk/DrunkOverlay.cs @@ -36,7 +36,7 @@ public DrunkOverlay() protected override void FrameUpdate(FrameEventArgs args) { - var playerEntity = _playerManager.LocalPlayer?.ControlledEntity; + var playerEntity = _playerManager.LocalEntity; if (playerEntity == null) return; @@ -58,7 +58,7 @@ protected override void FrameUpdate(FrameEventArgs args) protected override bool BeforeDraw(in OverlayDrawArgs args) { - if (!_entityManager.TryGetComponent(_playerManager.LocalPlayer?.ControlledEntity, out EyeComponent? eyeComp)) + if (!_entityManager.TryGetComponent(_playerManager.LocalEntity, out EyeComponent? eyeComp)) return false; if (args.Viewport.Eye != eyeComp.Eye) diff --git a/Content.Client/Drunk/DrunkSystem.cs b/Content.Client/Drunk/DrunkSystem.cs index dcd2758623e..d9c6bb192fd 100644 --- a/Content.Client/Drunk/DrunkSystem.cs +++ b/Content.Client/Drunk/DrunkSystem.cs @@ -38,13 +38,13 @@ private void OnPlayerDetached(EntityUid uid, DrunkComponent component, LocalPlay private void OnDrunkInit(EntityUid uid, DrunkComponent component, ComponentInit args) { - if (_player.LocalPlayer?.ControlledEntity == uid) + if (_player.LocalEntity == uid) _overlayMan.AddOverlay(_overlay); } private void OnDrunkShutdown(EntityUid uid, DrunkComponent component, ComponentShutdown args) { - if (_player.LocalPlayer?.ControlledEntity == uid) + if (_player.LocalEntity == uid) { _overlay.CurrentBoozePower = 0; _overlayMan.RemoveOverlay(_overlay); diff --git a/Content.Client/Examine/ExamineSystem.cs b/Content.Client/Examine/ExamineSystem.cs index 32ba78085ae..1be472b06d6 100644 --- a/Content.Client/Examine/ExamineSystem.cs +++ b/Content.Client/Examine/ExamineSystem.cs @@ -33,7 +33,6 @@ public sealed class ExamineSystem : ExamineSystemShared [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IEyeManager _eyeManager = default!; [Dependency] private readonly VerbSystem _verbSystem = default!; - [Dependency] private readonly IBaseClient _client = default!; public const string StyleClassEntityTooltip = "entity-tooltip"; @@ -66,12 +65,10 @@ private void OnExaminedItemDropped(EntityUid item, ItemComponent comp, DroppedEv { if (!args.User.Valid) return; - if (_playerManager.LocalPlayer == null) - return; if (_examineTooltipOpen == null) return; - if (item == _examinedEntity && args.User == _playerManager.LocalPlayer.ControlledEntity) + if (item == _examinedEntity && args.User == _playerManager.LocalEntity) CloseTooltip(); } @@ -118,7 +115,7 @@ private bool HandleExamine(in PointerInputCmdHandler.PointerInputCmdArgs args) return false; } - _playerEntity = _playerManager.LocalPlayer?.ControlledEntity ?? default; + _playerEntity = _playerManager.LocalEntity ?? default; if (_playerEntity == default || !CanExamine(_playerEntity, entity)) { @@ -149,7 +146,7 @@ private void AddExamineVerb(GetVerbsEvent args) private void OnExamineInfoResponse(ExamineSystemMessages.ExamineInfoResponseMessage ev) { - var player = _playerManager.LocalPlayer?.ControlledEntity; + var player = _playerManager.LocalEntity; if (player == null) return; @@ -356,7 +353,7 @@ public void VerbButtonPressed(BaseButton.ButtonEventArgs obj) public void DoExamine(EntityUid entity, bool centeredOnCursor = true, EntityUid? userOverride = null) { - var playerEnt = userOverride ?? _playerManager.LocalPlayer?.ControlledEntity; + var playerEnt = userOverride ?? _playerManager.LocalEntity; if (playerEnt == null) return; diff --git a/Content.Client/Explosion/ExplosionOverlay.cs b/Content.Client/Explosion/ExplosionOverlay.cs index 94e8ca59823..2d8c15f1b9f 100644 --- a/Content.Client/Explosion/ExplosionOverlay.cs +++ b/Content.Client/Explosion/ExplosionOverlay.cs @@ -14,7 +14,6 @@ namespace Content.Client.Explosion; public sealed class ExplosionOverlay : Overlay { [Dependency] private readonly IRobustRandom _robustRandom = default!; - [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IEntityManager _entMan = default!; [Dependency] private readonly IPrototypeManager _proto = default!; diff --git a/Content.Client/Eye/Blinding/BlindingSystem.cs b/Content.Client/Eye/Blinding/BlindingSystem.cs index 2bff5db4d61..99d215b7587 100644 --- a/Content.Client/Eye/Blinding/BlindingSystem.cs +++ b/Content.Client/Eye/Blinding/BlindingSystem.cs @@ -43,13 +43,13 @@ private void OnPlayerDetached(EntityUid uid, BlindableComponent component, Local private void OnBlindInit(EntityUid uid, BlindableComponent component, ComponentInit args) { - if (_player.LocalPlayer?.ControlledEntity == uid) + if (_player.LocalEntity == uid) _overlayMan.AddOverlay(_overlay); } private void OnBlindShutdown(EntityUid uid, BlindableComponent component, ComponentShutdown args) { - if (_player.LocalPlayer?.ControlledEntity == uid) + if (_player.LocalEntity == uid) { _overlayMan.RemoveOverlay(_overlay); } diff --git a/Content.Client/Eye/Blinding/BlurryVisionSystem.cs b/Content.Client/Eye/Blinding/BlurryVisionSystem.cs index 91090fc4607..ba687ead4eb 100644 --- a/Content.Client/Eye/Blinding/BlurryVisionSystem.cs +++ b/Content.Client/Eye/Blinding/BlurryVisionSystem.cs @@ -36,13 +36,13 @@ private void OnPlayerDetached(EntityUid uid, BlurryVisionComponent component, Lo private void OnBlurryInit(EntityUid uid, BlurryVisionComponent component, ComponentInit args) { - if (_player.LocalPlayer?.ControlledEntity == uid) + if (_player.LocalEntity == uid) _overlayMan.AddOverlay(_overlay); } private void OnBlurryShutdown(EntityUid uid, BlurryVisionComponent component, ComponentShutdown args) { - if (_player.LocalPlayer?.ControlledEntity == uid) + if (_player.LocalEntity == uid) { _overlayMan.RemoveOverlay(_overlay); } diff --git a/Content.Client/Eye/EyeLerpingSystem.cs b/Content.Client/Eye/EyeLerpingSystem.cs index 8889b971002..78e1b851fcb 100644 --- a/Content.Client/Eye/EyeLerpingSystem.cs +++ b/Content.Client/Eye/EyeLerpingSystem.cs @@ -41,7 +41,7 @@ public override void Initialize() private void OnEyeStartup(EntityUid uid, EyeComponent component, ComponentStartup args) { - if (_playerManager.LocalPlayer?.ControlledEntity == uid) + if (_playerManager.LocalEntity == uid) AddEye(uid, component, true); } @@ -77,7 +77,7 @@ public void RemoveEye(EntityUid uid) return; // If this is the currently controlled entity, we keep the component. - if (_playerManager.LocalPlayer?.ControlledEntity == uid) + if (_playerManager.LocalEntity == uid) lerp.ManuallyAdded = false; else RemComp(uid, lerp); diff --git a/Content.Client/Flash/FlashOverlay.cs b/Content.Client/Flash/FlashOverlay.cs index 433ee95e1cb..fe9c888227e 100644 --- a/Content.Client/Flash/FlashOverlay.cs +++ b/Content.Client/Flash/FlashOverlay.cs @@ -51,7 +51,7 @@ public void ReceiveFlash(double duration) protected override void Draw(in OverlayDrawArgs args) { - if (!_entityManager.TryGetComponent(_playerManager.LocalPlayer?.ControlledEntity, out EyeComponent? eyeComp)) + if (!_entityManager.TryGetComponent(_playerManager.LocalEntity, out EyeComponent? eyeComp)) return; if (args.Viewport.Eye != eyeComp.Eye) diff --git a/Content.Client/Flash/FlashSystem.cs b/Content.Client/Flash/FlashSystem.cs index 3393662fa40..ad8f8b0b82b 100644 --- a/Content.Client/Flash/FlashSystem.cs +++ b/Content.Client/Flash/FlashSystem.cs @@ -25,7 +25,7 @@ private void OnFlashableHandleState(EntityUid uid, FlashableComponent component, return; // Yes, this code is awful. I'm just porting it to an entity system so don't blame me. - if (_playerManager.LocalPlayer != null && _playerManager.LocalPlayer.Session.AttachedEntity != uid) + if (_playerManager.LocalEntity != uid) { return; } diff --git a/Content.Client/Fluids/PuddleOverlay.cs b/Content.Client/Fluids/PuddleOverlay.cs index 8c8b13a1efe..ac6661cfdd8 100644 --- a/Content.Client/Fluids/PuddleOverlay.cs +++ b/Content.Client/Fluids/PuddleOverlay.cs @@ -9,7 +9,6 @@ namespace Content.Client.Fluids; public sealed class PuddleOverlay : Overlay { - [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly IEyeManager _eyeManager = default!; [Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!; diff --git a/Content.Client/Forensics/ForensicScannerMenu.xaml b/Content.Client/Forensics/ForensicScannerMenu.xaml index fbfcb06f158..b508fa74338 100644 --- a/Content.Client/Forensics/ForensicScannerMenu.xaml +++ b/Content.Client/Forensics/ForensicScannerMenu.xaml @@ -18,7 +18,7 @@ Text="{Loc 'forensic-scanner-interface-clear'}" /> /// -1 (no effect) unless MaxSeverity is specified. Defaults to 1. Minimum severity level supported by this state. @@ -80,16 +79,6 @@ public sealed partial class AlertPrototype : IPrototype, ISerializationHooks [DataField("onClick", serverOnly: true)] public IAlertClick? OnClick { get; private set; } - void ISerializationHooks.AfterDeserialization() - { - if (AlertType == AlertType.Error) - { - Logger.ErrorS("alert", "missing or invalid alertType for alert with name {0}", Name); - } - - AlertKey = new AlertKey(AlertType, Category); - } - /// severity level, if supported by this alert /// the icon path to the texture for the provided severity level public SpriteSpecifier GetIcon(short? severity = null) diff --git a/Content.Shared/Anomaly/Effects/SharedGravityAnomalySystem.cs b/Content.Shared/Anomaly/Effects/SharedGravityAnomalySystem.cs index eca71e6fd73..f4b7cc8bf4f 100644 --- a/Content.Shared/Anomaly/Effects/SharedGravityAnomalySystem.cs +++ b/Content.Shared/Anomaly/Effects/SharedGravityAnomalySystem.cs @@ -5,16 +5,17 @@ using Content.Shared.Throwing; using Robust.Shared.Map; using Content.Shared.Physics; +using Robust.Shared.Map.Components; using Robust.Shared.Physics.Components; namespace Content.Shared.Anomaly.Effects; public abstract class SharedGravityAnomalySystem : EntitySystem { - [Dependency] private readonly IMapManager _map = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly ThrowingSystem _throwing = default!; [Dependency] private readonly SharedTransformSystem _xform = default!; + [Dependency] private readonly SharedMapSystem _mapSystem = default!; /// public override void Initialize() @@ -47,13 +48,18 @@ private void OnAnomalyPulse(EntityUid uid, GravityAnomalyComponent component, re private void OnSupercritical(EntityUid uid, GravityAnomalyComponent component, ref AnomalySupercriticalEvent args) { var xform = Transform(uid); - if (!_map.TryGetGrid(xform.GridUid, out var grid)) + if (!TryComp(xform.GridUid, out MapGridComponent? grid)) return; var worldPos = _xform.GetWorldPosition(xform); - var tileref = grid.GetTilesIntersecting(new Circle(worldPos, component.SpaceRange)).ToArray(); + var tileref = _mapSystem.GetTilesIntersecting( + xform.GridUid.Value, + grid, + new Circle(worldPos, component.SpaceRange)) + .ToArray(); + var tiles = tileref.Select(t => (t.GridIndices, Tile.Empty)).ToList(); - grid.SetTiles(tiles); + _mapSystem.SetTiles(xform.GridUid.Value, grid, tiles); var range = component.MaxThrowRange * 2; var strength = component.MaxThrowStrength * 2; diff --git a/Content.Shared/Anomaly/SharedAnomalySystem.cs b/Content.Shared/Anomaly/SharedAnomalySystem.cs index 711f9d1493c..6eba4221b49 100644 --- a/Content.Shared/Anomaly/SharedAnomalySystem.cs +++ b/Content.Shared/Anomaly/SharedAnomalySystem.cs @@ -27,7 +27,7 @@ public abstract class SharedAnomalySystem : EntitySystem [Dependency] protected readonly IGameTiming Timing = default!; [Dependency] private readonly INetManager _net = default!; [Dependency] protected readonly IRobustRandom Random = default!; - [Dependency] protected readonly ISharedAdminLogManager Log = default!; + [Dependency] protected readonly ISharedAdminLogManager AdminLog = default!; [Dependency] private readonly DamageableSystem _damageable = default!; [Dependency] protected readonly SharedAudioSystem Audio = default!; [Dependency] protected readonly SharedAppearanceSystem Appearance = default!; @@ -92,7 +92,7 @@ public void DoAnomalyBurnDamage(EntityUid source, EntityUid target, AnomalyCompo private void OnAnomalyUnpause(EntityUid uid, AnomalyComponent component, ref EntityUnpausedEvent args) { component.NextPulseTime += args.PausedTime; - Dirty(component); + Dirty(uid, component); } private void OnPulsingUnpause(EntityUid uid, AnomalyPulsingComponent component, ref EntityUnpausedEvent args) @@ -103,7 +103,7 @@ private void OnPulsingUnpause(EntityUid uid, AnomalyPulsingComponent component, private void OnSupercriticalUnpause(EntityUid uid, AnomalySupercriticalComponent component, ref EntityUnpausedEvent args) { component.EndTime += args.PausedTime; - Dirty(component); + Dirty(uid, component); } public void DoAnomalyPulse(EntityUid uid, AnomalyComponent? component = null) @@ -132,7 +132,7 @@ public void DoAnomalyPulse(EntityUid uid, AnomalyComponent? component = null) var stability = Random.NextFloat(minStability, maxStability); ChangeAnomalyStability(uid, stability, component); - Log.Add(LogType.Anomaly, LogImpact.Medium, $"Anomaly {ToPrettyString(uid)} pulsed with severity {component.Severity}."); + AdminLog.Add(LogType.Anomaly, LogImpact.Medium, $"Anomaly {ToPrettyString(uid)} pulsed with severity {component.Severity}."); if (_net.IsServer) Audio.PlayPvs(component.PulseSound, uid); @@ -154,14 +154,14 @@ public void StartSupercriticalEvent(EntityUid uid) if (HasComp(uid)) return; - Log.Add(LogType.Anomaly, LogImpact.High, $"Anomaly {ToPrettyString(uid)} began to go supercritical."); + AdminLog.Add(LogType.Anomaly, LogImpact.High, $"Anomaly {ToPrettyString(uid)} began to go supercritical."); if (_net.IsServer) _sawmill.Info($"Anomaly is going supercritical. Entity: {ToPrettyString(uid)}"); - var super = EnsureComp(uid); + var super = AddComp(uid); super.EndTime = Timing.CurTime + super.SupercriticalDuration; Appearance.SetData(uid, AnomalyVisuals.Supercritical, true); - Dirty(super); + Dirty(uid, super); } /// @@ -201,7 +201,7 @@ public void EndAnomaly(EntityUid uid, AnomalyComponent? component = null, bool s // Logging before resolve, in case the anomaly has deleted itself. if (_net.IsServer) _sawmill.Info($"Ending anomaly. Entity: {ToPrettyString(uid)}"); - Log.Add(LogType.Anomaly, LogImpact.Extreme, $"Anomaly {ToPrettyString(uid)} went supercritical."); + AdminLog.Add(LogType.Anomaly, LogImpact.Extreme, $"Anomaly {ToPrettyString(uid)} went supercritical."); if (!Resolve(uid, ref component)) return; @@ -231,7 +231,7 @@ public void ChangeAnomalyStability(EntityUid uid, float change, AnomalyComponent var newVal = component.Stability + change; component.Stability = Math.Clamp(newVal, 0, 1); - Dirty(component); + Dirty(uid, component); var ev = new AnomalyStabilityChangedEvent(uid, component.Stability, component.Severity); RaiseLocalEvent(uid, ref ev, true); @@ -254,7 +254,7 @@ public void ChangeAnomalySeverity(EntityUid uid, float change, AnomalyComponent? StartSupercriticalEvent(uid); component.Severity = Math.Clamp(newVal, 0, 1); - Dirty(component); + Dirty(uid, component); var ev = new AnomalySeverityChangedEvent(uid, component.Stability, component.Severity); RaiseLocalEvent(uid, ref ev, true); @@ -280,7 +280,7 @@ public void ChangeAnomalyHealth(EntityUid uid, float change, AnomalyComponent? c } component.Health = Math.Clamp(newVal, 0, 1); - Dirty(component); + Dirty(uid, component); var ev = new AnomalyHealthChangedEvent(uid, component.Health); RaiseLocalEvent(uid, ref ev, true); diff --git a/Content.Shared/Bed/Cryostorage/SharedCryostorageSystem.cs b/Content.Shared/Bed/Cryostorage/SharedCryostorageSystem.cs index 14a76ee45c0..1197e019d07 100644 --- a/Content.Shared/Bed/Cryostorage/SharedCryostorageSystem.cs +++ b/Content.Shared/Bed/Cryostorage/SharedCryostorageSystem.cs @@ -42,14 +42,7 @@ public override void Initialize() SubscribeLocalEvent(OnRoundRestart); - _configuration.OnValueChanged(CCVars.GameCryoSleepRejoining, OnCvarChanged, true); - } - - public override void Shutdown() - { - base.Shutdown(); - - _configuration.UnsubValueChanged(CCVars.GameCryoSleepRejoining, OnCvarChanged); + Subs.CVar(_configuration, CCVars.GameCryoSleepRejoining, OnCvarChanged, true); } private void OnCvarChanged(bool value) diff --git a/Content.Shared/Bed/Sleep/SharedSleepingSystem.cs b/Content.Shared/Bed/Sleep/SharedSleepingSystem.cs index 505b2a18e7b..8e76ce3a3e6 100644 --- a/Content.Shared/Bed/Sleep/SharedSleepingSystem.cs +++ b/Content.Shared/Bed/Sleep/SharedSleepingSystem.cs @@ -13,7 +13,6 @@ namespace Content.Server.Bed.Sleep public abstract class SharedSleepingSystem : EntitySystem { [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly INetManager _net = default!; [Dependency] private readonly SharedActionsSystem _actionsSystem = default!; [Dependency] private readonly BlindableSystem _blindableSystem = default!; diff --git a/Content.Shared/Blocking/BlockingSystem.cs b/Content.Shared/Blocking/BlockingSystem.cs index f2d41e5be95..3e1ff4284c7 100644 --- a/Content.Shared/Blocking/BlockingSystem.cs +++ b/Content.Shared/Blocking/BlockingSystem.cs @@ -26,7 +26,6 @@ namespace Content.Shared.Blocking; public sealed partial class BlockingSystem : EntitySystem { - [Dependency] private readonly IPrototypeManager _proto = default!; [Dependency] private readonly SharedActionsSystem _actionsSystem = default!; [Dependency] private readonly ActionContainerSystem _actionContainer = default!; [Dependency] private readonly SharedTransformSystem _transformSystem = default!; diff --git a/Content.Shared/CartridgeLoader/SharedCartridgeLoaderSystem.cs b/Content.Shared/CartridgeLoader/SharedCartridgeLoaderSystem.cs index ac12c5e7916..859a9f37a81 100644 --- a/Content.Shared/CartridgeLoader/SharedCartridgeLoaderSystem.cs +++ b/Content.Shared/CartridgeLoader/SharedCartridgeLoaderSystem.cs @@ -11,7 +11,6 @@ public abstract class SharedCartridgeLoaderSystem : EntitySystem [Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!; [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; [Dependency] private readonly SharedContainerSystem _container = default!; - [Dependency] private readonly INetManager _netMan = default!; public override void Initialize() { diff --git a/Content.Shared/Charges/Systems/SharedChargesSystem.cs b/Content.Shared/Charges/Systems/SharedChargesSystem.cs index 653a7f22a5a..021191ac263 100644 --- a/Content.Shared/Charges/Systems/SharedChargesSystem.cs +++ b/Content.Shared/Charges/Systems/SharedChargesSystem.cs @@ -38,7 +38,7 @@ public void AddCharges(EntityUid uid, int change, LimitedChargesComponent? comp var old = comp.Charges; comp.Charges = Math.Clamp(comp.Charges + change, 0, comp.MaxCharges); if (comp.Charges != old) - Dirty(comp); + Dirty(uid, comp); } /// diff --git a/Content.Shared/Clothing/EntitySystems/StealthClothingSystem.cs b/Content.Shared/Clothing/EntitySystems/StealthClothingSystem.cs index 4bf2f76ca34..e96d9f866aa 100644 --- a/Content.Shared/Clothing/EntitySystems/StealthClothingSystem.cs +++ b/Content.Shared/Clothing/EntitySystems/StealthClothingSystem.cs @@ -114,7 +114,7 @@ private void OnUnequipped(EntityUid uid, StealthClothingComponent comp, GotUnequ /// /// Raised on the stealth clothing when attempting to add an action. /// -public class AddStealthActionEvent : CancellableEntityEventArgs +public sealed class AddStealthActionEvent : CancellableEntityEventArgs { /// /// User that equipped the stealth clothing. @@ -130,7 +130,7 @@ public AddStealthActionEvent(EntityUid user) /// /// Raised on the stealth clothing when the user is attemping to enable it. /// -public class AttemptStealthEvent : CancellableEntityEventArgs +public sealed class AttemptStealthEvent : CancellableEntityEventArgs { /// /// User that is attempting to enable the stealth clothing. diff --git a/Content.Shared/Construction/SharedFlatpackSystem.cs b/Content.Shared/Construction/SharedFlatpackSystem.cs index c6f3e89744d..d4c2513cd3d 100644 --- a/Content.Shared/Construction/SharedFlatpackSystem.cs +++ b/Content.Shared/Construction/SharedFlatpackSystem.cs @@ -20,7 +20,6 @@ namespace Content.Shared.Construction; public abstract class SharedFlatpackSystem : EntitySystem { [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; - [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly INetManager _net = default!; [Dependency] protected readonly IPrototypeManager PrototypeManager = default!; [Dependency] protected readonly SharedAppearanceSystem Appearance = default!; diff --git a/Content.Shared/Damage/Systems/DamageableSystem.cs b/Content.Shared/Damage/Systems/DamageableSystem.cs index 9337e79439f..4aaf380c47d 100644 --- a/Content.Shared/Damage/Systems/DamageableSystem.cs +++ b/Content.Shared/Damage/Systems/DamageableSystem.cs @@ -18,7 +18,6 @@ namespace Content.Shared.Damage public sealed class DamageableSystem : EntitySystem { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly INetManager _netMan = default!; [Dependency] private readonly MobThresholdSystem _mobThreshold = default!; diff --git a/Content.Shared/Damage/Systems/PassiveDamageSystem.cs b/Content.Shared/Damage/Systems/PassiveDamageSystem.cs index 5a37d6a6e6c..e750863e243 100644 --- a/Content.Shared/Damage/Systems/PassiveDamageSystem.cs +++ b/Content.Shared/Damage/Systems/PassiveDamageSystem.cs @@ -10,7 +10,6 @@ public sealed class PassiveDamageSystem : EntitySystem { [Dependency] private readonly DamageableSystem _damageable = default!; [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly MobStateSystem _mobState = default!; public override void Initialize() { @@ -33,14 +32,14 @@ public override void Update(float frameTime) // Go through every entity with the component var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var comp, out var damage, out var mobState)) - { + { // Make sure they're up for a damage tick if (comp.NextDamage > curTime) continue; if (comp.DamageCap != 0 && damage.TotalDamage >= comp.DamageCap) continue; - + // Set the next time they can take damage comp.NextDamage = curTime + TimeSpan.FromSeconds(1f); diff --git a/Content.Shared/Doors/Systems/SharedDoorSystem.cs b/Content.Shared/Doors/Systems/SharedDoorSystem.cs index 53d79cada7a..f04f6c6dfe0 100644 --- a/Content.Shared/Doors/Systems/SharedDoorSystem.cs +++ b/Content.Shared/Doors/Systems/SharedDoorSystem.cs @@ -14,7 +14,6 @@ using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Systems; using Robust.Shared.Timing; -using Content.Shared.Prying.Components; using Robust.Shared.Audio.Systems; namespace Content.Shared.Doors.Systems; diff --git a/Content.Shared/Examine/ExamineSystemShared.cs b/Content.Shared/Examine/ExamineSystemShared.cs index 905492a65ba..5a3fb872293 100644 --- a/Content.Shared/Examine/ExamineSystemShared.cs +++ b/Content.Shared/Examine/ExamineSystemShared.cs @@ -17,6 +17,7 @@ namespace Content.Shared.Examine { public abstract partial class ExamineSystemShared : EntitySystem { + [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SharedContainerSystem _containerSystem = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; [Dependency] protected readonly MobStateSystem MobStateSystem = default!; @@ -77,7 +78,7 @@ public bool CanExamine(EntityUid examiner, EntityUid examined) if (IsClientSide(examined)) return true; - return !Deleted(examined) && CanExamine(examiner, EntityManager.GetComponent(examined).MapPosition, + return !Deleted(examined) && CanExamine(examiner, _transform.GetMapCoordinates(examined), entity => entity == examiner || entity == examined, examined); } @@ -109,7 +110,7 @@ public virtual bool CanExamine(EntityUid examiner, MapCoordinates target, Ignore return false; return InRangeUnOccluded( - EntityManager.GetComponent(examiner).MapPosition, + _transform.GetMapCoordinates(examiner), target, GetExaminerRange(examiner), predicate: predicate, diff --git a/Content.Shared/Explosion/Components/OnTrigger/SmokeOnTriggerComponent.cs b/Content.Shared/Explosion/Components/OnTrigger/SmokeOnTriggerComponent.cs index cfbe1fcb3d9..80d65f4c2cd 100644 --- a/Content.Shared/Explosion/Components/OnTrigger/SmokeOnTriggerComponent.cs +++ b/Content.Shared/Explosion/Components/OnTrigger/SmokeOnTriggerComponent.cs @@ -1,9 +1,7 @@ using Content.Shared.Explosion.EntitySystems; using Content.Shared.Chemistry.Components; -using Content.Shared.Explosion.EntitySystems; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; -using Robust.Shared.GameStates; namespace Content.Shared.Explosion.Components; diff --git a/Content.Shared/Eye/Blinding/Systems/BlurryVisionSystem.cs b/Content.Shared/Eye/Blinding/Systems/BlurryVisionSystem.cs index 4577bcda99a..099753d51e0 100644 --- a/Content.Shared/Eye/Blinding/Systems/BlurryVisionSystem.cs +++ b/Content.Shared/Eye/Blinding/Systems/BlurryVisionSystem.cs @@ -6,8 +6,6 @@ namespace Content.Shared.Eye.Blinding.Systems; public sealed class BlurryVisionSystem : EntitySystem { - [Dependency] private readonly IEntityManager _entityManager = default!; - public override void Initialize() { base.Initialize(); diff --git a/Content.Shared/Fluids/SharedDrainSystem.cs b/Content.Shared/Fluids/SharedDrainSystem.cs index f9bcee44eee..d65dddb0df9 100644 --- a/Content.Shared/Fluids/SharedDrainSystem.cs +++ b/Content.Shared/Fluids/SharedDrainSystem.cs @@ -3,7 +3,7 @@ namespace Content.Shared.Fluids; -public partial class SharedDrainSystem : EntitySystem +public abstract partial class SharedDrainSystem : EntitySystem { [Serializable, NetSerializable] public sealed partial class DrainDoAfterEvent : SimpleDoAfterEvent diff --git a/Content.Shared/Friction/TileFrictionController.cs b/Content.Shared/Friction/TileFrictionController.cs index 472f5b574b2..ba4d9fc24f8 100644 --- a/Content.Shared/Friction/TileFrictionController.cs +++ b/Content.Shared/Friction/TileFrictionController.cs @@ -31,20 +31,8 @@ public override void Initialize() { base.Initialize(); - _configManager.OnValueChanged(CCVars.TileFrictionModifier, SetFrictionModifier, true); - _configManager.OnValueChanged(CCVars.StopSpeed, SetStopSpeed, true); - } - - private void SetStopSpeed(float value) => _stopSpeed = value; - - private void SetFrictionModifier(float value) => _frictionModifier = value; - - public override void Shutdown() - { - base.Shutdown(); - - _configManager.UnsubValueChanged(CCVars.TileFrictionModifier, SetFrictionModifier); - _configManager.UnsubValueChanged(CCVars.StopSpeed, SetStopSpeed); + Subs.CVar(_configManager, CCVars.TileFrictionModifier, value => _frictionModifier = value, true); + Subs.CVar(_configManager, CCVars.StopSpeed, value => _stopSpeed = value, true); } public override void UpdateBeforeMapSolve(bool prediction, PhysicsMapComponent mapComponent, float frameTime) diff --git a/Content.Shared/Gibbing/Systems/GibbingSystem.cs b/Content.Shared/Gibbing/Systems/GibbingSystem.cs index 2f5a9cb61c0..f3d982977a7 100644 --- a/Content.Shared/Gibbing/Systems/GibbingSystem.cs +++ b/Content.Shared/Gibbing/Systems/GibbingSystem.cs @@ -15,7 +15,6 @@ public sealed class GibbingSystem : EntitySystem { [Dependency] private readonly SharedContainerSystem _containerSystem = default!; [Dependency] private readonly SharedTransformSystem _transformSystem = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!; [Dependency] private readonly SharedPhysicsSystem _physicsSystem = default!; [Dependency] private readonly IRobustRandom _random = default!; diff --git a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs index 699fb64ee8d..b72a7c4eb3c 100644 --- a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs +++ b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs @@ -18,7 +18,6 @@ public abstract partial class SharedHandsSystem [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!; [Dependency] protected readonly SharedContainerSystem ContainerSystem = default!; [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; - [Dependency] private readonly SharedItemSystem _items = default!; [Dependency] private readonly SharedStorageSystem _storage = default!; [Dependency] protected readonly SharedTransformSystem TransformSystem = default!; [Dependency] private readonly SharedVirtualItemSystem _virtualSystem = default!; diff --git a/Content.Shared/Inventory/InventorySystem.Slots.cs b/Content.Shared/Inventory/InventorySystem.Slots.cs index 210e21c2c9d..cbbee3a85bd 100644 --- a/Content.Shared/Inventory/InventorySystem.Slots.cs +++ b/Content.Shared/Inventory/InventorySystem.Slots.cs @@ -51,7 +51,7 @@ public bool TryGetSlotContainer(EntityUid uid, string slot, [NotNullWhen(true)] if (!TryGetSlot(uid, slot, out slotDefinition, inventory: inventory)) return false; - if (!containerComp.TryGetContainer(slotDefinition.Name, out var container)) + if (!_containerSystem.TryGetContainer(uid, slotDefinition.Name, out var container, containerComp)) { if (inventory.LifeStage >= ComponentLifeStage.Initialized) Log.Error($"Missing inventory container {slot} on entity {ToPrettyString(uid)}"); diff --git a/Content.Shared/Movement/Systems/SharedMoverController.Input.cs b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs index 6fb8c64b8e7..bce3aeff527 100644 --- a/Content.Shared/Movement/Systems/SharedMoverController.Input.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs @@ -57,13 +57,8 @@ private void InitializeInput() SubscribeLocalEvent(OnFollowedParentChange); - _configManager.OnValueChanged(CCVars.CameraRotationLocked, SetCameraRotationLocked, true); - _configManager.OnValueChanged(CCVars.GameDiagonalMovement, SetDiagonalMovement, true); - } - - private void SetCameraRotationLocked(bool obj) - { - CameraRotationLocked = obj; + Subs.CVar(_configManager, CCVars.CameraRotationLocked, obj => CameraRotationLocked = obj, true); + Subs.CVar(_configManager, CCVars.GameDiagonalMovement, value => DiagonalMovementEnabled = value, true); } /// @@ -141,14 +136,10 @@ private void OnMoverGetState(EntityUid uid, InputMoverComponent component, ref C private void ShutdownInput() { CommandBinds.Unregister(); - _configManager.UnsubValueChanged(CCVars.CameraRotationLocked, SetCameraRotationLocked); - _configManager.UnsubValueChanged(CCVars.GameDiagonalMovement, SetDiagonalMovement); } public bool DiagonalMovementEnabled { get; private set; } - private void SetDiagonalMovement(bool value) => DiagonalMovementEnabled = value; - protected virtual void HandleShuttleInput(EntityUid uid, ShuttleButtons button, ushort subTick, bool state) {} private void OnAutoParentChange(EntityUid uid, AutoOrientComponent component, ref EntParentChangedMessage args) diff --git a/Content.Shared/Movement/Systems/SharedMoverController.Relay.cs b/Content.Shared/Movement/Systems/SharedMoverController.Relay.cs index 846fbfaf7e0..8568290bffb 100644 --- a/Content.Shared/Movement/Systems/SharedMoverController.Relay.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.Relay.cs @@ -57,8 +57,8 @@ public void SetRelay(EntityUid uid, EntityUid relayEntity) Physics.UpdateIsPredicted(relayEntity); component.RelayEntity = relayEntity; targetComp.Source = uid; - Dirty(component); - Dirty(targetComp); + Dirty(uid, component); + Dirty(relayEntity, targetComp); } private void OnRelayShutdown(EntityUid uid, RelayInputMoverComponent component, ComponentShutdown args) diff --git a/Content.Shared/Movement/Systems/SharedMoverController.cs b/Content.Shared/Movement/Systems/SharedMoverController.cs index 49ad40ae596..4d9eedbf7c4 100644 --- a/Content.Shared/Movement/Systems/SharedMoverController.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.cs @@ -94,20 +94,15 @@ public override void Initialize() InitializeInput(); InitializeRelay(); - _configManager.OnValueChanged(CCVars.RelativeMovement, SetRelativeMovement, true); - _configManager.OnValueChanged(CCVars.StopSpeed, SetStopSpeed, true); + Subs.CVar(_configManager, CCVars.RelativeMovement, value => _relativeMovement = value, true); + Subs.CVar(_configManager, CCVars.StopSpeed, value => _stopSpeed = value, true); UpdatesBefore.Add(typeof(TileFrictionController)); } - private void SetRelativeMovement(bool value) => _relativeMovement = value; - private void SetStopSpeed(float value) => _stopSpeed = value; - public override void Shutdown() { base.Shutdown(); ShutdownInput(); - _configManager.UnsubValueChanged(CCVars.RelativeMovement, SetRelativeMovement); - _configManager.UnsubValueChanged(CCVars.StopSpeed, SetStopSpeed); } public override void UpdateAfterSolve(bool prediction, float frameTime) diff --git a/Content.Shared/Pinpointer/SharedPinpointerSystem.cs b/Content.Shared/Pinpointer/SharedPinpointerSystem.cs index 43550f29195..7f6b8891255 100644 --- a/Content.Shared/Pinpointer/SharedPinpointerSystem.cs +++ b/Content.Shared/Pinpointer/SharedPinpointerSystem.cs @@ -41,7 +41,7 @@ private void OnAfterInteract(EntityUid uid, PinpointerComponent component, After /// /// Set pinpointers target to track /// - public void SetTarget(EntityUid uid, EntityUid? target, PinpointerComponent? pinpointer = null) + public virtual void SetTarget(EntityUid uid, EntityUid? target, PinpointerComponent? pinpointer = null) { if (!Resolve(uid, ref pinpointer)) return; @@ -84,7 +84,7 @@ public void SetDistance(EntityUid uid, Distance distance, PinpointerComponent? p return; pinpointer.DistanceToTarget = distance; - Dirty(pinpointer); + Dirty(uid, pinpointer); } /// @@ -101,7 +101,7 @@ public bool TrySetArrowAngle(EntityUid uid, Angle arrowAngle, PinpointerComponen return false; pinpointer.ArrowAngle = arrowAngle; - Dirty(pinpointer); + Dirty(uid, pinpointer); return true; } @@ -117,7 +117,7 @@ public void SetActive(EntityUid uid, bool isActive, PinpointerComponent? pinpoin return; pinpointer.IsActive = isActive; - Dirty(pinpointer); + Dirty(uid, pinpointer); } @@ -125,7 +125,7 @@ public void SetActive(EntityUid uid, bool isActive, PinpointerComponent? pinpoin /// Toggle Pinpointer screen. If it has target it will start tracking it. /// /// True if pinpointer was activated, false otherwise - public bool TogglePinpointer(EntityUid uid, PinpointerComponent? pinpointer = null) + public virtual bool TogglePinpointer(EntityUid uid, PinpointerComponent? pinpointer = null) { if (!Resolve(uid, ref pinpointer)) return false; diff --git a/Content.Shared/Placeable/ItemPlacerSystem.cs b/Content.Shared/Placeable/ItemPlacerSystem.cs index f2fe58adcb8..9be6a4acd5a 100644 --- a/Content.Shared/Placeable/ItemPlacerSystem.cs +++ b/Content.Shared/Placeable/ItemPlacerSystem.cs @@ -11,7 +11,6 @@ public sealed class ItemPlacerSystem : EntitySystem { [Dependency] private readonly CollisionWakeSystem _wake = default!; [Dependency] private readonly PlaceableSurfaceSystem _placeableSurface = default!; - [Dependency] private readonly SharedPhysicsSystem _physics = default!; public override void Initialize() { diff --git a/Content.Shared/Power/Generator/ActiveGeneratorRevvingSystem.cs b/Content.Shared/Power/Generator/ActiveGeneratorRevvingSystem.cs index 1c39997f30d..9cd11ae6045 100644 --- a/Content.Shared/Power/Generator/ActiveGeneratorRevvingSystem.cs +++ b/Content.Shared/Power/Generator/ActiveGeneratorRevvingSystem.cs @@ -1,12 +1,7 @@ -using Content.Shared.DoAfter; - namespace Content.Shared.Power.Generator; public sealed class ActiveGeneratorRevvingSystem: EntitySystem { - [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; - [Dependency] private readonly EntityManager _entity = default!; - public override void Initialize() { base.Initialize(); diff --git a/Content.Shared/RCD/Systems/RCDSystem.cs b/Content.Shared/RCD/Systems/RCDSystem.cs index 402b424fb6d..187c8d8a9d8 100644 --- a/Content.Shared/RCD/Systems/RCDSystem.cs +++ b/Content.Shared/RCD/Systems/RCDSystem.cs @@ -34,7 +34,6 @@ public sealed class RCDSystem : EntitySystem [Dependency] private readonly SharedChargesSystem _charges = default!; [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; [Dependency] private readonly SharedInteractionSystem _interaction = default!; - [Dependency] private readonly SharedMapSystem _mapSystem = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly TagSystem _tag = default!; [Dependency] private readonly TurfSystem _turf = default!; diff --git a/Content.Shared/Spider/SharedSpiderSystem.cs b/Content.Shared/Spider/SharedSpiderSystem.cs index 2795d64b939..33473303aa9 100644 --- a/Content.Shared/Spider/SharedSpiderSystem.cs +++ b/Content.Shared/Spider/SharedSpiderSystem.cs @@ -7,7 +7,6 @@ namespace Content.Shared.Spider; public abstract class SharedSpiderSystem : EntitySystem { [Dependency] private readonly SharedActionsSystem _action = default!; - [Dependency] private readonly INetManager _net = default!; [Dependency] private readonly IRobustRandom _robustRandom = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; diff --git a/Content.Shared/SprayPainter/SharedSprayPainterSystem.cs b/Content.Shared/SprayPainter/SharedSprayPainterSystem.cs index 1e784797e33..529e321f8da 100644 --- a/Content.Shared/SprayPainter/SharedSprayPainterSystem.cs +++ b/Content.Shared/SprayPainter/SharedSprayPainterSystem.cs @@ -24,7 +24,6 @@ public abstract class SharedSprayPainterSystem : EntitySystem [Dependency] protected readonly SharedAudioSystem Audio = default!; [Dependency] protected readonly SharedDoAfterSystem DoAfter = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; - [Dependency] private readonly SharedUserInterfaceSystem _ui = default!; public List Styles { get; private set; } = new(); public List Groups { get; private set; } = new(); diff --git a/Content.Shared/Stealth/SharedStealthSystem.cs b/Content.Shared/Stealth/SharedStealthSystem.cs index aeb42453ca0..d0ea8045347 100644 --- a/Content.Shared/Stealth/SharedStealthSystem.cs +++ b/Content.Shared/Stealth/SharedStealthSystem.cs @@ -10,7 +10,6 @@ namespace Content.Shared.Stealth; public abstract class SharedStealthSystem : EntitySystem { [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly MobStateSystem _mobState = default!; public override void Initialize() { diff --git a/Content.Shared/Storage/EntitySystems/DumpableSystem.cs b/Content.Shared/Storage/EntitySystems/DumpableSystem.cs index cf548693f9d..c87174ba88c 100644 --- a/Content.Shared/Storage/EntitySystems/DumpableSystem.cs +++ b/Content.Shared/Storage/EntitySystems/DumpableSystem.cs @@ -141,7 +141,7 @@ private void OnDoAfter(EntityUid uid, DumpableComponent component, DoAfterEvent { var transform = Transform(entity); _container.AttachParentToContainerOrGrid((entity, transform)); - _transformSystem.SetLocalPositionRotation(transform, transform.LocalPosition + _random.NextVector2Box() / 2, _random.NextAngle()); + _transformSystem.SetLocalPositionRotation(entity, transform.LocalPosition + _random.NextVector2Box() / 2, _random.NextAngle(), transform); } if (args.Args.Target == null) diff --git a/Content.Shared/Tiles/FloorTileSystem.cs b/Content.Shared/Tiles/FloorTileSystem.cs index 04aa100cd1d..1f8408319d3 100644 --- a/Content.Shared/Tiles/FloorTileSystem.cs +++ b/Content.Shared/Tiles/FloorTileSystem.cs @@ -27,7 +27,6 @@ public sealed class FloorTileSystem : EntitySystem [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly INetManager _netManager = default!; - [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; diff --git a/Content.Shared/UserInterface/OpenUiActionEvent.cs b/Content.Shared/UserInterface/OpenUiActionEvent.cs index 3053861ea15..1c5ca3d62c7 100644 --- a/Content.Shared/UserInterface/OpenUiActionEvent.cs +++ b/Content.Shared/UserInterface/OpenUiActionEvent.cs @@ -1,23 +1,10 @@ using Content.Shared.Actions; -using Robust.Shared.Reflection; -using Robust.Shared.Serialization; +using Robust.Shared.Serialization.TypeSerializers.Implementations; namespace Content.Shared.UserInterface; -public sealed partial class OpenUiActionEvent : InstantActionEvent, ISerializationHooks +public sealed partial class OpenUiActionEvent : InstantActionEvent { - [ViewVariables] + [DataField(required: true, customTypeSerializer: typeof(EnumSerializer))] public Enum? Key { get; private set; } - - [DataField("key", required: true)] - private string _keyRaw = default!; - - void ISerializationHooks.AfterDeserialization() - { - var reflectionManager = IoCManager.Resolve(); - if (reflectionManager.TryParseEnumReference(_keyRaw, out var key)) - Key = key; - else - Logger.Error($"Invalid UI key ({_keyRaw}) in open-UI action"); - } } From 4b6362ab8b0918925f5f136b9ce6dd45ffe13c9e Mon Sep 17 00:00:00 2001 From: Alzore <140123969+Blackern5000@users.noreply.github.com> Date: Tue, 13 Feb 2024 16:03:13 -0600 Subject: [PATCH 099/200] Decrease the chemical cost of regen mesh and sutures and move them to their own file (#24948) * WHYWEREMEDSINMEALRECIPES * 20chem * didiforgettosavethis (cherry picked from commit 666460d14f0442cfc39bde033e7673d9372def72) --- .../Recipes/Cooking/meal_recipes.yml | 34 ------------------- .../Recipes/Cooking/medical_recipes.yml | 33 ++++++++++++++++++ 2 files changed, 33 insertions(+), 34 deletions(-) create mode 100644 Resources/Prototypes/Recipes/Cooking/medical_recipes.yml diff --git a/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml b/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml index 28761aa779d..fbaebe6635f 100644 --- a/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml +++ b/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml @@ -1703,40 +1703,6 @@ solids: LeavesCannabis: 1 -- type: microwaveMealRecipe - id: RecipeAloeCream - name: aloe cream recipe - result: AloeCream - time: 10 - solids: - FoodAloe: 1 - -- type: microwaveMealRecipe - id: RecipeMedicatedSuture - name: medicated suture recipe - result: MedicatedSuture - time: 10 - solids: - FoodPoppy: 1 - Brutepack: 1 - MaterialCloth1: 1 - reagents: - TranexamicAcid: 50 - Cryptobiolin: 50 - -- type: microwaveMealRecipe - id: RecipeRegenerativeMesh - name: regenerative mesh recipe - result: RegenerativeMesh - time: 10 - solids: - FoodAloe: 1 - Ointment: 1 - MaterialCloth1: 1 - reagents: - Sigynate: 50 - Dermaline: 50 - - type: microwaveMealRecipe id: RecipeTrashBakedBananaPeel name: baked banana peel recipe diff --git a/Resources/Prototypes/Recipes/Cooking/medical_recipes.yml b/Resources/Prototypes/Recipes/Cooking/medical_recipes.yml new file mode 100644 index 00000000000..9d1947f03eb --- /dev/null +++ b/Resources/Prototypes/Recipes/Cooking/medical_recipes.yml @@ -0,0 +1,33 @@ +- type: microwaveMealRecipe + id: RecipeAloeCream + name: aloe cream recipe + result: AloeCream + time: 10 + solids: + FoodAloe: 1 + +- type: microwaveMealRecipe + id: RecipeMedicatedSuture + name: medicated suture recipe + result: MedicatedSuture + time: 10 + solids: + FoodPoppy: 1 + Brutepack: 1 + MaterialCloth1: 1 + reagents: + TranexamicAcid: 20 + Cryptobiolin: 20 + +- type: microwaveMealRecipe + id: RecipeRegenerativeMesh + name: regenerative mesh recipe + result: RegenerativeMesh + time: 10 + solids: + FoodAloe: 1 + Ointment: 1 + MaterialCloth1: 1 + reagents: + Sigynate: 20 + Dermaline: 20 From aa2bf00c0b1992608fda8e7825b1a023f362a1f2 Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Tue, 13 Feb 2024 23:03:41 +0100 Subject: [PATCH 100/200] Split slime marking leg gradient (#24928) * Split slime marking leg gradient * up markings to 4 (cherry picked from commit 4b9f1a47bb3239ec046b653e16beae413da05699) --- .../Locale/en-US/markings/slimeperson.ftl | 6 +++++ .../Mobs/Customization/Markings/slime.yml | 24 +++++++++++++++--- Resources/Prototypes/Species/slime.yml | 2 +- .../slime_parts.rsi/gradient_l_foot.png | Bin 0 -> 353 bytes .../slime_parts.rsi/gradient_l_leg.png | Bin 453 -> 355 bytes .../slime_parts.rsi/gradient_r_foot.png | Bin 0 -> 335 bytes .../slime_parts.rsi/gradient_r_leg.png | Bin 451 -> 339 bytes .../Customization/slime_parts.rsi/meta.json | 8 ++++++ 8 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 Resources/Textures/Mobs/Customization/slime_parts.rsi/gradient_l_foot.png create mode 100644 Resources/Textures/Mobs/Customization/slime_parts.rsi/gradient_r_foot.png diff --git a/Resources/Locale/en-US/markings/slimeperson.ftl b/Resources/Locale/en-US/markings/slimeperson.ftl index b7a519aa4f6..05e295efd9b 100644 --- a/Resources/Locale/en-US/markings/slimeperson.ftl +++ b/Resources/Locale/en-US/markings/slimeperson.ftl @@ -4,6 +4,12 @@ marking-SlimeGradientLeftArm = Slime Left Arm (Gradient) marking-SlimeGradientRightArm-gradient_r_arm = Slime Right Arm (Gradient) marking-SlimeGradientRightArm = Slime Right Arm (Gradient) +marking-SlimeGradientLeftFoot-gradient_l_foot = Slime Left Foot (Gradient) +marking-SlimeGradientLeftFoot = Slime Left Foot (Gradient) + +marking-SlimeGradientRightFoot-gradient_r_foot = Slime Right Foot (Gradient) +marking-SlimeGradientRightFoot = Slime Right Foot (Gradient) + marking-SlimeGradientLeftLeg-gradient_l_leg = Slime Left Leg (Gradient) marking-SlimeGradientLeftLeg = Slime Left Leg (Gradient) diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/slime.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/slime.yml index b827b0221c9..092ebf2fddf 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/slime.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/slime.yml @@ -18,7 +18,7 @@ - type: marking id: SlimeGradientLeftLeg - bodyPart: LFoot + bodyPart: LLeg markingCategory: Legs speciesRestriction: [SlimePerson] sprites: @@ -27,13 +27,31 @@ - type: marking id: SlimeGradientRightLeg - bodyPart: RFoot + bodyPart: RLeg markingCategory: Legs speciesRestriction: [SlimePerson] sprites: - sprite: Mobs/Customization/slime_parts.rsi state: gradient_r_leg +- type: marking + id: SlimeGradientLeftFoot + bodyPart: LFoot + markingCategory: Legs + speciesRestriction: [SlimePerson] + sprites: + - sprite: Mobs/Customization/slime_parts.rsi + state: gradient_l_foot + +- type: marking + id: SlimeGradientRightFoot + bodyPart: RFoot + markingCategory: Legs + speciesRestriction: [SlimePerson] + sprites: + - sprite: Mobs/Customization/slime_parts.rsi + state: gradient_r_foot + - type: marking id: SlimeGradientLeftHand bodyPart: LHand @@ -50,4 +68,4 @@ speciesRestriction: [SlimePerson] sprites: - sprite: Mobs/Customization/slime_parts.rsi - state: gradient_r_hand \ No newline at end of file + state: gradient_r_hand diff --git a/Resources/Prototypes/Species/slime.yml b/Resources/Prototypes/Species/slime.yml index 93f23d599c8..ef49e9b7cf6 100644 --- a/Resources/Prototypes/Species/slime.yml +++ b/Resources/Prototypes/Species/slime.yml @@ -39,7 +39,7 @@ points: 1 required: false Legs: - points: 2 + points: 4 required: false Arms: points: 4 diff --git a/Resources/Textures/Mobs/Customization/slime_parts.rsi/gradient_l_foot.png b/Resources/Textures/Mobs/Customization/slime_parts.rsi/gradient_l_foot.png new file mode 100644 index 0000000000000000000000000000000000000000..07b01cd49867493e53448341fecae059f663eeb3 GIT binary patch literal 353 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fA0|TS5 zr;B4qMcmt4hJ1$%cv>GeSh%(GJ>tfILS`)O!ox%gGXK#^;MWrH+5RH|uwte(k6Ho%7x1uRgTEEbiX7 z+Wh1&tH&EwJLPpw*i*aj%j7sITN8#$GUs+q4^G}ud+g@VTc0Pj;2;`(8Y}0`KezM4kN-1oubTGtMd@mz8hQzqo#i&}&u34-uDZwz-IJOnK?_Xs-&xySe;(_3P8t3-`Nf zxq zCo4rv%VC;1QRc`0gGoCh&VJD0WjbqoVj{x?Wkv;eCWk(j1{qEUOCg3L6^17s49F4{ z>NA$TER|?WwmENntniP6qSukG2*$s6s|^|JRg+pdZ*1cgeWB}j*(6cejbq1>`~OVq zoFWe;yK+=G+8#=7&23DL?3*64V%C4E=^yvwAt|BIwyi4Y4`C&AoW4|42*`2P``^&f2iF;B)u`@z4c zJ*yaM>O08$7uSSsq5(j!2qCo!FMt-(GSXAu76#X zd)sUeP~e(=g6oB@`;pNL&T~H5{aYo`U#Kg;{f>UZMqPIQ`bn>4CP<5((`d3>wmtHZ Z@Z9D}>AL)Sihme@z|+;wWt~$(69CwLtPTJG diff --git a/Resources/Textures/Mobs/Customization/slime_parts.rsi/gradient_r_foot.png b/Resources/Textures/Mobs/Customization/slime_parts.rsi/gradient_r_foot.png new file mode 100644 index 0000000000000000000000000000000000000000..86d07d6341c358ddf4ebe750fcc537fcdf7ca11a GIT binary patch literal 335 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fA0|O(Y zr;B4qMcmt4wtUS7JZ%rRymBRaDbd#hcakQ*Jq) z`}Fba-JwcFlPmO$)V|%+^d|Q5efa34(MmFLtYu;CveM(n4ai?rqn#HZprC%1kd0fA9^7Wga emYi(^Pd+}m4*e1{cy90Ikza?M!~vX^E0o4Gq&%**^Htkew*b`2E2 z9UxJ+#6!~HhJMbrVjB*H1_mY^!~y=sDVK61r+r;}-&i5C*owQGqx~y?Vom?kWpj=& zEERda_kCbT*?G|g&z4p$sb{$UUGe;RNATqXZWD#({ zNhEMJ*8107S<_Iem(V=L%zgWgeE+)Z)Bb&5<6yDnRp|5C3|UN;>Eg+I_;<`&cuq6p zInx^R16L;Jw_H_Wf6F^#p}M^@U$4wR)!PaNJ`Y%be)3a)`%`-j0}yz+`njxgN@xNA D@0)FK delta 404 zcmcc2beMU9Wqqlqi(^Q|oVT+ayIKrHT(T3^J&2Q-ZP{q8Z&_aSoO9N_9R<%7=hV#P zxwKj(-X!4bf{Sh2g6$?N{Q1vWq{8sTgW<$Ph6&1y3hqn}eJl+!oD7yi49F6e_HxHR z?tcIKZ_O+tee;`ex(qB)4|21{&KD7r&ELHcwOAd#u!QZ; z^(XwPFIQKy-t+!?oqGdASQpo~`U2azcWW}^9hQVR@YXUdPtgz!aGrlaQ!>W;z_R_h zE;~&t^-piwlk;W=i>(OvhJ$aPCFj~LS9`B`=a1NLhDXdFzG#c=XTR~F{2R{^!@Xyv a_NVWed+yq|y}Zl}K;Y@>=d#Wzp$P!|c(Pgm diff --git a/Resources/Textures/Mobs/Customization/slime_parts.rsi/meta.json b/Resources/Textures/Mobs/Customization/slime_parts.rsi/meta.json index e3137407bd0..0db3ae1bccf 100644 --- a/Resources/Textures/Mobs/Customization/slime_parts.rsi/meta.json +++ b/Resources/Textures/Mobs/Customization/slime_parts.rsi/meta.json @@ -30,6 +30,14 @@ { "name": "gradient_l_leg", "directions": 4 + }, + { + "name": "gradient_r_foot", + "directions": 4 + }, + { + "name": "gradient_l_foot", + "directions": 4 } ] } From 2482756840640277bc4d41fcc17b0f57e1564495 Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 13 Feb 2024 22:04:19 +0000 Subject: [PATCH 101/200] Automatic changelog update (cherry picked from commit 78392e6d899f68fbbf9af15f916af0256d6bc7fc) --- 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 136ee72dfc5..ee627b3d76d 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,5 @@ Order: 1 Entries: -- author: PJB3005 - changes: - - message: Fix starting to follow a moving player as a ghost causing your camera - to keep jumping around anymore. - type: Fix - id: 5433 - time: '2023-12-20T23:33:00.0000000+00:00' - url: null - author: Velcroboy changes: - message: Fixed coal not generating! @@ -3880,3 +3872,10 @@ Order: 1 id: 5932 time: '2024-02-13T21:43:19.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25142 +- author: Blackern5000 + changes: + - message: Advanced topical meds now cost significantly less chemicals + type: Tweak + id: 5933 + time: '2024-02-13T22:03:13.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/24948 From 78c9dc61606327a780de242b13e7e8729905eebd Mon Sep 17 00:00:00 2001 From: Kevin Zheng Date: Tue, 13 Feb 2024 14:05:28 -0800 Subject: [PATCH 102/200] Require plants to be harvestable before sampling (#24851) (cherry picked from commit 52f74fa39d674d311bbc6440a638f33ebac5a468) --- Content.Server/Botany/Systems/PlantHolderSystem.cs | 9 ++++++++- .../en-US/botany/components/plant-holder-component.ftl | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Content.Server/Botany/Systems/PlantHolderSystem.cs b/Content.Server/Botany/Systems/PlantHolderSystem.cs index 6bf0b9692ce..601dca36856 100644 --- a/Content.Server/Botany/Systems/PlantHolderSystem.cs +++ b/Content.Server/Botany/Systems/PlantHolderSystem.cs @@ -262,13 +262,20 @@ private void OnInteractUsing(Entity entity, ref InteractUs return; } + component.Health -= (_random.Next(3, 5) * 10); + + if (!component.Harvest) + { + _popup.PopupCursor(Loc.GetString("plant-holder-component-early-sample"), args.User); + return; + } + component.Seed.Unique = false; var seed = _botany.SpawnSeedPacket(component.Seed, Transform(args.User).Coordinates, args.User); _randomHelper.RandomOffset(seed, 0.25f); var displayName = Loc.GetString(component.Seed.DisplayName); _popup.PopupCursor(Loc.GetString("plant-holder-component-take-sample-message", ("seedName", displayName)), args.User); - component.Health -= (_random.Next(3, 5) * 10); if (component.Seed != null && component.Seed.CanScream) { diff --git a/Resources/Locale/en-US/botany/components/plant-holder-component.ftl b/Resources/Locale/en-US/botany/components/plant-holder-component.ftl index 1e7dbe689cc..01d713ab34e 100644 --- a/Resources/Locale/en-US/botany/components/plant-holder-component.ftl +++ b/Resources/Locale/en-US/botany/components/plant-holder-component.ftl @@ -32,3 +32,4 @@ plant-holder-component-light-improper-warning = The [color=yellow]improper light plant-holder-component-heat-improper-warning = The [color=orange]improper temperature level alert[/color] is blinking. plant-holder-component-pressure-improper-warning = The [color=lightblue]improper environment pressure alert[/color] is blinking. plant-holder-component-gas-missing-warning = The [color=cyan]improper gas environment alert[/color] is blinking. +plant-holder-component-early-sample = It is not ready to sample, but you cut a bit of the plant anyway. From b39407bae3b9d275a0ae35819a23d06225a496bc Mon Sep 17 00:00:00 2001 From: Tayrtahn Date: Tue, 13 Feb 2024 17:08:07 -0500 Subject: [PATCH 103/200] Add verbs to Open/Close Openable containers, and add optional seals (#24780) * Implement closing; add open/close verbs * Add breakable seals * Allow custom verb names; make condiment bottles closeable * Remove pointless VV annotations and false defaults * Split Sealable off into a new component * Should have a Closed event too * Oh hey, there are icons I could use * Ternary operator * Add support for seal visualizers * Moved Sealable to Shared, added networking * Replaced bottle_close1.ogg (cherry picked from commit 75e47fff9e5150a4de37e4d3c8a8b278f0a1a2cd) --- .../Nutrition/Components/OpenableComponent.cs | 34 ++++++++-- .../Nutrition/EntitySystems/OpenableSystem.cs | 64 +++++++++++++++++- .../Nutrition/Components/SealableComponent.cs | 32 +++++++++ .../Components/SharedFoodComponent.cs | 7 ++ .../Nutrition/EntitySystems/SealableSystem.cs | 59 ++++++++++++++++ .../EntitySystems/SharedOpenableSystem.cs | 17 +++++ Resources/Audio/Items/attributions.yml | 7 +- Resources/Audio/Items/bottle_close1.ogg | Bin 0 -> 6427 bytes .../nutrition/components/drink-component.ftl | 2 + .../components/openable-component.ftl | 2 + .../Consumable/Drinks/drinks-cartons.yml | 4 ++ .../Consumable/Drinks/drinks_bottles.yml | 31 ++++++++- .../Consumable/Food/Containers/condiments.yml | 1 + .../SoundCollections/drink_close_sounds.yml | 4 ++ 14 files changed, 255 insertions(+), 9 deletions(-) create mode 100644 Content.Shared/Nutrition/Components/SealableComponent.cs create mode 100644 Content.Shared/Nutrition/EntitySystems/SealableSystem.cs create mode 100644 Content.Shared/Nutrition/EntitySystems/SharedOpenableSystem.cs create mode 100644 Resources/Audio/Items/bottle_close1.ogg create mode 100644 Resources/Locale/en-US/nutrition/components/openable-component.ftl create mode 100644 Resources/Prototypes/SoundCollections/drink_close_sounds.yml diff --git a/Content.Server/Nutrition/Components/OpenableComponent.cs b/Content.Server/Nutrition/Components/OpenableComponent.cs index 63efd520962..cc24bf44dca 100644 --- a/Content.Server/Nutrition/Components/OpenableComponent.cs +++ b/Content.Server/Nutrition/Components/OpenableComponent.cs @@ -14,20 +14,20 @@ public sealed partial class OpenableComponent : Component /// Whether this drink or food is opened or not. /// Drinks can only be drunk or poured from/into when open, and food can only be eaten when open. /// - [DataField, ViewVariables(VVAccess.ReadWrite)] + [DataField] public bool Opened; /// /// If this is false you cant press Z to open it. /// Requires an OpenBehavior damage threshold or other logic to open. /// - [DataField, ViewVariables(VVAccess.ReadWrite)] + [DataField] public bool OpenableByHand = true; /// /// Text shown when examining and its open. /// - [DataField, ViewVariables(VVAccess.ReadWrite)] + [DataField] public LocId ExamineText = "drink-component-on-examine-is-opened"; /// @@ -35,12 +35,38 @@ public sealed partial class OpenableComponent : Component /// Defaults to the popup drink uses since its "correct". /// It's still generic enough that you should change it if you make openable non-drinks, i.e. unwrap it first, peel it first. /// - [DataField, ViewVariables(VVAccess.ReadWrite)] + [DataField] public LocId ClosedPopup = "drink-component-try-use-drink-not-open"; + /// + /// Text to show in the verb menu for the "Open" action. + /// You may want to change this for non-drinks, i.e. "Peel", "Unwrap" + /// + [DataField] + public LocId OpenVerbText = "openable-component-verb-open"; + + /// + /// Text to show in the verb menu for the "Close" action. + /// You may want to change this for non-drinks, i.e. "Wrap" + /// + [DataField] + public LocId CloseVerbText = "openable-component-verb-close"; + /// /// Sound played when opening. /// [DataField] public SoundSpecifier Sound = new SoundCollectionSpecifier("canOpenSounds"); + + /// + /// Can this item be closed again after opening? + /// + [DataField] + public bool Closeable; + + /// + /// Sound played when closing. + /// + [DataField] + public SoundSpecifier? CloseSound; } diff --git a/Content.Server/Nutrition/EntitySystems/OpenableSystem.cs b/Content.Server/Nutrition/EntitySystems/OpenableSystem.cs index d7b7da25b88..373b97700f4 100644 --- a/Content.Server/Nutrition/EntitySystems/OpenableSystem.cs +++ b/Content.Server/Nutrition/EntitySystems/OpenableSystem.cs @@ -1,22 +1,23 @@ using Content.Server.Chemistry.EntitySystems; using Content.Server.Fluids.EntitySystems; +using Content.Shared.Nutrition.EntitySystems; using Content.Server.Nutrition.Components; using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; using Content.Shared.Nutrition.Components; using Content.Shared.Popups; +using Content.Shared.Verbs; using Content.Shared.Weapons.Melee.Events; -using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; -using Robust.Shared.GameObjects; +using Robust.Shared.Utility; namespace Content.Server.Nutrition.EntitySystems; /// /// Provides API for openable food and drinks, handles opening on use and preventing transfer when closed. /// -public sealed class OpenableSystem : EntitySystem +public sealed class OpenableSystem : SharedOpenableSystem { [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; @@ -32,6 +33,7 @@ public override void Initialize() SubscribeLocalEvent(OnTransferAttempt); SubscribeLocalEvent(HandleIfClosed); SubscribeLocalEvent(HandleIfClosed); + SubscribeLocalEvent>(AddOpenCloseVerbs); } private void OnInit(EntityUid uid, OpenableComponent comp, ComponentInit args) @@ -71,6 +73,36 @@ private void HandleIfClosed(EntityUid uid, OpenableComponent comp, HandledEntity args.Handled = !comp.Opened; } + private void AddOpenCloseVerbs(EntityUid uid, OpenableComponent comp, GetVerbsEvent args) + { + if (args.Hands == null || !args.CanAccess || !args.CanInteract) + return; + + Verb verb; + if (comp.Opened) + { + if (!comp.Closeable) + return; + + verb = new() + { + Text = Loc.GetString(comp.CloseVerbText), + Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/close.svg.192dpi.png")), + Act = () => TryClose(args.Target, comp) + }; + } + else + { + verb = new() + { + Text = Loc.GetString(comp.OpenVerbText), + Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/open.svg.192dpi.png")), + Act = () => TryOpen(args.Target, comp) + }; + } + args.Verbs.Add(verb); + } + /// /// Returns true if the entity either does not have OpenableComponent or it is opened. /// Drinks that don't have OpenableComponent are automatically open, so it returns true. @@ -123,6 +155,17 @@ public void SetOpen(EntityUid uid, bool opened = true, OpenableComponent? comp = comp.Opened = opened; + if (opened) + { + var ev = new OpenableOpenedEvent(); + RaiseLocalEvent(uid, ref ev); + } + else + { + var ev = new OpenableClosedEvent(); + RaiseLocalEvent(uid, ref ev); + } + UpdateAppearance(uid, comp); } @@ -139,4 +182,19 @@ public bool TryOpen(EntityUid uid, OpenableComponent? comp = null) _audio.PlayPvs(comp.Sound, uid); return true; } + + /// + /// If opened, closes it and plays the close sound, if one is defined. + /// + /// Whether it got closed + public bool TryClose(EntityUid uid, OpenableComponent? comp = null) + { + if (!Resolve(uid, ref comp, false) || !comp.Opened || !comp.Closeable) + return false; + + SetOpen(uid, false, comp); + if (comp.CloseSound != null) + _audio.PlayPvs(comp.CloseSound, uid); + return true; + } } diff --git a/Content.Shared/Nutrition/Components/SealableComponent.cs b/Content.Shared/Nutrition/Components/SealableComponent.cs new file mode 100644 index 00000000000..1c2f732e7a9 --- /dev/null +++ b/Content.Shared/Nutrition/Components/SealableComponent.cs @@ -0,0 +1,32 @@ +using Content.Shared.Nutrition.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Nutrition.Components; + +/// +/// Represents a tamper-evident seal on an Openable. +/// Only affects the Examine text. +/// Once the seal has been broken, it cannot be resealed. +/// +[NetworkedComponent, AutoGenerateComponentState] +[RegisterComponent, Access(typeof(SealableSystem))] +public sealed partial class SealableComponent : Component +{ + /// + /// Whether the item's seal is intact (i.e. it has never been opened) + /// + [DataField, AutoNetworkedField] + public bool Sealed = true; + + /// + /// Text shown when examining and the item's seal has not been broken. + /// + [DataField] + public LocId ExamineTextSealed = "drink-component-on-examine-is-sealed"; + + /// + /// Text shown when examining and the item's seal has been broken. + /// + [DataField] + public LocId ExamineTextUnsealed = "drink-component-on-examine-is-unsealed"; +} diff --git a/Content.Shared/Nutrition/Components/SharedFoodComponent.cs b/Content.Shared/Nutrition/Components/SharedFoodComponent.cs index 99ddabd3ce4..07c02fb22b2 100644 --- a/Content.Shared/Nutrition/Components/SharedFoodComponent.cs +++ b/Content.Shared/Nutrition/Components/SharedFoodComponent.cs @@ -16,4 +16,11 @@ public enum OpenableVisuals : byte Opened, Layer } + + [Serializable, NetSerializable] + public enum SealableVisuals : byte + { + Sealed, + Layer, + } } diff --git a/Content.Shared/Nutrition/EntitySystems/SealableSystem.cs b/Content.Shared/Nutrition/EntitySystems/SealableSystem.cs new file mode 100644 index 00000000000..b0873f23a12 --- /dev/null +++ b/Content.Shared/Nutrition/EntitySystems/SealableSystem.cs @@ -0,0 +1,59 @@ +using Content.Shared.Examine; +using Content.Shared.Nutrition.EntitySystems; +using Content.Shared.Nutrition.Components; + +namespace Content.Shared.Nutrition.EntitySystems; + +public sealed partial class SealableSystem : EntitySystem +{ + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnExamined, after: new[] { typeof(SharedOpenableSystem) }); + SubscribeLocalEvent(OnOpened); + } + + private void OnExamined(EntityUid uid, SealableComponent comp, ExaminedEvent args) + { + if (!args.IsInDetailsRange) + return; + + var sealedText = comp.Sealed ? Loc.GetString(comp.ExamineTextSealed) : Loc.GetString(comp.ExamineTextUnsealed); + + args.PushMarkup(sealedText); + } + + private void OnOpened(EntityUid uid, SealableComponent comp, OpenableOpenedEvent args) + { + comp.Sealed = false; + + Dirty(uid, comp); + + UpdateAppearance(uid, comp); + } + + /// + /// Update seal visuals to the current value. + /// + public void UpdateAppearance(EntityUid uid, SealableComponent? comp = null, AppearanceComponent? appearance = null) + { + if (!Resolve(uid, ref comp)) + return; + + _appearance.SetData(uid, SealableVisuals.Sealed, comp.Sealed, appearance); + } + + /// + /// Returns true if the entity's seal is intact. + /// Items without SealableComponent are considered unsealed. + /// + public bool IsSealed(EntityUid uid, SealableComponent? comp = null) + { + if (!Resolve(uid, ref comp, false)) + return false; + + return comp.Sealed; + } +} diff --git a/Content.Shared/Nutrition/EntitySystems/SharedOpenableSystem.cs b/Content.Shared/Nutrition/EntitySystems/SharedOpenableSystem.cs new file mode 100644 index 00000000000..274de89003a --- /dev/null +++ b/Content.Shared/Nutrition/EntitySystems/SharedOpenableSystem.cs @@ -0,0 +1,17 @@ +namespace Content.Shared.Nutrition.EntitySystems; + +public abstract partial class SharedOpenableSystem : EntitySystem +{ +} + +/// +/// Raised after an Openable is opened. +/// +[ByRefEvent] +public record struct OpenableOpenedEvent; + +/// +/// Raised after an Openable is closed. +/// +[ByRefEvent] +public record struct OpenableClosedEvent; diff --git a/Resources/Audio/Items/attributions.yml b/Resources/Audio/Items/attributions.yml index 51d8d9cf95a..8942e41db23 100644 --- a/Resources/Audio/Items/attributions.yml +++ b/Resources/Audio/Items/attributions.yml @@ -63,6 +63,11 @@ copyright: "User volivieri on freesound.org. Modified by Velcroboy on github." source: "https://freesound.org/people/volivieri/sounds/37190/" +- files: ["bottle_close1.ogg"] + license: "CC0-1.0" + copyright: "User MellowAudio on freesound.org. Modified by Tayrtahn on github." + source: "https://freesound.org/people/MellowAudio/sounds/591485/" + - files: ["bow_pull.ogg"] license: "CC-BY-3.0" copyright: "User jzdnvdoosj on freesound.org. Converted to ogg by mirrorcult" @@ -92,7 +97,7 @@ license: "CC-BY-4.0" copyright: "User LoafDV on freesound.org. Converted to ogg end edited by lzk228" source: "https://freesound.org/people/LoafDV/sounds/131596/" - + - files: ["shovel_dig.ogg"] license: "CC-BY-SA-3.0" copyright: "Taken from tgstation, modified by themias (github) for ss14" diff --git a/Resources/Audio/Items/bottle_close1.ogg b/Resources/Audio/Items/bottle_close1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b6db8fae79e3f6bc0e849581fd2e2d9f2e5b0f7f GIT binary patch literal 6427 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 x`~s>EDaMQD*x0`83xQ6GE!xC>qwl1IzJ%I0w(D Date: Tue, 13 Feb 2024 22:09:13 +0000 Subject: [PATCH 104/200] Automatic changelog update (cherry picked from commit f8640cf97ed68dc65f55045cf608ac9ee87e65b4) --- 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 ee627b3d76d..fa1a62602ab 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Velcroboy - changes: - - message: Fixed coal not generating! - type: Fix - id: 5434 - time: '2023-12-20T23:46:20.0000000+00:00' - url: null - author: whateverusername0 changes: - message: "Miasma now reacts with oxygen at 50\xB0C to produce nitrous oxide and\ @@ -3879,3 +3872,11 @@ Order: 1 id: 5933 time: '2024-02-13T22:03:13.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/24948 +- author: Tayrtahn + changes: + - message: Drink bottles can now be opened and closed from the verbs menu, and some + have been given tamper-evident seals. + type: Add + id: 5934 + time: '2024-02-13T22:08:07.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/24780 From 9dcdbea279c7bbeb5c511790e60881449c97f6c0 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Wed, 14 Feb 2024 01:12:32 +0300 Subject: [PATCH 105/200] Shadow anomaly returns (#24629) * content * add cat * ambient * I FORGOT HEARTS! * fix ambient * some fixes * canCollide: false * connect to damageable * pi * remove fx * some fixes * *sad bruh* * hazed * Update base_shadow.yml (cherry picked from commit ae321151cab2e3f4327dfcbc73ffc01bbb2e3de6) --- .../Components/DamagedByFlashingComponent.cs | 15 ++++ .../Flash/DamagedByFlashingSystem.cs | 22 +++++ Content.Server/Flash/FlashSystem.cs | 13 ++- Content.Shared/Flash/FlashableComponent.cs | 4 + Resources/Audio/Ambience/anomaly_scary.ogg | Bin 0 -> 158397 bytes Resources/Audio/Ambience/attributions.yml | 8 +- .../interaction-popup-component.ftl | 1 + Resources/Prototypes/Damage/containers.yml | 5 ++ .../Prototypes/Entities/Effects/portal.yml | 23 ++++++ .../Markers/Spawners/Random/anomaly.yml | 1 + .../Markers/Spawners/Random/shadowkudzu.yml | 26 ++++++ .../Prototypes/Entities/Mobs/NPCs/shadows.yml | 67 +++++++++++++++ .../Entities/Objects/Misc/kudzu.yml | 77 +++++++++++++----- .../Entities/Objects/base_shadow.yml | 26 ++++++ .../Structures/Specific/Anomaly/anomalies.yml | 54 ++++++++++++ .../Structures/Specific/Anomaly/cores.yml | 26 ++++++ Resources/Prototypes/audio.yml | 37 +++++++++ Resources/Prototypes/tags.yml | 3 + .../Effects/spookysmoke.rsi/meta.json | 30 +++++++ .../Effects/spookysmoke.rsi/spookysmoke.png | Bin 0 -> 113491 bytes .../Anomalies/Cores/shadow_core.rsi/core.png | Bin 0 -> 252 bytes .../Anomalies/Cores/shadow_core.rsi/meta.json | 25 ++++++ .../Anomalies/Cores/shadow_core.rsi/pulse.png | Bin 0 -> 371 bytes .../Anomalies/shadow_anom.rsi/anom.png | Bin 0 -> 1042 bytes .../Anomalies/shadow_anom.rsi/meta.json | 34 ++++++++ .../Anomalies/shadow_anom.rsi/pulse.png | Bin 0 -> 2004 bytes 26 files changed, 468 insertions(+), 29 deletions(-) create mode 100644 Content.Server/Flash/Components/DamagedByFlashingComponent.cs create mode 100644 Content.Server/Flash/DamagedByFlashingSystem.cs create mode 100644 Resources/Audio/Ambience/anomaly_scary.ogg create mode 100644 Resources/Prototypes/Entities/Markers/Spawners/Random/shadowkudzu.yml create mode 100644 Resources/Prototypes/Entities/Mobs/NPCs/shadows.yml create mode 100644 Resources/Prototypes/Entities/Objects/base_shadow.yml create mode 100644 Resources/Textures/Effects/spookysmoke.rsi/meta.json create mode 100644 Resources/Textures/Effects/spookysmoke.rsi/spookysmoke.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/Cores/shadow_core.rsi/core.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/Cores/shadow_core.rsi/meta.json create mode 100644 Resources/Textures/Structures/Specific/Anomalies/Cores/shadow_core.rsi/pulse.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/shadow_anom.rsi/anom.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/shadow_anom.rsi/meta.json create mode 100644 Resources/Textures/Structures/Specific/Anomalies/shadow_anom.rsi/pulse.png diff --git a/Content.Server/Flash/Components/DamagedByFlashingComponent.cs b/Content.Server/Flash/Components/DamagedByFlashingComponent.cs new file mode 100644 index 00000000000..2a9024607d6 --- /dev/null +++ b/Content.Server/Flash/Components/DamagedByFlashingComponent.cs @@ -0,0 +1,15 @@ +using Content.Shared.Damage; +using Robust.Shared.Prototypes; + +namespace Content.Server.Flash.Components; + +// Also needed FlashableComponent on entity to work +[RegisterComponent, Access(typeof(DamagedByFlashingSystem))] +public sealed partial class DamagedByFlashingComponent : Component +{ + /// + /// damage from flashing + /// + [DataField(required: true), ViewVariables(VVAccess.ReadWrite)] + public DamageSpecifier FlashDamage = new (); +} diff --git a/Content.Server/Flash/DamagedByFlashingSystem.cs b/Content.Server/Flash/DamagedByFlashingSystem.cs new file mode 100644 index 00000000000..cf0368ca42a --- /dev/null +++ b/Content.Server/Flash/DamagedByFlashingSystem.cs @@ -0,0 +1,22 @@ +using Content.Server.Flash.Components; +using Content.Shared.Damage; + +namespace Content.Server.Flash; +public sealed class DamagedByFlashingSystem : EntitySystem +{ + [Dependency] private readonly DamageableSystem _damageable = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnFlashAttempt); + } + private void OnFlashAttempt(Entity ent, ref FlashAttemptEvent args) + { + _damageable.TryChangeDamage(ent, ent.Comp.FlashDamage); + + //To Do: It would be more logical if different flashes had different power, + //and the damage would be inflicted depending on the strength of the flash. + } +} diff --git a/Content.Server/Flash/FlashSystem.cs b/Content.Server/Flash/FlashSystem.cs index bc2cca5c0b8..fe7eb81d1e1 100644 --- a/Content.Server/Flash/FlashSystem.cs +++ b/Content.Server/Flash/FlashSystem.cs @@ -31,6 +31,7 @@ internal sealed class FlashSystem : SharedFlashSystem [Dependency] private readonly SharedChargesSystem _charges = default!; [Dependency] private readonly EntityLookupSystem _entityLookup = default!; [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SharedInteractionSystem _interaction = default!; [Dependency] private readonly InventorySystem _inventory = default!; [Dependency] private readonly PopupSystem _popup = default!; @@ -150,27 +151,23 @@ public void Flash(EntityUid target, public void FlashArea(EntityUid source, EntityUid? user, float range, float duration, float slowTo = 0.8f, bool displayPopup = false, SoundSpecifier? sound = null) { var transform = EntityManager.GetComponent(source); - var mapPosition = transform.MapPosition; - var flashableEntities = new List(); + var mapPosition = _transform.GetMapCoordinates(transform); var flashableQuery = GetEntityQuery(); foreach (var entity in _entityLookup.GetEntitiesInRange(transform.Coordinates, range)) { - if (!flashableQuery.HasComponent(entity)) + if (!flashableQuery.TryGetComponent(entity, out var flashable)) continue; - flashableEntities.Add(entity); - } - foreach (var entity in flashableEntities) - { // Check for unobstructed entities while ignoring the mobs with flashable components. - if (!_interaction.InRangeUnobstructed(entity, mapPosition, range, CollisionGroup.Opaque, (e) => flashableEntities.Contains(e) || e == source)) + if (!_interaction.InRangeUnobstructed(entity, mapPosition, range, flashable.CollisionGroup, (e) => e == source)) continue; // They shouldn't have flash removed in between right? Flash(entity, user, source, duration, slowTo, displayPopup, flashableQuery.GetComponent(entity)); } + if (sound != null) { _audio.PlayPvs(sound, source, AudioParams.Default.WithVolume(1f).WithMaxDistance(3f)); diff --git a/Content.Shared/Flash/FlashableComponent.cs b/Content.Shared/Flash/FlashableComponent.cs index e20e2e79414..c4f8074ceaf 100644 --- a/Content.Shared/Flash/FlashableComponent.cs +++ b/Content.Shared/Flash/FlashableComponent.cs @@ -1,3 +1,4 @@ +using Content.Shared.Physics; using Robust.Shared.GameStates; using Robust.Shared.Serialization; @@ -9,6 +10,9 @@ public sealed partial class FlashableComponent : Component public float Duration; public TimeSpan LastFlash; + [DataField] + public CollisionGroup CollisionGroup = CollisionGroup.Opaque; + public override bool SendOnlyToOwner => true; } diff --git a/Resources/Audio/Ambience/anomaly_scary.ogg b/Resources/Audio/Ambience/anomaly_scary.ogg new file mode 100644 index 0000000000000000000000000000000000000000..badefbec3bdba22ee6c1e5f9d85da1fd0f654325 GIT binary patch literal 158397 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

b?aa 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�Tx>=x@r;r7@enoI;s#2avo$b-?pqFfvje14-o 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

L!BS;Q0q5 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:<~{2(2BXX*}I?Oe18eg17kphGAYeGsCxU-z*lX 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Specific/Anomalies/Cores/shadow_core.rsi/core.png b/Resources/Textures/Structures/Specific/Anomalies/Cores/shadow_core.rsi/core.png new file mode 100644 index 0000000000000000000000000000000000000000..d37b98aa15aaceb83e5257e157fae697dc3bfeb0 GIT binary patch literal 252 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 Date: Tue, 13 Feb 2024 22:13:38 +0000 Subject: [PATCH 106/200] Automatic changelog update (cherry picked from commit 40823416f0f72bb1ea913edf824a4350629e8d7f) --- 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 fa1a62602ab..74d5147b3f2 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,5 @@ Order: 1 Entries: -- author: whateverusername0 - changes: - - message: "Miasma now reacts with oxygen at 50\xB0C to produce nitrous oxide and\ - \ water vapor." - type: Add - id: 5435 - time: '2023-12-21T00:14:59.0000000+00:00' - url: null - author: whateverusername0 changes: - message: Nitrous oxide now decomposes at high temperatures. @@ -3880,3 +3872,10 @@ Order: 1 id: 5934 time: '2024-02-13T22:08:07.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/24780 +- author: TheShuEd + changes: + - message: Darkness is coming. A new shadow anomaly added. + type: Add + id: 5935 + time: '2024-02-13T22:12:32.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/24629 From 1083aeb8e183716fb7735f25b505118f1617bfeb Mon Sep 17 00:00:00 2001 From: James Simonson Date: Wed, 14 Feb 2024 06:16:00 +0800 Subject: [PATCH 107/200] Microwave UX enhancements (#24547) * Facelift Microwave UI Includes new background light in UI, Uses predictive input, UI now properly disables buttons when microwave is active * Microwave now shows Elapsed time * Fixed bad formatting * Added new term for "BottomMargin" * Change yellow color * Update StyleNano.cs just spacing fixed * Cook time countdown now detached from server Instead of the server constantly sending out messages for the cook countdown, it is now predicted client side using TimeSpan * Update MicrowaveMenu.xaml forgot to re-add item space (cherry picked from commit 25f73f64065f370d8560ff4695579c259e4b7667) --- .../Kitchen/UI/MicrowaveBoundUserInterface.cs | 73 +++++++- Content.Client/Kitchen/UI/MicrowaveMenu.xaml | 172 +++++++++++------- .../Kitchen/UI/MicrowaveMenu.xaml.cs | 51 ++++-- Content.Client/Stylesheets/StyleNano.cs | 12 ++ .../Kitchen/Components/MicrowaveComponent.cs | 6 + .../Kitchen/EntitySystems/MicrowaveSystem.cs | 8 +- .../Kitchen/Components/SharedMicrowave.cs | 5 +- .../components/microwave-component.ftl | 2 + 8 files changed, 239 insertions(+), 90 deletions(-) diff --git a/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs b/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs index 74579b26994..7e7dd2d6935 100644 --- a/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs +++ b/Content.Client/Kitchen/UI/MicrowaveBoundUserInterface.cs @@ -4,6 +4,7 @@ using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.UserInterface.Controls; +using Robust.Shared.Timing; namespace Content.Client.Kitchen.UI { @@ -18,6 +19,9 @@ public sealed class MicrowaveBoundUserInterface : BoundUserInterface [ViewVariables] private readonly Dictionary _reagents = new(); + [Dependency] private readonly IGameTiming _gameTiming = default!; + + public MicrowaveUpdateUserInterfaceState currentState = default!; private IEntityManager _entManager; @@ -26,23 +30,47 @@ public MicrowaveBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, ui _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.StartButton.OnPressed += _ => SendMessage(new MicrowaveStartCookMessage()); - _menu.EjectButton.OnPressed += _ => SendMessage(new MicrowaveEjectMessage()); + _menu.StartButton.OnPressed += _ => SendPredictedMessage(new MicrowaveStartCookMessage()); + _menu.EjectButton.OnPressed += _ => SendPredictedMessage(new MicrowaveEjectMessage()); _menu.IngredientsList.OnItemSelected += args => { - SendMessage(new MicrowaveEjectSolidIndexedMessage(EntMan.GetNetEntity(_solids[args.ItemIndex]))); + SendPredictedMessage(new MicrowaveEjectSolidIndexedMessage(EntMan.GetNetEntity(_solids[args.ItemIndex]))); }; _menu.OnCookTimeSelected += (args, buttonIndex) => { - var actualButton = (MicrowaveMenu.MicrowaveCookTimeButton) args.Button; - SendMessage(new MicrowaveSelectCookTimeMessage(buttonIndex, actualButton.CookTime)); + var selectedCookTime = (uint) 0; + + if (args.Button is MicrowaveMenu.MicrowaveCookTimeButton microwaveCookTimeButton) + { + // args.Button is a MicrowaveCookTimeButton + var actualButton = (MicrowaveMenu.MicrowaveCookTimeButton) args.Button; + selectedCookTime = actualButton.CookTime == 0 ? 0 : actualButton.CookTime; + // SendMessage(new MicrowaveSelectCookTimeMessage((int) selectedCookTime / 5, actualButton.CookTime)); + SendPredictedMessage(new MicrowaveSelectCookTimeMessage((int) selectedCookTime / 5, actualButton.CookTime)); + + _menu.CookTimeInfoLabel.Text = Loc.GetString("microwave-bound-user-interface-cook-time-label", + ("time", selectedCookTime)); + } + else + { + // args.Button is a normal button aka instant cook button + SendPredictedMessage(new MicrowaveSelectCookTimeMessage((int) selectedCookTime, 0)); + + _menu.CookTimeInfoLabel.Text = Loc.GetString("microwave-bound-user-interface-cook-time-label", + ("time", Loc.GetString("microwave-menu-instant-button"))); + } }; } @@ -67,20 +95,47 @@ protected override void UpdateState(BoundUserInterfaceState state) return; } - _menu?.ToggleBusyDisableOverlayPanel(cState.IsMicrowaveBusy); + + _menu?.ToggleBusyDisableOverlayPanel(cState.IsMicrowaveBusy || cState.ContainedSolids.Length == 0); + currentState = cState; // TODO move this to a component state and ensure the net ids. RefreshContentsDisplay(_entManager.GetEntityArray(cState.ContainedSolids)); if (_menu == null) return; - var currentlySelectedTimeButton = (Button) _menu.CookTimeButtonVbox.GetChild(cState.ActiveButtonIndex); - currentlySelectedTimeButton.Pressed = true; - var cookTime = cState.ActiveButtonIndex == 0 + //Set the cook time info label + var cookTime = cState.ActiveButtonIndex == 0 ? Loc.GetString("microwave-menu-instant-button") : cState.CurrentCookTime.ToString(); + + _menu.CookTimeInfoLabel.Text = Loc.GetString("microwave-bound-user-interface-cook-time-label", ("time", cookTime)); + _menu.StartButton.Disabled = cState.IsMicrowaveBusy || cState.ContainedSolids.Length == 0; + _menu.EjectButton.Disabled = cState.IsMicrowaveBusy || cState.ContainedSolids.Length == 0; + + + //Set the correct button active button + if (cState.ActiveButtonIndex == 0) + { + _menu.InstantCookButton.Pressed = true; + } + else + { + var currentlySelectedTimeButton = (Button) _menu.CookTimeButtonVbox.GetChild(cState.ActiveButtonIndex - 1); + currentlySelectedTimeButton.Pressed = true; + } + + //Set the "micowave light" ui color to indicate if the microwave is busy or not + if (cState.IsMicrowaveBusy && cState.ContainedSolids.Length > 0) + { + _menu.IngredientsPanel.PanelOverride = new StyleBoxFlat { BackgroundColor = Color.FromHex("#947300") }; + } + else + { + _menu.IngredientsPanel.PanelOverride = new StyleBoxFlat { BackgroundColor = Color.FromHex("#1B1B1E") }; + } } private void RefreshContentsDisplay(EntityUid[] containedSolids) diff --git a/Content.Client/Kitchen/UI/MicrowaveMenu.xaml b/Content.Client/Kitchen/UI/MicrowaveMenu.xaml index c0418088da2..cd81ea0a9bf 100644 --- a/Content.Client/Kitchen/UI/MicrowaveMenu.xaml +++ b/Content.Client/Kitchen/UI/MicrowaveMenu.xaml @@ -1,73 +1,113 @@ - - - - - - - -

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

[ValidatePrototypeId] private const string DefaultPaperPrototypeId = "Paper"; + + [ValidatePrototypeId] + private const string OfficePaperPrototypeId = "PaperOffice"; public override void Initialize() { @@ -72,6 +75,7 @@ public override void Initialize() // UI SubscribeLocalEvent(OnToggleInterface); + SubscribeLocalEvent(OnFileButtonPressed); SubscribeLocalEvent(OnCopyButtonPressed); SubscribeLocalEvent(OnSendButtonPressed); SubscribeLocalEvent(OnRefreshButtonPressed); @@ -301,6 +305,12 @@ private void OnToggleInterface(EntityUid uid, FaxMachineComponent component, Aft UpdateUserInterface(uid, component); } + private void OnFileButtonPressed(EntityUid uid, FaxMachineComponent component, FaxFileMessage args) + { + args.Content = args.Content[..Math.Min(args.Content.Length, FaxFileMessageValidation.MaxContentSize)]; + PrintFile(uid, component, args); + } + private void OnCopyButtonPressed(EntityUid uid, FaxMachineComponent component, FaxCopyMessage args) { Copy(uid, component); @@ -387,6 +397,27 @@ public void Refresh(EntityUid uid, FaxMachineComponent? component = null) _deviceNetworkSystem.QueuePacket(uid, null, payload); } + /// + /// Makes fax print from a file from the computer. A timeout is set after copying, + /// which is shared by the send button. + /// + public void PrintFile(EntityUid uid, FaxMachineComponent component, FaxFileMessage args) + { + string prototype; + if (args.OfficePaper) + prototype = OfficePaperPrototypeId; + else + prototype = DefaultPaperPrototypeId; + + var name = Loc.GetString("fax-machine-printed-paper-name"); + + var printout = new FaxPrintout(args.Content, name, prototype); + component.PrintingQueue.Enqueue(printout); + component.SendTimeoutRemaining += component.SendTimeout; + + UpdateUserInterface(uid, component); + } + /// /// Copies the paper in the fax. A timeout is set after copying, /// which is shared by the send button. diff --git a/Content.Shared/Fax/SharedFax.cs b/Content.Shared/Fax/SharedFax.cs index ccb998925f1..15674aef7e5 100644 --- a/Content.Shared/Fax/SharedFax.cs +++ b/Content.Shared/Fax/SharedFax.cs @@ -34,6 +34,24 @@ public FaxUiState(string deviceName, } } +[Serializable, NetSerializable] +public sealed class FaxFileMessage : BoundUserInterfaceMessage +{ + public string Content; + public bool OfficePaper; + + public FaxFileMessage(string content, bool officePaper) + { + Content = content; + OfficePaper = officePaper; + } +} + +public static class FaxFileMessageValidation +{ + public const int MaxContentSize = 10000; +} + [Serializable, NetSerializable] public sealed class FaxCopyMessage : BoundUserInterfaceMessage { diff --git a/Resources/Locale/en-US/fax/fax.ftl b/Resources/Locale/en-US/fax/fax.ftl index 76d477f9421..1f1881a05d6 100644 --- a/Resources/Locale/en-US/fax/fax.ftl +++ b/Resources/Locale/en-US/fax/fax.ftl @@ -8,6 +8,9 @@ fax-machine-dialog-rename = Rename fax-machine-dialog-field-name = Name fax-machine-ui-window = Fax Machine +fax-machine-ui-file-button = Print File +fax-machine-ui-paper-button-normal = Normal Paper +fax-machine-ui-paper-button-office = Office Paper fax-machine-ui-copy-button = Copy fax-machine-ui-send-button = Send fax-machine-ui-refresh-button = Refresh @@ -19,3 +22,5 @@ fax-machine-ui-paper-inserted = Paper in tray fax-machine-ui-paper-not-inserted = No paper fax-machine-chat-notify = Received new fax message from "{$fax}" fax + +fax-machine-printed-paper-name = printed paper From dc8c6ed4dbd6f5ae613299453f8899ec2ad36119 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 14 Feb 2024 01:15:57 +0000 Subject: [PATCH 114/200] Automatic changelog update (cherry picked from commit bd669a93cd34ecc4c4f2a553b573fcfee92ff3f6) --- 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 682c81a738a..903ecc1b7da 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,14 +1,5 @@ Order: 1 Entries: -- author: mirrorcult - changes: - - message: Miasma has been renamed to Ammonia - type: Add - - message: Miasmic subsumation reaction has been removed - type: Remove - id: 5438 - time: '2023-12-21T04:19:50.0000000+00:00' - url: null - author: joshepvodka changes: - message: NanoTrasen updated the designs for their emergency medipens. Space medipens @@ -3885,3 +3876,10 @@ Order: 1 id: 5937 time: '2024-02-13T22:19:22.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/24461 +- author: joshepvodka + changes: + - message: Fax machines can now print text files from your computer. + type: Add + id: 5938 + time: '2024-02-14T01:14:51.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/23262 From 77e5628bb0c8af9a411f4ccf1be57537e44a6cca Mon Sep 17 00:00:00 2001 From: Debug <49997488+DebugOk@users.noreply.github.com> Date: Sun, 18 Feb 2024 23:05:55 +0100 Subject: [PATCH 115/200] Revert "Felinid bubble speech. (#808)" This reverts commit 40c61f84e48d8e6515b8e4178bbcf26e09007768. --- .../Prototypes/DeltaV/typing_indicator.yml | 4 ---- .../Entities/Mobs/Species/felinid.yml | 2 -- .../Textures/Effects/speech.rsi/felinid0.png | Bin 899 -> 0 bytes .../Textures/Effects/speech.rsi/felinid1.png | Bin 721 -> 0 bytes .../Textures/Effects/speech.rsi/felinid2.png | Bin 712 -> 0 bytes .../Textures/Effects/speech.rsi/meta.json | 17 ----------------- 6 files changed, 23 deletions(-) delete mode 100644 Resources/Prototypes/DeltaV/typing_indicator.yml delete mode 100644 Resources/Textures/Effects/speech.rsi/felinid0.png delete mode 100644 Resources/Textures/Effects/speech.rsi/felinid1.png delete mode 100644 Resources/Textures/Effects/speech.rsi/felinid2.png diff --git a/Resources/Prototypes/DeltaV/typing_indicator.yml b/Resources/Prototypes/DeltaV/typing_indicator.yml deleted file mode 100644 index c5372b3cc35..00000000000 --- a/Resources/Prototypes/DeltaV/typing_indicator.yml +++ /dev/null @@ -1,4 +0,0 @@ -- type: typingIndicator - id: felinid - typingState: felinid0 - offset: 0, 0.2 # 0625 diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/felinid.yml b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/felinid.yml index d9b25c5dd1b..406a2c698bf 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/felinid.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/felinid.yml @@ -48,8 +48,6 @@ Blunt: 1 - type: Stamina critThreshold: 85 - - type: TypingIndicator - proto: felinid - type: PseudoItem storedOffset: 0,17 shape: diff --git a/Resources/Textures/Effects/speech.rsi/felinid0.png b/Resources/Textures/Effects/speech.rsi/felinid0.png deleted file mode 100644 index 586d1e6a343b2f9ed7f295291819c9f9905d7dc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 899 zcmV-}1AP36P)l(9dr-<1J{FO{Ay^ONFincozR8K8i!|56}a;_!ZCmgf#1*0;L`jS@Do}H1} zCA%AsBnjeZq$#jM9-jfJwq*9VZ}7)A&8m0|c{>zw#gQc^-hNRF($$oj5#5w0Pf_Lm zJ5Mh&JXG%98i&TmAb9P8@HTvvg5dKo2)>S>{sGSIs()2-8hsbNRMlep5Z!>&i>j91 zfwN8Mymxe0|B>othcX#>If1r$XupQYVmYhIImdU9T9;pR1-pCDEBB*I-_bc|^xxnq zzyJUM32;bRa{vGf5&!@T5&_cPe*6Fc0lY~>K~#8N?V7(!12Gteds5KNy_5JCh>MGx z|F45?Lig$-xC-JZZcc&<*EcnhnETOdxvwASb8y^|qbv=YZxT50R^W zKHr{XEbR69XsmVwP0R2{#xfXcrG@Bzn>ov(qw|^cus$`>)kNr2b52%I2!o@F+&*#1MdzTpU1FTkH`h@@lAOHafKmY;|fB*y_009U<00Izz00eeU ZUzcsbCj%Xe(HCX<|QwriLU%imTw_P;d}k z{2KfRx(coef}jW@j?R89QsTK*sEFQha~|G%-^0lp@J|&C(`g(Bv*_CKSX7%!&1=n1 z_z4iCow2mxSksBgB>%4W8+@u>M^vx>@BO)2mokn4z82vT!?ImrnTDxV*HXMG+-2m` zOTzoYVOs_izEHYe<44808ow&Glko}gtDai!2kSrB$lIpyfN;nxl#K6r)RzP^#o2_^ z9@)J(#EB6_L#M;4tVY4lC>N?i->LB~3roYysd z8%{T%`_4++=`X24wm+MN=VNF~LFW|&7HV02pL28z$u;>!m$0)7{c^u!@e>~qXc(-W zx)}ff010qNS#tmY3labT3lag+-G2N4009X}L_t(oN9~g_3&JoEg&QgAP;htj7l?y8 zxcPq_bQ9cL7eR0moQty{6rsM;JE3}%5Hw2wM9D-C;V zMg&8coXMC5<`c?TUyu&S5%yBd+uod6NC?b|!eop{U>aG5qox`t=@JDd;M?;}PY9GA zp2OAqH#9KXBF1bO%R4AG02;KM^4 zBuyQgYT%P@)%Wp>-qceGC;=s)1eAahPy$Ne4+z`=g0EB#V{wto00000NkvXXu0mjf DP!vS` diff --git a/Resources/Textures/Effects/speech.rsi/felinid2.png b/Resources/Textures/Effects/speech.rsi/felinid2.png deleted file mode 100644 index abb5f04373eeaeb41d4e7946340372195b52cfb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 712 zcmV;(0yq7MP)zcsbCj%Xe(HCX<|QwriLU%imTw_P;d}k z{2KfRx(coef}jW@j?R89QsTK*sEFQha~|G%-^0lp@J|&C(`g(Bv*_CKSX7%!&1=n1 z_z4iCow2mxSksBgB>%4W8+@u>M^vx>@BO)2mokn4z82vT!?ImrnTDxV*HXMG+-2m` zOTzoYVOs_izEHYe<44808ow&Glko}gtDai!2kSrB$lIpyfN;nxl#K6r)RzP^#o2_^ z9@)J(#EB6_L#M;4tVY4lC>N?i->LB~3roYysd z8%{T%`_4++=`X24wm+MN=VNF~LFW|&7HV02pL28z$u;>!m$0)7{c^u!@e>~qXc(-W zx)}ff010qNS#tmY3labT3lag+-G2N40096=L_t(oN9|KF3IZ_@yvTtTg1x0L5DT@i z^S>6_3HGOrU@KUQA2>LLIEz^c3DF!R2(k+yo9t$0ZZ0W`SL`uXCJ#+p6pmkdT9-TK zgwk3MkZ%GAYt%=r(IXC&rl-L?1WB!ws@!wfr+SuP2OdE0g1iA);SSnIoy4->WMWuA z36dKTb6`E=9Q%E&uUOxcF&iKju!sbnMD|6uu>kJ?zM5V}_Fw_t#j}5br6Tz=Q~*C< zObtn8-vjGDP&zm39p+^!Ye)dc1qr?Nw;L=5ZctATW1NcE#W@9l$q^F7qRzPle8Tna u$1g+(r#K)Ehy&t)I3Ny)1LDB{I`9Oll1NI}FYCwv0000 Date: Wed, 14 Feb 2024 04:08:45 +0100 Subject: [PATCH 116/200] Vox names, species prototype cleanup, some cosmetic changes (#24994) * voxnames * New generator parameters, names are more readable * bunch of missing vox stuff * more names * sad (cherry picked from commit 5a9ab3b315c90ddd054f2e2524af023d909e2a9e) --- Content.Shared/Humanoid/NamingSystem.cs | 3 + .../Humanoid/Prototypes/SpeciesPrototype.cs | 1 + Resources/Audio/Voice/Talk/attributions.yml | 5 + Resources/Audio/Voice/Talk/vox.ogg | Bin 0 -> 9591 bytes Resources/Audio/Voice/Talk/vox_ask.ogg | Bin 0 -> 11520 bytes Resources/Audio/Voice/Talk/vox_exclaim.ogg | Bin 0 -> 9091 bytes Resources/Audio/Voice/Vox/vox_laugh.ogg | Bin 0 -> 10872 bytes .../en-US/chat/managers/chat-manager.ftl | 4 + .../Locale/en-US/reagents/meta/biological.ftl | 5 +- Resources/Locale/en-US/species/namepreset.ftl | 3 +- Resources/Locale/en-US/species/species.ftl | 1 + Resources/Prototypes/Damage/modifier_sets.yml | 7 +- Resources/Prototypes/Datasets/Names/vox.yml | 2765 +++++++++++++++++ .../Prototypes/Entities/Mobs/Species/vox.yml | 118 +- Resources/Prototypes/Reagents/biological.yml | 14 +- Resources/Prototypes/Species/vox.yml | 8 +- .../Prototypes/Voice/speech_emote_sounds.yml | 12 +- Resources/Prototypes/Voice/speech_sounds.yml | 13 +- Resources/Prototypes/Voice/speech_verbs.yml | 7 + Resources/Prototypes/typing_indicator.yml | 5 + .../Textures/Effects/speech.rsi/meta.json | 11 + .../Textures/Effects/speech.rsi/vox0.png | Bin 0 -> 411 bytes RobustToolbox | 2 +- 23 files changed, 2883 insertions(+), 101 deletions(-) create mode 100644 Resources/Audio/Voice/Talk/vox.ogg create mode 100644 Resources/Audio/Voice/Talk/vox_ask.ogg create mode 100644 Resources/Audio/Voice/Talk/vox_exclaim.ogg create mode 100644 Resources/Audio/Voice/Vox/vox_laugh.ogg create mode 100644 Resources/Prototypes/Datasets/Names/vox.yml create mode 100644 Resources/Textures/Effects/speech.rsi/vox0.png diff --git a/Content.Shared/Humanoid/NamingSystem.cs b/Content.Shared/Humanoid/NamingSystem.cs index 7ca4fac5b54..d4cca026ef0 100644 --- a/Content.Shared/Humanoid/NamingSystem.cs +++ b/Content.Shared/Humanoid/NamingSystem.cs @@ -26,6 +26,9 @@ public string GetName(string species, Gender? gender = null) switch (speciesProto.Naming) { + case SpeciesNaming.First: + return Loc.GetString("namepreset-first", + ("first", GetFirstName(speciesProto, gender))); // Start of Nyano - Summary: for Oni naming case SpeciesNaming.LastNoFirst: return Loc.GetString("namepreset-lastnofirst", diff --git a/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs b/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs index e4adb4d55bb..909b618d597 100644 --- a/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs +++ b/Content.Shared/Humanoid/Prototypes/SpeciesPrototype.cs @@ -124,6 +124,7 @@ public sealed partial class SpeciesPrototype : IPrototype public enum SpeciesNaming : byte { + First, FirstLast, FirstDashFirst, //Start of Nyano - Summary: for Oni naming diff --git a/Resources/Audio/Voice/Talk/attributions.yml b/Resources/Audio/Voice/Talk/attributions.yml index d55b9737d0e..19b0b66b9cc 100644 --- a/Resources/Audio/Voice/Talk/attributions.yml +++ b/Resources/Audio/Voice/Talk/attributions.yml @@ -31,3 +31,8 @@ license: "CC-BY-NC-SA-3.0" copyright: "Goonstation, Modified by Whisper" source: "https://github.com/goonstation/goonstation/tree/eb3e7df6292d23f6af2f18b4372d3a8ba4b0fda7/sound/misc/talk" + +- files: ["vox.ogg","vox_ask.ogg","vox_exclaim.ogg" ] + license: "CC-BY-NC-SA-3.0" + copyright: "Derived from shriek1.ogg by Errant" + source: "https://github.com/goonstation/goonstation/tree/eb3e7df6292d23f6af2f18b4372d3a8ba4b0fda7/sound/misc/talk" diff --git a/Resources/Audio/Voice/Talk/vox.ogg b/Resources/Audio/Voice/Talk/vox.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c3b2a268ac2b178fc9d57c0354054f55df3e74a1 GIT binary patch literal 9591 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 literal 0 HcmV?d00001 diff --git a/Resources/Audio/Voice/Vox/vox_laugh.ogg b/Resources/Audio/Voice/Vox/vox_laugh.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8c356045c361cf76c6b6f4ad96b85bb68e09859c GIT binary patch literal 10872 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 x+!ZX*8GlA=0E~~{{!dc(Gmav literal 0 HcmV?d00001 diff --git a/Resources/Locale/en-US/chat/managers/chat-manager.ftl b/Resources/Locale/en-US/chat/managers/chat-manager.ftl index 6b8a7a3ec37..a0cc5cf634c 100644 --- a/Resources/Locale/en-US/chat/managers/chat-manager.ftl +++ b/Resources/Locale/en-US/chat/managers/chat-manager.ftl @@ -92,6 +92,10 @@ chat-speech-verb-skeleton-1 = rattles chat-speech-verb-skeleton-2 = clacks chat-speech-verb-skeleton-3 = gnashes +chat-speech-verb-vox-1 = screeches +chat-speech-verb-vox-2 = shrieks +chat-speech-verb-vox-3 = croaks + chat-speech-verb-canine-1 = barks chat-speech-verb-canine-2 = woofs chat-speech-verb-canine-3 = howls diff --git a/Resources/Locale/en-US/reagents/meta/biological.ftl b/Resources/Locale/en-US/reagents/meta/biological.ftl index 9078397a73c..10a9a07e08a 100644 --- a/Resources/Locale/en-US/reagents/meta/biological.ftl +++ b/Resources/Locale/en-US/reagents/meta/biological.ftl @@ -10,6 +10,9 @@ reagent-desc-slime = You thought this was gradient blood at first, but you were reagent-name-hemocyanin-blood = blue blood reagent-desc-hemocyanin-blood = Contains copper as opposed to iron which gives it a distinct blue color. +reagent-name-ammonia-blood = anaerobic blood +reagent-desc-ammonia-blood = Nothing else in the entire galaxy smells quite so appalling. + reagent-name-zombie-blood = zombie blood reagent-desc-zombie-blood = Would not advise eating. Can be used to create an inoculation against the infection. @@ -20,4 +23,4 @@ reagent-name-fat = fat reagent-desc-fat = No matter how it was obtained, its application is important. reagent-name-vomit = vomit -reagent-desc-vomit = You can see a few chunks of someone's last meal in it. \ No newline at end of file +reagent-desc-vomit = You can see a few chunks of someone's last meal in it. diff --git a/Resources/Locale/en-US/species/namepreset.ftl b/Resources/Locale/en-US/species/namepreset.ftl index 2d43b5f00d1..5a42c87b78e 100644 --- a/Resources/Locale/en-US/species/namepreset.ftl +++ b/Resources/Locale/en-US/species/namepreset.ftl @@ -1,3 +1,4 @@ +namepreset-first = {$first} namepreset-firstlast = {$first} {$last} namepreset-firstdashfirst = {$first1}-{$first2} -namepreset-thefirstoflast = The {$first} of {$last} \ No newline at end of file +namepreset-thefirstoflast = The {$first} of {$last} diff --git a/Resources/Locale/en-US/species/species.ftl b/Resources/Locale/en-US/species/species.ftl index 081b626d452..f31b1fa0f00 100644 --- a/Resources/Locale/en-US/species/species.ftl +++ b/Resources/Locale/en-US/species/species.ftl @@ -8,3 +8,4 @@ species-name-diona = Diona species-name-arachnid = Arachnid species-name-moth = Moth Person species-name-skeleton = Skeleton +species-name-vox = Vox diff --git a/Resources/Prototypes/Damage/modifier_sets.yml b/Resources/Prototypes/Damage/modifier_sets.yml index 8a7b84ff1a7..31dd47a9e16 100644 --- a/Resources/Prototypes/Damage/modifier_sets.yml +++ b/Resources/Prototypes/Damage/modifier_sets.yml @@ -66,7 +66,7 @@ Piercing: 0.7 Shock: 2 Heat: 3 - + # Like metallic, but without flat reduction so it can be damaged with fists. - type: damageModifierSet id: FlimsyMetallic @@ -190,6 +190,11 @@ Cold: 0.7 Heat: 1.3 +- type: damageModifierSet + id: Vox + coefficients: # To be decided + Poison: 1 + - type: damageModifierSet id: Zombie #Blunt resistant and immune to biological threats, but can be hacked apart and burned coefficients: diff --git a/Resources/Prototypes/Datasets/Names/vox.yml b/Resources/Prototypes/Datasets/Names/vox.yml new file mode 100644 index 00000000000..891094d95b2 --- /dev/null +++ b/Resources/Prototypes/Datasets/Names/vox.yml @@ -0,0 +1,2765 @@ +- type: dataset + id: names_vox + values: + - Bakabepa + - Babapir + - Babasri + - Babepipit + - Bachakehi + - Bacheska + - Bachishesher + - Bacrapri + - Bacreska + - Bahepra + - Bahicrecrek + - Bahikravre + - Bakabepa + - Bakehahak + - Bakeki + - Bapechichik + - Bapekikik + - Baperi + - Bapravavar + - Bapreba + - Bapretritrir + - Baracreber + - Barahri + - Baraskahrita + - Baraxixik + - Bashiskir + - Baskaskakre + - Baskivihi + - Basreba + - Batapriri + - Batasrecrar + - Batehrahrat + - Batrakiha + - Batravika + - Batrepriski + - Batresri + - Batriska + - Batritra + - Bavasha + - Bavebebek + - Bavraskikaka + - Bavricriski + - Baxahehrer + - Baxeve + - Bebebapa + - Bebeterara + - Bebipaska + - Bechetapeka + - Becrerisre + - Becretretrer + - Beheka + - Behivresha + - Behrechechek + - Behrekri + - Behreyayat + - Behricririri + - Behritixaxa + - Bekapesresre + - Bekashishik + - Beketatratra + - Bekrechaxe + - Bekresrare + - Bekribe + - Bepararakrit + - Bepatricher + - Bepehisrepra + - Bepihar + - Bepitrashi + - Bepresri + - Berabi + - Beraka + - Berecricrir + - Berisre + - Beshachari + - Besheskexexe + - Beshesre + - Beshesretre + - Beskayavrer + - Beskisrasrak + - Beskitre + - Besravivit + - Besrivir + - Betababatrat + - Betere + - Beticreche + - Bevekakat + - Bevihichabi + - Bevihraki + - Bevrasheshet + - Bibaba + - Bibabir + - Bibati + - Bibekricha + - Bibexa + - Bibibabat + - Bibiya + - Bichechir + - Bicrakipepe + - Bicrevrite + - Bihrapivra + - Bihraxibebe + - Bihrishicha + - Bihrivriski + - Bikivri + - Bikraskixexe + - Bikrivrivrit + - Bipekisri + - Bipiritecre + - Bipratraxi + - Biprexi + - Biprivar + - Birachi + - Bisheba + - Bishehri + - Bishevrivra + - Bishiki + - Biskeskavra + - Bisrahresha + - Bisrepipit + - Bitavi + - Bitehatiti + - Bivacri + - Bivape + - Bivihachakre + - Bivitikiva + - Bivrapri + - Bivraske + - Bivrehaski + - Bivrihra + - Bixachetra + - Bixapetra + - Bixapriprik + - Bixexir + - Biyakir + - Chabaha + - Chabakrekrer + - Chabebache + - Chabepebe + - Chabikrahihi + - Chachahe + - Chachevra + - Chacrerehra + - Chahekre + - Chahixe + - Chahravrer + - Chahrixehra + - Chakakiva + - Chakapraprar + - Chakehashe + - Chakiprihi + - Chakivre + - Chakricrivi + - Chapachichit + - Chaparachi + - Chapehresha + - Chapeshiski + - Chapixahi + - Chaprahebibi + - Chaprecraha + - Chaprecrevi + - Charaprehiki + - Charapriska + - Charara + - Charate + - Charatraki + - Charekreski + - Charesribe + - Charichechet + - Charisha + - Chashaber + - Chashereska + - Chaskeke + - Chasraskaska + - Chasrechata + - Chasrevravi + - Chasrihiprer + - Chatrexixe + - Chavicreshi + - Chavrikre + - Chaxakrahehe + - Chaxeskehre + - Chaxevrahi + - Chaxivre + - Chebabebet + - Chebavi + - Chebebibivar + - Chebehecri + - Chebehrihrit + - Chebihihit + - Chebiretete + - Chebisra + - Chechapraver + - Checraxa + - Checrera + - Checretasre + - Checretrisre + - Checrisre + - Chehashababa + - Chehebicri + - Chehepre + - Chehisker + - Chehraxashir + - Chekrahraka + - Chekravixa + - Chekretitit + - Chepakakatat + - Chepekakak + - Chepipracra + - Chepitipe + - Chepraskavri + - Cheshirikra + - Cheshive + - Cheskapra + - Cheskavre + - Chesrakeyaya + - Chesravre + - Chesrevi + - Chesrevratra + - Chesrirititi + - Chetaxapa + - Chetaxapre + - Cheterarat + - Chetiska + - Chetritreti + - Chetriya + - Chevasrasrak + - Chevrepre + - Chevrivir + - Chexararahir + - Chexecraski + - Chexepraprar + - Chexexaxapa + - Chexisreka + - Chexitre + - Cheyaverere + - Chibakre + - Chibihra + - Chichabikaka + - Chichavrehre + - Chicrikishi + - Chicrirake + - Chicrivivit + - Chihahrehrek + - Chihasre + - Chihatrachi + - Chihayayabik + - Chiheche + - Chihehreba + - Chihreratri + - Chihriveka + - Chikakre + - Chikaskitre + - Chikate + - Chikiprecri + - Chikraki + - Chikraskiska + - Chikrekra + - Chikrekre + - Chipabeske + - Chipererer + - Chipicracrak + - Chiprexexet + - Chipriprisre + - Chiprivrecha + - Chishakepi + - Chishipepri + - Chisrashi + - Chisretri + - Chisriher + - Chisriva + - Chisrivevri + - Chitisrevre + - Chitixahra + - Chitrechicra + - Chitresravri + - Chivechachat + - Chiveprepret + - Chiveprikri + - Chiviki + - Chivikiya + - Chivishir + - Chivrakakak + - Chivrakri + - Chivrasher + - Chivrepapar + - Chixacra + - Chixihebakra + - Crabecrapapa + - Crachikrisre + - Cracrahravri + - Cracratiya + - Cracretipi + - Cracrihe + - Cracritri + - Crahayayak + - Craheki + - Crahrashi + - Crahrehi + - Crahretetek + - Crakapeper + - Crakaskeba + - Crakavravrat + - Crakehri + - Crakirer + - Crakrashiski + - Crakrehra + - Crakriskipir + - Crapipaka + - Crapiriyaya + - Craprati + - Crapresker + - Craresraxe + - Crarevexa + - Crashahresri + - Crashehihik + - Craskahraske + - Craskatrapra + - Craskicrete + - Craskivi + - Cratatrihi + - Cratikre + - Cratikrekrek + - Cratiprar + - Cratrehra + - Cravehri + - Cravrikra + - Cravrisrere + - Cravritiriri + - Cravriyayak + - Crayahrehret + - Crayakrer + - Crayapraprar + - Crayaripipi + - Crayayaricri + - Crebaxa + - Crebehrita + - Crechavre + - Crechesrehar + - Crechichevre + - Crecrabibik + - Crecriri + - Crehepapepe + - Creheriki + - Crehexi + - Crehipavava + - Crehraver + - Crekatri + - Crekavexa + - Crekeki + - Creketri + - Crekiskeya + - Crekitati + - Crekrepreki + - Crekrivavak + - Crepahripa + - Crepekecre + - Crepekrekret + - Crepiba + - Crepihri + - Creprepravri + - Creraxi + - Crerehihit + - Creshekrapa + - Creskekri + - Cresketita + - Creskihre + - Cresripepet + - Cretarevripa + - Cretebe + - Cretehra + - Creterarar + - Cretibehihi + - Cretrapi + - Cretrekerara + - Cretrepepet + - Crevapir + - Crevixesra + - Crexahava + - Crexepapacre + - Cribavribibi + - Cribitratrat + - Crichecrite + - Crichipi + - Cricraprehre + - Cricrirar + - Cricrisre + - Cricritika + - Crihevar + - Crihitehre + - Crikatrikre + - Crikebepapa + - Crikekakat + - Crikeshivra + - Crikisheski + - Crikrahrata + - Crikretevabi + - Crikricretri + - Cripichahi + - Criprishapa + - Crirachi + - Crirakratra + - Crishave + - Criskahe + - Crisrehapahi + - Critachatri + - Critrabibir + - Critresrir + - Critrikracri + - Crivacriti + - Crivacrive + - Crivayasra + - Crivrakre + - Crivrecri + - Crixixaske + - Habavavak + - Habepa + - Habikikaka + - Habikrihita + - Hachabe + - Hachehekre + - Hacheske + - Hacreha + - Hacrere + - Hahebapapa + - Hahecrecha + - Haheha + - Hahetasrike + - Hahihahatrar + - Hahihasreche + - Hahripraxaxa + - Hakepa + - Hakirer + - Hakraxixit + - Hakrekikik + - Hakrixexeret + - Hapacharepri + - Hapacre + - Hapahri + - Hapeti + - Hapitahri + - Hapreska + - Haprihrisha + - Harebabi + - Harexiveve + - Haricracre + - Haririsheska + - Harishi + - Hashakrakrak + - Hashehracri + - Hashepracha + - Haskaritepra + - Hasketer + - Haskibebeyat + - Haskikretete + - Hasrabake + - Hasracritehe + - Hasrekitra + - Hasrekrer + - Hasrihaxa + - Hasripeshar + - Hatabibivet + - Havavresra + - Havixe + - Havreki + - Havrepekre + - Havretri + - Havrichatata + - Haxikeker + - Hayahriyaxa + - Hebahrevrir + - Hebapri + - Hebihihichit + - Hebikratahe + - Hecheshehixi + - Hechetra + - Hechevakrer + - Hecraba + - Hecrabi + - Hecrevrivrik + - Hecrirecha + - Hehere + - Hehiskitri + - Hehrapike + - Hehrepri + - Hehreskaskat + - Hehrikra + - Hekikrexa + - Hekrasre + - Hekrekicre + - Hekreracre + - Hekriheti + - Hepevivikrik + - Hepraskibebe + - Heprivresker + - Heprixasheri + - Herecrerivi + - Hereririket + - Heriheyacri + - Heripa + - Heripreka + - Heshahraveti + - Heshepepevik + - Heskashachi + - Heskaxixe + - Heskererepet + - Heskeshishit + - Heskisker + - Hesrepahri + - Hesreski + - Hetahetritri + - Hetiheheprit + - Hetrare + - Hetrevihra + - Hetrihahri + - Hetrirebibi + - Hevababaker + - Hevetihre + - Hevexixik + - Heviricrecre + - Hevrevipa + - Hevrexir + - Hevrichar + - Hevriraravit + - Hevrivrivre + - Hexasrichi + - Hexaxipri + - Heyashipre + - Hibasher + - Hiberarakrar + - Hibesrache + - Hicrapre + - Hicrecrahera + - Hicreteba + - Hicriba + - Hihacha + - Hihepapak + - Hihichitre + - Hihireret + - Hihrevra + - Hikikri + - Hikitritrir + - Hikrakre + - Hikrepa + - Hipavi + - Hipitratrak + - Hirepabe + - Hirichachar + - Hiricheya + - Hiricrabakri + - Hiricraske + - Hiricrevitri + - Hirihrachi + - Hirihraski + - Hirihraxaxat + - Hirikachi + - Hirikretetet + - Hirikrikra + - Hiripebahre + - Hiripehixixi + - Hiriper + - Hiripesri + - Hiripeta + - Hiripevivik + - Hirirahehet + - Hirirecrevre + - Hirishihra + - Hiriskeva + - Hiritapatiti + - Hiriteker + - Hiritrari + - Hiritraxe + - Hiritricri + - Hirivavavri + - Hiriviske + - Hirivivre + - Hirivra + - Hirivrari + - Hirivrexita + - Hirivrivri + - Hirixashahre + - Hirixicraya + - Hishave + - Hishesritra + - Hishiskahra + - Hishivrevrek + - Hiskakecra + - Hiskatetek + - Hiskekreche + - Hiskeva + - Hiskisrare + - Hisrakikit + - Hisratrepepe + - Hitava + - Hiterehaha + - Hitratra + - Hivacracrat + - Hivatritrik + - Hivayayar + - Hivrababar + - Hivrahrir + - Hixacre + - Hixashape + - Hixashetiti + - Hixekrasra + - Hixepi + - Hixeripe + - Hiyacrakra + - Hrabatitit + - Hrabaxa + - Hrabike + - Hrabipre + - Hracrabixi + - Hracrehra + - Hrahepivivi + - Hraherikrexi + - Hrahikrer + - Hrahrakahre + - Hrahraska + - Hrahrasrebe + - Hrahrehehek + - Hrahritra + - Hrakachabexi + - Hrakarerek + - Hrakeshi + - Hrakiski + - Hrakretri + - Hrakrichapri + - Hrakrishi + - Hrapavevek + - Hrapicra + - Hrapraber + - Hraprapreche + - Hrarachihi + - Hrarahrahrar + - Hrarecri + - Hrarikrixabi + - Hrarishesher + - Hrashepa + - Hrashibisra + - Hrashihir + - Hrashikavexa + - Hrasketre + - Hraskibe + - Hraskikexaxa + - Hrasrecrixi + - Hrasrevraxi + - Hrasrevrehra + - Hratatrasre + - Hratayati + - Hratere + - Hratrachari + - Hratreki + - Hravahiche + - Hravapeki + - Hravaskeki + - Hraveska + - Hravihre + - Hravrahaheya + - Hravrekra + - Hraxehrehiri + - Hraxekrebe + - Hraxichebar + - Hraxivivivet + - Hrayacha + - Hrayavrar + - Hrebavihra + - Hrebetra + - Hrechaxer + - Hrecreti + - Hrecrihahar + - Hrehikrekrer + - Hrehresra + - Hreketra + - Hrekrativi + - Hrepihepre + - Hrepipake + - Hrerasri + - Hreravexe + - Hrereprehir + - Hreriba + - Hreshahetiti + - Hreshehakake + - Hreskapahre + - Hresrakakre + - Hresrechike + - Hresrekasha + - Hretite + - Hretrecre + - Hretreski + - Hretrevri + - Hrevrehe + - Hrexakekek + - Hrexatika + - Hrexebe + - Hribahar + - Hribehrati + - Hribipe + - Hrichiski + - Hrihevrivrir + - Hrihitra + - Hrihrakihri + - Hrihrechar + - Hrikichecra + - Hrikiskate + - Hripricrahra + - Hrirehrikra + - Hriresri + - Hrishabar + - Hrishaxeyar + - Hrishehrahi + - Hrishexixik + - Hrisheyakra + - Hrishipete + - Hriskacrecra + - Hriskaheba + - Hriskari + - Hriskevetabi + - Hriskexa + - Hriskihete + - Hriskihri + - Hrisrechi + - Hrisrera + - Hrisriri + - Hrisrishapa + - Hrisrivavar + - Hritachecri + - Hritexa + - Hritihihri + - Hritihra + - Hritiker + - Hritisrasrat + - Hrivaxa + - Hrivripira + - Hrixebabatir + - Hrixebi + - Hrixihri + - Hrixiva + - Hriyahriya + - Kabavi + - Kabaxesha + - Kachaske + - Kachaya + - Kachihe + - Kacrahesha + - Kahakichi + - Kahaxipa + - Kahepapatret + - Kahiki + - Kahishe + - Kahrakrekret + - Kahratrer + - Kahriche + - Kahricrikra + - Kakatahrare + - Kakebi + - Kakihrasri + - Kapakriska + - Kapracre + - Kaprashesher + - Kaprehrakaka + - Kapreri + - Karakahre + - Karapihehe + - Kashaya + - Kashipri + - Kaskachekeke + - Kaskivrer + - Kasrabacre + - Kasrakapre + - Kasraxar + - Kasresreyaya + - Kasrivrata + - Katasker + - Katehreyaya + - Katetrike + - Katexaxak + - Katrehre + - Kavababat + - Kavashishit + - Kavihrahrat + - Kavitratrak + - Kavratevriya + - Kaxecri + - Kaxetavre + - Kaxetretret + - Kayararat + - Kayavrivrik + - Kayaxi + - Kebasrevikri + - Kechatra + - Kechavrepri + - Kecresra + - Kecrevrir + - Kecriha + - Kecrikra + - Kecrixa + - Kehave + - Kehitichacha + - Kehivehrihri + - Kehrachechek + - Kehrehi + - Kekabibit + - Kekahi + - Kekahrexi + - Kekarar + - Kekasritri + - Kekebapisra + - Kekebibivrer + - Kekekahihi + - Kekrishe + - Kepetre + - Kepevra + - Kepraki + - Keprepara + - Kerahacheche + - Keratra + - Kerihi + - Keriskehisri + - Keshevaskiva + - Keshika + - Keshiti + - Keskarahita + - Keteskesket + - Ketesketa + - Ketribabar + - Ketribipi + - Kevatra + - Kevatre + - Keveki + - Keveshatra + - Keveshexiki + - Kevesraxe + - Kevexa + - Kevikaxe + - Kevivri + - Kevrahreri + - Kevrahrihrit + - Kexapriprik + - Kexerava + - Kexeshacha + - Kexisrepe + - Keyararak + - Kibevavacrak + - Kibeyachichi + - Kibipavava + - Kichitra + - Kicricreva + - Kicrikrikrik + - Kiharesra + - Kihiya + - Kihrexexevek + - Kihriprira + - Kikeke + - Kikexitretre + - Kikrabikichi + - Kikrehi + - Kikrekrakrat + - Kikreri + - Kikretrapa + - Kikrevavak + - Kikrivikar + - Kipivaxe + - Kipreya + - Kireche + - Kiresrisrir + - Kirevi + - Kiribapra + - Kiribaprive + - Kirichaketra + - Kirichiska + - Kiricrakakri + - Kirihererek + - Kirihrepi + - Kirihreviche + - Kirikachicha + - Kirikatriki + - Kirikivrivri + - Kirikrakra + - Kiripabi + - Kiripahritri + - Kiriprihri + - Kirirahixera + - Kirireti + - Kirirevri + - Kirishavavar + - Kirishekeket + - Kiriteska + - Kiritracha + - Kiritrepeper + - Kiritreyapri + - Kirivipe + - Kirivrivepi + - Kirixaticher + - Kirixepepek + - Kirixicra + - Kishahapatre + - Kishehakaka + - Kiskashapra + - Kiskekehra + - Kiskekicre + - Kiskipri + - Kitraka + - Kitrevevri + - Kivraheherat + - Kivrahi + - Kivrashe + - Kivrera + - Kivretrakeke + - Kixatritrit + - Kixichetiti + - Kixichicrar + - Kixivra + - Krabareyaya + - Krabeherere + - Krachehre + - Kracheyaba + - Kracrirarak + - Krahebikaba + - Krahechikri + - Krahiha + - Krahrakri + - Krahraririk + - Krahrepexi + - Krahrepri + - Krahrerar + - Krakahra + - Krakrekiski + - Krakrepapat + - Krapari + - Krapibi + - Krapitahri + - Krapreve + - Kraprisrisre + - Kraprivrarar + - Krarakrikrit + - Krarekri + - Kraricri + - Krashatatahi + - Krashavecra + - Kraskisretra + - Krasrarevi + - Krasripapat + - Kratachavri + - Kratare + - Kratikepi + - Kraveke + - Kravraxeveve + - Kravrepachi + - Kravricrahra + - Kraxabi + - Kraxasrir + - Krayakrikrit + - Krebekri + - Krebibikre + - Krebivi + - Krechahe + - Krechepraxa + - Krechititik + - Krecrashepra + - Krecravicha + - Krecreri + - Krehekikihit + - Krehrakakre + - Krehrita + - Krehrixa + - Krekacrechi + - Krekebeta + - Krekracri + - Krekrapri + - Krekrishaski + - Krepeviske + - Krepitir + - Krepiya + - Kreprahetaya + - Krepretasha + - Kreprivreski + - Krererisri + - Krerexeskeva + - Kreskaviha + - Kresrepaxexe + - Kretahre + - Kretavi + - Kretepapatir + - Krevavikeke + - Krevesher + - Krevesrisrit + - Krevrexer + - Krevrivriske + - Krexaya + - Kreyacrepe + - Kreyatriri + - Kreyavi + - Kribeshi + - Kribetibi + - Kribexixik + - Kribirecri + - Kribivra + - Krichakehra + - Kricrava + - Kricrirepe + - Kricritaka + - Krihaprir + - Krihesre + - Krihexarava + - Krihreskekre + - Krikapepek + - Krikatitixer + - Krikesrixixi + - Krikrashar + - Krikrikesre + - Kripahri + - Kripritri + - Kriripriprit + - Kririve + - Krishebiriba + - Krishebite + - Krishecrapi + - Kriskexer + - Krisribariri + - Krisrisher + - Kritahe + - Kritarerek + - Kritechihihi + - Kritiha + - Kritixa + - Kritresra + - Kritrivrevra + - Krivaxixipak + - Krivripri + - Krixehraski + - Krixesrepri + - Krixirar + - Pabaskare + - Pabecrechi + - Pabixashaha + - Pachatatak + - Pachetra + - Pachikri + - Pachisra + - Pacrachisri + - Pacraheha + - Pahrecrahati + - Pahrixeke + - Pakaririhrek + - Pakashexa + - Pakaskesha + - Pakavrevaha + - Pakihechacha + - Pakishi + - Pakivrapapa + - Pakrakrasra + - Pakrasrer + - Pakrava + - Pakresra + - Pakrexetihe + - Pakrika + - Papaskaxa + - Papavivivrik + - Papesheher + - Papivahre + - Papratrakiki + - Parerakre + - Pashaskaskak + - Pashevravrat + - Paskasretiti + - Paskiske + - Paskixexek + - Pasrabicra + - Pasraprikepa + - Pasrehe + - Pasrepratri + - Pataprivra + - Patesrateke + - Patexexet + - Patreshe + - Pavaba + - Pavrapishi + - Paxarerechak + - Paxecri + - Paxitirechi + - Payahreshi + - Pebakrikrik + - Pebate + - Pebeskahepre + - Pebevravi + - Pebibebek + - Pechaka + - Pechekripi + - Pechetraya + - Pechikreke + - Pechivrar + - Pecracha + - Pecritrasre + - Pehasra + - Pehecha + - Pehisresrer + - Pehrakresha + - Pehrihivreya + - Pehriva + - Pekecricrik + - Pekrava + - Pekraya + - Pekrepitri + - Pepehri + - Pepexekaka + - Pepirer + - Pepiska + - Pepitre + - Pepreba + - Pepreha + - Peprerar + - Pepresri + - Pepresrikeke + - Peprevahe + - Peraxatrikri + - Perebecrate + - Peribi + - Perisrehri + - Peshipaha + - Peskavavaxek + - Peskehihik + - Peskikikitir + - Pesraski + - Pesratra + - Pesravre + - Pesraya + - Pesretetetat + - Pesrikre + - Pesritra + - Petevrivrit + - Petihri + - Petivrate + - Petripetete + - Pevekriska + - Pevera + - Pevetiska + - Pevetrepri + - Pevikixi + - Pevipraprak + - Pevitetecrak + - Pevixihre + - Pevracher + - Pevrakrakrat + - Pevrehita + - Pexepraprat + - Pexihibe + - Pibehra + - Pibekrite + - Pibetiskiski + - Pibibipa + - Pibikekek + - Pichehi + - Pichetreta + - Pichicreve + - Pichikrarar + - Picreprecha + - Pihasresret + - Piheki + - Pihepa + - Pihibeskaska + - Pihichar + - Pihitetek + - Pihrebi + - Pihreshapibe + - Pihretitir + - Pikaskaskar + - Pikaxer + - Pikrehreka + - Pikripreprer + - Pipasha + - Pipaxacricri + - Pipesresri + - Pipribepri + - Piprishixi + - Piraxiprar + - Pirekrehi + - Pireveverik + - Piribaxa + - Piribipriski + - Pirichivapi + - Piricrahra + - Piricrakra + - Pirihepre + - Pirihichati + - Pirikretra + - Pirikritere + - Pirikrivra + - Piripaba + - Piripacripri + - Piripihrishe + - Piripite + - Piripitri + - Piriprabepa + - Pirireprishe + - Piriririke + - Piriskateke + - Piriskiki + - Pirisretiva + - Piritavre + - Piritihre + - Piritratavri + - Piritrecrara + - Piritreke + - Pirivakixaxa + - Pirivikrar + - Pirixaxa + - Pirixaxevre + - Piriyakribi + - Piriyapesra + - Pishakakaxet + - Pishashetepi + - Pishavraska + - Pishevra + - Piskipre + - Pisrasheshek + - Pisripre + - Pisrixekete + - Pitibi + - Pitraprivre + - Pitraskeche + - Pitratebi + - Pitrevreyaya + - Pitriprivra + - Pitriske + - Pivaka + - Pivatatakir + - Pivekrixehri + - Piveyashi + - Pivrakevi + - Pivrakipre + - Pivrakitibe + - Pivrashir + - Pivrirater + - Pivritatabet + - Pixeriti + - Pixicha + - Prabibiprepi + - Prabichixaxa + - Prabixite + - Pracheteter + - Prachiba + - Pracrahrive + - Prahihrahrak + - Prahisresrek + - Prahitrivi + - Prahrebesra + - Prahripebaba + - Prahrivapapa + - Prakiskesket + - Prakrehrahri + - Prakripi + - Prapicresri + - Praprexexek + - Prarachaxi + - Prarecrahi + - Prarikra + - Praripraka + - Prashicribi + - Prashivepapa + - Prashixitata + - Pratakra + - Praterahira + - Pratreki + - Pravashipebe + - Pravesrisrit + - Pravixihehe + - Pravrashi + - Pravrepi + - Pravricrir + - Pravritrer + - Praxahihir + - Praxechaxere + - Praxekrakrat + - Praxevitetra + - Praxexe + - Praxichi + - Prayaraxir + - Prebavre + - Prechakavra + - Prechavre + - Precratetet + - Preherihra + - Prehiviveve + - Prehrakriska + - Prehribi + - Prekakra + - Prekaya + - Prekiprever + - Prekirar + - Prepahihibar + - Prepetratrat + - Prepixihrapa + - Preprete + - Preretetre + - Prerexike + - Presharesre + - Presravi + - Presrere + - Presriskipre + - Pretere + - Pretetisrir + - Pretexiprar + - Pretihre + - Pretrakre + - Pretrike + - Pretrisra + - Prevakre + - Prevecrere + - Prevesriti + - Preveti + - Previkrahihi + - Previkri + - Prevritrare + - Prevrivi + - Prexatrar + - Prexeshe + - Prexicracrak + - Preyatra + - Pribatretrek + - Pribavibache + - Pribirivava + - Pribivrivrit + - Pricheyayat + - Pricrapapat + - Pricrihi + - Prihavri + - Prihetiya + - Prihrechabi + - Prikebixi + - Prikricha + - Prikripi + - Prikripikiki + - Prikrishi + - Pripachiya + - Pripavrepri + - Pripixixik + - Pripraske + - Priprecheha + - Pripripepek + - Prirakre + - Prirasher + - Priraske + - Prireprehar + - Pririhi + - Prishehe + - Prishepaxixi + - Prishitarabe + - Priskake + - Prisraxi + - Pritabaski + - Pritakir + - Pritecra + - Pritehavivi + - Pritepa + - Pritichahi + - Privayayak + - Privipecre + - Privrihareya + - Prixarake + - Prixepa + - Prixetre + - Prixivrekri + - Priyaprar + - Rabehiya + - Rabeparere + - Rabereshebe + - Rabichechet + - Rachare + - Racraba + - Racrakeka + - Racrakreheri + - Rahavevahi + - Rahevripeshi + - Rahibebetat + - Rahihratata + - Rahipe + - Rahraba + - Rahrecri + - Rahreyavri + - Rahritretrek + - Rakekikitrir + - Rakicrecrek + - Rakipipihrat + - Rakreprikri + - Rapivrivrere + - Rarahaka + - Raretriya + - Rasheshashat + - Rasheshevri + - Rashihretra + - Rashikrehre + - Rasriber + - Ratabibihet + - Ratesraprar + - Ratitritrik + - Ratravi + - Ratrebi + - Ratreyayak + - Ratrihrikri + - Ravecher + - Ravepexi + - Ravihrahrak + - Ravixexebet + - Ravrisheke + - Ravrivrikri + - Raxahehet + - Raxetapa + - Raxete + - Raxevahre + - Rayachesheta + - Rebakre + - Rebebikiki + - Rebicracrak + - Rebipi + - Rebisriyaya + - Rebitetebit + - Recheper + - Recraskehe + - Recrekariri + - Rehepipibet + - Rehresheshet + - Rehrikrikrik + - Rehrire + - Rekaskaskak + - Rekracha + - Rekripreprek + - Repeche + - Repetrir + - Repexishe + - Repivesheri + - Repivrasra + - Reprihri + - Reprishishik + - Rerahahat + - Rereba + - Rerirevra + - Reskebexexe + - Reskehahat + - Reskivavak + - Reskixibira + - Resrecracrat + - Resretra + - Resrihrepeke + - Resriske + - Resrixiha + - Retaskahri + - Retavavatet + - Retaveche + - Retecha + - Retevravrak + - Retrete + - Retrexehehri + - Retripritri + - Revasri + - Revetitipret + - Revikrebiya + - Revripra + - Revritrer + - Rexabaska + - Rexataxa + - Ribatre + - Ribebahihi + - Ribehashishi + - Ribiheva + - Ricrehaska + - Rihava + - Rihaxicre + - Rihekrekrek + - Rihipapar + - Rihrachepi + - Rihravatir + - Rikevra + - Rikipa + - Rikiskapipi + - Rikivrevra + - Rikrachi + - Rikrepa + - Rikreravribe + - Ripibivrir + - Ripihrepapa + - Ripreshikre + - Rirevi + - Riribebe + - Riribeska + - Riricheshe + - Riricrehra + - Riricriti + - Ririhari + - Ririhepreski + - Ririhite + - Ririhixir + - Ririkavrire + - Ririkeve + - Ririkrekaska + - Ririkrexeti + - Riripasha + - Riripraprapi + - Ririrarerera + - Riririhacha + - Ririshihi + - Ririskatre + - Ririskihe + - Ririskiri + - Ririsravra + - Riritihihit + - Riritiskaba + - Rirititahi + - Riritrebi + - Riritrexexek + - Ririvihrar + - Ririvreshiya + - Ririvretra + - Ririyaskihe + - Rishacriker + - Rishaskar + - Rishepi + - Riskavrer + - Riskekar + - Riskepriba + - Riskesre + - Riskirasre + - Riskiskeha + - Risratretete + - Risratrihihi + - Risrevre + - Risritracre + - Risrivire + - Ritaha + - Ritahrecra + - Ritekrakapre + - Riteva + - Ritresrakri + - Ritrihe + - Ritrirecra + - Ritrishixi + - Rivretripapa + - Rivrivrishi + - Rixahritri + - Rixaterete + - Rixecrekre + - Rixepapat + - Rixeti + - Rixibihrihri + - Rixiskirepri + - Rixixaxavrat + - Riyahrahrat + - Riyapare + - Riyasri + - Shabirivri + - Shachikir + - Shacrevavak + - Shacrevrake + - Shahaprahri + - Shahaxaxak + - Shahekeket + - Shaheskate + - Shahexer + - Shahrasher + - Shahrati + - Shahripracri + - Shakekrirabe + - Shakrichar + - Shapesrikaka + - Shapibi + - Shapretra + - Sharapire + - Sharesrasrat + - Sharihesrehi + - Sharihre + - Sharipiva + - Sharitrihri + - Shashishibe + - Shashisravi + - Shaskehepre + - Shaskepahre + - Shaskitra + - Shatretaxi + - Shavaprika + - Shavashakri + - Shavexexati + - Shavisha + - Shavrivre + - Shaxepachi + - Shayakrakrak + - Shebevrirere + - Shebipeskixa + - Shebiva + - Shecheyababa + - Shecrapricre + - Shehibe + - Shehrayashar + - Shehrebite + - Shehreha + - Shehreske + - Shehreyayar + - Shehriskar + - Shekake + - Shekakesri + - Shekapiski + - Shekeska + - Shekikakat + - Shekrira + - Shepechichik + - Shepeshesra + - Shepeskiskik + - Shepetrati + - Shepevrevrer + - Shepikitepa + - Sheprekritri + - Shepreskete + - Sherati + - Sherikre + - Sheriskahe + - Sheshasri + - Sheshihesha + - Shesrabibik + - Shesrachiski + - Shesrihihit + - Shetachavre + - Shetasre + - Shetikitata + - Shetracrar + - Shetriha + - Shevabi + - Shevecrepi + - Shevrahe + - Shevrevri + - Shevriya + - Shexachi + - Shexahrehret + - Shexecra + - Shexishishit + - Shexivir + - Sheyasha + - Shibatra + - Shibecreka + - Shibekrekret + - Shibivribe + - Shichebebet + - Shichecha + - Shicheririt + - Shichikrakre + - Shicrachi + - Shihebihre + - Shihecricrik + - Shihishar + - Shihiska + - Shihrapikra + - Shihrehepri + - Shihrerebe + - Shihrevihre + - Shikechachat + - Shikeshecra + - Shikikivri + - Shikraxi + - Shikrehre + - Shikreprer + - Shipehabaske + - Shipicreki + - Shipipapaxak + - Shipratate + - Shipriki + - Shipritraha + - Shiribebepit + - Shisrisheri + - Shitehechi + - Shitexihre + - Shitibibik + - Shitravrekra + - Shivababat + - Shivexehra + - Shivive + - Shivraheki + - Shivrayayak + - Shivrebapra + - Shivrepa + - Shixaya + - Sikibavipa + - Sikibisriche + - Sikichape + - Sikichapi + - Sikichekasha + - Sikichiyaski + - Sikicracre + - Sikicrexa + - Sikicrixi + - Sikiketraya + - Sikikrasre + - Sikikreke + - Sikipecripre + - Sikipetre + - Sikiprasrake + - Sikiprira + - Sikirehivre + - Sikirepreri + - Sikiskacra + - Sikiskevavak + - Sikiskite + - Sikisraber + - Sikisrekakat + - Sikisresha + - Sikitaski + - Sikitevre + - Sikiticre + - Sikitrashate + - Sikitrihrepi + - Sikitrirepre + - Sikivate + - Sikiveskar + - Sikivrahra + - Sikivrisrita + - Sikivritiri + - Sikixicrebar + - Siribacrache + - Siribetraska + - Siribikra + - Siricharabe + - Sirihaxer + - Sirihicripa + - Sirihihahat + - Sirihihapa + - Sirikaski + - Sirikatatat + - Siripepahe + - Siriprahra + - Siriprehavi + - Siripreteske + - Siriraki + - Siriraski + - Sirirekeba + - Sirireter + - Sirishatache + - Sirishehevre + - Siriskesrave + - Siriskihipe + - Sirisrekivi + - Sirisretre + - Siriteche + - Siritrahe + - Siritrixexet + - Sirivrekehri + - Sirivretatre + - Skabaresre + - Skabehricra + - Skabipre + - Skachabeta + - Skachibi + - Skachihive + - Skachishaha + - Skacraxaxak + - Skacrehrapre + - Skacrichisre + - Skacrixiche + - Skahipevra + - Skahixahehe + - Skahracha + - Skahravrive + - Skahreve + - Skahrivrepra + - Skakasha + - Skakava + - Skakavevet + - Skakeskaskat + - Skakevravrak + - Skapape + - Skapapriprit + - Skarebihira + - Skarechachak + - Skarepishi + - Skarexapreti + - Skashihrir + - Skaterarar + - Skatetasre + - Skatrichebe + - Skavarerahri + - Skavicrecrer + - Skavitetexi + - Skavrekreti + - Skavritre + - Skaxisrakre + - Skayabere + - Skayatepra + - Skebaprara + - Skechikreba + - Skecracheker + - Skecraprir + - Skecrita + - Skehevreshe + - Skehichitra + - Skehipe + - Skekapra + - Skekekritra + - Skeketir + - Skekrababe + - Skekraxer + - Skekretake + - Skepare + - Skepitetexik + - Skerepepehit + - Skereri + - Skeripribihe + - Skeriska + - Skeshikite + - Skeskahe + - Skeskibishi + - Skesrisrer + - Sketaha + - Sketahevra + - Sketashakra + - Sketatretrek + - Sketavri + - Sketepechi + - Sketivapapa + - Sketivre + - Sketrarivava + - Sketrekrepe + - Skevaskiskik + - Skevaxi + - Skevrabari + - Skevrahrepa + - Skevrecra + - Skevrehraki + - Skevrihrave + - Skexipi + - Skexixeska + - Skibacricrit + - Skibapraxe + - Skibevravrat + - Skibiravri + - Skibita + - Skichabi + - Skichapipit + - Skichebir + - Skichiske + - Skicreraskar + - Skicrihihe + - Skihekar + - Skiheyaskir + - Skihricher + - Skikeskesket + - Skikrahre + - Skikraprara + - Skikrisha + - Skipashihre + - Skipechishi + - Skiprapra + - Skipraripi + - Skipreve + - Skiprevivik + - Skiripipik + - Skishachi + - Skishapehehe + - Skiskevaski + - Skiskevririr + - Skisrekecra + - Skitraki + - Skitrepi + - Skitreske + - Skivekri + - Skivibibik + - Skiviska + - Skivrihri + - Skivrivreki + - Skixara + - Skixareter + - Skixetihechi + - Skixiha + - Skixisrapre + - Srabavrechi + - Srabisreveke + - Srachavicha + - Sracrare + - Srahahihir + - Srahihripra + - Srahriyar + - Srakipahehe + - Srakireret + - Srakrakrishi + - Srapahre + - Srapikretra + - Srapribekehi + - Srarekepar + - Sraribeski + - Srariprer + - Srarisha + - Srashacha + - Srashakri + - Srashaxata + - Srashikirir + - Sraskabikri + - Sraskechipe + - Sraskehreri + - Sraskekepiva + - Sraskekisra + - Sraskiba + - Sraskishar + - Srasrivate + - Sratepre + - Srateve + - Sraticre + - Sratihi + - Sratiki + - Sratraxixir + - Sratrike + - Sravechachar + - Sravrapapat + - Sraxape + - Sraxepipir + - Sraxeskicri + - Srebaskaskar + - Srebecrir + - Srebekrabi + - Srebikrir + - Srechepe + - Srecravra + - Srecravre + - Srecrisre + - Srehetahi + - Srehikrar + - Srehivavri + - Srehrehiske + - Srekacrexeve + - Srekreprexe + - Srekrikra + - Srekrititit + - Srepesrexi + - Srepipritri + - Srepisrasre + - Sreprekra + - Srepreshe + - Sreracricrar + - Srerevre + - Srerihra + - Sreshebakiki + - Sresheskixi + - Sreshiprari + - Sreskichi + - Sreskicre + - Sresrahapi + - Sresrekikit + - Sresrikre + - Sretasresri + - Sretishashak + - Sretraticrir + - Srevesra + - Srevesrixari + - Srevivre + - Srevraxipi + - Srevreyayak + - Srexatreva + - Srexikrata + - Srexiskahehe + - Sribavar + - Sribebe + - Sribireke + - Srichepi + - Srichivekaka + - Sricrevepa + - Sriheshexi + - Srihrahevrir + - Srihrakratri + - Srihrekexi + - Srikasresha + - Srikiriki + - Srikratra + - Sripaba + - Sripahebevri + - Sripahre + - Sriprikacha + - Sriracricrit + - Sririhre + - Sriripre + - Srisheyaxexe + - Srishibicri + - Srishikatre + - Sriskicrixi + - Sriskihra + - Sriskisha + - Srisratreba + - Srisrebepi + - Srisrete + - Sritasker + - Sritekrikrir + - Sriteskabe + - Sritiprebe + - Sritiske + - Sritrapashe + - Sritricha + - Sritripipir + - Srivake + - Srivaxa + - Srivekater + - Srivisra + - Srivrasrer + - Srivratre + - Srivrihrir + - Srixakrabebe + - Srixiveyaya + - Sriyapir + - Taabavrivrir + - Taabexitaski + - Taabiprete + - Taachabe + - Taacrahre + - Taacrecrasra + - Taacripi + - Taacrisretri + - Taahahre + - Taahecreta + - Taaherarak + - Taahiha + - Taahiska + - Taahivri + - Taahreke + - Taahrishepri + - Taakahevava + - Taakapa + - Taakexisker + - Taakraba + - Taapavevekik + - Taapecra + - Taapikashi + - Taapipihare + - Taapishi + - Taaprachikri + - Taaprivrapre + - Taarecra + - Taareshekra + - Taashaxikir + - Taashebititi + - Taaskatir + - Taaskevevava + - Taaskiteki + - Taasrebicre + - Taasrehrira + - Taasrikikit + - Taasritar + - Taataxe + - Taatevasre + - Taatihra + - Taatrate + - Taatrivivit + - Taavape + - Taavavrexi + - Taavrerapava + - Taavretri + - Taavrivi + - Taaxekakat + - Taaxesrite + - Taaxikra + - Taayarashe + - Teebapresri + - Teebechiya + - Teebivrichi + - Teechacraha + - Teechexe + - Teechihakri + - Teecrekrihre + - Teecrepeski + - Teecretri + - Teecrevretre + - Teehapraprar + - Teeheri + - Teehrahar + - Teehrepeskir + - Teehrirepipi + - Teekahicravi + - Teekepraxahe + - Teekipra + - Teepracrivri + - Teeprikexixi + - Teeraheher + - Teerecritri + - Teeriviyara + - Teeskapesri + - Teeskebecrar + - Teesrasraxa + - Teesrecha + - Teesretrir + - Teesribiba + - Teetahra + - Teetixi + - Teetrasrer + - Teetreskapri + - Teevahihivik + - Teevapriprar + - Teevepa + - Teevravreske + - Teexaketiti + - Teexera + - Teexihrir + - Teeyakra + - Tibaskaskak + - Tibasravava + - Tibihi + - Tibixita + - Ticheskivre + - Tichetritrir + - Tichiber + - Ticratevipe + - Tihichisketi + - Tihitre + - Tihresrevivi + - Tihrikakar + - Tikara + - Tikecribe + - Tikekitata + - Tikrasra + - Tikrevrihre + - Tipape + - Tipekrihripa + - Tipetripe + - Tipicre + - Tipreritaha + - Tipresrita + - Tiprititik + - Tireper + - Tiribavre + - Tiriberihehe + - Tiribikehe + - Tiribirakeke + - Tirichera + - Tirihayaya + - Tirihi + - Tirihra + - Tirihretrir + - Tirihriririk + - Tiriketeche + - Tirikeviha + - Tirikihrer + - Tirikrachir + - Tirikrasri + - Tiripechapre + - Tiripratra + - Tiriprexer + - Tirirahi + - Tirirapahre + - Tirirarat + - Tirirexiprer + - Tirisrehihit + - Tirisribe + - Tiritetasra + - Tiritrexi + - Tiritrivever + - Tiriveshi + - Tirivihachi + - Tirivrebire + - Tirixahiri + - Tirixebayar + - Tirixetatak + - Tirixishiski + - Tiriyaskacha + - Tishetrakaka + - Tiskasheske + - Tiskevritre + - Tiskicrar + - Tisraprepret + - Tisrasheshet + - Tisreshishit + - Tisreska + - Tisricre + - Tisriskiskir + - Tisrivexa + - Titeskeskek + - Titrabetiti + - Titretepeka + - Tivarahi + - Tivecra + - Tivecri + - Tivepa + - Tivevipe + - Tivexa + - Tiviskaskak + - Tixapipripri + - Tixetritrik + - Tixikekra + - Tixititik + - Tixixesrer + - Tiyapraprak + - Tiyaskaskat + - Trabari + - Trabisrer + - Tracrecrehri + - Tracreprake + - Trahahehetir + - Trahekehe + - Trahevreske + - Trahrepa + - Trahrevrava + - Trakehre + - Trakrapra + - Trakritevrer + - Trapavrivrir + - Trareskire + - Trashete + - Trasheve + - Trashevepri + - Trashipaxe + - Trasraveski + - Trasreve + - Tratibekaka + - Tratihrer + - Tratravi + - Tratraxixik + - Tratribi + - Travaxeski + - Travetretrek + - Travraripepe + - Travribesre + - Traxipi + - Traxiprer + - Trebahe + - Trebirerever + - Trebishivava + - Trebitratrak + - Trechacra + - Trechekrasri + - Trechesre + - Trechesrecre + - Trecrehehek + - Trehixapri + - Trehrakrepre + - Trehripra + - Trekatri + - Trekatricre + - Trekavixixi + - Trekavriki + - Trekebeti + - Trekeski + - Treketibita + - Treketra + - Trekibabat + - Trepake + - Treprabiveve + - Treprahrepi + - Treprebekra + - Treprehehet + - Trerevivipek + - Treshepra + - Treshibar + - Treshipeska + - Treskari + - Tresketara + - Treskiskakir + - Tresracrir + - Tresrasker + - Tresratracre + - Tresravritre + - Tresreba + - Tresrihivri + - Tretapra + - Tretrahri + - Tretreske + - Tretrikicha + - Trevabihra + - Trevepa + - Trevetretrek + - Trevicra + - Trexatri + - Trexavra + - Trexetri + - Trexiricrara + - Treyakracra + - Treyaxihehe + - Tribexexet + - Tribirekri + - Trichakripre + - Trichiski + - Tricracri + - Tricrekapa + - Tricripe + - Trihavever + - Trihera + - Trihexisra + - Trihicrecrek + - Trihitrar + - Tripesrishe + - Tripever + - Triprakraxi + - Triprakri + - Trirahecri + - Trirapraxar + - Trireche + - Trishakretra + - Trishecrexir + - Trishepi + - Trishisrar + - Triskavri + - Trisketir + - Triskiyayat + - Trisrachiri + - Trisrevre + - Trisrisri + - Trisrisriper + - Trisrite + - Tritetre + - Tritrakepre + - Tritrichatri + - Tritriskari + - Trivriskeki + - Trivritipipi + - Trivriyayak + - Trixihahar + - Trixitri + - Triyashekiki + - Vabahecre + - Vabahrabebe + - Vabebir + - Vabehetre + - Vabetrahacha + - Vabivri + - Vachahrirere + - Vachavri + - Vachekihri + - Vachicratata + - Vachiske + - Vacracreki + - Vacrebihi + - Vacripra + - Vahapapashek + - Vahapraxe + - Vahasker + - Vaherekiki + - Vahibebeprek + - Vahivihahe + - Vakaheva + - Vakecha + - Vakevixixi + - Vakikepripra + - Vapeyayak + - Vapikevra + - Vapipribe + - Vaprakakak + - Vaprisra + - Vapritasha + - Varebitacre + - Varekricreki + - Vashakrikrik + - Vaskexititi + - Vaskiprexi + - Vaskivri + - Vaskiyahi + - Vasraprikre + - Vasrevi + - Vatracraxixi + - Vatrevi + - Vatriva + - Vavehihisrek + - Vavrisrasri + - Vaxeki + - Vaxeraskeske + - Vebexaxat + - Vebicheta + - Vechecricrik + - Vecraxicra + - Vecriche + - Vecritrika + - Vehevrer + - Vehratrir + - Vehraxexek + - Vehritrexe + - Vekarasra + - Vekaxivivi + - Vekehribaba + - Vekirevi + - Vekracri + - Vekreka + - Vekrekrikrit + - Vekrerikra + - Vekrishar + - Vekrishicha + - Vepekre + - Veprahahat + - Veprechahri + - Veprecrar + - Veprecrecrek + - Vepreritare + - Veretitishit + - Vericharihra + - Verikisresre + - Veshacricrik + - Veshebixexe + - Veshecrihapi + - Veshehe + - Veshepreprek + - Veshishakra + - Veskapi + - Veskepayaya + - Veskepevra + - Vesrihiska + - Vetepeti + - Vetracripi + - Vetreshashat + - Vetriskira + - Vevatre + - Vevevre + - Vevivesha + - Vevreshir + - Vevricrecrek + - Vevrisrasrat + - Vexachebashi + - Vexavever + - Vexikar + - Vexisrecri + - Vibepraxaba + - Vibeta + - Vichehiriri + - Vichitribihe + - Vicrahrehrek + - Vicrevevre + - Vicrikre + - Vicripasre + - Vicritebaba + - Vicriviriki + - Viheche + - Vihecracheki + - Vihepra + - Vihratekra + - Vihrexahihi + - Vihribihiska + - Vihricra + - Vihriher + - Vihriprar + - Vihrisreher + - Vikahrekri + - Vikakehreri + - Vikavebari + - Vikekiski + - Vikihahre + - Vikitrexa + - Vikrebibit + - Vikrihi + - Vikritahahe + - Vipeskixa + - Vipravrakrar + - Viprevrar + - Virabebevrek + - Viratrerera + - Virepri + - Viriprixiche + - Virirevrare + - Viritritrik + - Viskeski + - Visrecrecret + - Visriskir + - Vitexexet + - Vitibibihrik + - Vitika + - Vitracrevi + - Vitrasheshek + - Vitraviketa + - Vitravrire + - Vitreskaskak + - Vitrisrasha + - Vitrivechere + - Vivashate + - Vivecrixexe + - Viveprehehe + - Viveprepe + - Vivixixihir + - Vivrashaya + - Vixiticrixi + - Vrabaprakaka + - Vrabikape + - Vracharitri + - Vrachishachi + - Vrachitasre + - Vracrebihehe + - Vraheska + - Vrahrehripre + - Vrakasrahi + - Vrakayasraxi + - Vrakebibit + - Vrakriperi + - Vrakritatat + - Vrapaheke + - Vrapresriki + - Vraprexave + - Vrarekikik + - Vrarihritete + - Vraripechi + - Vrashexa + - Vraskekaki + - Vraskevexar + - Vrasrehahar + - Vrasreshahi + - Vratavivit + - Vratevretra + - Vratrakere + - Vratreskevi + - Vratrite + - Vratrivar + - Vravabepra + - Vravacrahri + - Vravavra + - Vravexe + - Vraviveya + - Vravrache + - Vraxihihit + - Vrayavri + - Vrebehrihrik + - Vrebisra + - Vrecrarake + - Vrecrihri + - Vrehabi + - Vrehacre + - Vrehakatar + - Vrehasker + - Vrehecreri + - Vrehibehe + - Vrehibibipik + - Vrehipe + - Vrehipraprak + - Vrehriviche + - Vrekahrichi + - Vrekihrer + - Vrekipepet + - Vrekrixa + - Vrepate + - Vrepexexer + - Vreprehapre + - Vreprihrite + - Vrererikra + - Vrerikriskir + - Vreshabar + - Vreshihishar + - Vreshike + - Vreskatre + - Vresrasre + - Vresretatra + - Vretesravi + - Vretixixir + - Vretrapapar + - Vretrehivivi + - Vretricre + - Vrevahrir + - Vrevashixexe + - Vrevrekrer + - Vrexacracrat + - Vrexaker + - Vribetretret + - Vribipita + - Vribiprevite + - Vricrehakra + - Vricrihi + - Vricriskeche + - Vrihehra + - Vriheski + - Vrihrakre + - Vrihrekrepi + - Vrikayaba + - Vrikivresker + - Vrikrake + - Vrikrebacre + - Vrikresrasri + - Vripere + - Vripexavri + - Vripitikeske + - Vriprivra + - Vrirachesri + - Vririsha + - Vrisketaske + - Vriskiraxe + - Vriskire + - Vrisracrakri + - Vrisrekari + - Vrisreviki + - Vritasre + - Vriterepi + - Vritetrexa + - Vritika + - Vritiske + - Vritivraki + - Vritrihrar + - Vritrisre + - Vrivahi + - Vrivahishaya + - Vrivehatri + - Vrivitri + - Vrixashashar + - Vrixavribape + - Vrixeprir + - Vrixiprehre + - Vrixitreveki + - Vrixivraxe + - Xabishetra + - Xachivrivrit + - Xacripikar + - Xacriprixi + - Xacrivir + - Xahatavri + - Xahesketivri + - Xahrapaba + - Xahraprer + - Xahrebave + - Xahripavava + - Xakahri + - Xakayayakat + - Xakrevaratra + - Xapakra + - Xapikrikrik + - Xapipevrevre + - Xapraskapika + - Xaprate + - Xapravri + - Xapripraprar + - Xaracrivri + - Xaratripepe + - Xarebiya + - Xareva + - Xariheheprat + - Xashihapa + - Xaskakaba + - Xaskararater + - Xasrapipik + - Xasreskihibi + - Xatachasri + - Xatereret + - Xatiriskiski + - Xatrexixik + - Xavasrarihi + - Xaveshi + - Xavicrari + - Xavrahavri + - Xavricri + - Xavrire + - Xavrixecre + - Xaxikaxexe + - Xaxikresha + - Xaxiska + - Xayaskihri + - Xebechi + - Xebetetet + - Xebitretrek + - Xechacrecrek + - Xechibare + - Xecrixaxitre + - Xehekikir + - Xehetipe + - Xehichatavra + - Xehiprishe + - Xehiteche + - Xehrevrakre + - Xehrishe + - Xekerarivra + - Xekicra + - Xekrecri + - Xekrevri + - Xekrevripa + - Xepavikeba + - Xepehati + - Xepeter + - Xepetitipet + - Xeprasre + - Xeprekivra + - Xeprihehek + - Xeshachikaha + - Xeskapakre + - Xeskehrabe + - Xesribar + - Xetekir + - Xetraskesket + - Xetravivik + - Xetrexahihi + - Xetribirer + - Xetripi + - Xevetaske + - Xevratikepa + - Xevriya + - Xexapra + - Xexavi + - Xexibir + - Xexiski + - Xeyapre + - Xeyaribe + - Xeyaskapibe + - Xibecracrak + - Xibeha + - Xibepribe + - Xibitratrar + - Xihechevar + - Xihrahehete + - Xihrashehihi + - Xihrecreve + - Xihresra + - Xihrivever + - Xikabebet + - Xikahihi + - Xikashaxe + - Xikaske + - Xikepehrahra + - Xikicha + - Xikrahrihrik + - Xikrakipi + - Xikreshe + - Xikreska + - Xikrexiva + - Xikrihe + - Xikripar + - Xipahihik + - Xipita + - Xiprahahatek + - Xirechiske + - Xireshishit + - Xiribakrivi + - Xirichare + - Xirichebacra + - Xirichiter + - Xiricraki + - Xirihacrir + - Xirihiske + - Xirihiyatape + - Xirihrekakar + - Xirihretecre + - Xirihriti + - Xirikesrirer + - Xiriketi + - Xiripape + - Xiririhecher + - Xiririke + - Xiriripatibe + - Xirishepivre + - Xirishexi + - Xiriskapa + - Xirisketa + - Xiriskicreha + - Xirisrevre + - Xirisricreva + - Xiritracre + - Xiritreprer + - Xiritretrar + - Xirivetrikra + - Xirivexicri + - Xirivre + - Xirivrehra + - Xirixekrari + - Xishahrixixi + - Xishatre + - Xishehraxaxa + - Xishikra + - Xiskatreka + - Xiskeche + - Xiskehrahar + - Xiskicratake + - Xiskiririr + - Xisrecracrak + - Xisreva + - Xisritetet + - Xitachabibi + - Xitachixaxa + - Xitariritak + - Xitebehrer + - Xitreprecri + - Xivavraxexe + - Xiveski + - Xivivri + - Xivrahrare + - Xivrakrakrak + - Xivrihihicra + - Xixaxekaka + - Xixecra + - Xixiche diff --git a/Resources/Prototypes/Entities/Mobs/Species/vox.yml b/Resources/Prototypes/Entities/Mobs/Species/vox.yml index e17b2f70805..184711ec1e5 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/vox.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/vox.yml @@ -8,105 +8,45 @@ - type: Icon sprite: Mobs/Species/Vox/parts.rsi state: vox_m - - type: Sprite - layers: - - map: [ "enum.HumanoidVisualLayers.Chest" ] - sprite: Mobs/Species/Vox/parts.rsi - state: torso_m - - map: [ "enum.HumanoidVisualLayers.Head" ] - sprite: Mobs/Species/Vox/parts.rsi - state: head_m - - map: [ "enum.HumanoidVisualLayers.Eyes" ] - color: "#008800" - sprite: Mobs/Customization/eyes.rsi - state: vox_eyes_s - - map: [ "enum.HumanoidVisualLayers.RArm" ] - sprite: Mobs/Species/Vox/parts.rsi - state: r_arm - - map: [ "enum.HumanoidVisualLayers.LArm" ] - sprite: Mobs/Species/Vox/parts.rsi - state: l_arm - - map: [ "enum.HumanoidVisualLayers.RLeg" ] - sprite: Mobs/Species/Vox/parts.rsi - state: r_leg - - map: [ "enum.HumanoidVisualLayers.LLeg" ] - sprite: Mobs/Species/Vox/parts.rsi - state: l_leg - # Vox don't have female clothing masks. - #- shader: StencilClear - # sprite: Mobs/Species/Vox/parts.rsi - # state: l_leg - #- shader: StencilMask - # map: [ "enum.HumanoidVisualLayers.FemaleStencilMask" ] - # sprite: Mobs/Customization/masking_helpers.rsi - # state: female_full - # visible: false - #- map: [ "jumpsuit" ] - # shader: StencilDraw - - map: [ "enum.HumanoidVisualLayers.LHand" ] - sprite: Mobs/Species/Vox/parts.rsi - state: l_hand - - map: [ "enum.HumanoidVisualLayers.RHand" ] - sprite: Mobs/Species/Vox/parts.rsi - state: r_hand - - map: [ "enum.HumanoidVisualLayers.LFoot" ] - sprite: Mobs/Species/Vox/parts.rsi - state: l_foot - - map: [ "enum.HumanoidVisualLayers.RFoot" ] - sprite: Mobs/Species/Vox/parts.rsi - state: r_foot - - map: [ "enum.HumanoidVisualLayers.Handcuffs" ] - color: "#ffffff" - sprite: Objects/Misc/handcuffs.rsi - state: body-overlay-2 - visible: false - - map: [ "gloves" ] - - map: [ "shoes" ] - - map: [ "ears" ] - - map: [ "outerClothing" ] - - map: [ "eyes" ] - - map: [ "belt" ] - - map: [ "id" ] - - map: [ "neck" ] - - map: [ "back" ] - - map: [ "enum.HumanoidVisualLayers.FacialHair" ] - state: shaved - sprite: Mobs/Customization/human_facial_hair.rsi - - map: [ "enum.HumanoidVisualLayers.Hair" ] - state: bald - sprite: Mobs/Customization/human_hair.rsi - - map: [ "mask" ] - - map: [ "head" ] - - map: [ "pocket1" ] - - map: [ "pocket2" ] - type: Body prototype: Vox requiredLegs: 2 - # Vox nitrogen stuff is handled in their metabolism - - type: Respirator - damage: - types: - Asphyxiation: 2 - damageRecovery: - types: - Asphyxiation: -1.0 - type: HumanoidAppearance species: Vox - # canColorHair: false - # canColorFacialHair: false - - type: Inventory - speciesId: vox - - type: InventorySlots - - type: Butcherable - butcheringType: Spike - spawned: - - id: FoodMeatChicken - amount: 5 + #- type: VoxAccent # Not yet coded + - type: Speech + speechVerb: Vox + speechSounds: Vox + - type: TypingIndicator + proto: vox - type: Vocal sounds: Male: UnisexVox Female: UnisexVox Unsexed: UnisexVox + - type: Butcherable + butcheringType: Spike + spawned: + - id: FoodMeatChicken + amount: 5 + - type: Damageable + damageContainer: Biological + damageModifierSet: Vox + - type: DamageVisuals + damageOverlayGroups: + Brute: + sprite: Mobs/Effects/brute_damage.rsi + color: "#7a8bf2" + - type: Bloodstream + bloodReagent: AmmoniaBlood + - type: MeleeWeapon + soundHit: + path: /Audio/Weapons/pierce.ogg + angle: 30 + animation: WeaponArcClaw + damage: + types: + Slash: 5 # Reduce? - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Prototypes/Reagents/biological.yml b/Resources/Prototypes/Reagents/biological.yml index d29d5f7e4da..ce3d0a04637 100644 --- a/Resources/Prototypes/Reagents/biological.yml +++ b/Resources/Prototypes/Reagents/biological.yml @@ -91,6 +91,18 @@ physicalDesc: reagent-physical-desc-ferrous slippery: false +- type: reagent + parent: Blood + id: AmmoniaBlood + name: reagent-name-ammonia-blood + group: Biological + desc: reagent-desc-ammonia-blood + flavor: bitter + color: "#7a8bf2" + recognizable: true + physicalDesc: reagent-physical-desc-pungent + slippery: false + - type: reagent id: ZombieBlood name: reagent-name-zombie-blood @@ -183,4 +195,4 @@ footstepSound: collection: FootstepBlood params: - volume: 6 \ No newline at end of file + volume: 6 diff --git a/Resources/Prototypes/Species/vox.yml b/Resources/Prototypes/Species/vox.yml index 482997a1068..605087a687b 100644 --- a/Resources/Prototypes/Species/vox.yml +++ b/Resources/Prototypes/Species/vox.yml @@ -1,12 +1,18 @@ - type: species id: Vox - name: Vox + name: species-name-vox roundStart: false # sad... prototype: MobVox sprites: MobVoxSprites markingLimits: MobVoxMarkingLimits dollPrototype: MobVoxDummy skinColoration: Hues + maleFirstNames: names_vox + femaleFirstNames: names_vox + naming: First + sexes: + - Unsexed + - type: speciesBaseSprites id: MobVoxSprites diff --git a/Resources/Prototypes/Voice/speech_emote_sounds.yml b/Resources/Prototypes/Voice/speech_emote_sounds.yml index f6b630e5c00..8df129f7869 100644 --- a/Resources/Prototypes/Voice/speech_emote_sounds.yml +++ b/Resources/Prototypes/Voice/speech_emote_sounds.yml @@ -157,10 +157,14 @@ - type: emoteSounds id: UnisexVox - sound: - path: /Audio/Voice/Vox/shriek1.ogg - params: - variation: 0.125 + sounds: + Scream: + path: /Audio/Voice/Vox/shriek1.ogg + Laugh: + path: /Audio/Voice/Vox/vox_laugh.ogg + params: + variation: 0.125 + # We need vox sounds for the other emotes - type: emoteSounds id: UnisexDiona diff --git a/Resources/Prototypes/Voice/speech_sounds.yml b/Resources/Prototypes/Voice/speech_sounds.yml index abe6a831029..eb47b5363b6 100644 --- a/Resources/Prototypes/Voice/speech_sounds.yml +++ b/Resources/Prototypes/Voice/speech_sounds.yml @@ -88,6 +88,15 @@ exclaimSound: path: /Audio/Voice/Talk/slime_exclaim.ogg +- type: speechSounds + id: Vox + saySound: + path: /Audio/Voice/Talk/vox.ogg + askSound: + path: /Audio/Voice/Talk/vox_ask.ogg + exclaimSound: + path: /Audio/Voice/Talk/vox_exclaim.ogg + - type: speechSounds id: Arachnid saySound: @@ -105,7 +114,7 @@ path: /Audio/Animals/cat_meow.ogg exclaimSound: path: /Audio/Animals/cat_meow.ogg - + - type: speechSounds id: Dog saySound: @@ -113,4 +122,4 @@ askSound: path: /Audio/Animals/dog_bark3.ogg exclaimSound: - path: /Audio/Animals/dog_bark2.ogg \ No newline at end of file + path: /Audio/Animals/dog_bark2.ogg diff --git a/Resources/Prototypes/Voice/speech_verbs.yml b/Resources/Prototypes/Voice/speech_verbs.yml index b849a32a548..1cdda32ece1 100644 --- a/Resources/Prototypes/Voice/speech_verbs.yml +++ b/Resources/Prototypes/Voice/speech_verbs.yml @@ -74,6 +74,13 @@ - chat-speech-verb-slime-2 - chat-speech-verb-slime-3 +- type: speechVerb + id: Vox + speechVerbStrings: + - chat-speech-verb-vox-1 + - chat-speech-verb-vox-2 + - chat-speech-verb-vox-3 + - type: speechVerb id: Plant speechVerbStrings: diff --git a/Resources/Prototypes/typing_indicator.yml b/Resources/Prototypes/typing_indicator.yml index 3a0484fc0b3..7271770ef50 100644 --- a/Resources/Prototypes/typing_indicator.yml +++ b/Resources/Prototypes/typing_indicator.yml @@ -34,6 +34,11 @@ typingState: spider0 offset: 0, 0.125 +- type: typingIndicator + id: vox + typingState: vox0 + offset: -0.125, 0.125 + - type: typingIndicator id: lizard typingState: lizard0 diff --git a/Resources/Textures/Effects/speech.rsi/meta.json b/Resources/Textures/Effects/speech.rsi/meta.json index 65d5615b3e3..98dd3b20607 100644 --- a/Resources/Textures/Effects/speech.rsi/meta.json +++ b/Resources/Textures/Effects/speech.rsi/meta.json @@ -411,6 +411,17 @@ }, { "name": "spider2" + }, + { + "name": "vox0", + "delays": [ + [ + 0.3, + 0.3, + 0.3, + 0.4 + ] + ] } ] } diff --git a/Resources/Textures/Effects/speech.rsi/vox0.png b/Resources/Textures/Effects/speech.rsi/vox0.png new file mode 100644 index 0000000000000000000000000000000000000000..d4640b8f3518fdbf677e0ba827da2808f908f775 GIT binary patch literal 411 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9GGLLkg|>2BR01_nl7 zPZ!6KinzD89Qh79h#dR4az{e}mu(|Ur|iZevFh+7bE3+ z*`)n*m;L(scUi4iK2vH0OrTqHOw>gSdH3n~{UlBX1aY?}L(|zsV zwtpTMTDm83?E4fQ)cU&u1;r^V|RYrvELG^|Kv()jxH=x3Xssxc78&J;T+@+VWnuZ$FmSK93fE zzKMUz-6`*DvNil%7#LXu9Iz1!BAHr0PJ8`x&&h{Y^ZzowN literal 0 HcmV?d00001 diff --git a/RobustToolbox b/RobustToolbox index e7beb2032b0..9e0fc7017c4 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit e7beb2032b05f629ffddf1ba48f4aefbc7f0b628 +Subproject commit 9e0fc7017c4740b6bc8302cb724dc7c3b60b3299 From 42f43e95a5fae267968a5b91452edd5ffbc3cdb1 Mon Sep 17 00:00:00 2001 From: wafehling Date: Wed, 14 Feb 2024 06:22:41 +0100 Subject: [PATCH 117/200] Balanced ChemVend Stock (#25207) --- .../VendingMachines/Inventories/chemvend.yml | 65 +++++++++---------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/chemvend.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/chemvend.yml index 6af9dd81dcd..78386af931a 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/chemvend.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/chemvend.yml @@ -2,62 +2,57 @@ id: ChemVendInventory startingInventory: Jug: 4 -## Delta V - begin jug adjustments, see rebase PR #53 JugAluminium: 2 - JugCarbon: 8 - JugChlorine: 3 + JugCarbon: 4 + JugChlorine: 1 JugCopper: 2 JugEthanol: 2 - JugFluorine: 2 - JugHydrogen: 4 - JugIodine: 2 - JugIron: 4 + JugFluorine: 1 + JugHydrogen: 3 + JugIodine: 1 + JugIron: 2 JugLithium: 2 - JugMercury: 2 - JugNitrogen: 5 - JugOxygen: 6 - JugPhosphorus: 5 - JugPotassium: 5 - JugRadium: 4 - JugSilicon: 5 - JugSodium: 4 - JugSugar: 5 - JugSulfur: 2 -## Delta V - end change of jug adjustments + JugMercury: 1 + JugNitrogen: 3 + JugOxygen: 3 + JugPhosphorus: 1 + JugPotassium: 2 + JugRadium: 1 + JugSilicon: 2 + JugSodium: 2 + JugSugar: 3 + JugSulfur: 1 emaggedInventory: - ToxinChemistryBottle: 6 # Delta V - changed from 1 -> 6 - # DeltaV - Added other chems from emagging chem dispenser - EpinephrineChemistryBottle: 6 - NapalmChemistryBottle: 6 - UltravasculineChemistryBottle: 6 + ToxinChemistryBottle: 1 - type: vendingMachineInventory id: ChemVendInventorySyndicate startingInventory: Jug: 4 JugAluminium: 2 - JugCarbon: 2 - JugChlorine: 2 + JugCarbon: 4 + JugChlorine: 1 JugCopper: 2 JugEthanol: 2 - JugFluorine: 2 - JugHydrogen: 2 - JugIodine: 2 + JugFluorine: 1 + JugHydrogen: 3 + JugIodine: 1 JugIron: 2 JugLithium: 2 - JugMercury: 2 - JugNitrogen: 2 - JugOxygen: 2 - JugPhosphorus: 2 + JugMercury: 1 + JugNitrogen: 3 + JugOxygen: 3 + JugPhosphorus: 1 JugPotassium: 2 - JugRadium: 2 + JugRadium: 1 JugSilicon: 2 JugSodium: 2 - JugSugar: 2 - JugSulfur: 2 + JugSugar: 3 + JugSulfur: 1 JugWeldingFuel: 1 emaggedInventory: PaxChemistryBottle: 3 MuteToxinChemistryBottle: 3 LeadChemistryBottle: 2 ToxinChemistryBottle: 1 + From e6628cfadca1a83760148752c1a96e567b661474 Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Tue, 13 Feb 2024 21:25:59 -0800 Subject: [PATCH 118/200] Ranged Holosigns (#25120) * Changed holo signs to be ranged and used on click rather than Z. * Updated comments * Failed attempt at ignoring walls * Getting rid of unused libraries --------- Co-authored-by: Plykiya (cherry picked from commit e6c21d66fae707bb3e31663e57ca0901fc200130) --- Content.Server/Holosign/HolosignSystem.cs | 25 +++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/Content.Server/Holosign/HolosignSystem.cs b/Content.Server/Holosign/HolosignSystem.cs index f0fc3bbe142..c52272e957f 100644 --- a/Content.Server/Holosign/HolosignSystem.cs +++ b/Content.Server/Holosign/HolosignSystem.cs @@ -1,19 +1,21 @@ -using Content.Shared.Interaction.Events; using Content.Shared.Examine; using Content.Shared.Coordinates.Helpers; using Content.Server.Power.Components; using Content.Server.PowerCell; +using Content.Shared.Interaction; namespace Content.Server.Holosign; public sealed class HolosignSystem : EntitySystem { [Dependency] private readonly PowerCellSystem _powerCell = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; + public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnUse); + SubscribeLocalEvent(OnBeforeInteract); SubscribeLocalEvent(OnExamine); } @@ -36,16 +38,21 @@ private void OnExamine(EntityUid uid, HolosignProjectorComponent component, Exam } } - private void OnUse(EntityUid uid, HolosignProjectorComponent component, UseInHandEvent args) + private void OnBeforeInteract(EntityUid uid, HolosignProjectorComponent component, BeforeRangedInteractEvent args) { - if (args.Handled || - !_powerCell.TryGetBatteryFromSlot(uid, out var battery) || - !battery.TryUseCharge(component.ChargeUse)) + + if (args.Handled + || !args.CanReach // prevent placing out of range + || !_powerCell.TryUseCharge(uid, component.ChargeUse) // if no battery or no charge, doesn't work + ) return; - // TODO: Too tired to deal - var holo = EntityManager.SpawnEntity(component.SignProto, Transform(args.User).Coordinates.SnapToGrid(EntityManager)); - Transform(holo).Anchored = true; + // places the holographic sign at the click location, snapped to grid. + // overlapping of the same holo on one tile remains allowed to allow holofan refreshes + var holoUid = EntityManager.SpawnEntity(component.SignProto, args.ClickLocation.SnapToGrid(EntityManager)); + var xform = Transform(holoUid); + if (!xform.Anchored) + _transform.AnchorEntity(holoUid, xform); // anchor to prevent any tempering with (don't know what could even interact with it) args.Handled = true; } From 578522b579d2ad0e0a342efa35089ed3c5b0deb1 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 14 Feb 2024 05:27:08 +0000 Subject: [PATCH 119/200] Automatic changelog update (cherry picked from commit 159eadebc8375c71ddc236afd59367adda0c358b) --- 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 903ecc1b7da..65d9aa381af 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,5 @@ Order: 1 Entries: -- author: joshepvodka - changes: - - message: NanoTrasen updated the designs for their emergency medipens. Space medipens - are now magenta colored and epi pens have a green band on them. - type: Tweak - id: 5439 - time: '2023-12-21T05:30:58.0000000+00:00' - url: null - author: Hqlle changes: - message: Resprited carpet sprites. @@ -3883,3 +3875,10 @@ Order: 1 id: 5938 time: '2024-02-14T01:14:51.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/23262 +- author: Plykiya + changes: + - message: Holosigns can now be placed at range. No more being eaten by forcefields! + type: Tweak + id: 5939 + time: '2024-02-14T05:25:59.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25120 From 2cf99bd6a94a5dce8a59ad205ae9d9ad24970730 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Wed, 14 Feb 2024 18:14:40 +1100 Subject: [PATCH 120/200] Minor test fixes (#25174) Stuff that probably shoulda been wrapped ig but our test runner stinky. (cherry picked from commit 212c8b2b46a5f0e3a3280b8a94e3c2eeb59942db) --- .../Construction/ConstructionActionValid.cs | 52 +++++++++------- .../Construction/ConstructionPrototypeTest.cs | 62 ++++++++++++------- 2 files changed, 69 insertions(+), 45 deletions(-) diff --git a/Content.IntegrationTests/Tests/Construction/ConstructionActionValid.cs b/Content.IntegrationTests/Tests/Construction/ConstructionActionValid.cs index 408b0e0bd03..c59b42d6389 100644 --- a/Content.IntegrationTests/Tests/Construction/ConstructionActionValid.cs +++ b/Content.IntegrationTests/Tests/Construction/ConstructionActionValid.cs @@ -55,33 +55,36 @@ public async Task ConstructionGraphSpawnPrototypeValid() var valid = true; var message = new StringBuilder(); - foreach (var graph in protoMan.EnumeratePrototypes()) + await server.WaitPost(() => { - foreach (var node in graph.Nodes.Values) + foreach (var graph in protoMan.EnumeratePrototypes()) { - foreach (var action in node.Actions) + foreach (var node in graph.Nodes.Values) { - if (IsValid(action, protoMan, out var prototype)) continue; - - valid = false; - message.Append($"Invalid entity prototype \"{prototype}\" on graph action in node \"{node.Name}\" of graph \"{graph.ID}\"\n"); - } - - foreach (var edge in node.Edges) - { - foreach (var action in edge.Completed) + foreach (var action in node.Actions) { if (IsValid(action, protoMan, out var prototype)) continue; valid = false; - message.Append($"Invalid entity prototype \"{prototype}\" on graph action in edge \"{edge.Target}\" of node \"{node.Name}\" of graph \"{graph.ID}\"\n"); + message.Append($"Invalid entity prototype \"{prototype}\" on graph action in node \"{node.Name}\" of graph \"{graph.ID}\"\n"); + } + + foreach (var edge in node.Edges) + { + foreach (var action in edge.Completed) + { + if (IsValid(action, protoMan, out var prototype)) continue; + + valid = false; + message.Append($"Invalid entity prototype \"{prototype}\" on graph action in edge \"{edge.Target}\" of node \"{node.Name}\" of graph \"{graph.ID}\"\n"); + } } } } - } - await pair.CleanReturnAsync(); + }); Assert.That(valid, Is.True, $"One or more SpawnPrototype actions specified invalid entity prototypes!\n{message}"); + await pair.CleanReturnAsync(); } [Test] @@ -95,19 +98,24 @@ public async Task ConstructionGraphEdgeValid() var valid = true; var message = new StringBuilder(); - foreach (var graph in protoMan.EnumeratePrototypes()) + await server.WaitPost(() => { - foreach (var node in graph.Nodes.Values) + foreach (var graph in protoMan.EnumeratePrototypes()) { - foreach (var edge in node.Edges) + foreach (var node in graph.Nodes.Values) { - if (graph.Nodes.ContainsKey(edge.Target)) continue; + foreach (var edge in node.Edges) + { + if (graph.Nodes.ContainsKey(edge.Target)) + continue; - valid = false; - message.Append($"Invalid target \"{edge.Target}\" in edge on node \"{node.Name}\" of graph \"{graph.ID}\"\n"); + valid = false; + message.Append( + $"Invalid target \"{edge.Target}\" in edge on node \"{node.Name}\" of graph \"{graph.ID}\"\n"); + } } } - } + }); Assert.That(valid, Is.True, $"One or more edges specified invalid node targets!\n{message}"); await pair.CleanReturnAsync(); diff --git a/Content.IntegrationTests/Tests/Construction/ConstructionPrototypeTest.cs b/Content.IntegrationTests/Tests/Construction/ConstructionPrototypeTest.cs index 01173c9660f..d3a10dcfaf4 100644 --- a/Content.IntegrationTests/Tests/Construction/ConstructionPrototypeTest.cs +++ b/Content.IntegrationTests/Tests/Construction/ConstructionPrototypeTest.cs @@ -58,13 +58,17 @@ public async Task TestStartIsValid() var protoMan = server.ResolveDependency(); - foreach (var proto in protoMan.EnumeratePrototypes()) + await server.WaitAssertion(() => { - var start = proto.StartNode; - var graph = protoMan.Index(proto.Graph); + foreach (var proto in protoMan.EnumeratePrototypes()) + { + var start = proto.StartNode; + var graph = protoMan.Index(proto.Graph); - Assert.That(graph.Nodes.ContainsKey(start), $"Found no startNode \"{start}\" on graph \"{graph.ID}\" for construction prototype \"{proto.ID}\"!"); - } + Assert.That(graph.Nodes.ContainsKey(start), + $"Found no startNode \"{start}\" on graph \"{graph.ID}\" for construction prototype \"{proto.ID}\"!"); + } + }); await pair.CleanReturnAsync(); } @@ -76,13 +80,17 @@ public async Task TestTargetIsValid() var protoMan = server.ResolveDependency(); - foreach (var proto in protoMan.EnumeratePrototypes()) + await server.WaitAssertion(() => { - var target = proto.TargetNode; - var graph = protoMan.Index(proto.Graph); + foreach (var proto in protoMan.EnumeratePrototypes()) + { + var target = proto.TargetNode; + var graph = protoMan.Index(proto.Graph); - Assert.That(graph.Nodes.ContainsKey(target), $"Found no targetNode \"{target}\" on graph \"{graph.ID}\" for construction prototype \"{proto.ID}\"!"); - } + Assert.That(graph.Nodes.ContainsKey(target), + $"Found no targetNode \"{target}\" on graph \"{graph.ID}\" for construction prototype \"{proto.ID}\"!"); + } + }); await pair.CleanReturnAsync(); } @@ -92,7 +100,6 @@ public async Task DeconstructionIsValid() await using var pair = await PoolManager.GetServerClient(); var server = pair.Server; - var entMan = server.ResolveDependency(); var protoMan = server.ResolveDependency(); var compFact = server.ResolveDependency(); @@ -126,22 +133,31 @@ public async Task TestStartReachesValidTarget() var protoMan = server.ResolveDependency(); var entMan = server.ResolveDependency(); - foreach (var proto in protoMan.EnumeratePrototypes()) + await server.WaitAssertion(() => { - var start = proto.StartNode; - var target = proto.TargetNode; - var graph = protoMan.Index(proto.Graph); + foreach (var proto in protoMan.EnumeratePrototypes()) + { + var start = proto.StartNode; + var target = proto.TargetNode; + var graph = protoMan.Index(proto.Graph); #pragma warning disable NUnit2045 // Interdependent assertions. - Assert.That(graph.TryPath(start, target, out var path), $"Unable to find path from \"{start}\" to \"{target}\" on graph \"{graph.ID}\""); - Assert.That(path, Has.Length.GreaterThanOrEqualTo(1), $"Unable to find path from \"{start}\" to \"{target}\" on graph \"{graph.ID}\"."); - var next = path[0]; - var nextId = next.Entity.GetId(null, null, new(entMan)); - Assert.That(nextId, Is.Not.Null, $"The next node ({next.Name}) in the path from the start node ({start}) to the target node ({target}) must specify an entity! Graph: {graph.ID}"); - Assert.That(protoMan.TryIndex(nextId, out EntityPrototype entity), $"The next node ({next.Name}) in the path from the start node ({start}) to the target node ({target}) specified an invalid entity prototype ({nextId} [{next.Entity}])"); - Assert.That(entity.Components.ContainsKey("Construction"), $"The next node ({next.Name}) in the path from the start node ({start}) to the target node ({target}) specified an entity prototype ({next.Entity}) without a ConstructionComponent."); + Assert.That(graph.TryPath(start, target, out var path), + $"Unable to find path from \"{start}\" to \"{target}\" on graph \"{graph.ID}\""); + Assert.That(path, Has.Length.GreaterThanOrEqualTo(1), + $"Unable to find path from \"{start}\" to \"{target}\" on graph \"{graph.ID}\"."); + var next = path[0]; + var nextId = next.Entity.GetId(null, null, new(entMan)); + Assert.That(nextId, Is.Not.Null, + $"The next node ({next.Name}) in the path from the start node ({start}) to the target node ({target}) must specify an entity! Graph: {graph.ID}"); + Assert.That(protoMan.TryIndex(nextId, out EntityPrototype entity), + $"The next node ({next.Name}) in the path from the start node ({start}) to the target node ({target}) specified an invalid entity prototype ({nextId} [{next.Entity}])"); + Assert.That(entity.Components.ContainsKey("Construction"), + $"The next node ({next.Name}) in the path from the start node ({start}) to the target node ({target}) specified an entity prototype ({next.Entity}) without a ConstructionComponent."); #pragma warning restore NUnit2045 - } + } + }); + await pair.CleanReturnAsync(); } } From 20829cda9c827393f2eec69eac9b4975e155ed24 Mon Sep 17 00:00:00 2001 From: Interrobang01 <113810873+Interrobang01@users.noreply.github.com> Date: Tue, 13 Feb 2024 23:42:33 -0800 Subject: [PATCH 121/200] Add pun to diagnostic hud description (#25209) Seaborgium is element number 106 and is presumably what lets these glasses "see" "borgs". (cherry picked from commit a2ac6e417738d1c76603fa2ecd5cd49e7457fd5e) --- Resources/Prototypes/Entities/Clothing/Eyes/hud.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml b/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml index 89010ca30e0..aa1aea4df7a 100644 --- a/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml +++ b/Resources/Prototypes/Entities/Clothing/Eyes/hud.yml @@ -2,7 +2,7 @@ parent: ClothingEyesBase id: ClothingEyesHudDiagnostic name: diagnostic hud - description: A heads-up display capable of analyzing the integrity and status of robotics and exosuits. + description: A heads-up display capable of analyzing the integrity and status of robotics and exosuits. Made out of see-borg-ium. components: - type: Sprite sprite: Clothing/Eyes/Hud/diag.rsi From c3f420815f8c218dffcf238bb01b89e5fdc5a60d Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Wed, 14 Feb 2024 02:44:47 -0500 Subject: [PATCH 122/200] Add events for TemperatureProtection and PressureProtection (#25165) (cherry picked from commit 8ed32a1e42d768322ccb6dc6f5311bd58fd0dea3) --- .../Components/PressureProtectionComponent.cs | 41 +++++++++---- .../TemperatureProtectionComponent.cs | 13 +++- .../Atmos/EntitySystems/BarotraumaSystem.cs | 59 +++++++++++++++---- .../Temperature/Systems/TemperatureSystem.cs | 5 +- 4 files changed, 92 insertions(+), 26 deletions(-) diff --git a/Content.Server/Atmos/Components/PressureProtectionComponent.cs b/Content.Server/Atmos/Components/PressureProtectionComponent.cs index a3a2842159b..e1f13bca793 100644 --- a/Content.Server/Atmos/Components/PressureProtectionComponent.cs +++ b/Content.Server/Atmos/Components/PressureProtectionComponent.cs @@ -1,18 +1,33 @@ -namespace Content.Server.Atmos.Components +using Content.Server.Atmos.EntitySystems; + +namespace Content.Server.Atmos.Components; + +[RegisterComponent] +[Access(typeof(BarotraumaSystem))] +public sealed partial class PressureProtectionComponent : Component { - [RegisterComponent] - public sealed partial class PressureProtectionComponent : Component - { - [DataField("highPressureMultiplier")] - public float HighPressureMultiplier { get; private set; } = 1f; + [DataField] + public float HighPressureMultiplier = 1f; + + [DataField] + public float HighPressureModifier; - [DataField("highPressureModifier")] - public float HighPressureModifier { get; private set; } = 0f; + [DataField] + public float LowPressureMultiplier = 1f; - [DataField("lowPressureMultiplier")] - public float LowPressureMultiplier { get; private set; } = 1f; + [DataField] + public float LowPressureModifier; +} - [DataField("lowPressureModifier")] - public float LowPressureModifier { get; private set; } = 0f; - } +///

+/// Event raised on an entity with in order to adjust its default values. +/// +[ByRefEvent] +public record struct GetPressureProtectionValuesEvent +{ + public float HighPressureMultiplier; + public float HighPressureModifier; + public float LowPressureMultiplier; + public float LowPressureModifier; } + diff --git a/Content.Server/Atmos/Components/TemperatureProtectionComponent.cs b/Content.Server/Atmos/Components/TemperatureProtectionComponent.cs index 3f9d7bc7711..bdee5ff5140 100644 --- a/Content.Server/Atmos/Components/TemperatureProtectionComponent.cs +++ b/Content.Server/Atmos/Components/TemperatureProtectionComponent.cs @@ -1,11 +1,20 @@ -namespace Content.Server.Atmos.Components; +using Content.Server.Temperature.Systems; + +namespace Content.Server.Atmos.Components; [RegisterComponent] +[Access(typeof(TemperatureSystem))] public sealed partial class TemperatureProtectionComponent : Component { /// /// How much to multiply temperature deltas by. /// - [DataField("coefficient")] + [DataField] public float Coefficient = 1.0f; } + +/// +/// Event raised on an entity with to determine the actual value of the coefficient. +/// +[ByRefEvent] +public record struct GetTemperatureProtectionEvent(float Coefficient); diff --git a/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs b/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs index 1b3e1b07a6f..023ac287634 100644 --- a/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs +++ b/Content.Server/Atmos/EntitySystems/BarotraumaSystem.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Content.Server.Administration.Logs; using Content.Server.Atmos.Components; using Content.Shared.Alert; @@ -97,7 +98,11 @@ private void UpdateCachedResistances(EntityUid uid, BarotraumaComponent barotrau foreach (var slot in barotrauma.ProtectionSlots) { if (!_inventorySystem.TryGetSlotEntity(uid, slot, out var equipment, inv, contMan) - || !TryComp(equipment, out PressureProtectionComponent? protection)) + || !TryGetPressureProtectionValues(equipment.Value, + out var itemHighMultiplier, + out var itemHighModifier, + out var itemLowMultiplier, + out var itemLowModifier)) { // Missing protection, skin is exposed. hPModifier = 0f; @@ -108,10 +113,10 @@ private void UpdateCachedResistances(EntityUid uid, BarotraumaComponent barotrau } // The entity is as protected as its weakest part protection - hPModifier = Math.Max(hPModifier, protection.HighPressureModifier); - hPMultiplier = Math.Max(hPMultiplier, protection.HighPressureMultiplier); - lPModifier = Math.Min(lPModifier, protection.LowPressureModifier); - lPMultiplier = Math.Min(lPMultiplier, protection.LowPressureMultiplier); + hPModifier = Math.Max(hPModifier, itemHighModifier.Value); + hPMultiplier = Math.Max(hPMultiplier, itemHighMultiplier.Value); + lPModifier = Math.Min(lPModifier, itemLowModifier.Value); + lPMultiplier = Math.Min(lPMultiplier, itemLowMultiplier.Value); } barotrauma.HighPressureModifier = hPModifier; @@ -121,12 +126,16 @@ private void UpdateCachedResistances(EntityUid uid, BarotraumaComponent barotrau } // any innate pressure resistance ? - if (TryComp(uid, out var innatePressureProtection)) + if (TryGetPressureProtectionValues(uid, + out var highMultiplier, + out var highModifier, + out var lowMultiplier, + out var lowModifier)) { - barotrauma.HighPressureModifier += innatePressureProtection.HighPressureModifier; - barotrauma.HighPressureMultiplier *= innatePressureProtection.HighPressureMultiplier; - barotrauma.LowPressureModifier += innatePressureProtection.LowPressureModifier; - barotrauma.LowPressureMultiplier *= innatePressureProtection.LowPressureMultiplier; + barotrauma.HighPressureModifier += highModifier.Value; + barotrauma.HighPressureMultiplier *= highMultiplier.Value; + barotrauma.LowPressureModifier += lowModifier.Value; + barotrauma.LowPressureMultiplier *= lowMultiplier.Value; } } @@ -156,6 +165,36 @@ public float GetFeltHighPressure(EntityUid uid, BarotraumaComponent barotrauma, return (environmentPressure + barotrauma.HighPressureModifier) * (barotrauma.HighPressureMultiplier); } + public bool TryGetPressureProtectionValues( + Entity ent, + [NotNullWhen(true)] out float? highMultiplier, + [NotNullWhen(true)] out float? highModifier, + [NotNullWhen(true)] out float? lowMultiplier, + [NotNullWhen(true)] out float? lowModifier) + { + highMultiplier = null; + highModifier = null; + lowMultiplier = null; + lowModifier = null; + if (!Resolve(ent, ref ent.Comp, false)) + return false; + + var comp = ent.Comp; + var ev = new GetPressureProtectionValuesEvent + { + HighPressureMultiplier = comp.HighPressureMultiplier, + HighPressureModifier = comp.HighPressureModifier, + LowPressureMultiplier = comp.LowPressureMultiplier, + LowPressureModifier = comp.LowPressureModifier + }; + RaiseLocalEvent(ent, ref ev); + highMultiplier = ev.HighPressureMultiplier; + highModifier = ev.HighPressureModifier; + lowMultiplier = ev.LowPressureMultiplier; + lowModifier = ev.LowPressureModifier; + return true; + } + public override void Update(float frameTime) { _timer += frameTime; diff --git a/Content.Server/Temperature/Systems/TemperatureSystem.cs b/Content.Server/Temperature/Systems/TemperatureSystem.cs index 9f7057d9b61..aef4b89d509 100644 --- a/Content.Server/Temperature/Systems/TemperatureSystem.cs +++ b/Content.Server/Temperature/Systems/TemperatureSystem.cs @@ -293,7 +293,10 @@ private void ChangeDamage(EntityUid uid, TemperatureComponent temperature) private void OnTemperatureChangeAttempt(EntityUid uid, TemperatureProtectionComponent component, InventoryRelayedEvent args) { - args.Args.TemperatureDelta *= component.Coefficient; + var ev = new GetTemperatureProtectionEvent(component.Coefficient); + RaiseLocalEvent(uid, ref ev); + + args.Args.TemperatureDelta *= ev.Coefficient; } private void OnParentChange(EntityUid uid, TemperatureComponent component, From 2a3eba2399f0853fa94d269dbb9eacab0285bf08 Mon Sep 17 00:00:00 2001 From: k3yw Date: Thu, 15 Feb 2024 00:02:57 +0700 Subject: [PATCH 123/200] Update criminal-records.ftl (#25229) (cherry picked from commit d2541d6c1f90a4b76594f008d402e174f9d25ac6) --- Resources/Locale/en-US/criminal-records/criminal-records.ftl | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Locale/en-US/criminal-records/criminal-records.ftl b/Resources/Locale/en-US/criminal-records/criminal-records.ftl index 49cd59914ac..8e8124edcbd 100644 --- a/Resources/Locale/en-US/criminal-records/criminal-records.ftl +++ b/Resources/Locale/en-US/criminal-records/criminal-records.ftl @@ -31,6 +31,7 @@ criminal-records-console-wanted = {$name} is wanted by {$officer} for: {$reason} criminal-records-console-detained = {$name} has been detained by {$officer}. criminal-records-console-released = {$name} has been released by {$officer}. criminal-records-console-not-wanted = {$name} is no longer wanted. +criminal-records-console-unknown-officer = ## Filters From 81aaf8d0efe533ea33be2fe45371098adedf1dda Mon Sep 17 00:00:00 2001 From: Velcroboy <107660393+IamVelcroboy@users.noreply.github.com> Date: Wed, 14 Feb 2024 12:03:59 -0600 Subject: [PATCH 124/200] Adds always powered variants of colored lights (#25185) Co-authored-by: Jeff (cherry picked from commit 95990c4c792a7636824e8e746c1491be48b66d39) --- .../Structures/Lighting/base_lighting.yml | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml index ede31b5e56c..2e381bf9bdd 100644 --- a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml +++ b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml @@ -370,6 +370,17 @@ types: Heat: 5 +- type: entity + id: AlwaysPoweredlightCyan + suffix: Always Powered, Cyan + parent: AlwaysPoweredWallLight + components: + - type: PointLight + radius: 8 + energy: 3 + softness: 0.5 + color: "#47f8ff" + - type: entity id: PoweredlightBlue suffix: Blue @@ -381,6 +392,17 @@ types: Heat: 5 +- type: entity + id: AlwaysPoweredlightBlue + suffix: Always Powered, Blue + parent: AlwaysPoweredWallLight + components: + - type: PointLight + radius: 8 + energy: 3 + softness: 0.5 + color: "#39a1ff" + - type: entity id: PoweredlightPink suffix: Pink @@ -392,6 +414,17 @@ types: Heat: 5 +- type: entity + id: AlwaysPoweredlightPink + suffix: Always Powered, Pink + parent: AlwaysPoweredWallLight + components: + - type: PointLight + radius: 8 + energy: 3 + softness: 0.5 + color: "#ff66cc" + - type: entity id: PoweredlightOrange suffix: Orange @@ -403,6 +436,17 @@ types: Heat: 5 +- type: entity + id: AlwaysPoweredlightOrange + suffix: Always Powered, Orange + parent: AlwaysPoweredWallLight + components: + - type: PointLight + radius: 8 + energy: 3 + softness: 0.5 + color: "#ff8227" + - type: entity id: PoweredlightRed suffix: Red @@ -414,6 +458,17 @@ types: Heat: 5 +- type: entity + id: AlwaysPoweredlightRed + suffix: Always Powered, Red + parent: AlwaysPoweredWallLight + components: + - type: PointLight + radius: 8 + energy: 3 + softness: 0.5 + color: "#fb4747" + - type: entity id: PoweredlightGreen suffix: Green @@ -425,3 +480,13 @@ types: Heat: 5 +- type: entity + id: AlwaysPoweredlightGreen + suffix: Always Powered, Green + parent: AlwaysPoweredWallLight + components: + - type: PointLight + radius: 8 + energy: 3 + softness: 0.5 + color: "#52ff39" From f53bcf5ac347b79d92a9e83d048195a08dea998b Mon Sep 17 00:00:00 2001 From: Velcroboy <107660393+IamVelcroboy@users.noreply.github.com> Date: Wed, 14 Feb 2024 14:45:33 -0600 Subject: [PATCH 125/200] Fixes silver bars being whole stacks (#25239) Co-authored-by: Jeff (cherry picked from commit f61f30fec96d414ac6752353d75ac4a976fafa85) --- Resources/Prototypes/Entities/Objects/Materials/ingots.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Objects/Materials/ingots.yml b/Resources/Prototypes/Entities/Objects/Materials/ingots.yml index 24e8ca649c9..7e8e6a5b746 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/ingots.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/ingots.yml @@ -59,7 +59,7 @@ reagents: - ReagentId: Gold Quantity: 10 - + - type: entity parent: IngotGold id: IngotGold1 @@ -113,3 +113,5 @@ components: - type: Sprite state: silver + - type: Stack + count: 1 From f5a0ac168879068441fc88a579182f43fe138249 Mon Sep 17 00:00:00 2001 From: Jessica M Date: Wed, 14 Feb 2024 15:04:06 -0800 Subject: [PATCH 126/200] Makes clumsy not delete guns (#25243) clumsy no longer deletes guns Co-authored-by: Jessica M (cherry picked from commit d0c24f9aff574e4f929dff66c7dac4c167e51fb5) --- Content.Server/Weapons/Ranged/Systems/GunSystem.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs index 756a4c90656..b8f8f122111 100644 --- a/Content.Server/Weapons/Ranged/Systems/GunSystem.cs +++ b/Content.Server/Weapons/Ranged/Systems/GunSystem.cs @@ -87,8 +87,6 @@ public override void Shoot(EntityUid gunUid, GunComponent gun, List<(EntityUid? Audio.PlayPvs(clumsy.ClumsySound, gunUid); PopupSystem.PopupEntity(Loc.GetString("gun-clumsy"), user.Value); - _adminLogger.Add(LogType.EntityDelete, LogImpact.Medium, $"Clumsy fire by {ToPrettyString(user.Value)} deleted {ToPrettyString(gunUid)}"); - Del(gunUid); userImpulse = false; return; } From 1031a93942f229683f88a97dea3e4e65855b071c Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Thu, 15 Feb 2024 00:05:01 +0100 Subject: [PATCH 127/200] Predict Injector (syringes), cleanup (#25235) At least the mode/transfer amount logic. Actual transfer logic needs Bloodstream which I didn't wanna move into shared. (cherry picked from commit 6d8be538c90cf4c3a6636e2f8b84631af457cd42) --- .../Chemistry/Components/InjectorComponent.cs | 21 - .../Chemistry/EntitySystems/InjectorSystem.cs | 19 +- .../Chemistry/UI/InjectorStatusControl.cs | 39 +- .../Chemistry/Components/InjectorComponent.cs | 83 ---- .../EntitySystems/ChemistrySystem.Injector.cs | 447 ------------------ .../EntitySystems/ChemistrySystem.cs | 9 - .../Chemistry/EntitySystems/InjectorSystem.cs | 366 ++++++++++++++ .../Chemistry/Components/InjectorComponent.cs | 104 ++++ .../Components/SharedInjectorComponent.cs | 44 -- .../EntitySystems/SharedInjectorSystem.cs | 120 +++++ .../components/injector-component.ftl | 3 +- 11 files changed, 613 insertions(+), 642 deletions(-) delete mode 100644 Content.Client/Chemistry/Components/InjectorComponent.cs delete mode 100644 Content.Server/Chemistry/Components/InjectorComponent.cs delete mode 100644 Content.Server/Chemistry/EntitySystems/ChemistrySystem.Injector.cs create mode 100644 Content.Server/Chemistry/EntitySystems/InjectorSystem.cs create mode 100644 Content.Shared/Chemistry/Components/InjectorComponent.cs delete mode 100644 Content.Shared/Chemistry/Components/SharedInjectorComponent.cs create mode 100644 Content.Shared/Chemistry/EntitySystems/SharedInjectorSystem.cs diff --git a/Content.Client/Chemistry/Components/InjectorComponent.cs b/Content.Client/Chemistry/Components/InjectorComponent.cs deleted file mode 100644 index 4d10517a11e..00000000000 --- a/Content.Client/Chemistry/Components/InjectorComponent.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Content.Shared.Chemistry.Components; -using Content.Shared.FixedPoint; - -namespace Content.Client.Chemistry.Components -{ - /// - /// Client behavior for injectors & syringes. Used for item status on injectors - /// - [RegisterComponent] - public sealed partial class InjectorComponent : SharedInjectorComponent - { - [ViewVariables] - public FixedPoint2 CurrentVolume; - [ViewVariables] - public FixedPoint2 TotalVolume; - [ViewVariables] - public InjectorToggleMode CurrentMode; - [ViewVariables(VVAccess.ReadWrite)] - public bool UiUpdateNeeded; - } -} diff --git a/Content.Client/Chemistry/EntitySystems/InjectorSystem.cs b/Content.Client/Chemistry/EntitySystems/InjectorSystem.cs index 896349a1614..12eb7f3d14d 100644 --- a/Content.Client/Chemistry/EntitySystems/InjectorSystem.cs +++ b/Content.Client/Chemistry/EntitySystems/InjectorSystem.cs @@ -2,34 +2,21 @@ using Content.Client.Chemistry.UI; using Content.Client.Items; using Content.Shared.Chemistry.Components; +using Content.Shared.Chemistry.EntitySystems; using Robust.Shared.GameStates; namespace Content.Client.Chemistry.EntitySystems; -public sealed class InjectorSystem : EntitySystem +public sealed class InjectorSystem : SharedInjectorSystem { public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnHandleInjectorState); - Subs.ItemStatus(ent => new InjectorStatusControl(ent)); + Subs.ItemStatus(ent => new InjectorStatusControl(ent, SolutionContainers)); SubscribeLocalEvent(OnHandleHyposprayState); Subs.ItemStatus(ent => new HyposprayStatusControl(ent)); } - private void OnHandleInjectorState(EntityUid uid, InjectorComponent component, ref ComponentHandleState args) - { - if (args.Current is not SharedInjectorComponent.InjectorComponentState state) - { - return; - } - - component.CurrentVolume = state.CurrentVolume; - component.TotalVolume = state.TotalVolume; - component.CurrentMode = state.CurrentMode; - component.UiUpdateNeeded = true; - } - private void OnHandleHyposprayState(EntityUid uid, HyposprayComponent component, ref ComponentHandleState args) { if (args.Current is not HyposprayComponentState cState) diff --git a/Content.Client/Chemistry/UI/InjectorStatusControl.cs b/Content.Client/Chemistry/UI/InjectorStatusControl.cs index f7723201686..979e9ea6455 100644 --- a/Content.Client/Chemistry/UI/InjectorStatusControl.cs +++ b/Content.Client/Chemistry/UI/InjectorStatusControl.cs @@ -1,7 +1,7 @@ -using Content.Client.Chemistry.Components; using Content.Client.Message; using Content.Client.Stylesheets; using Content.Shared.Chemistry.Components; +using Content.Shared.Chemistry.EntitySystems; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.Timing; @@ -10,40 +10,37 @@ namespace Content.Client.Chemistry.UI; public sealed class InjectorStatusControl : Control { - private readonly InjectorComponent _parent; + private readonly Entity _parent; + private readonly SharedSolutionContainerSystem _solutionContainers; private readonly RichTextLabel _label; - public InjectorStatusControl(InjectorComponent parent) + public InjectorStatusControl(Entity parent, SharedSolutionContainerSystem solutionContainers) { _parent = parent; + _solutionContainers = solutionContainers; _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } }; AddChild(_label); - - Update(); } protected override void FrameUpdate(FrameEventArgs args) { base.FrameUpdate(args); - if (!_parent.UiUpdateNeeded) - return; - Update(); - } - public void Update() - { - _parent.UiUpdateNeeded = false; + if (!_solutionContainers.TryGetSolution(_parent.Owner, InjectorComponent.SolutionName, out _, out var solution)) + return; - //Update current volume and injector state - var modeStringLocalized = _parent.CurrentMode switch + // Update current volume and injector state + var modeStringLocalized = Loc.GetString(_parent.Comp.ToggleState switch { - SharedInjectorComponent.InjectorToggleMode.Draw => Loc.GetString("injector-draw-text"), - SharedInjectorComponent.InjectorToggleMode.Inject => Loc.GetString("injector-inject-text"), - _ => Loc.GetString("injector-invalid-injector-toggle-mode") - }; + InjectorToggleMode.Draw => "injector-draw-text", + InjectorToggleMode.Inject => "injector-inject-text", + _ => "injector-invalid-injector-toggle-mode" + }); + _label.SetMarkup(Loc.GetString("injector-volume-label", - ("currentVolume", _parent.CurrentVolume), - ("totalVolume", _parent.TotalVolume), - ("modeString", modeStringLocalized))); + ("currentVolume", solution.Volume), + ("totalVolume", solution.MaxVolume), + ("modeString", modeStringLocalized), + ("transferVolume", _parent.Comp.TransferAmount))); } } diff --git a/Content.Server/Chemistry/Components/InjectorComponent.cs b/Content.Server/Chemistry/Components/InjectorComponent.cs deleted file mode 100644 index d6d149ad0f4..00000000000 --- a/Content.Server/Chemistry/Components/InjectorComponent.cs +++ /dev/null @@ -1,83 +0,0 @@ -using Content.Shared.Chemistry.Components; -using Content.Shared.FixedPoint; - -namespace Content.Server.Chemistry.Components -{ - /// - /// Server behavior for reagent injectors and syringes. Can optionally support both - /// injection and drawing or just injection. Can inject/draw reagents from solution - /// containers, and can directly inject into a mobs bloodstream. - /// - [RegisterComponent] - public sealed partial class InjectorComponent : SharedInjectorComponent - { - public const string SolutionName = "injector"; - - /// - /// Whether or not the injector is able to draw from containers or if it's a single use - /// device that can only inject. - /// - [DataField("injectOnly")] - public bool InjectOnly; - - /// - /// Whether or not the injector is able to draw from or inject from mobs - /// - /// - /// for example: droppers would ignore mobs - /// - [DataField("ignoreMobs")] - public bool IgnoreMobs = false; - - /// - /// The minimum amount of solution that can be transferred at once from this solution. - /// - [DataField("minTransferAmount")] - [ViewVariables(VVAccess.ReadWrite)] - public FixedPoint2 MinimumTransferAmount { get; set; } = FixedPoint2.New(5); - - /// - /// The maximum amount of solution that can be transferred at once from this solution. - /// - [DataField("maxTransferAmount")] - [ViewVariables(VVAccess.ReadWrite)] - public FixedPoint2 MaximumTransferAmount { get; set; } = FixedPoint2.New(50); - - /// - /// Amount to inject or draw on each usage. If the injector is inject only, it will - /// attempt to inject it's entire contents upon use. - /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField("transferAmount")] - public FixedPoint2 TransferAmount = FixedPoint2.New(5); - - /// - /// Injection delay (seconds) when the target is a mob. - /// - /// - /// The base delay has a minimum of 1 second, but this will still be modified if the target is incapacitated or - /// in combat mode. - /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField("delay")] - public float Delay = 5; - - [DataField("toggleState")] private InjectorToggleMode _toggleState; - - /// - /// The state of the injector. Determines it's attack behavior. Containers must have the - /// right SolutionCaps to support injection/drawing. For InjectOnly injectors this should - /// only ever be set to Inject - /// - [ViewVariables(VVAccess.ReadWrite)] - public InjectorToggleMode ToggleState - { - get => _toggleState; - set - { - _toggleState = value; - Dirty(); - } - } - } -} diff --git a/Content.Server/Chemistry/EntitySystems/ChemistrySystem.Injector.cs b/Content.Server/Chemistry/EntitySystems/ChemistrySystem.Injector.cs deleted file mode 100644 index 4f149db8362..00000000000 --- a/Content.Server/Chemistry/EntitySystems/ChemistrySystem.Injector.cs +++ /dev/null @@ -1,447 +0,0 @@ -using Content.Server.Body.Components; -using Content.Server.Chemistry.Components; -using Content.Server.Chemistry.Containers.EntitySystems; -using Content.Shared.Chemistry.Components; -using Content.Shared.Chemistry.Components.SolutionManager; -using Content.Shared.Chemistry.EntitySystems; -using Content.Shared.Chemistry.Reagent; -using Content.Shared.Database; -using Content.Shared.DoAfter; -using Content.Shared.FixedPoint; -using Content.Shared.Forensics; -using Content.Shared.IdentityManagement; -using Content.Shared.Interaction; -using Content.Shared.Interaction.Events; -using Content.Shared.Mobs.Components; -using Content.Shared.Stacks; -using Content.Shared.Verbs; -using Robust.Shared.GameStates; -using Robust.Shared.Player; - -namespace Content.Server.Chemistry.EntitySystems; - -public sealed partial class ChemistrySystem -{ - - /// - /// Default transfer amounts for the set-transfer verb. - /// - public static readonly List TransferAmounts = new() { 1, 5, 10, 15 }; - private void InitializeInjector() - { - SubscribeLocalEvent>(AddSetTransferVerbs); - SubscribeLocalEvent(OnSolutionChange); - SubscribeLocalEvent(OnInjectDoAfter); - SubscribeLocalEvent(OnInjectorStartup); - SubscribeLocalEvent(OnInjectorUse); - SubscribeLocalEvent(OnInjectorAfterInteract); - SubscribeLocalEvent(OnInjectorGetState); - } - - private void AddSetTransferVerbs(Entity entity, ref GetVerbsEvent args) - { - if (!args.CanAccess || !args.CanInteract || args.Hands == null) - return; - - if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor)) - return; - - var (uid, component) = entity; - - // Add specific transfer verbs according to the container's size - var priority = 0; - var user = args.User; - foreach (var amount in TransferAmounts) - { - if (amount < component.MinimumTransferAmount.Int() || amount > component.MaximumTransferAmount.Int()) - continue; - - AlternativeVerb verb = new(); - verb.Text = Loc.GetString("comp-solution-transfer-verb-amount", ("amount", amount)); - verb.Category = VerbCategory.SetTransferAmount; - verb.Act = () => - { - component.TransferAmount = FixedPoint2.New(amount); - _popup.PopupEntity(Loc.GetString("comp-solution-transfer-set-amount", ("amount", amount)), user, user); - }; - - // we want to sort by size, not alphabetically by the verb text. - verb.Priority = priority; - priority--; - - args.Verbs.Add(verb); - } - } - - private void UseInjector(Entity injector, EntityUid target, EntityUid user) - { - // Handle injecting/drawing for solutions - if (injector.Comp.ToggleState == SharedInjectorComponent.InjectorToggleMode.Inject) - { - if (_solutionContainers.TryGetInjectableSolution(target, out var injectableSolution, out _)) - { - TryInject(injector, target, injectableSolution.Value, user, false); - } - else if (_solutionContainers.TryGetRefillableSolution(target, out var refillableSolution, out _)) - { - TryInject(injector, target, refillableSolution.Value, user, true); - } - else if (TryComp(target, out var bloodstream)) - { - TryInjectIntoBloodstream(injector, (target, bloodstream), user); - } - else - { - _popup.PopupEntity(Loc.GetString("injector-component-cannot-transfer-message", - ("target", Identity.Entity(target, EntityManager))), injector, user); - } - } - else if (injector.Comp.ToggleState == SharedInjectorComponent.InjectorToggleMode.Draw) - { - // Draw from a bloodstream, if the target has that - if (TryComp(target, out var stream) && - _solutionContainers.ResolveSolution(target, stream.BloodSolutionName, ref stream.BloodSolution)) - { - TryDraw(injector, (target, stream), stream.BloodSolution.Value, user); - return; - } - - // Draw from an object (food, beaker, etc) - if (_solutionContainers.TryGetDrawableSolution(target, out var drawableSolution, out _)) - { - TryDraw(injector, target, drawableSolution.Value, user); - } - else - { - _popup.PopupEntity(Loc.GetString("injector-component-cannot-draw-message", - ("target", Identity.Entity(target, EntityManager))), injector.Owner, user); - } - } - } - - private void OnSolutionChange(Entity entity, ref SolutionContainerChangedEvent args) - { - Dirty(entity); - } - - private void OnInjectorGetState(Entity entity, ref ComponentGetState args) - { - _solutionContainers.TryGetSolution(entity.Owner, InjectorComponent.SolutionName, out _, out var solution); - - var currentVolume = solution?.Volume ?? FixedPoint2.Zero; - var maxVolume = solution?.MaxVolume ?? FixedPoint2.Zero; - - args.State = new SharedInjectorComponent.InjectorComponentState(currentVolume, maxVolume, entity.Comp.ToggleState); - } - - private void OnInjectDoAfter(Entity entity, ref InjectorDoAfterEvent args) - { - if (args.Cancelled || args.Handled || args.Args.Target == null) - return; - - UseInjector(entity, args.Args.Target.Value, args.Args.User); - args.Handled = true; - } - - private void OnInjectorAfterInteract(Entity entity, ref AfterInteractEvent args) - { - if (args.Handled || !args.CanReach) - return; - - //Make sure we have the attacking entity - if (args.Target is not { Valid: true } target || !HasComp(entity)) - return; - - // Is the target a mob? If yes, use a do-after to give them time to respond. - if (HasComp(target) || HasComp(target)) - { - // Are use using an injector capible of targeting a mob? - if (entity.Comp.IgnoreMobs) - return; - - InjectDoAfter(entity, target, args.User); - args.Handled = true; - return; - } - - UseInjector(entity, target, args.User); - args.Handled = true; - } - - private void OnInjectorStartup(Entity entity, ref ComponentStartup args) - { - // ???? why ????? - Dirty(entity); - } - - private void OnInjectorUse(Entity entity, ref UseInHandEvent args) - { - if (args.Handled) - return; - - Toggle(entity, args.User); - args.Handled = true; - } - - /// - /// Toggle between draw/inject state if applicable - /// - private void Toggle(Entity injector, EntityUid user) - { - if (injector.Comp.InjectOnly) - { - return; - } - - string msg; - switch (injector.Comp.ToggleState) - { - case SharedInjectorComponent.InjectorToggleMode.Inject: - injector.Comp.ToggleState = SharedInjectorComponent.InjectorToggleMode.Draw; - msg = "injector-component-drawing-text"; - break; - case SharedInjectorComponent.InjectorToggleMode.Draw: - injector.Comp.ToggleState = SharedInjectorComponent.InjectorToggleMode.Inject; - msg = "injector-component-injecting-text"; - break; - default: - throw new ArgumentOutOfRangeException(); - } - - _popup.PopupEntity(Loc.GetString(msg), injector, user); - } - - /// - /// Send informative pop-up messages and wait for a do-after to complete. - /// - private void InjectDoAfter(Entity injector, EntityUid target, EntityUid user) - { - // Create a pop-up for the user - _popup.PopupEntity(Loc.GetString("injector-component-injecting-user"), target, user); - - if (!_solutionContainers.TryGetSolution(injector.Owner, InjectorComponent.SolutionName, out _, out var solution)) - return; - - var actualDelay = MathF.Max(injector.Comp.Delay, 1f); - - // Injections take 0.5 seconds longer per additional 5u - actualDelay += (float) injector.Comp.TransferAmount / injector.Comp.Delay - 0.5f; - - var isTarget = user != target; - - if (isTarget) - { - // Create a pop-up for the target - var userName = Identity.Entity(user, EntityManager); - _popup.PopupEntity(Loc.GetString("injector-component-injecting-target", - ("user", userName)), user, target); - - // Check if the target is incapacitated or in combat mode and modify time accordingly. - if (_mobState.IsIncapacitated(target)) - { - actualDelay /= 2.5f; - } - else if (_combat.IsInCombatMode(target)) - { - // Slightly increase the delay when the target is in combat mode. Helps prevents cheese injections in - // combat with fast syringes & lag. - actualDelay += 1; - } - - // Add an admin log, using the "force feed" log type. It's not quite feeding, but the effect is the same. - if (injector.Comp.ToggleState == SharedInjectorComponent.InjectorToggleMode.Inject) - { - _adminLogger.Add(LogType.ForceFeed, - $"{EntityManager.ToPrettyString(user):user} is attempting to inject {EntityManager.ToPrettyString(target):target} with a solution {SolutionContainerSystem.ToPrettyString(solution):solution}"); - } - else - { - _adminLogger.Add(LogType.ForceFeed, - $"{EntityManager.ToPrettyString(user):user} is attempting to draw {injector.Comp.TransferAmount.ToString()} units from {EntityManager.ToPrettyString(target):target}"); - } - } - else - { - // Self-injections take half as long. - actualDelay /= 2; - - if (injector.Comp.ToggleState == SharedInjectorComponent.InjectorToggleMode.Inject) - { - _adminLogger.Add(LogType.Ingestion, - $"{EntityManager.ToPrettyString(user):user} is attempting to inject themselves with a solution {SolutionContainerSystem.ToPrettyString(solution):solution}."); - } - else - { - _adminLogger.Add(LogType.ForceFeed, - $"{EntityManager.ToPrettyString(user):user} is attempting to draw {injector.Comp.TransferAmount.ToString()} units from themselves."); - } - } - - _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, user, actualDelay, new InjectorDoAfterEvent(), injector.Owner, target: target, used: injector.Owner) - { - BreakOnUserMove = true, - BreakOnDamage = true, - BreakOnTargetMove = true, - MovementThreshold = 0.1f, - }); - } - - private void TryInjectIntoBloodstream(Entity injector, Entity target, EntityUid user) - { - // Get transfer amount. May be smaller than _transferAmount if not enough room - if (!_solutionContainers.ResolveSolution(target.Owner, target.Comp.ChemicalSolutionName, ref target.Comp.ChemicalSolution, out var chemSolution)) - { - _popup.PopupEntity(Loc.GetString("injector-component-cannot-inject-message", ("target", Identity.Entity(target, EntityManager))), injector.Owner, user); - return; - } - - var realTransferAmount = FixedPoint2.Min(injector.Comp.TransferAmount, chemSolution.AvailableVolume); - if (realTransferAmount <= 0) - { - _popup.PopupEntity(Loc.GetString("injector-component-cannot-inject-message", ("target", Identity.Entity(target, EntityManager))), injector.Owner, user); - return; - } - - // Move units from attackSolution to targetSolution - var removedSolution = _solutionContainers.SplitSolution(target.Comp.ChemicalSolution.Value, realTransferAmount); - - _blood.TryAddToChemicals(target, removedSolution, target.Comp); - - _reactiveSystem.DoEntityReaction(target, removedSolution, ReactionMethod.Injection); - - _popup.PopupEntity(Loc.GetString("injector-component-inject-success-message", - ("amount", removedSolution.Volume), - ("target", Identity.Entity(target, EntityManager))), injector.Owner, user); - - Dirty(injector); - AfterInject(injector, target); - } - - private void TryInject(Entity injector, EntityUid targetEntity, Entity targetSolution, EntityUid user, bool asRefill) - { - if (!_solutionContainers.TryGetSolution(injector.Owner, InjectorComponent.SolutionName, out var soln, out var solution) || solution.Volume == 0) - return; - - // Get transfer amount. May be smaller than _transferAmount if not enough room - var realTransferAmount = FixedPoint2.Min(injector.Comp.TransferAmount, targetSolution.Comp.Solution.AvailableVolume); - - if (realTransferAmount <= 0) - { - _popup.PopupEntity(Loc.GetString("injector-component-target-already-full-message", ("target", Identity.Entity(targetEntity, EntityManager))), - injector.Owner, user); - return; - } - - // Move units from attackSolution to targetSolution - Solution removedSolution; - if (TryComp(targetEntity, out var stack)) - removedSolution = _solutionContainers.SplitStackSolution(soln.Value, realTransferAmount, stack.Count); - else - removedSolution = _solutionContainers.SplitSolution(soln.Value, realTransferAmount); - - _reactiveSystem.DoEntityReaction(targetEntity, removedSolution, ReactionMethod.Injection); - - if (!asRefill) - _solutionContainers.Inject(targetEntity, targetSolution, removedSolution); - else - _solutionContainers.Refill(targetEntity, targetSolution, removedSolution); - - _popup.PopupEntity(Loc.GetString("injector-component-transfer-success-message", - ("amount", removedSolution.Volume), - ("target", Identity.Entity(targetEntity, EntityManager))), injector.Owner, user); - - Dirty(injector); - AfterInject(injector, targetEntity); - } - - private void AfterInject(Entity injector, EntityUid target) - { - // Automatically set syringe to draw after completely draining it. - if (_solutionContainers.TryGetSolution(injector.Owner, InjectorComponent.SolutionName, out _, out var solution) && solution.Volume == 0) - { - injector.Comp.ToggleState = SharedInjectorComponent.InjectorToggleMode.Draw; - } - - // Leave some DNA from the injectee on it - var ev = new TransferDnaEvent { Donor = target, Recipient = injector }; - RaiseLocalEvent(target, ref ev); - } - - private void AfterDraw(Entity injector, EntityUid target) - { - // Automatically set syringe to inject after completely filling it. - if (_solutionContainers.TryGetSolution(injector.Owner, InjectorComponent.SolutionName, out _, out var solution) && solution.AvailableVolume == 0) - { - injector.Comp.ToggleState = SharedInjectorComponent.InjectorToggleMode.Inject; - } - - // Leave some DNA from the drawee on it - var ev = new TransferDnaEvent { Donor = target, Recipient = injector }; - RaiseLocalEvent(target, ref ev); - } - - private void TryDraw(Entity injector, Entity target, Entity targetSolution, EntityUid user) - { - if (!_solutionContainers.TryGetSolution(injector.Owner, InjectorComponent.SolutionName, out var soln, out var solution) || solution.AvailableVolume == 0) - { - return; - } - - // Get transfer amount. May be smaller than _transferAmount if not enough room, also make sure there's room in the injector - var realTransferAmount = FixedPoint2.Min(injector.Comp.TransferAmount, targetSolution.Comp.Solution.Volume, solution.AvailableVolume); - - if (realTransferAmount <= 0) - { - _popup.PopupEntity(Loc.GetString("injector-component-target-is-empty-message", ("target", Identity.Entity(target, EntityManager))), - injector.Owner, user); - return; - } - - // We have some snowflaked behavior for streams. - if (target.Comp != null) - { - DrawFromBlood(injector, (target.Owner, target.Comp), soln.Value, realTransferAmount, user); - return; - } - - // Move units from attackSolution to targetSolution - var removedSolution = _solutionContainers.Draw(target.Owner, targetSolution, realTransferAmount); - - if (!_solutionContainers.TryAddSolution(soln.Value, removedSolution)) - { - return; - } - - _popup.PopupEntity(Loc.GetString("injector-component-draw-success-message", - ("amount", removedSolution.Volume), - ("target", Identity.Entity(target, EntityManager))), injector.Owner, user); - - Dirty(injector); - AfterDraw(injector, target); - } - - private void DrawFromBlood(Entity injector, Entity target, Entity injectorSolution, FixedPoint2 transferAmount, EntityUid user) - { - var drawAmount = (float) transferAmount; - - if (_solutionContainers.ResolveSolution(target.Owner, target.Comp.ChemicalSolutionName, ref target.Comp.ChemicalSolution)) - { - var chemTemp = _solutionContainers.SplitSolution(target.Comp.ChemicalSolution.Value, drawAmount * 0.15f); - _solutionContainers.TryAddSolution(injectorSolution, chemTemp); - drawAmount -= (float) chemTemp.Volume; - } - - if (_solutionContainers.ResolveSolution(target.Owner, target.Comp.BloodSolutionName, ref target.Comp.BloodSolution)) - { - var bloodTemp = _solutionContainers.SplitSolution(target.Comp.BloodSolution.Value, drawAmount); - _solutionContainers.TryAddSolution(injectorSolution, bloodTemp); - } - - _popup.PopupEntity(Loc.GetString("injector-component-draw-success-message", - ("amount", transferAmount), - ("target", Identity.Entity(target, EntityManager))), injector.Owner, user); - - Dirty(injector); - AfterDraw(injector, target); - } -} diff --git a/Content.Server/Chemistry/EntitySystems/ChemistrySystem.cs b/Content.Server/Chemistry/EntitySystems/ChemistrySystem.cs index a2b4f399e2d..c4f22dc63aa 100644 --- a/Content.Server/Chemistry/EntitySystems/ChemistrySystem.cs +++ b/Content.Server/Chemistry/EntitySystems/ChemistrySystem.cs @@ -1,12 +1,8 @@ using Content.Server.Administration.Logs; -using Content.Server.Body.Systems; using Content.Server.Chemistry.Containers.EntitySystems; using Content.Server.Interaction; using Content.Server.Popups; using Content.Shared.Chemistry; -using Content.Shared.CombatMode; -using Content.Shared.DoAfter; -using Content.Shared.Mobs.Systems; using Robust.Shared.Audio.Systems; namespace Content.Server.Chemistry.EntitySystems; @@ -16,20 +12,15 @@ public sealed partial class ChemistrySystem : EntitySystem [Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly IEntityManager _entMan = default!; [Dependency] private readonly InteractionSystem _interaction = default!; - [Dependency] private readonly BloodstreamSystem _blood = default!; - [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly ReactiveSystem _reactiveSystem = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly MobStateSystem _mobState = default!; - [Dependency] private readonly SharedCombatModeSystem _combat = default!; [Dependency] private readonly SolutionContainerSystem _solutionContainers = default!; public override void Initialize() { // Why ChemMaster duplicates reagentdispenser nobody knows. InitializeHypospray(); - InitializeInjector(); InitializeMixing(); } } diff --git a/Content.Server/Chemistry/EntitySystems/InjectorSystem.cs b/Content.Server/Chemistry/EntitySystems/InjectorSystem.cs new file mode 100644 index 00000000000..a4497c0bd65 --- /dev/null +++ b/Content.Server/Chemistry/EntitySystems/InjectorSystem.cs @@ -0,0 +1,366 @@ +using Content.Server.Body.Components; +using Content.Server.Body.Systems; +using Content.Shared.Chemistry; +using Content.Shared.Chemistry.Components; +using Content.Shared.Chemistry.Components.SolutionManager; +using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.Database; +using Content.Shared.DoAfter; +using Content.Shared.FixedPoint; +using Content.Shared.Forensics; +using Content.Shared.IdentityManagement; +using Content.Shared.Interaction; +using Content.Shared.Mobs.Components; +using Content.Shared.Stacks; + +namespace Content.Server.Chemistry.EntitySystems; + +public sealed class InjectorSystem : SharedInjectorSystem +{ + [Dependency] private readonly BloodstreamSystem _blood = default!; + [Dependency] private readonly ReactiveSystem _reactiveSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInjectDoAfter); + SubscribeLocalEvent(OnInjectorAfterInteract); + } + + private void UseInjector(Entity injector, EntityUid target, EntityUid user) + { + // Handle injecting/drawing for solutions + if (injector.Comp.ToggleState == InjectorToggleMode.Inject) + { + if (SolutionContainers.TryGetInjectableSolution(target, out var injectableSolution, out _)) + { + TryInject(injector, target, injectableSolution.Value, user, false); + } + else if (SolutionContainers.TryGetRefillableSolution(target, out var refillableSolution, out _)) + { + TryInject(injector, target, refillableSolution.Value, user, true); + } + else if (TryComp(target, out var bloodstream)) + { + TryInjectIntoBloodstream(injector, (target, bloodstream), user); + } + else + { + Popup.PopupEntity(Loc.GetString("injector-component-cannot-transfer-message", + ("target", Identity.Entity(target, EntityManager))), injector, user); + } + } + else if (injector.Comp.ToggleState == InjectorToggleMode.Draw) + { + // Draw from a bloodstream, if the target has that + if (TryComp(target, out var stream) && + SolutionContainers.ResolveSolution(target, stream.BloodSolutionName, ref stream.BloodSolution)) + { + TryDraw(injector, (target, stream), stream.BloodSolution.Value, user); + return; + } + + // Draw from an object (food, beaker, etc) + if (SolutionContainers.TryGetDrawableSolution(target, out var drawableSolution, out _)) + { + TryDraw(injector, target, drawableSolution.Value, user); + } + else + { + Popup.PopupEntity(Loc.GetString("injector-component-cannot-draw-message", + ("target", Identity.Entity(target, EntityManager))), injector.Owner, user); + } + } + } + + private void OnInjectDoAfter(Entity entity, ref InjectorDoAfterEvent args) + { + if (args.Cancelled || args.Handled || args.Args.Target == null) + return; + + UseInjector(entity, args.Args.Target.Value, args.Args.User); + args.Handled = true; + } + + private void OnInjectorAfterInteract(Entity entity, ref AfterInteractEvent args) + { + if (args.Handled || !args.CanReach) + return; + + //Make sure we have the attacking entity + if (args.Target is not { Valid: true } target || !HasComp(entity)) + return; + + // Is the target a mob? If yes, use a do-after to give them time to respond. + if (HasComp(target) || HasComp(target)) + { + // Are use using an injector capible of targeting a mob? + if (entity.Comp.IgnoreMobs) + return; + + InjectDoAfter(entity, target, args.User); + args.Handled = true; + return; + } + + UseInjector(entity, target, args.User); + args.Handled = true; + } + + /// + /// Send informative pop-up messages and wait for a do-after to complete. + /// + private void InjectDoAfter(Entity injector, EntityUid target, EntityUid user) + { + // Create a pop-up for the user + Popup.PopupEntity(Loc.GetString("injector-component-injecting-user"), target, user); + + if (!SolutionContainers.TryGetSolution(injector.Owner, InjectorComponent.SolutionName, out _, out var solution)) + return; + + var actualDelay = MathHelper.Max(injector.Comp.Delay, TimeSpan.FromSeconds(1)); + + // Injections take 0.5 seconds longer per additional 5u + actualDelay += TimeSpan.FromSeconds(injector.Comp.TransferAmount.Float() / injector.Comp.Delay.TotalSeconds - 0.5f); + + var isTarget = user != target; + + if (isTarget) + { + // Create a pop-up for the target + var userName = Identity.Entity(user, EntityManager); + Popup.PopupEntity(Loc.GetString("injector-component-injecting-target", + ("user", userName)), user, target); + + // Check if the target is incapacitated or in combat mode and modify time accordingly. + if (MobState.IsIncapacitated(target)) + { + actualDelay /= 2.5f; + } + else if (Combat.IsInCombatMode(target)) + { + // Slightly increase the delay when the target is in combat mode. Helps prevents cheese injections in + // combat with fast syringes & lag. + actualDelay += TimeSpan.FromSeconds(1); + } + + // Add an admin log, using the "force feed" log type. It's not quite feeding, but the effect is the same. + if (injector.Comp.ToggleState == InjectorToggleMode.Inject) + { + AdminLogger.Add(LogType.ForceFeed, + $"{EntityManager.ToPrettyString(user):user} is attempting to inject {EntityManager.ToPrettyString(target):target} with a solution {SharedSolutionContainerSystem.ToPrettyString(solution):solution}"); + } + else + { + AdminLogger.Add(LogType.ForceFeed, + $"{EntityManager.ToPrettyString(user):user} is attempting to draw {injector.Comp.TransferAmount.ToString()} units from {EntityManager.ToPrettyString(target):target}"); + } + } + else + { + // Self-injections take half as long. + actualDelay /= 2; + + if (injector.Comp.ToggleState == InjectorToggleMode.Inject) + { + AdminLogger.Add(LogType.Ingestion, + $"{EntityManager.ToPrettyString(user):user} is attempting to inject themselves with a solution {SharedSolutionContainerSystem.ToPrettyString(solution):solution}."); + } + else + { + AdminLogger.Add(LogType.ForceFeed, + $"{EntityManager.ToPrettyString(user):user} is attempting to draw {injector.Comp.TransferAmount.ToString()} units from themselves."); + } + } + + DoAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, user, actualDelay, new InjectorDoAfterEvent(), injector.Owner, target: target, used: injector.Owner) + { + BreakOnUserMove = true, + BreakOnDamage = true, + BreakOnTargetMove = true, + MovementThreshold = 0.1f, + }); + } + + private void TryInjectIntoBloodstream(Entity injector, Entity target, + EntityUid user) + { + // Get transfer amount. May be smaller than _transferAmount if not enough room + if (!SolutionContainers.ResolveSolution(target.Owner, target.Comp.ChemicalSolutionName, + ref target.Comp.ChemicalSolution, out var chemSolution)) + { + Popup.PopupEntity( + Loc.GetString("injector-component-cannot-inject-message", + ("target", Identity.Entity(target, EntityManager))), injector.Owner, user); + return; + } + + var realTransferAmount = FixedPoint2.Min(injector.Comp.TransferAmount, chemSolution.AvailableVolume); + if (realTransferAmount <= 0) + { + Popup.PopupEntity( + Loc.GetString("injector-component-cannot-inject-message", + ("target", Identity.Entity(target, EntityManager))), injector.Owner, user); + return; + } + + // Move units from attackSolution to targetSolution + var removedSolution = SolutionContainers.SplitSolution(target.Comp.ChemicalSolution.Value, realTransferAmount); + + _blood.TryAddToChemicals(target, removedSolution, target.Comp); + + _reactiveSystem.DoEntityReaction(target, removedSolution, ReactionMethod.Injection); + + Popup.PopupEntity(Loc.GetString("injector-component-inject-success-message", + ("amount", removedSolution.Volume), + ("target", Identity.Entity(target, EntityManager))), injector.Owner, user); + + Dirty(injector); + AfterInject(injector, target); + } + + private void TryInject(Entity injector, EntityUid targetEntity, + Entity targetSolution, EntityUid user, bool asRefill) + { + if (!SolutionContainers.TryGetSolution(injector.Owner, InjectorComponent.SolutionName, out var soln, + out var solution) || solution.Volume == 0) + return; + + // Get transfer amount. May be smaller than _transferAmount if not enough room + var realTransferAmount = + FixedPoint2.Min(injector.Comp.TransferAmount, targetSolution.Comp.Solution.AvailableVolume); + + if (realTransferAmount <= 0) + { + Popup.PopupEntity( + Loc.GetString("injector-component-target-already-full-message", + ("target", Identity.Entity(targetEntity, EntityManager))), + injector.Owner, user); + return; + } + + // Move units from attackSolution to targetSolution + Solution removedSolution; + if (TryComp(targetEntity, out var stack)) + removedSolution = SolutionContainers.SplitStackSolution(soln.Value, realTransferAmount, stack.Count); + else + removedSolution = SolutionContainers.SplitSolution(soln.Value, realTransferAmount); + + _reactiveSystem.DoEntityReaction(targetEntity, removedSolution, ReactionMethod.Injection); + + if (!asRefill) + SolutionContainers.Inject(targetEntity, targetSolution, removedSolution); + else + SolutionContainers.Refill(targetEntity, targetSolution, removedSolution); + + Popup.PopupEntity(Loc.GetString("injector-component-transfer-success-message", + ("amount", removedSolution.Volume), + ("target", Identity.Entity(targetEntity, EntityManager))), injector.Owner, user); + + Dirty(injector); + AfterInject(injector, targetEntity); + } + + private void AfterInject(Entity injector, EntityUid target) + { + // Automatically set syringe to draw after completely draining it. + if (SolutionContainers.TryGetSolution(injector.Owner, InjectorComponent.SolutionName, out _, + out var solution) && solution.Volume == 0) + { + SetMode(injector, InjectorToggleMode.Draw); + } + + // Leave some DNA from the injectee on it + var ev = new TransferDnaEvent { Donor = target, Recipient = injector }; + RaiseLocalEvent(target, ref ev); + } + + private void AfterDraw(Entity injector, EntityUid target) + { + // Automatically set syringe to inject after completely filling it. + if (SolutionContainers.TryGetSolution(injector.Owner, InjectorComponent.SolutionName, out _, + out var solution) && solution.AvailableVolume == 0) + { + SetMode(injector, InjectorToggleMode.Inject); + } + + // Leave some DNA from the drawee on it + var ev = new TransferDnaEvent { Donor = target, Recipient = injector }; + RaiseLocalEvent(target, ref ev); + } + + private void TryDraw(Entity injector, Entity target, + Entity targetSolution, EntityUid user) + { + if (!SolutionContainers.TryGetSolution(injector.Owner, InjectorComponent.SolutionName, out var soln, + out var solution) || solution.AvailableVolume == 0) + { + return; + } + + // Get transfer amount. May be smaller than _transferAmount if not enough room, also make sure there's room in the injector + var realTransferAmount = FixedPoint2.Min(injector.Comp.TransferAmount, targetSolution.Comp.Solution.Volume, + solution.AvailableVolume); + + if (realTransferAmount <= 0) + { + Popup.PopupEntity( + Loc.GetString("injector-component-target-is-empty-message", + ("target", Identity.Entity(target, EntityManager))), + injector.Owner, user); + return; + } + + // We have some snowflaked behavior for streams. + if (target.Comp != null) + { + DrawFromBlood(injector, (target.Owner, target.Comp), soln.Value, realTransferAmount, user); + return; + } + + // Move units from attackSolution to targetSolution + var removedSolution = SolutionContainers.Draw(target.Owner, targetSolution, realTransferAmount); + + if (!SolutionContainers.TryAddSolution(soln.Value, removedSolution)) + { + return; + } + + Popup.PopupEntity(Loc.GetString("injector-component-draw-success-message", + ("amount", removedSolution.Volume), + ("target", Identity.Entity(target, EntityManager))), injector.Owner, user); + + Dirty(injector); + AfterDraw(injector, target); + } + + private void DrawFromBlood(Entity injector, Entity target, + Entity injectorSolution, FixedPoint2 transferAmount, EntityUid user) + { + var drawAmount = (float) transferAmount; + + if (SolutionContainers.ResolveSolution(target.Owner, target.Comp.ChemicalSolutionName, + ref target.Comp.ChemicalSolution)) + { + var chemTemp = SolutionContainers.SplitSolution(target.Comp.ChemicalSolution.Value, drawAmount * 0.15f); + SolutionContainers.TryAddSolution(injectorSolution, chemTemp); + drawAmount -= (float) chemTemp.Volume; + } + + if (SolutionContainers.ResolveSolution(target.Owner, target.Comp.BloodSolutionName, + ref target.Comp.BloodSolution)) + { + var bloodTemp = SolutionContainers.SplitSolution(target.Comp.BloodSolution.Value, drawAmount); + SolutionContainers.TryAddSolution(injectorSolution, bloodTemp); + } + + Popup.PopupEntity(Loc.GetString("injector-component-draw-success-message", + ("amount", transferAmount), + ("target", Identity.Entity(target, EntityManager))), injector.Owner, user); + + Dirty(injector); + AfterDraw(injector, target); + } +} diff --git a/Content.Shared/Chemistry/Components/InjectorComponent.cs b/Content.Shared/Chemistry/Components/InjectorComponent.cs new file mode 100644 index 00000000000..e29047b6ded --- /dev/null +++ b/Content.Shared/Chemistry/Components/InjectorComponent.cs @@ -0,0 +1,104 @@ +using Content.Shared.Chemistry.EntitySystems; +using Content.Shared.DoAfter; +using Content.Shared.FixedPoint; +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; + +namespace Content.Shared.Chemistry.Components; + +[Serializable, NetSerializable] +public sealed partial class InjectorDoAfterEvent : SimpleDoAfterEvent +{ +} + +/// +/// Implements draw/inject behavior for droppers and syringes. +/// +/// +/// Can optionally support both +/// injection and drawing or just injection. Can inject/draw reagents from solution +/// containers, and can directly inject into a mobs bloodstream. +/// +/// +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class InjectorComponent : Component +{ + public const string SolutionName = "injector"; + + /// + /// Whether or not the injector is able to draw from containers or if it's a single use + /// device that can only inject. + /// + [DataField("injectOnly")] + public bool InjectOnly; + + /// + /// Whether or not the injector is able to draw from or inject from mobs + /// + /// + /// for example: droppers would ignore mobs + /// + [DataField("ignoreMobs")] + public bool IgnoreMobs; + + /// + /// The minimum amount of solution that can be transferred at once from this solution. + /// + [DataField("minTransferAmount")] + [ViewVariables(VVAccess.ReadWrite)] + public FixedPoint2 MinimumTransferAmount = FixedPoint2.New(5); + + /// + /// The maximum amount of solution that can be transferred at once from this solution. + /// + [DataField("maxTransferAmount")] + [ViewVariables(VVAccess.ReadWrite)] + public FixedPoint2 MaximumTransferAmount = FixedPoint2.New(50); + + /// + /// Amount to inject or draw on each usage. If the injector is inject only, it will + /// attempt to inject it's entire contents upon use. + /// + [ViewVariables(VVAccess.ReadWrite)] + [DataField("transferAmount")] + [AutoNetworkedField] + public FixedPoint2 TransferAmount = FixedPoint2.New(5); + + /// + /// Injection delay (seconds) when the target is a mob. + /// + /// + /// The base delay has a minimum of 1 second, but this will still be modified if the target is incapacitated or + /// in combat mode. + /// + [ViewVariables(VVAccess.ReadWrite)] + [DataField("delay")] + public TimeSpan Delay = TimeSpan.FromSeconds(5); + + /// + /// The state of the injector. Determines it's attack behavior. Containers must have the + /// right SolutionCaps to support injection/drawing. For InjectOnly injectors this should + /// only ever be set to Inject + /// + [ViewVariables(VVAccess.ReadWrite)] + [AutoNetworkedField] + [DataField] + public InjectorToggleMode ToggleState = InjectorToggleMode.Draw; +} + +/// +/// Possible modes for an . +/// +public enum InjectorToggleMode : byte +{ + /// + /// The injector will try to inject reagent into things. + /// + Inject, + + /// + /// The injector will try to draw reagent from things. + /// + Draw +} diff --git a/Content.Shared/Chemistry/Components/SharedInjectorComponent.cs b/Content.Shared/Chemistry/Components/SharedInjectorComponent.cs deleted file mode 100644 index a4cea4e7c47..00000000000 --- a/Content.Shared/Chemistry/Components/SharedInjectorComponent.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Content.Shared.DoAfter; -using Content.Shared.FixedPoint; -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; - -namespace Content.Shared.Chemistry.Components -{ - [Serializable, NetSerializable] - public sealed partial class InjectorDoAfterEvent : SimpleDoAfterEvent - { - } - - /// - /// Shared class for injectors & syringes - /// - [NetworkedComponent, ComponentProtoName("Injector")] - public abstract partial class SharedInjectorComponent : Component - { - /// - /// Component data used for net updates. Used by client for item status ui - /// - [Serializable, NetSerializable] - public sealed class InjectorComponentState : ComponentState - { - public FixedPoint2 CurrentVolume { get; } - public FixedPoint2 TotalVolume { get; } - public InjectorToggleMode CurrentMode { get; } - - public InjectorComponentState(FixedPoint2 currentVolume, FixedPoint2 totalVolume, - InjectorToggleMode currentMode) - { - CurrentVolume = currentVolume; - TotalVolume = totalVolume; - CurrentMode = currentMode; - } - } - - public enum InjectorToggleMode : byte - { - Inject, - Draw - } - } -} diff --git a/Content.Shared/Chemistry/EntitySystems/SharedInjectorSystem.cs b/Content.Shared/Chemistry/EntitySystems/SharedInjectorSystem.cs new file mode 100644 index 00000000000..7ad21702817 --- /dev/null +++ b/Content.Shared/Chemistry/EntitySystems/SharedInjectorSystem.cs @@ -0,0 +1,120 @@ +using Content.Shared.Administration.Logs; +using Content.Shared.Chemistry.Components; +using Content.Shared.CombatMode; +using Content.Shared.DoAfter; +using Content.Shared.FixedPoint; +using Content.Shared.Interaction.Events; +using Content.Shared.Mobs.Systems; +using Content.Shared.Popups; +using Content.Shared.Verbs; +using Robust.Shared.Player; + +namespace Content.Shared.Chemistry.EntitySystems; + +public abstract class SharedInjectorSystem : EntitySystem +{ + /// + /// Default transfer amounts for the set-transfer verb. + /// + public static readonly FixedPoint2[] TransferAmounts = { 1, 5, 10, 15 }; + + [Dependency] protected readonly SharedPopupSystem Popup = default!; + [Dependency] protected readonly SharedSolutionContainerSystem SolutionContainers = default!; + [Dependency] protected readonly MobStateSystem MobState = default!; + [Dependency] protected readonly SharedCombatModeSystem Combat = default!; + [Dependency] protected readonly SharedDoAfterSystem DoAfter = default!; + [Dependency] protected readonly ISharedAdminLogManager AdminLogger = default!; + + public override void Initialize() + { + SubscribeLocalEvent>(AddSetTransferVerbs); + SubscribeLocalEvent(OnInjectorStartup); + SubscribeLocalEvent(OnInjectorUse); + } + + private void AddSetTransferVerbs(Entity entity, ref GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract || args.Hands == null) + return; + + if (!HasComp(args.User)) + return; + + var (_, component) = entity; + + // Add specific transfer verbs according to the container's size + var priority = 0; + var user = args.User; + foreach (var amount in TransferAmounts) + { + if (amount < component.MinimumTransferAmount || amount > component.MaximumTransferAmount) + continue; + + AlternativeVerb verb = new() + { + Text = Loc.GetString("comp-solution-transfer-verb-amount", ("amount", amount)), + Category = VerbCategory.SetTransferAmount, + Act = () => + { + component.TransferAmount = amount; + Popup.PopupClient(Loc.GetString("comp-solution-transfer-set-amount", ("amount", amount)), user, user); + Dirty(entity); + }, + + // we want to sort by size, not alphabetically by the verb text. + Priority = priority + }; + + priority -= 1; + + args.Verbs.Add(verb); + } + } + + private void OnInjectorStartup(Entity entity, ref ComponentStartup args) + { + // ???? why ????? + Dirty(entity); + } + + private void OnInjectorUse(Entity entity, ref UseInHandEvent args) + { + if (args.Handled) + return; + + Toggle(entity, args.User); + args.Handled = true; + } + + /// + /// Toggle between draw/inject state if applicable + /// + private void Toggle(Entity injector, EntityUid user) + { + if (injector.Comp.InjectOnly) + return; + + string msg; + switch (injector.Comp.ToggleState) + { + case InjectorToggleMode.Inject: + SetMode(injector, InjectorToggleMode.Draw); + msg = "injector-component-drawing-text"; + break; + case InjectorToggleMode.Draw: + SetMode(injector, InjectorToggleMode.Inject); + msg = "injector-component-injecting-text"; + break; + default: + throw new ArgumentOutOfRangeException(); + } + + Popup.PopupClient(Loc.GetString(msg), injector, user); + } + + public void SetMode(Entity injector, InjectorToggleMode mode) + { + injector.Comp.ToggleState = mode; + Dirty(injector); + } +} diff --git a/Resources/Locale/en-US/chemistry/components/injector-component.ftl b/Resources/Locale/en-US/chemistry/components/injector-component.ftl index e137130290c..4fafc9cd3bb 100644 --- a/Resources/Locale/en-US/chemistry/components/injector-component.ftl +++ b/Resources/Locale/en-US/chemistry/components/injector-component.ftl @@ -3,7 +3,8 @@ injector-draw-text = Draw injector-inject-text = Inject injector-invalid-injector-toggle-mode = Invalid -injector-volume-label = Volume: [color=white]{$currentVolume}/{$totalVolume}[/color] | [color=white]{$modeString}[/color] +injector-volume-label = Volume: [color=white]{$currentVolume}/{$totalVolume}[/color] + Mode: [color=white]{$modeString}[/color] ([color=white]{$transferVolume}u[/color]) ## Entity From cfc47017c311a5468d5138c417e561e944bc6df6 Mon Sep 17 00:00:00 2001 From: Zadeon Date: Wed, 14 Feb 2024 17:07:31 -0600 Subject: [PATCH 128/200] Updated disabler to have suitStorage tag under slots. (#25238) (cherry picked from commit 9d87d4be4fd8bfe857180ed6ae2d18188398748e) --- .../Entities/Objects/Weapons/Guns/Battery/battery_guns.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml index 389b3f517bb..00d12606841 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml @@ -427,6 +427,7 @@ sprite: Objects/Weapons/Guns/Battery/disabler.rsi quickEquip: false slots: + - suitStorage - Belt - type: Gun fireRate: 2 From 400ca3a4d91f98c745e237c57ec059e67c388f83 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 14 Feb 2024 23:08:37 +0000 Subject: [PATCH 129/200] Automatic changelog update (cherry picked from commit ef4ca651a9d04ec89946b4b00a773f319a833c50) --- 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 65d9aa381af..844d64b7562 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Hqlle - changes: - - message: Resprited carpet sprites. - type: Add - id: 5440 - time: '2023-12-21T05:32:38.0000000+00:00' - url: null - author: CrigCrag changes: - message: Added Fresium, a military grade coolant that you SHOULD NOT INGEST OR @@ -3882,3 +3875,10 @@ Order: 1 id: 5939 time: '2024-02-14T05:25:59.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25120 +- author: Zadeon + changes: + - message: Disablers now fit inside the suit storage slot. + type: Fix + id: 5940 + time: '2024-02-14T23:07:31.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25238 From 5a315ab91afa81d71a42f216909b3bc5a5f3f0ec Mon Sep 17 00:00:00 2001 From: Krunklehorn <42424291+Krunklehorn@users.noreply.github.com> Date: Wed, 14 Feb 2024 19:24:35 -0500 Subject: [PATCH 130/200] Fix spawn priority persistence on reconnect and restart (#25246) Because of course I would forget one line (cherry picked from commit 2f0c837816589b24b1548eafa278e28340577eb3) --- Content.Server/Database/ServerDbBase.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Content.Server/Database/ServerDbBase.cs b/Content.Server/Database/ServerDbBase.cs index 5365bfb05b2..27ccb6ee0ea 100644 --- a/Content.Server/Database/ServerDbBase.cs +++ b/Content.Server/Database/ServerDbBase.cs @@ -260,6 +260,7 @@ private static Profile ConvertProfiles(HumanoidCharacterProfile humanoid, int sl profile.SkinColor = appearance.SkinColor.ToHex(); profile.Clothing = humanoid.Clothing.ToString(); profile.Backpack = humanoid.Backpack.ToString(); + profile.SpawnPriority = (int) humanoid.SpawnPriority; profile.Markings = markings; profile.Slot = slot; profile.PreferenceUnavailable = (DbPreferenceUnavailableMode) humanoid.PreferenceUnavailable; From 0b848034e945c756ff77191d5f552603623e5f3a Mon Sep 17 00:00:00 2001 From: brainfood1183 <113240905+brainfood1183@users.noreply.github.com> Date: Thu, 15 Feb 2024 00:52:24 +0000 Subject: [PATCH 131/200] Add French accent beret (#21430) (cherry picked from commit e1805e04d43bc7c8cb240ebc1d1271fa229bcc62) --- .../Components/FrenchAccentComponent.cs | 11 +++++ .../EntitySystems/FrenchAccentSystem.cs | 45 ++++++++++++++++++ .../VendingMachines/Inventories/theater.yml | 1 + .../Entities/Clothing/Head/hats.yml | 17 +++++++ .../Prototypes/Roles/Jobs/Civilian/mime.yml | 1 + .../Hats/beret_french.rsi/equipped-HELMET.png | Bin 0 -> 16970 bytes .../Head/Hats/beret_french.rsi/icon.png | Bin 0 -> 15283 bytes .../Hats/beret_french.rsi/inhand-left.png | Bin 0 -> 16928 bytes .../Hats/beret_french.rsi/inhand-right.png | Bin 0 -> 16926 bytes .../Head/Hats/beret_french.rsi/meta.json | 26 ++++++++++ 10 files changed, 101 insertions(+) create mode 100644 Content.Server/Speech/Components/FrenchAccentComponent.cs create mode 100644 Content.Server/Speech/EntitySystems/FrenchAccentSystem.cs create mode 100644 Resources/Textures/Clothing/Head/Hats/beret_french.rsi/equipped-HELMET.png create mode 100644 Resources/Textures/Clothing/Head/Hats/beret_french.rsi/icon.png create mode 100644 Resources/Textures/Clothing/Head/Hats/beret_french.rsi/inhand-left.png create mode 100644 Resources/Textures/Clothing/Head/Hats/beret_french.rsi/inhand-right.png create mode 100644 Resources/Textures/Clothing/Head/Hats/beret_french.rsi/meta.json diff --git a/Content.Server/Speech/Components/FrenchAccentComponent.cs b/Content.Server/Speech/Components/FrenchAccentComponent.cs new file mode 100644 index 00000000000..f696c35ea03 --- /dev/null +++ b/Content.Server/Speech/Components/FrenchAccentComponent.cs @@ -0,0 +1,11 @@ +using Content.Server.Speech.EntitySystems; + +namespace Content.Server.Speech.Components; + +/// +/// French accent replaces spoken letters. "th" becomes "z" and "H" at the start of a word becomes "'". +/// +[RegisterComponent] +[Access(typeof(FrenchAccentSystem))] +public sealed partial class FrenchAccentComponent : Component +{ } diff --git a/Content.Server/Speech/EntitySystems/FrenchAccentSystem.cs b/Content.Server/Speech/EntitySystems/FrenchAccentSystem.cs new file mode 100644 index 00000000000..56372887325 --- /dev/null +++ b/Content.Server/Speech/EntitySystems/FrenchAccentSystem.cs @@ -0,0 +1,45 @@ +using Content.Server.Speech.Components; +using System.Text.RegularExpressions; + +namespace Content.Server.Speech.EntitySystems; + +/// +/// System that gives the speaker a faux-French accent. +/// +public sealed class FrenchAccentSystem : EntitySystem +{ + [Dependency] private readonly ReplacementAccentSystem _replacement = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnAccentGet); + } + + public string Accentuate(string message, FrenchAccentComponent component) + { + var msg = message; + + msg = _replacement.ApplyReplacements(msg, "french"); + + // replaces th with dz + msg = Regex.Replace(msg, @"th", "'z", RegexOptions.IgnoreCase); + + // removes the letter h from the start of words. + msg = Regex.Replace(msg, @"(?a z)G>wOG!5Z~3E@g93piwz-mT}St)KbM z%9-=Hg1$qhU06El$+^cl=N`X!gTMHTU$aYA8w(E2>^N#o#mtQH_9gt@WrK5$d^2Le z!ZEWqjKA6LmTzOvmlr=vvtgb-(Y2J9qu@=VfQVxYo0e`4Y8s zaZmDF%hu(e<+>j{e417@*1x*u)-kv)mQ{3V8DC~E#7V}RMNo_rWQDveTtx&i=Z08< ztOC5k3EZ?VM|pF{Zl!{za+G8AcFfM^gG#!f#t%wrMwXH_Riueh=2|k$Ashzq0-jKW zydEEihjNtRxH$YRG^0vI7{XWODD#AbiZZ)Hk zYCVc+Q7xv@XmK5e>okh!OKHh~zs!Ehg%?|gM$^H+a+H-k&*CT=3qC|N+wrY%>uL-a7@5Yf*})tkMEZ%)G(Xf5sxHH z*G+rb@Py$aq)bkcaXcIFd%{?XM1co*VG<6GTb+^zxJXAbP5Cu(6Ft93bL$VZGwr zEe7CeSHf0JrZ4ogNCP3d1)9(kp@mHx@s=6R!EVQ`3>gp>!)CPz%ZXDANmF?ECz%cO zCbb5ZiJr(-=?D|1G69!Sr8PRKY)or30kz32NYOM*!oJZIHXp|mJ`%tb5S&HB_&VTp znMfm{A}}gjrODO-mD8v!hP9!i0I6~s2)HbIOb=X6jX|T;#1e?;E$84E7at`2AkPggW*G(z zrqE=mF-7JW+D9=#u750AQ((&hgO$K%(O?>_3WKA>N-?-i>v63<7AM@FOgE##_UfVk z@2e!zOj;#GTp*$+PcdPighFby3e%OU4Y*c^>x>nxN|fL?U5Us=GjW!JM=9YV`M)n< z%$MJ3)YOX>X>D3@u_|s}p=RNdh37eJ7EKmrM&o}a)Qcb-9)fo#>O zTWBxg1}N)uo6$sLQ=~BXX2@ux2nkJx=lcNxH?mTO@mRjc>LycCMFUoX2a&2wcutFB zYUsH*KLSdk+Zl>>Ri~myEi2GPpkz8c;!y-od{+Q5OcX+NAixV5k`VUYusm=hO~8cG z5cZG3gc}t#o5kmeR_NwbSxPFIpidM`QjTPDlMH!&KFIj1iu^^+*8s^&&CxQwNtR-G zNauKewN0{6DVb*BaE03hpO*w!)1rvqf4YY9UPmAIE(EX{R8V<3~$8pYbq$SU11|ccfI!344oJ@J87YxlgtTyOP2g zpgp{b_9?jHVS~kSL_kp>;dF|_qZGW0)VBzz>OoJ5ki zvRtxUk`#~xmfa=GB}oBEVA)-=T#^)!1eV<;%OyzxNnqJsvRslBkOY?9CCepA0ZCxl zU9wz~6p#d#-6hKHEc442kMYo@xKe*o7xj6kr z;=!iw#h-x_bNLa^(pEIgUp%p4GS>NU;qqPw&Y>B7Kd?Z@BL)?=jo!zGuyS+}5cuAM|brTzs@@)#gj5+iWB6Ec(}#BU?N>wN|Wl z-MUF<-+Qm2eoN&B{p^cho-^9Je9&PvUGpKkrfcU>TXTN&{GCnX$KUG1el+&soVwrk nXxz5{f~l2pgu6a|W8(A3?SeL!4qiYW3N5xFBdr?;zgqWS#yIcZ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hats/beret_french.rsi/icon.png b/Resources/Textures/Clothing/Head/Hats/beret_french.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..608a155cfdc842548333de8732dd527a1dc06ec2 GIT binary patch literal 15283 zcmeI3du$X%9LEQZP^&~xt4Po+2O4~A_jP;MTdxPD2W<`4mOiwgMz_0j*9~{O$L_Yh z7XFY&A_O&xiI3Vu{!ol05~DF{w2BW*jE{dvtkE>!Bc^HE>J!2G7hXdC)wym!T1^yv%^oP#w)dIJz%nMteKCg?KVFkzUrzT-<74T1*kd#f+OU1FxkDS=q=j_f%1C86qo4pO=&DR6l{6hCQ|rsdRnTv*ne#E( zF7BpUU!9kb>58>7^_C48xjMjVd?3gKL)C&D4Elq&Fd{F=94~Pa&x(@b=M}%mO z68#F>dR%FXuFa=IR;{ncb<+yR_4oHz_e<55o#2E}D8%t1CyFfU!8!w`t7cf!S(Xbj z6(^Gc-)iA*QY4pHPXYMK+Od9IvD*9w|+ubs>e zP1iV>gehpc4$=u_b?F|r-Bh!+=US|rai>)2t&m__D!at5FX@EKQR(QatNvYp(rzUobWMp{c1m?4MoLXU zE^Q{lT(PmFXJIcX^;Xid(THF~3UlR}OH|qYr8Jq2tC|{YibhaFwPEOrEck=nFc4=Y zwMJ&88o$7*vL>?rZY>b+_N!uCgxR^rVx{sKp`(`8>(vMfojXo+OGDv{!_oqBjT(we zY_MC5vw{F28xkaq4M7>g8Y#dBG&GIeI7@=fNYr8*=(JOlC4IcP=qQ;a`XxOs_|Y`f z5bM|cLAFNfhHOv`KrJ2!Ng=r~moi~yq-r!Av_}U@_Ac7N+4HO&Zl2ycK+^aR7Q#{c{@pU1TUGs|Wted; z{eLS^+`w9oY9^o_;imTPRKvL~T5c()7uD2RFtZ55-oKH83K(rBHCs4Bn48g7%$)1r zq?vWNE1zmlle zk@;X=iVFimHYqMLAIwW}VL-?x#YN_Wc_}Uo2-&2#$b2v_#f1SOn-mwB59Xz~Fd$@; z;v)0Gyc8D(gltk=WImXe;=+KCO^S=m2lG-~7!a~aagq68UWy9?LN+NbG9S!KabZBn zCdEbOgLx?~3<%kzxX64kFU5rcA)6EznGfcrxG*4Olj0)t!Mqd~283)J zkWGq<%m?#QTo@3tNyJrId}b4x=t0eX^hD+}iS*unqw=ux z+R@{$jhV|HNo?-CcH6qXLtCCcJcs$9LfYY&`f2{s*E_0&wd+1TWWVlTxNX;=(7e5G z@9eC4{G*HZ9QL(X@m<2#TO%zWtr|M{$D8-7i=O>+aO47T>aBSnCePf`uA91O!T6rz`|1`|4xn`aO>3H?2Up*_{V&;C!F2!t literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hats/beret_french.rsi/inhand-left.png b/Resources/Textures/Clothing/Head/Hats/beret_french.rsi/inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..84d21a6738cdc91042032e3fe12be58f727de5c7 GIT binary patch literal 16928 zcmeI4Yj6|S701^BYGdjG11XP|A_PoB%4#2aS&J;NEkD#CaBKtS6d!#5|^@#U?-kghxt=Asr}WCIP2FVG=r+0u9Y%+VC*YyOJzj$ub*v zGSe@s8Ka}S=YP(vPWhk2$JI}b(VwgDav2gx4^$U`9+t(SAVf| zwuB%9hA4j-$c9bB5hPvU9_iS;=2A0{rpikgwpn=?c|tklU8&V{mImPZ+XkK>*2j?2W>9e@!G!H-SoPZx%Miq|m9MOltK3s5M(`VGR`76!uwMkT zh#>aKVUcF)I9cc6s`)^k{`R5w^g5o+)6X)yakp5=)$pZDf?UOtX_d^9I>yH8Cp)t3 zVG0EBb26<9`+Wh43g_t~aVcOc&6r*nagpot^!Z9cU6s2`S11HIo!MYP8QfykS#1Ww zY_*!K6Llm`m@(Xl8F7>}QYM@-k-FGN@5lz0J;-{ga%XWY9r%@}uaRYu!mv;%WC$4z zLa-VmY&IK)lNd>&zyp;U0x}&&1Jc-NkghmRPGW+*DDy%rVCZ# za+k#;DZ{Pi{bFRmU=q?MXPLOaSReF7d|3wLe4HO7kwCwRv^o$kE==3yblr1_GGhYD zqHtoofG!isD#T zrRZwtS;BXp7J{@H2?EDaj}1(Qi7;}ghcPoK;q@}+T(8+;RHh}`B}m?L4oUFJAv(zA zSA!CBlz;-$kp=?SJvECDutG?h&=oD&vFCuH8ZO`8-^2=Nf(tz8s_^(8PL_NxUwCojven+e0#LAC5?35aP=BgTBTh%Tv0Bi&MWFg(Z_SaG#v-4K6wHjtAb+2O1^g?yNjX`3k9(OoH}ac z>7hU`y4j;F8g(kqZ~;m9`om5mu*Z*GB;)I$LpP_;E& zs)%3*4Hry9)z)ySB7z+>Trdq)Tf?P_2zJnL!8BBD4VNk+*g?Yu(@?cFT&jp*2MrfY zL)F%BsUm_MG+ZzZRr|5HvJ-Efa{=(Wc?i5$-cP=>1-z54V@k{22(n~6f;Tv|Qu@FJ1^$0RdShJw582pz53tZ0p%J79-7mlr3h7axc;a4xdsPm2zpM3PF z_0p>4Qc_DD;&Y>jFYjC! zZfx08Iiv0Df6V^T1zX;28Fv4ZcXuCe+?ADsoLIl@)se0H{r88ye|YKYS2jsaSwhCb z)vkukLyQ%xzqr^jza7<2&73T}w_MDfGW#{xgd(E2cEhy*a{2xYv{k>$r4$P<+u3yr8Dy0kEA|@?`)d9{+ekn^QF|sxnS<~i- F_%E>;#d81v literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hats/beret_french.rsi/inhand-right.png b/Resources/Textures/Clothing/Head/Hats/beret_french.rsi/inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..aee4b59f97a0cd033d24f6255e6c88fb3ff99e28 GIT binary patch literal 16926 zcmeI4Yj6|S6~~tj6l0(`layC@2oajVu-es1mb8m3YD<0yBkWiP41vIUcO|baX&3Dp z$+#hu$4m$$q);*`=}_KnXoHgm3Y1_5&)7P;d;aI#`@84fz58Lkv3g$l$o%p72!f1sSGa1x=eL#Lysv}52l*8rfRABf z#UcqohTpIJ4nlVPa4doh+RQth)zuAxEJzK4sB=4=Ix#Hx_yC6>(aYO^JFCGv=z+8U z_`}IZ8~5*jYMhH&f>VnMCU-o#XYAnN)1GTkDAL*xkW7tD^_u1b)7r7X*bypp`vU%Gl?cRr8e*EDdoiFRCA$Qzr z?EIPYBDrAWiN9|@a(;;SRy@{WGbz2i<)_OChq@6IEI>?@CSKmE<0>gPW((o@Iz^_Ss(FmG^DZs$;z2d@r`{^pLc`sPMzxb?v8Czfx$GTUEvyBFy|!f!tPlX2@1#IcvJt&{6Kb16m$8faFi=M2%H z2xbvM?6adH%`|bcuAcMrp(1_HiBozV&lc$y7J6`x=;RvsidA9GyJ}u7v#N<9S^aEB zzCB8T06|WsbtZf)Q<1({NvNyyRO_5Vn9~&+EGUCptU4=c zFcw;^X6sBHfg1}k+=Q8MlrT|doH7%-#E;&Q4=j6_^-(phvP3%Ytw`S>%OZtgkx0Z4 zF&TugA2X69iQxoB5Ge3KrIwIPN70ZpH6A1x$HhrZm=|SU2%&33`Ad7NteZXuz>x5X+^MeECxAX1diKKoInXOX9vVUvjq2`S>lwYSf~K&!;}Fl&~x=eOl~}I zfOxel^Od^XZvdJ1rOPT~_{x=jWn7f+N2Xkf%VI?wuPr+mgU3U;1g2S;47banOee(( z49`+AlkwFPoDHW@+{&`3nFOV5D^!?SSSx9wZ7f;nvnwbv!=%eMk-{C4WIDufAO&zX z@F2d0CT!+<&Wc)$W*Q|;W*nvK>q!)6aFRBe!8-J@$<1<0CnRZ|MSwdsGK#*(Zd9jzn1|TvN^2 z{12$2vJY(P1(#Tglj!*WCjH&unJ>Ki#m9%zpK;GQZdW}@T=7P7A>9?>a?E#TDAAXh~~ z1L$VIvUt?FJi~<~;mZ#@hrpgXT2f9SAcVoX;T$G=`osw}r^_2sfd}R4_;a#D*(!DQ z&3r&c`H)VkDKCNJK#ou#<#bAcqZGK+$Ci=lYHPSu5y1``E|`X@t>IEd1UqQBU>d5n zhD#L@?4aR-X{g#7E>%RZgN6&Hp=xWmR1v`r8ZMZIs;%KtMFcx&xL_KpwuVa;5$vGh zf@!GQ8ZK2tu!DvRrlD$UxKt6r4jL|)hN`XMQbhziXt-b+sXwsJNJKK>n_0GZ7bB0WD{c`!zu06U>ds}tHqCZXRn!ubs}qevO3!5Yc*$% z2;$XE56@`Z`Nz)Ay7nj zSM8GE=~Kw+Z6n46JBIvPkZu-yEfINF=gmn->65Rmtem;1U1@Wd&T}0qS-$qagS@{g literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Head/Hats/beret_french.rsi/meta.json b/Resources/Textures/Clothing/Head/Hats/beret_french.rsi/meta.json new file mode 100644 index 00000000000..a470e009443 --- /dev/null +++ b/Resources/Textures/Clothing/Head/Hats/beret_french.rsi/meta.json @@ -0,0 +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-HELMET", + "directions": 4 + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} From 7e6a8ef6e5bc3afc5b90751330fb52198d7c4825 Mon Sep 17 00:00:00 2001 From: Menshin Date: Thu, 15 Feb 2024 02:00:21 +0100 Subject: [PATCH 132/200] Allow thermomachines to exchange with air instead of inlet (#25247) Add purely atmospheric heat exchange to the gas thermomachine component (in preparation for space heaters). (cherry picked from commit ce4bd8568cba4d64fb19e80d3182e21f010a86c1) --- .../Components/GasThermoMachineComponent.cs | 6 ++ .../EntitySystems/GasThermoMachineSystem.cs | 55 ++++++++++++++----- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/Content.Server/Atmos/Piping/Unary/Components/GasThermoMachineComponent.cs b/Content.Server/Atmos/Piping/Unary/Components/GasThermoMachineComponent.cs index 93d973d1231..5da4ec9fdf2 100644 --- a/Content.Server/Atmos/Piping/Unary/Components/GasThermoMachineComponent.cs +++ b/Content.Server/Atmos/Piping/Unary/Components/GasThermoMachineComponent.cs @@ -64,5 +64,11 @@ public sealed partial class GasThermoMachineComponent : Component ///
[DataField, ViewVariables(VVAccess.ReadWrite)] public float EnergyLeakPercentage; + + /// + /// If true, heat is exclusively exchanged with the local atmosphere instead of the inlet pipe air + /// + [DataField, ViewVariables(VVAccess.ReadWrite)] + public bool Atmospheric = false; } } diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs index 645b2ecc459..29000826232 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasThermoMachineSystem.cs @@ -55,17 +55,17 @@ private void OnBeforeOpened(Entity ent, ref BeforeAct private void OnThermoMachineUpdated(EntityUid uid, GasThermoMachineComponent thermoMachine, ref AtmosDeviceUpdateEvent args) { - if (!(_power.IsPowered(uid) && TryComp(uid, out var receiver)) - || !TryComp(uid, out var nodeContainer) - || !_nodeContainer.TryGetNode(nodeContainer, thermoMachine.InletName, out PipeNode? inlet)) - { + if (!(_power.IsPowered(uid) && TryComp(uid, out var receiver))) + return; + + GetHeatExchangeGasMixture(uid, thermoMachine, out var heatExchangeGasMixture); + if (heatExchangeGasMixture == null) return; - } float sign = Math.Sign(thermoMachine.Cp); // 1 if heater, -1 if freezer float targetTemp = thermoMachine.TargetTemperature; float highTemp = targetTemp + sign * thermoMachine.TemperatureTolerance; - float temp = inlet.Air.Temperature; + float temp = heatExchangeGasMixture.Temperature; if (sign * temp >= sign * highTemp) // upper bound thermoMachine.HysteresisState = false; // turn off @@ -74,8 +74,7 @@ private void OnThermoMachineUpdated(EntityUid uid, GasThermoMachineComponent the if (thermoMachine.HysteresisState) targetTemp = highTemp; // when on, target upper hysteresis bound - - if (!thermoMachine.HysteresisState) // Hysteresis is the same as "Should this be on?" + else // Hysteresis is the same as "Should this be on?" { // Turn dynamic load back on when power has been adjusted to not cause lights to // blink every time this heater comes on. @@ -87,7 +86,7 @@ private void OnThermoMachineUpdated(EntityUid uid, GasThermoMachineComponent the float dQ = thermoMachine.HeatCapacity * thermoMachine.Cp * args.dt; // Clamps the heat transferred to not overshoot - float Cin = _atmosphereSystem.GetHeatCapacity(inlet.Air, true); + float Cin = _atmosphereSystem.GetHeatCapacity(heatExchangeGasMixture, true); float dT = targetTemp - temp; float dQLim = dT * Cin; float scale = 1f; @@ -96,17 +95,45 @@ private void OnThermoMachineUpdated(EntityUid uid, GasThermoMachineComponent the scale = dQLim / dQ; // reduce power consumption thermoMachine.HysteresisState = false; // turn off } + float dQActual = dQ * scale; - float dQLeak = dQActual * thermoMachine.EnergyLeakPercentage; - float dQPipe = dQActual - dQLeak; - _atmosphereSystem.AddHeat(inlet.Air, dQPipe); + if (thermoMachine.Atmospheric) + { + _atmosphereSystem.AddHeat(heatExchangeGasMixture, dQActual); + } + else + { + float dQLeak = dQActual * thermoMachine.EnergyLeakPercentage; + float dQPipe = dQActual - dQLeak; + _atmosphereSystem.AddHeat(heatExchangeGasMixture, dQPipe); - if (_atmosphereSystem.GetContainingMixture(uid) is { } containingMixture) - _atmosphereSystem.AddHeat(containingMixture, dQLeak); + if (dQLeak != 0f && _atmosphereSystem.GetContainingMixture(uid) is { } containingMixture) + _atmosphereSystem.AddHeat(containingMixture, dQLeak); + } receiver.Load = thermoMachine.HeatCapacity;// * scale; // we're not ready for dynamic load yet, see note above } + /// + /// Returns the gas mixture with which the thermomachine will exchange heat (the local atmosphere if atmospheric or the inlet pipe + /// air if not). Returns null if no gas mixture is found. + /// + private void GetHeatExchangeGasMixture(EntityUid uid, GasThermoMachineComponent thermoMachine, out GasMixture? heatExchangeGasMixture) + { + heatExchangeGasMixture = null; + if (thermoMachine.Atmospheric) + { + heatExchangeGasMixture = _atmosphereSystem.GetContainingMixture(uid); + } + else + { + if (!TryComp(uid, out var nodeContainer) + || !_nodeContainer.TryGetNode(nodeContainer, thermoMachine.InletName, out PipeNode? inlet)) + return; + heatExchangeGasMixture = inlet.Air; + } + } + private bool IsHeater(GasThermoMachineComponent comp) { return comp.Cp >= 0; From 15d22b8315b939da2474fef16f23b6bfb4e9ff10 Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:06:11 -0800 Subject: [PATCH 133/200] Fix: Holosigns can be stored again (#25249) * Holosigns can be stored again * TryComp to HasComp --------- Co-authored-by: Plykiya (cherry picked from commit d6139429ad59a4137c383044613364137a8a338b) --- Content.Server/Holosign/HolosignSystem.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Content.Server/Holosign/HolosignSystem.cs b/Content.Server/Holosign/HolosignSystem.cs index c52272e957f..58a0bf0d5f9 100644 --- a/Content.Server/Holosign/HolosignSystem.cs +++ b/Content.Server/Holosign/HolosignSystem.cs @@ -3,6 +3,7 @@ using Content.Server.Power.Components; using Content.Server.PowerCell; using Content.Shared.Interaction; +using Content.Shared.Storage; namespace Content.Server.Holosign; @@ -43,6 +44,7 @@ private void OnBeforeInteract(EntityUid uid, HolosignProjectorComponent componen if (args.Handled || !args.CanReach // prevent placing out of range + || HasComp(args.Target) // if it's a storage component like a bag, we ignore usage so it can be stored || !_powerCell.TryUseCharge(uid, component.ChargeUse) // if no battery or no charge, doesn't work ) return; From 53bd523984d7011a84221bfa0f5cc7bbf79ab747 Mon Sep 17 00:00:00 2001 From: Jezithyr Date: Wed, 14 Feb 2024 17:37:56 -0800 Subject: [PATCH 134/200] Death acidifier fix (#25251) (cherry picked from commit be29a054de37b54d7c0a09c75b6fded91374341a) --- Content.Server/Body/Systems/BodySystem.cs | 3 +-- .../Explosion/EntitySystems/TriggerSystem.cs | 14 +++++++++++--- .../Body/Systems/SharedBodySystem.Body.cs | 3 +-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Content.Server/Body/Systems/BodySystem.cs b/Content.Server/Body/Systems/BodySystem.cs index 0e9b295f718..18119909abc 100644 --- a/Content.Server/Body/Systems/BodySystem.cs +++ b/Content.Server/Body/Systems/BodySystem.cs @@ -111,7 +111,6 @@ public override HashSet GibBody( EntityUid bodyId, bool gibOrgans = false, BodyComponent? body = null , - bool deleteItems = false, bool launchGibs = true, Vector2? splatDirection = null, float splatModifier = 1, @@ -129,7 +128,7 @@ public override HashSet GibBody( if (xform.MapUid == null) return new HashSet(); - var gibs = base.GibBody(bodyId, gibOrgans, body, deleteItems, launchGibs: launchGibs, + var gibs = base.GibBody(bodyId, gibOrgans, body, launchGibs: launchGibs, splatDirection: splatDirection, splatModifier: splatModifier, splatCone:splatCone); RaiseLocalEvent(bodyId, new BeingGibbedEvent(gibs)); QueueDel(bodyId); diff --git a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs index aa81f80c501..5830018c488 100644 --- a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs +++ b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs @@ -12,6 +12,7 @@ using Content.Shared.Explosion.Components.OnTrigger; using Content.Shared.Implants.Components; using Content.Shared.Interaction; +using Content.Shared.Inventory; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Payload.Components; @@ -68,6 +69,7 @@ public sealed partial class TriggerSystem : EntitySystem [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; + [Dependency] private readonly InventorySystem _inventory = default!; public override void Initialize() { @@ -154,9 +156,15 @@ private void HandleGibTrigger(EntityUid uid, GibOnTriggerComponent component, Tr { if (!TryComp(uid, out var xform)) return; - - _body.GibBody(xform.ParentUid, true, deleteItems: component.DeleteItems); - + if (component.DeleteItems) + { + var items = _inventory.GetHandOrInventoryEntities(xform.ParentUid); + foreach (var item in items) + { + Del(item); + } + } + _body.GibBody(xform.ParentUid, true); args.Handled = true; } diff --git a/Content.Shared/Body/Systems/SharedBodySystem.Body.cs b/Content.Shared/Body/Systems/SharedBodySystem.Body.cs index 85b6758d78a..bc7cf63124c 100644 --- a/Content.Shared/Body/Systems/SharedBodySystem.Body.cs +++ b/Content.Shared/Body/Systems/SharedBodySystem.Body.cs @@ -274,8 +274,7 @@ public IEnumerable GetBodyAllSlots(EntityUid bodyId, BodyComponent public virtual HashSet GibBody( EntityUid bodyId, bool gibOrgans = false, - BodyComponent? body = null , - bool deleteItems = false, + BodyComponent? body = null, bool launchGibs = true, Vector2? splatDirection = null, float splatModifier = 1, From f599c1db27a0d34f6bb111b134e26d2a3904956e Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 15 Feb 2024 01:39:02 +0000 Subject: [PATCH 135/200] Automatic changelog update (cherry picked from commit d6502cd71b0e727d38ad998cc2dd06ddab681526) --- 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 844d64b7562..e2cad1c15fb 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,5 @@ Order: 1 Entries: -- author: CrigCrag - changes: - - message: Added Fresium, a military grade coolant that you SHOULD NOT INGEST OR - SPLASH ON YOUR FRIENDS! - type: Add - id: 5441 - time: '2023-12-21T05:35:22.0000000+00:00' - url: null - author: RiceMar changes: - message: Energy swords and double energy swords now look as long as they seem @@ -3882,3 +3874,10 @@ Order: 1 id: 5940 time: '2024-02-14T23:07:31.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25238 +- author: Jezithyr + changes: + - message: Death Acidifier implants not deleting items when activated + type: Fix + id: 5941 + time: '2024-02-15T01:37:56.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25251 From a37bd5b2a7188ae45e45c4efbabb60847376dccd Mon Sep 17 00:00:00 2001 From: nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com> Date: Thu, 15 Feb 2024 21:36:43 +0200 Subject: [PATCH 136/200] Clarify stripping logs (#25190) * Indicate whether pickpocketing is stealthy in logs, change :user to :actor, and clean up messages. * Remove ugly whitespace * Do the thing I should have done but didn't because I didn't want to think * Fix spacing (cherry picked from commit 82f5bf8121f6f018d8af6442a031b21f9d95cba7) --- Content.Server/Strip/StrippableSystem.cs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Content.Server/Strip/StrippableSystem.cs b/Content.Server/Strip/StrippableSystem.cs index 89eb202b25e..50a9cb9b691 100644 --- a/Content.Server/Strip/StrippableSystem.cs +++ b/Content.Server/Strip/StrippableSystem.cs @@ -238,7 +238,8 @@ bool Check() _popup.PopupEntity(message, target, target, PopupType.Large); } - _adminLogger.Add(LogType.Stripping, LogImpact.Low, $"{ToPrettyString(user):user} is trying to place the item {ToPrettyString(held):item} in {ToPrettyString(target):target}'s {slot} slot"); + var prefix = ev.Stealth ? "stealthily " : ""; + _adminLogger.Add(LogType.Stripping, LogImpact.Low, $"{ToPrettyString(user):actor} is trying to {prefix}place the item {ToPrettyString(held):item} in {ToPrettyString(target):target}'s {slot} slot"); var result = await _doAfter.WaitDoAfter(doAfterArgs); if (result != DoAfterStatus.Finished) @@ -250,7 +251,7 @@ bool Check() { _inventorySystem.TryEquip(user, target, held, slot); - _adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):user} has placed the item {ToPrettyString(held):item} in {ToPrettyString(target):target}'s {slot} slot"); + _adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):actor} has placed the item {ToPrettyString(held):item} in {ToPrettyString(target):target}'s {slot} slot"); } } @@ -305,14 +306,15 @@ bool Check() DuplicateCondition = DuplicateConditions.SameTool }; - _adminLogger.Add(LogType.Stripping, LogImpact.Low, $"{ToPrettyString(user):user} is trying to place the item {ToPrettyString(held):item} in {ToPrettyString(target):target}'s hands"); + var prefix = ev.Stealth ? "stealthily " : ""; + _adminLogger.Add(LogType.Stripping, LogImpact.Low, $"{ToPrettyString(user):actor} is trying to {prefix}place the item {ToPrettyString(held):item} in {ToPrettyString(target):target}'s hands"); var result = await _doAfter.WaitDoAfter(doAfterArgs); if (result != DoAfterStatus.Finished) return; _handsSystem.TryDrop(user, checkActionBlocker: false, handsComp: userHands); _handsSystem.TryPickup(target, held, handName, checkActionBlocker: false, animateUser: !ev.Stealth, animate: !ev.Stealth, handsComp: hands); - _adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):user} has placed the item {ToPrettyString(held):item} in {ToPrettyString(target):target}'s hands"); + _adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):actor} has placed the item {ToPrettyString(held):item} in {ToPrettyString(target):target}'s hands"); // hand update will trigger strippable update } @@ -381,7 +383,8 @@ bool Check() } } - _adminLogger.Add(LogType.Stripping, LogImpact.Low, $"{ToPrettyString(user):user} is trying to strip the item {ToPrettyString(item):item} from {ToPrettyString(target):target}"); + var prefix = ev.Stealth ? "stealthily " : ""; + _adminLogger.Add(LogType.Stripping, LogImpact.Low, $"{ToPrettyString(user):actor} is trying to {prefix}strip the item {ToPrettyString(item):item} from {ToPrettyString(target):target}'s {slot} slot"); var result = await _doAfter.WaitDoAfter(doAfterArgs); if (result != DoAfterStatus.Finished) @@ -394,7 +397,7 @@ bool Check() RaiseLocalEvent(item, new DroppedEvent(user), true); _handsSystem.PickupOrDrop(user, item, animateUser: !ev.Stealth, animate: !ev.Stealth); - _adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):user} has stripped the item {ToPrettyString(item):item} from {ToPrettyString(target):target}"); + _adminLogger.Add(LogType.Stripping, LogImpact.Medium, $"{ToPrettyString(user):actor} has stripped the item {ToPrettyString(item):item} from {ToPrettyString(target):target}'s {slot} slot"); } @@ -453,8 +456,9 @@ bool Check() strippable.Owner); } + var prefix = ev.Stealth ? "stealthily " : ""; _adminLogger.Add(LogType.Stripping, LogImpact.Low, - $"{ToPrettyString(user):user} is trying to strip the item {ToPrettyString(item):item} from {ToPrettyString(target):target}"); + $"{ToPrettyString(user):actor} is trying to {prefix}strip the item {ToPrettyString(item):item} from {ToPrettyString(target):target}'s hands"); var result = await _doAfter.WaitDoAfter(doAfterArgs); if (result != DoAfterStatus.Finished) @@ -464,7 +468,7 @@ bool Check() _handsSystem.PickupOrDrop(user, item, animateUser: !ev.Stealth, animate: !ev.Stealth, handsComp: userHands); // hand update will trigger strippable update _adminLogger.Add(LogType.Stripping, LogImpact.Medium, - $"{ToPrettyString(user):user} has stripped the item {ToPrettyString(item):item} from {ToPrettyString(target):target}"); + $"{ToPrettyString(user):actor} has stripped the item {ToPrettyString(item):item} from {ToPrettyString(target):target}'s hands"); } } } From 8cdd3d1cb7914a4eff358a54a37d429e1fba211a Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Thu, 15 Feb 2024 21:52:52 +0100 Subject: [PATCH 137/200] Fix disposals bins not automatically flushing after an object is inserted (#25233) Fix disposals bins not automatically flushing after an object is inserted. Because of Spaghetti Code:tm:, AfterInsert() in DisposalUnitSystem still handles insertion itself. Except in all cases except drag/drop insert, the object is already inserted so this check fails and the remaining logic doesn't happen anymore. Fixed now. (cherry picked from commit 571d4f735888343ca3ba90eaea0908257095cdb9) --- .../Disposal/Unit/EntitySystems/DisposalUnitSystem.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs b/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs index 0dfc1ffe0d4..35b2afc2e0f 100644 --- a/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs +++ b/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs @@ -198,7 +198,7 @@ private void OnDoAfter(EntityUid uid, SharedDisposalUnitComponent component, DoA if (args.Handled || args.Cancelled || args.Args.Target == null || args.Args.Used == null) return; - AfterInsert(uid, component, args.Args.Target.Value, args.Args.User); + AfterInsert(uid, component, args.Args.Target.Value, args.Args.User, doInsert: true); args.Handled = true; } @@ -512,7 +512,7 @@ public bool TryInsert(EntityUid unitId, EntityUid toInsertId, EntityUid? userId, if (delay <= 0 || userId == null) { - AfterInsert(unitId, unit, toInsertId, userId); + AfterInsert(unitId, unit, toInsertId, userId, doInsert: true); return true; } @@ -796,11 +796,11 @@ public void QueueAutomaticEngage(EntityUid uid, SharedDisposalUnitComponent comp Dirty(component); } - public void AfterInsert(EntityUid uid, SharedDisposalUnitComponent component, EntityUid inserted, EntityUid? user = null) + public void AfterInsert(EntityUid uid, SharedDisposalUnitComponent component, EntityUid inserted, EntityUid? user = null, bool doInsert = false) { _audioSystem.PlayPvs(component.InsertSound, uid); - if (!_containerSystem.Insert(inserted, component.Container)) + if (doInsert && !_containerSystem.Insert(inserted, component.Container)) return; if (user != inserted && user != null) From e0ac6275d41be5c20949980116d0a360d70ef2f1 Mon Sep 17 00:00:00 2001 From: Flareguy <78941145+Flareguy@users.noreply.github.com> Date: Thu, 15 Feb 2024 14:53:32 -0600 Subject: [PATCH 138/200] Sec & greysec jumpskirt fix (#25269) * "resprites" sec & greysec jumpskirts * adjustments (cherry picked from commit 1ecc3a0b47108dc10a80db89843fe7a062b794ac) --- .../equipped-INNERCLOTHING-monkey.png | Bin 20674 -> 7292 bytes .../equipped-INNERCLOTHING-monkey.png | Bin 20993 -> 7655 bytes .../security.rsi/equipped-INNERCLOTHING.png | Bin 1285 -> 611 bytes .../Uniforms/Jumpskirt/security.rsi/icon.png | Bin 374 -> 338 bytes .../Uniforms/Jumpskirt/security.rsi/meta.json | 2 +- .../equipped-INNERCLOTHING-monkey.png | Bin 1148 -> 543 bytes .../equipped-INNERCLOTHING.png | Bin 1157 -> 727 bytes .../Jumpskirt/security_grey.rsi/icon.png | Bin 634 -> 402 bytes 8 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Textures/Clothing/Uniforms/Jumpskirt/Color/grey.rsi/equipped-INNERCLOTHING-monkey.png b/Resources/Textures/Clothing/Uniforms/Jumpskirt/Color/grey.rsi/equipped-INNERCLOTHING-monkey.png index d1a348ddd1bbbea1e76e21fddc98239f3b531684..7edf356ec60ddb4aef6d94a10a89afd5cf1518a2 100644 GIT binary patch delta 1568 zcmX@KknxYj1j$rp1_p+?+Z*2iDaPU;cPEB*=VV?2IV|apzK#qG8~eHcB(eheasfUe zuA!l!+qZA;?(Uv4WlC07R&a3e&6_uyo13kytbj_A?O&S!DXx+rzu^Bcz_96z&iRRo z;!INOCR+J3@=ol`W8&qS_|q9kPPS)MoSeg`Ie8(Y&g7enrjwq~1ftHeD2wuPDL{cuQA(PXQ)0Ru zP=<%q8l<3sLt}C&t1gUr0m0N}gNwEym=6(58+N#Y=?La01k;xTsvs0%yyj#UPO$sU zIQ>B)-JI@XNRHD-a@|`_6_5&1u5b`lz?BN3ZgQpTz|`ARA5bn{Jq#Vd-Y8)T!dfFwbKZ26H40>>LjC)5c93}K%nCIPedtRVN~cLLz} z$L4VM$#VsvUKgHxRxpyFyDkZl?=EO4#lqay$Im^vRzd;BCC_uVV#In*YODpM^BHFYbC)saEl~3xP_$BL6+4?WrC>JQc@s_ zQyQEdETzGrT>_!jOM~@2mDU3(5tlIqQ2{ch^$`1Qz;?T&7AF^F7L;V>=Yi8cL^R07 z4aft!#R}+}+|-gp5YN7%ATc>RwL~E`FU3}=NXg#Lr0)YKuyhmmba4!caDO}PVONU* zPfPIGxa;5RAI{$LbX%~n=(`91QdkOSe8~VWDbZh>%@#g*>_C)a3FTNSYObgs5x-nSG>77$&i0fl$*!^3o zI&XKd-%|a%`^##1%df3_E48khA?S73>g~1DryD0YGuEn1n|^*>t$W>Z74!7VrgtLa zWWw!3n1m8QwsS_*F^bnek=HeSvL^SQf`NQNdSdci=k~&-(|eEd75HxWdRj27;jMs> zfz1s8LFNVQ4Da$j8-EEq+GB9WQ$jA}{$U=&2g~-~-&$VN8YcL)+&qq9=`9Wc<|s!V p31){4_xcY%S`M=3Kd(h!zEO8;@25vT9>Btz!PC{xWt~$(69BsNzDNK7 literal 20674 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 L6u+{^s44#jy0L8$ diff --git a/Resources/Textures/Clothing/Uniforms/Jumpskirt/security.rsi/equipped-INNERCLOTHING-monkey.png b/Resources/Textures/Clothing/Uniforms/Jumpskirt/security.rsi/equipped-INNERCLOTHING-monkey.png index 790650960e56c817c49df0cb7e9ff814dfeb02ac..9acfc278c02231c7215acaa2c23b7051e6c7b594 100644 GIT binary patch delta 1577 zcmZo%!uZ^Jf@C5y0|Ud{?Tv4M6k~CayA#8@b22Z19F}xPUq=Rpjs4tz5?O(K=>VS) z*BE&fTXC6M4V{C!2J^M_^z{rwf&-M5)PVAx^OoNLQk*40e!>5tfFanwLTI9*IFk(5 zL@R$r-ie)gOuSqZe>wxn$@YwjlXDm~Cog2wnS7Jcbg~qa-sBJ_`^oc}Y$v~9(w;2O ztOHW!&+G-F<}y2gsD}_rmBj_b%VkjmQPWwBK-5_lWl>%(1t_p7N=dVFN=&x{%J8sS zgA`2U)R)sUXUg zCmlp>;1NX+hTzmfkh351XoD17~a+7C?K#e5E0QSkU zLU8;1g}|YO%_8>6oWf8)3QzVI;-2gx><4ltHnmXe)h64Ckmo3<0qT>#h?+ry#g6zO zLGzKoGd~Y#kb(k4G|0sb$OBqt1+*?VwImV5v#%&fOwLX%QAo{8 zu~jNkvbRfaTz(E%q-lA&IEF;HznylM@2~<#t6=@J-}WE*uB{C^s&{kJ-2y$Smj};> z&1Sl)|CE8fqmHXyfolibrUh4IlUI~yIH;l!(X%(O8nDKO}t!8z6z_Ghyhe$0^b zepl|2u6LBl$!${HBUPIQ0fYTL|2RA>87G`zIpLke`*i+c0j5btK9XmxYG$sf*($az z^2*{!Ms*kQU2F;6Gjk7|y3UYew468LVSk{t`ezZ|c=q-xlkC*n^*7~DG4csm9$-{r zk71m>=+m@3ev^ie=dXWLaVy*)#Z$r&RI#1kF(}TL;c3&qrsLlpE;~4#Rr!j zd!D_^5b*usqUIMLRkr9ey!e*L;$X0K{gxur2g~-|pIUyC<>ZD}zc1}$P_k>4U7&iS pVK-Z1>g<#AK{o!C4tOoRKvbyw>i-jI0>FZt!PC{xWt~$(69Bi-(0~8{ literal 20993 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 diff --git a/Resources/Textures/Clothing/Uniforms/Jumpskirt/security.rsi/equipped-INNERCLOTHING.png b/Resources/Textures/Clothing/Uniforms/Jumpskirt/security.rsi/equipped-INNERCLOTHING.png index 7c12f7cbe985b4a20551f87313f607dc8f2db2e2..8ffa6e2e94c567458f9b73486a6a8c7270680bc5 100644 GIT binary patch delta 597 zcmV-b0;>Im3gZNj8Gi!+005o0f$RVP00DDSM?wIu&K&6g000DMK}|sb0I`n?{9y$E z001FSOjJdEC@fqbBs~`#!7VVKDlRWBF(V=-R8vqG7a27)H~;_u<2Ib10000BbW%=J z|NsC0|NsC0|Nj6=PXY1(000SaNLh0L01m?d01m?e$8V@)0Dk}hv`IukR9Hvtmf=pr zFbst4Bu>}9{{wTEg*EP+3IP)Q$bq`L=YDa*ge}JpwEzo1{VG5-;hJ;?6;)i-`$Hf( zmvp3(b4-w2fKVyUKkqG*Q2BmH!27U-N!j`{=#^?)Rb&`^e7+O7K0K_SrEVwTm6@ug zlmNgrDnW{HcYpj%R(V)YeP-gFM*`lkNJPLBK5pAckHLQd1m}kYY@yv<0m}1*4|)Id zMw0^|@_PDMpB2LAAGB#)=>){Wx-7u^9?;LA$5#PRVBY`|z9-6JV}-s06fBSnjw@E^ z4*+}#pFdjr6R+4G0d;Q)dz}D6{{&RkV*9>Z(XfPxKYvzWNGY&wQbFjChlnE0Y_b6= z@*UtiT7U(h7U2H@M03BJDqqG27ol&U{ofP?Q_)&_)HDWS#{XDzg3v8y?xp@o)r~WP zOh+8-5C~@Vm>QEexE3Q%aBD)W#PK2V=qrK>2M1xC5Yf zV;eoDMovIN-~0jqX+5SK0Br;P^L`7|J-`idUKk#lrhq0)06l(F8xE)*Q7?5K88-v^hMz7 z7nrJwB}ocx;D6Nrg-85wFaQ87NfLH@4l31p*m+3;02~emcrh~*MM_qr^$FMMCiW-M zf6xINn_KK?bq$w6fPG2EWe@-eouJL>QRnG6035BZVPkVE6DN$)w>=N0szTEjK|^9v z{RbWJ>gyK(z=z*-)NZ|K{H3uy54Bqle?6Z~T=!Vg`hTO25tHcOJ67V8&b}l^2Gr%y z)6IqDNT}t9laZyU*a>`4$UbI1Nb3W@PT<2-)jQ{=&ly+$-Uw*Ns^*Dq2>Fq6m{fv_rVpOC9}%nowO7c>HR!kh#EzM zr8U#G99*1p>5ugojB`~i!BSLQ6-y)c^TblZnV&i61MCDoxBgfY27U0% zYC68T4qgr4ziIZZ%QB8u*PzYmaIYPlwOg4^h9$GgD%E<_{`$#rq)T=*7nURYT&Fv> z{(sm;k`r8~i?}mpH63T|7UIYL{rpenPlAojEk^CTP8T#B;+>{rJkIAfl)lADEdKi` z)&$}=B5lW0u1N?40)apv5C{YUfk5!HQ8KG6tK44}Y;10^Q8feOz`ZOEgb5PY>0)DZ zi@k1aGcsb5wkCnJUN^QGtrU&Q6^sM-3V%wYXs|z?J&Uq3Z@>Fbx*`N5SB3ukRgP@= z*zf0?7-=|Wt{_+jBZ7aG7lq-B^tf0BD%-trJ1FnjtXcd-{r13lORKz2Y5`VL_ zLd=_@<4TRWP8Yj9C(6as+Pv*~umPN%TDZw5D?Eyp@8jy!N|eg9d>@eHFjvuY@b){O zK34?9D@1CyUZPf@xv-4+iw^fB#KXbGd13yd6NNh60D1yYl?o4B5s)s9h-YV-T(XbH zR8?R&50Nco;{iuITnTR%ED)Mtd734fBjsTBhnfj2dUI=Q)Hzo*wLRytVPWjI zx&32Ox5fj(^xfhC4e^HcS3A`oEH2ftkGVLtF@3ViosZQA->@Xw%d>pZ*i!&>G=rzB KpUXO@geCy1BYal? delta 359 zcmV-t0hs>M0`>xs7=Hu<0001iRAfFDZ*Bkpc$`yKaB_9` z^iy#0_2eo`Eh^5;&r`5fFwryM;w;ZhDainGjE%TBGg33tGk;1ToZ^zil2jm5sW>&c zI6JebM2U+tC9|j)C}haRnO2mTn+jnoE4cc(fK3Jfo;e$Hs}*%Z0001yNklM3M7~}vKF!C@B54CWD>tRlo zXf`qK5QgjFuwY=cFtIS?uz(A6a0sU)OK@}`xvQhGqY=fSjzEASpi)wT;`YW8b$6!* zBmv=eC#PfqBppu9$<6A>dPGE26dfIq1Q-MzMFbe=2moRO8Vp!@!eamc002ovPDHLk FV1mlFh#LR^ diff --git a/Resources/Textures/Clothing/Uniforms/Jumpskirt/security.rsi/meta.json b/Resources/Textures/Clothing/Uniforms/Jumpskirt/security.rsi/meta.json index bbcef071e2e..45e0f9141cb 100644 --- a/Resources/Textures/Clothing/Uniforms/Jumpskirt/security.rsi/meta.json +++ b/Resources/Textures/Clothing/Uniforms/Jumpskirt/security.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039. In hand sprite scaled down by potato1234_x, monkey derivative made by brainfood1183 (github) for ss14", + "copyright": "Original sec jumpsuit from tgstation at commit https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039, jumpskirt sprite made by Flareguy for SS14. In hand sprite scaled down by potato1234_x, monkey derivative made by brainfood1183 (github) for ss14", "size": { "x": 32, "y": 32 diff --git a/Resources/Textures/Clothing/Uniforms/Jumpskirt/security_grey.rsi/equipped-INNERCLOTHING-monkey.png b/Resources/Textures/Clothing/Uniforms/Jumpskirt/security_grey.rsi/equipped-INNERCLOTHING-monkey.png index e326d766b1ddb747e4f202e5331bcbd462550eaa..8615d18b0440887633ec7d0201435a173e3d9949 100644 GIT binary patch delta 529 zcmeyvF`s3EWIZzj1H;_yjcNS%G|~0G|-o z3JD1t8yj9;-nlX|Q>IKQDJhvDEnQk#I%(3RE%Nfp%F1S@rgnCA;o;%x>gxXf{;{#K zIWl}bGBSF)x^;DRKx69tR&xO4|3p^r=85sBugD~Uq z{1quc7rJ=5IEF;HznykF@2~<-+rozto7CQ(`n~^EPEziS8B44^c0Zi#u*1G)(N06H z|C1CYn4b8vdc`N~doeHMCGWKG)>%EJHzSQtvYGyTV9PTtJUh3ZM?&Y!th$F8@=h9y z&+TWaxHlsr?c{=oFVr{|p2}`yW#`!Pmg7$u`wZ8{Zax)3zQ>(& zeP-S4%Trg`YM%W(M<`UPq?&Y+6T@VWVo1zG(f z#s~c+niL({5;!I(X0S$O)pzlpl~dbM&Hu5H#p&(exvQAOeLgf51f{FaX=XomMKs|) zoAZ(&g+rA&pF@<^GQ=^|Iv@Gs@S&qWoMl6AR!eR3ocj~iMXl$lE^B(wH2GiMwR;Qe zr_1jBr+2LPfZh+57u=`X_C0vhsBrYG`yV@J1C|r@+(rKw0;TN2*Jj=O!oUEG3{O`- Jmvv4FO#mvV;u`<} delta 1138 zcmV-&1daQj1pEk)8Gi-<0063Kaozv`00DDSM?wIu&K&6g00bOKL_t(|ob8&=OCx6( z$G;PWswR5zgV2OJem^ln&yFF&XgOZFQ2rftk=@wd={sm3hmL38N9s+^I z9mD2kp@-Tf;K2b8-CPtw+A*7z6l1YMGzIP3Lo>s;X3M;@iGSN4@8>dke}13$;r#)5 z9)QE)a5x+ehx7kLVCgK&GVOV*6Pw#Rs8lNUSV9O5zc-BI-%nu}2Gg8xTHoikV`}&& z9jn%`xxIsFZ32W4x)d3qgb+HdO<;3-2V>P5Qo}bXive$1-?g`vA|o{2-3L{Xu(rMd zRgqB6{eV#Xj(=Sa4GhAc&0wmy)$(27)DH~|qFmaw+pMw|eODbn{dj>oMF2q0<*{(` z8`9l<(Bk6&V7He`yLj+Tx@Asirr!)N`mT<^+WH0n;F10WdM*zD(Bk9xc3-d;ujlf3 zq(3>=zg0BTe;Kd(oo+e}m5$)gX7Kg(tC%tj!8A?!`G04hAQqsg0{G&~uTZH}gr&#` zMK*(>eF27R6WH}tMY?d#4a4xH&%8}#S*BWi9Ocq3MxUDUWaL#ZFhhuic~l|#n8K=UH9`(CTK^e zCw*5(z<+`eLJ1*I6$#g_-@w5yFA!;b*VZ>suh*&beQq^QedncEF70~OckKWz7^ab) z4xn1YL6i2eY7OWOpcw3@`rc;CozO0QCPTGgm;ykgrvvX?IkoGb*E&%=J_7)>WAW|O z_hhVPh?90M{GX=J;cz${4u`|xa5x+ehr{7;{(rr={v)waDA>P~$s`4UR4Vn#@zH4X zHO#uG{de=pvV6`S7H!x00T#x+1*$3%R7FBEnWTwCf&zf`y$lE;)cRVXGF6da+*@F_ zfhjU%G5T~B)tOnSjq;0+KBTvO{a&W>#BE3C{^KzYJ{-hr{7; zI2_J@i9Z3Wd<-1|U>uGB000hUSV?A0O#mtY000O800000007cclK=n!07*qoM6N<$ Ef=qQ8B>(^b diff --git a/Resources/Textures/Clothing/Uniforms/Jumpskirt/security_grey.rsi/equipped-INNERCLOTHING.png b/Resources/Textures/Clothing/Uniforms/Jumpskirt/security_grey.rsi/equipped-INNERCLOTHING.png index 81d1e1a0ea305f057821f8676d299ee290faf691..77471c7dc44bd10071ffdef10f4aac0ba03e6c9e 100644 GIT binary patch delta 714 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 Date: Thu, 15 Feb 2024 20:53:58 +0000 Subject: [PATCH 139/200] Automatic changelog update (cherry picked from commit d799a83135d41c30a6ff4218b55daa43309c0cd9) --- 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 e2cad1c15fb..a114d90a3f6 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,5 @@ Order: 1 Entries: -- author: RiceMar - changes: - - message: Energy swords and double energy swords now look as long as they seem - to be in your hand. - type: Tweak - id: 5442 - time: '2023-12-21T06:32:11.0000000+00:00' - url: null - author: Emisse changes: - message: Borgs now see who is crew @@ -3881,3 +3873,10 @@ Order: 1 id: 5941 time: '2024-02-15T01:37:56.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25251 +- author: PJB3005 + changes: + - message: Fixed disposals bins not automatically flushing after an item was inserted. + type: Fix + id: 5942 + time: '2024-02-15T20:52:52.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25233 From 31f5351fef4af1b3a87b685cc22c41ceb8394849 Mon Sep 17 00:00:00 2001 From: liltenhead <104418166+liltenhead@users.noreply.github.com> Date: Thu, 15 Feb 2024 12:54:41 -0800 Subject: [PATCH 140/200] Reduce eshield hp (#25258) reduce eshield hp (cherry picked from commit 11cd4ff5aa136281e970d9d6410b8e7f1914d2dd) --- Resources/Prototypes/Entities/Objects/Shields/shields.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Objects/Shields/shields.yml b/Resources/Prototypes/Entities/Objects/Shields/shields.yml index 7427b7f87a3..b794e42ff7d 100644 --- a/Resources/Prototypes/Entities/Objects/Shields/shields.yml +++ b/Resources/Prototypes/Entities/Objects/Shields/shields.yml @@ -439,7 +439,7 @@ acts: [ "Destruction" ] - trigger: !type:DamageTrigger - damage: 150 + damage: 100 behaviors: - !type:DoActsBehavior acts: [ "Destruction" ] From 971506c5d8e78eff8b08794b352b205ea6ea25e9 Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 15 Feb 2024 20:55:47 +0000 Subject: [PATCH 141/200] Automatic changelog update (cherry picked from commit 57492b6aac0867405e685a4e6cca49ae5a833276) --- 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 a114d90a3f6..0d172d1af62 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Emisse - changes: - - message: Borgs now see who is crew - type: Tweak - id: 5443 - time: '2023-12-21T07:09:53.0000000+00:00' - url: null - author: KittenColony changes: - message: Rotated fireaxe 'icon' 45 degrees @@ -3880,3 +3873,10 @@ Order: 1 id: 5942 time: '2024-02-15T20:52:52.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25233 +- author: liltenhead + changes: + - message: Reduced energy shield's hp from 150 to 100. + type: Tweak + id: 5943 + time: '2024-02-15T20:54:41.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25258 From 406fb71e07f49487ff17d260cabefd9a566813bf Mon Sep 17 00:00:00 2001 From: wafehling Date: Thu, 15 Feb 2024 14:56:22 -0600 Subject: [PATCH 142/200] Artifact hemoglobin trigger now accepts all sentient blood types (#25240) * Artifact blood trigger now accepts all sentient blood types * Update artifact-hints.ftl (cherry picked from commit f4876bdb265602765c8f22e007a93701ce88cb35) --- Resources/Locale/en-US/xenoarchaeology/artifact-hints.ftl | 2 +- Resources/Prototypes/XenoArch/artifact_triggers.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/Locale/en-US/xenoarchaeology/artifact-hints.ftl b/Resources/Locale/en-US/xenoarchaeology/artifact-hints.ftl index 84d832a0824..98dfa89fa9f 100644 --- a/Resources/Locale/en-US/xenoarchaeology/artifact-hints.ftl +++ b/Resources/Locale/en-US/xenoarchaeology/artifact-hints.ftl @@ -31,7 +31,7 @@ artifact-trigger-hint-physical = Physical trauma artifact-trigger-hint-tool = Tool usage artifact-trigger-hint-music = Sonic vibrations artifact-trigger-hint-water = Hydro-reactive -artifact-trigger-hint-blood = Reaction with hemoglobin +artifact-trigger-hint-blood = Reaction with hematological fluid artifact-trigger-hint-magnet = Magnetic waves artifact-trigger-hint-death = Life essence artifact-trigger-hint-radiation = Radiation diff --git a/Resources/Prototypes/XenoArch/artifact_triggers.yml b/Resources/Prototypes/XenoArch/artifact_triggers.yml index 57d1173fe3e..b16a9de8dea 100644 --- a/Resources/Prototypes/XenoArch/artifact_triggers.yml +++ b/Resources/Prototypes/XenoArch/artifact_triggers.yml @@ -112,7 +112,7 @@ groups: Acidic: [ Touch ] reactions: - - reagents: [ Blood ] + - reagents: [ Blood, CopperBlood, InsectBlood, Slime, AmmoniaBlood, ZombieBlood ] methods: [ Touch ] effects: - !type:ActivateArtifact From ca4645aef5a7509e5945ac5fff1d212974fc42b6 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+electrojr@users.noreply.github.com> Date: Thu, 15 Feb 2024 23:31:00 +0100 Subject: [PATCH 143/200] Update engine to v210.1.0 (#25288) --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index 9e0fc7017c4..f8cb1729a3e 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 9e0fc7017c4740b6bc8302cb724dc7c3b60b3299 +Subproject commit f8cb1729a3e0f790fe1b72f060fed0b27b1eefc2 From 09393bcd299b77aab52e1c72f133fae90240c1b4 Mon Sep 17 00:00:00 2001 From: Vasilis Date: Fri, 16 Feb 2024 00:30:55 +0100 Subject: [PATCH 144/200] Made ghost.role_time a server modifiable only cvar (#25292) Fix (cherry picked from commit 7e44c50d19b84facce7563d534344a5197d294eb) --- Content.Shared/CCVar/CCVars.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index ed47fd27e82..2bf612c7ed3 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -1836,7 +1836,7 @@ public static readonly CVarDef /// The time you must spend reading the rules, before the "Request" button is enabled ///
public static readonly CVarDef GhostRoleTime = - CVarDef.Create("ghost.role_time", 8f, CVar.REPLICATED); + CVarDef.Create("ghost.role_time", 8f, CVar.REPLICATED | CVar.SERVER); /* * Fire alarm From e9975e23e818ed540ef1d08baa41b1ff28f76783 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Fri, 16 Feb 2024 01:26:45 +0100 Subject: [PATCH 145/200] Nuke fancification (#25297) Actually use more icon states for deployed/armed/about to explode Also unlit layer. Also examine text (cherry picked from commit 3a45d519dcc3679375b5239b6f1881cdd1a07344) --- Content.Server/Nuke/NukeSystem.cs | 38 ++++++++++++++++++ Content.Shared/Nuke/SharedNuke.cs | 21 ++++++++++ .../Locale/en-US/nuke/nuke-component.ftl | 4 ++ .../Entities/Objects/Devices/nuke.yml | 17 ++++++++ .../Objects/Devices/nuke.rsi/meta.json | 3 ++ .../Devices/nuke.rsi/nuclearbomb_deployed.png | Bin 1310 -> 1328 bytes .../nuke.rsi/nuclearbomb_deployed_unlit.png | Bin 0 -> 108 bytes .../nuke.rsi/nuclearbomb_exploding.png | Bin 1614 -> 366 bytes .../Devices/nuke.rsi/nuclearbomb_timing.png | Bin 1381 -> 113 bytes 9 files changed, 83 insertions(+) create mode 100644 Resources/Textures/Objects/Devices/nuke.rsi/nuclearbomb_deployed_unlit.png diff --git a/Content.Server/Nuke/NukeSystem.cs b/Content.Server/Nuke/NukeSystem.cs index 77689c4e2b1..652852ece28 100644 --- a/Content.Server/Nuke/NukeSystem.cs +++ b/Content.Server/Nuke/NukeSystem.cs @@ -9,6 +9,7 @@ using Content.Shared.Containers.ItemSlots; using Content.Shared.Coordinates.Helpers; using Content.Shared.DoAfter; +using Content.Shared.Examine; using Content.Shared.Maps; using Content.Shared.Nuke; using Content.Shared.Popups; @@ -40,6 +41,7 @@ public sealed class NukeSystem : EntitySystem [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly StationSystem _station = default!; [Dependency] private readonly UserInterfaceSystem _ui = default!; + [Dependency] private readonly AppearanceSystem _appearance = default!; /// /// Used to calculate when the nuke song should start playing for maximum kino with the nuke sfx @@ -60,6 +62,7 @@ public override void Initialize() SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnItemSlotChanged); SubscribeLocalEvent(OnItemSlotChanged); + SubscribeLocalEvent(OnExaminedEvent); // Shouldn't need re-anchoring. SubscribeLocalEvent(OnAnchorChanged); @@ -148,6 +151,8 @@ private void OnAnchorChanged(EntityUid uid, NukeComponent component, ref AnchorS // without the doafter. but that takes some effort, and it won't allow you to disarm a nuke that can't be disarmed by the doafter. DisarmBomb(uid, component); } + + UpdateAppearance(uid, component); } #endregion @@ -299,6 +304,7 @@ private void TickTimer(EntityUid uid, float frameTime, NukeComponent? nuke = nul _sound.PlayGlobalOnStation(uid, _audio.GetSound(nuke.AlertSound), new AudioParams{Volume = -5f}); _sound.StopStationEventMusic(uid, StationEventMusicType.Nuke); nuke.PlayedAlertSound = true; + UpdateAppearance(uid, nuke); } if (nuke.RemainingTime <= 0) @@ -473,6 +479,7 @@ public void ArmBomb(EntityUid uid, NukeComponent? component = null) component.Status = NukeStatus.ARMED; UpdateUserInterface(uid, component); + UpdateAppearance(uid, component); } /// @@ -514,6 +521,7 @@ public void DisarmBomb(EntityUid uid, NukeComponent? component = null) component.CooldownTime = component.Cooldown; UpdateUserInterface(uid, component); + UpdateAppearance(uid, component); } /// @@ -589,6 +597,36 @@ private void DisarmBombDoafter(EntityUid uid, EntityUid user, NukeComponent nuke _popups.PopupEntity(Loc.GetString("nuke-component-doafter-warning"), user, user, PopupType.LargeCaution); } + + private void UpdateAppearance(EntityUid uid, NukeComponent nuke) + { + var xform = Transform(uid); + + _appearance.SetData(uid, NukeVisuals.Deployed, xform.Anchored); + + NukeVisualState state; + if (nuke.PlayedAlertSound) + state = NukeVisualState.YoureFucked; + else if (nuke.Status == NukeStatus.ARMED) + state = NukeVisualState.Armed; + else + state = NukeVisualState.Idle; + + _appearance.SetData(uid, NukeVisuals.State, state); + } + + private void OnExaminedEvent(EntityUid uid, NukeComponent component, ExaminedEvent args) + { + if (component.PlayedAlertSound) + args.PushMarkup(Loc.GetString("nuke-examine-exploding")); + else if (component.Status == NukeStatus.ARMED) + args.PushMarkup(Loc.GetString("nuke-examine-armed")); + + if (Transform(uid).Anchored) + args.PushMarkup(Loc.GetString("examinable-anchored")); + else + args.PushMarkup(Loc.GetString("examinable-unanchored")); + } } public sealed class NukeExplodedEvent : EntityEventArgs diff --git a/Content.Shared/Nuke/SharedNuke.cs b/Content.Shared/Nuke/SharedNuke.cs index 1c471e11c66..c845ed6c2a6 100644 --- a/Content.Shared/Nuke/SharedNuke.cs +++ b/Content.Shared/Nuke/SharedNuke.cs @@ -3,6 +3,27 @@ namespace Content.Shared.Nuke { + public enum NukeVisualLayers + { + Base, + Unlit + } + + [NetSerializable, Serializable] + public enum NukeVisuals + { + Deployed, + State, + } + + [NetSerializable, Serializable] + public enum NukeVisualState + { + Idle, + Armed, + YoureFucked + } + [Serializable, NetSerializable] public enum NukeUiKey : byte { diff --git a/Resources/Locale/en-US/nuke/nuke-component.ftl b/Resources/Locale/en-US/nuke/nuke-component.ftl index 4a44ae88eac..b2a61dfcc2c 100644 --- a/Resources/Locale/en-US/nuke/nuke-component.ftl +++ b/Resources/Locale/en-US/nuke/nuke-component.ftl @@ -41,3 +41,7 @@ nuke-codes-fax-paper-name = nuclear authentication codes # Nuke disk slot nuke-slot-component-slot-name-disk = Disk + +## Examine +nuke-examine-armed = Hey uh, why's that [color=red]red light[/color] blinking? +nuke-examine-exploding = Yeah... I think it's too late buddy. diff --git a/Resources/Prototypes/Entities/Objects/Devices/nuke.yml b/Resources/Prototypes/Entities/Objects/Devices/nuke.yml index d1206215590..811210d429e 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/nuke.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/nuke.yml @@ -11,6 +11,11 @@ noRot: true layers: - state: nuclearbomb_base + map: ["enum.NukeVisualLayers.Base"] + - state: nuclearbomb_deployed_unlit + map: ["enum.NukeVisualLayers.Unlit"] + shader: unshaded + visible: false - state: nukefestive map: ["christmas"] visible: false @@ -24,6 +29,18 @@ enum.HolidayVisuals.Holiday: christmas: festive: { visible: true } + enum.NukeVisuals.Deployed: + enum.NukeVisualLayers.Base: + False: { state: nuclearbomb_base } + True: { state: nuclearbomb_deployed } + enum.NukeVisualLayers.Unlit: + True: { visible: true } + False: { visible: false } + enum.NukeVisuals.State: + enum.NukeVisualLayers.Unlit: + Idle: { state: nuclearbomb_deployed_unlit } + Armed: { state: nuclearbomb_timing } + YoureFucked: { state: nuclearbomb_exploding } - type: Physics bodyType: Static - type: Fixtures diff --git a/Resources/Textures/Objects/Devices/nuke.rsi/meta.json b/Resources/Textures/Objects/Devices/nuke.rsi/meta.json index 2828b13ddba..4bc62a96b2d 100644 --- a/Resources/Textures/Objects/Devices/nuke.rsi/meta.json +++ b/Resources/Textures/Objects/Devices/nuke.rsi/meta.json @@ -10,6 +10,9 @@ { "name": "nuclearbomb_deployed" }, + { + "name": "nuclearbomb_deployed_unlit" + }, { "name": "nukefestive", "delays": [ diff --git a/Resources/Textures/Objects/Devices/nuke.rsi/nuclearbomb_deployed.png b/Resources/Textures/Objects/Devices/nuke.rsi/nuclearbomb_deployed.png index fa39a744cdd5f07aa3637736286dd29ffeecd20e..4a01cf2d68fcba38e737bc652d4bc17c9199de74 100644 GIT binary patch delta 1309 zcmV+&1>*Xi3a|>0B!2;OQb$4nuFf3k000E)Nkl#zlqAr)C^YXMtrZJFOL%J;S(rFhtdH~w$>9-ia>d4In5DLlqwJYuL4T^LN6 z()2UOpeLdH!ypED^k&ok<{ zHslpq$l1Q0p?~3WPDWft=^2`t5@ng)$>p33`t42y8)7jNjry!~QZ*?e0DwHB4uD|q z2-fJvcOy*n)W!O>;I zw{8gm=YIqMeSMQWpDVtMnco2!fj|g6rwPsrld4JK=!t5Ay(6Tqic)@HZwf6J9`7~ za0u^kh_ zp5YMBsBiL$U!q}O?NqiO2-)@yuR^z_$qA%WyjV+jjAPk(UtfeFRaMn4DL;P|$4=Ce zXVi%(-7cR{nESqmw4)}9?@Us(ua=tkj$^TGq~f*j;sTIM0kExd9R7C0lX^t}JIYlw zet&!u$Dl`*G&(wh(U?PNNktq3`mA*R4Lu?Dr`>k}uvj+I({o-S+jjPbq7*X4u_cqy zbSnDhC3SS1QJp&V8Tt9EFfS`p2)bQ9=BV#5aS@!uA>PtQTBfJxJQmAFcGlfiWFNbh z?_zr(*6y0y5mu4`Iy%m%0I9HWJph-jUw;eX(vk|e3!`gBumeRg45ZDEI6Bm*V{@5K z=*Z3ioazkZqR3^fxCPd!A)uHAPd~Mu!ou|o4D@oLtCiyi>xCij*aSMQa`?Qny8(zk z)6K0l;wgtHYp30JnWMhL{(=Sc|2)okIGJl|E$yQ=3UQdsC9jQRF(8 zNGu^dy?({s>zl-?(xWaaz-qO!!hcJA31Ttlm*2T08@u99B=*3tTCLb@HWg;G#OOU{ zLGhIz#CpCinX5xVbm{k;;Ir!3Y&OBV*=(MD8vf{yG)tKw`YOs)-V4)p#>2@F9fFEL z62fdYOY-l@lP9GuTee8@+5PCo>TF(UzHi;Q0Oa+98kny0K>82k@KM(e Tp(8{Q&^oh!4xSZ>Ft1ACb4Js0-Ub4<<+`LKgXr@0mpuM3B4Gr`>4s-=!y;dk zV+sQo(e6r3!hdB(%%}?>h0W8WH?cl@(4}bAkOYL|OFs_FO(HVw8X`p2H!uccW@-d@ zH0%3w64{IZsmV-|2vdMQPI_l~-!tyxk03#9&08%P8TpHkbM|JU^>hvIJARwQ)6cDr z3cijMEVW3IL7$w&lGl((P}JKh4&s$v6@0EVC}8=KQ-3&i>~KtQZS-Vxytc+}$P4ltSxqxT0UB4V9%bnmG0it5d>CmZ$jPkK=Sci9DigRHX0Zazk-ItwZUjVkZU_SyUszUJuo|l)8?%qY@=}E_I59_=)j3!2+ZVQTvHlylg zlZ;#tpvZ-NyL*Z&fJe=8?!;#b_EiSZ_|Xh6&+%^e7|P1ZP+nRE$JNd-0(4(pH$vyv z=6|_^V%8FPfB$(#;34^qWG54ZgmDFQfe{HAWM}6YIuvEorWg3cW&2tAk!nC3OW5fP zzzieus#ygja3W!?JIn91R(|Re32WU=KGrKB{I0)g#waG#9Ee4Nl))Xqy?zXXY^+rv zc_lcItBu{2gvqGZ{v8!- z*|Q(}4>SY;!OJw&1yRa5cu=)A*2Wob;r)U%4E->Lsd)x#&=Js*sH}Wl&eb;_h29$K zs?pJP4cn*G?dRY_?V;DWT0?{CZ6Yu{tX{vuYS_7ew{{#&rrjUqkp4o zfP<+DOmhV;TvSUk9RV_oc*0A29DHwU>xa_u&@3YUqzLc=#lw!k9I1dXZB7u0;_-95 ze6Vyv0kwbhcWp)Pc za4^Lz76tAlN^!}RZ)AU^DIV8G=6_&Hx%)rTi|ygyL9;LtF};1~SCeIHwolHHl;Zqi znSPHp^R+~x66kO{mJvf*=rmartJMl;Z*NG#B}~7E&fH0*!X3WuuJj~8o6V+ZncwRk z2Wu^ilzv@Q0u;U8A@0!@+apw6lED1{-VdRF0FM(nT^vOUXaE2J07*qoL9rvFzl8-v3V)?Rt$|NZG7+JQP4JYD@<);T3K F0RYitApigX literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Devices/nuke.rsi/nuclearbomb_exploding.png b/Resources/Textures/Objects/Devices/nuke.rsi/nuclearbomb_exploding.png index ac5c5d9654ff5a545b508efe26f5687251b3d7a7..c5861c43bcbb07bb152b4d475afe9b9cb180b53b 100644 GIT binary patch delta 339 zcmV-Z0j&Pc4DJGuB!2;OQb$4nuFf3k0003fNkltDtsP~2J~C1`oVUXax7*N?H!C+EQ$R1#W&XMZJ31xnuiV`&^f1dxKl zwj`iN$Xi_pM#i-Y*aEiyz!L;s4#nhCP_U|mc)(j=F2I%W`i&o1U^tHBIF1sn^MM1v zF0`Bo`RjiLIC;oY8&&t)vVR$nr+9#3d&|Xb+>d`F{PsWAl3#osBgGxdx z@T`QXK*@W|Elf)3=h9>CfI^Ls!`%5m&^s4k%=ZQ60xyRm`4kkaDj^>57MKfgB|I9F1Q0kxRPNO~`NJQzum*_@5H`yAXfEexi=`lFXh*@+ajbr(A z=tI<}_KF&ugit`8^HaZGR2zwrX~BsQMf2IKu*{ks1U^zU|J#csMu60WAi>sCz#5>! zUe67l?&|1cNXOofmN&xLx26}eu8 zp{c`&j+u;opA}+=ExzbQe#v)kpNvBXI|9t-x9wonr{nPV|9|nLu3-`0DY(JsKRRAkW5_qm&L*Dr zT)FKhu<7k3ISn`yL}2!sohW$;h}}0I+gO98W=3RCLfMXDWwalwb*pPU0c}YMw&pqE zW)AER0(ZM*g`zfXdQV!oa1k1s4CHB?fg6o1@!>`6WF#_g#iML@F^WELV%f4BYzOj!hfCV-+@4(j*w&eLx{^Y&ju?u79`S{e}LH*R8n{1a>_xaF6qN z?{IK)dI}D=wsPWH1%hJIZ-3yV=wgcZBM;*bNCI?>{s0tzAYb`4FYpu4fRDl-;Me=`2ZS1& zgit`8^DzDZ9*{qvuBY+z2hhQkADch0UiJr8C_8%A{rdxf2E{n|1EF`qAb%iP_6M*_ z_6H6|{DBAP58zSt2k^-I118}QupiP!MErsA^aq^E+e!EX7^6SH^EPz;KoIdz{s4U( vs9!1f;12|WMf`!0+C=<;h(9pl{DJ=gu;8G&MXS6r00000NkvXXu0mjf@%Rk1 diff --git a/Resources/Textures/Objects/Devices/nuke.rsi/nuclearbomb_timing.png b/Resources/Textures/Objects/Devices/nuke.rsi/nuclearbomb_timing.png index ee674e57dbab6224861ef747620f9486b53d2be0..b59fac42b86cb3f6ffb4a2aa447f569aa9edac96 100644 GIT binary patch delta 83 zcmaFLRX9P#m$5j=-HBn{IhmIX3=GFT&5x`B{K{*v87l(T2?m5uID|s_w@FbmW>!SfAPM_z31F>&v~Ecea^>i z-+27XrW4Q!L?w`&n=WbFMu#U>{38SkH)TrqM)9pKMHgRYoP79*>*XyhXZkTU{T zjKJ@IFe8El^)vhD;8~Rj^O_XiW;CtjWgu`<^h-)IC{^D7g2x|5B#Zz#-SkLqSmf(+ zOkv#B1{2#Iq99{bNqa^z4rB z5TSs2@sJVl)e$fHJg2Z7KQ8LrQfTB(W657~j}e!H;0;y@rYr-xzFdcjCn3dDfL8Em zaxaR^PveU&;M3|ZJ_YZTvnj~QL{D%E4!0z*`+^u(vwvO?8nrv%duTlZu4(@4bS~i0 zEU`0Uf1iY0k%@N9t(r$-QUZ>CP=h(P_!9F&k~ber!0}@)?A|L&O!Wq<35~XZi2hrR zvTBP-pwICXK8ybto5yFcYfXB{VetKj@2|wx@&R7oxlP_3r#}CaUuV1X@zTq)eEt*D zWHsgj^Xx9~K<~AiAp(2$yef6uPec${yQ3NPe~$ynM{{w24cKg8MEnvO57h;ueM|K1 z==6q-B_-IJ=Y)GXaL5SU>68_UC-A(ye019vk*6mevpuZx#xR;0iIN*>Xl$uN?dz>5 zD%y&wXG|h;g#bma*w?$KxB|G>EZUBJB4KZ308Q`B@Z&k&?H)r}SsBVptKhiY8AgEi zf2-?SX#Uzgw@}PV0`KcP%Lv>h-jVEN3L(X~0-C^xgb1>;^CV4*v}MZ^yy0U1Y4MWI zfH<~br_TX1jL7q58IZtaqzKiZSM-lL$iqZk)nVXNFFu?=12t; zQ?CgkQ9OQzA0KQvp@7QY`tVv_sQ)f(hya@y@P|EneG44iP+Wjh{r#MHR03piKm3IA zinB|8{9V@1z#R^zn8hN&y~I&me{$(7QD1F}$CZ&em{M;4hxB4&IC#)3j6_Ut-}vRl zvMt*u+DJ-e{$iPSjC$p(i9{vP;dZPbhSbq%vPf2|6;8W7B;gXK9Yb^Oq@%(e-tV^b zBtV Date: Fri, 16 Feb 2024 00:27:50 +0000 Subject: [PATCH 146/200] Automatic changelog update (cherry picked from commit af41768e4efb48e28656614e07c5856ce3470338) --- 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 0d172d1af62..ab0fe71bb3b 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: KittenColony - changes: - - message: Rotated fireaxe 'icon' 45 degrees - type: Tweak - id: 5444 - time: '2023-12-21T08:03:52.0000000+00:00' - url: null - author: themias changes: - message: Damp rags can mop puddles again @@ -3880,3 +3873,10 @@ Order: 1 id: 5943 time: '2024-02-15T20:54:41.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25258 +- author: PJB3005 + changes: + - message: Nuke has some more blinkenlights now. + type: Tweak + id: 5944 + time: '2024-02-16T00:26:45.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25297 From 5169d9137aa9c8d388abef7499470a670febaf5b Mon Sep 17 00:00:00 2001 From: Daxxi3 <158596935+Daxxi3@users.noreply.github.com> Date: Fri, 16 Feb 2024 12:38:18 +1100 Subject: [PATCH 147/200] Change copper blood from ferrous to metallic (#25217) changed copper blood from ferrous to metallic (cherry picked from commit 4c1e03fd705d0b526099a66a0a72b1770cbc59ed) --- Resources/Prototypes/Reagents/biological.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Reagents/biological.yml b/Resources/Prototypes/Reagents/biological.yml index ce3d0a04637..978ec717f95 100644 --- a/Resources/Prototypes/Reagents/biological.yml +++ b/Resources/Prototypes/Reagents/biological.yml @@ -88,7 +88,7 @@ flavor: metallic color: "#162581" recognizable: true - physicalDesc: reagent-physical-desc-ferrous + physicalDesc: reagent-physical-desc-metallic slippery: false - type: reagent From 3eccc61b169ae3855fad3aecb42d316ce1f09c7c Mon Sep 17 00:00:00 2001 From: MACMAN2003 Date: Thu, 15 Feb 2024 20:03:51 -0800 Subject: [PATCH 148/200] Thindow glass dupe fix (#25304) smite glass dupe off the face of the planet eww nasty dupe exploits blehh (cherry picked from commit 4a97a4729cb532261a940bcd64063d55f765b62e) --- Resources/Prototypes/Entities/Structures/Windows/plasma.yml | 2 +- .../Prototypes/Entities/Structures/Windows/reinforced.yml | 2 +- Resources/Prototypes/Entities/Structures/Windows/rplasma.yml | 4 ++-- Resources/Prototypes/Entities/Structures/Windows/window.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Resources/Prototypes/Entities/Structures/Windows/plasma.yml b/Resources/Prototypes/Entities/Structures/Windows/plasma.yml index 70c1573fb8d..5503ea856c8 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/plasma.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/plasma.yml @@ -92,7 +92,7 @@ spawn: ShardGlassPlasma: min: 1 - max: 2 + max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - type: StaticPrice diff --git a/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml b/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml index e2399654940..26d9da0745b 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml @@ -112,7 +112,7 @@ spawn: ShardGlassReinforced: min: 1 - max: 2 + max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - type: StaticPrice diff --git a/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml b/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml index 67dfe028d93..9281e0c7ff9 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml @@ -101,10 +101,10 @@ spawn: ShardGlassPlasma: min: 1 - max: 2 + max: 1 PartRodMetal: min: 1 - max: 2 + max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - type: StaticPrice diff --git a/Resources/Prototypes/Entities/Structures/Windows/window.yml b/Resources/Prototypes/Entities/Structures/Windows/window.yml index ee3a7d52b08..3ae2707f461 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/window.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/window.yml @@ -161,7 +161,7 @@ spawn: ShardGlass: min: 1 - max: 2 + max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - type: Airtight From 87728a6fa0ec105579514f7eb60b47a9b46f7dad Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 16 Feb 2024 04:04:56 +0000 Subject: [PATCH 149/200] Automatic changelog update (cherry picked from commit 0a64e086c4049fe6d3d9399f55bb337f0e72e2ed) --- 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 ab0fe71bb3b..c5ca13405a6 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,14 +1,5 @@ Order: 1 Entries: -- author: themias - changes: - - message: Damp rags can mop puddles again - type: Fix - - message: Syndie soap cleans evidence a little faster than other soap - type: Tweak - id: 5445 - time: '2023-12-21T08:54:52.0000000+00:00' - url: null - author: Emisse changes: - message: Nukies don't start with agent ID anymore @@ -3880,3 +3871,10 @@ Order: 1 id: 5944 time: '2024-02-16T00:26:45.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25297 +- author: MACMAN2003 + changes: + - message: Thindows no longer duplicate glass when broken. + type: Fix + id: 5945 + time: '2024-02-16T04:03:51.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25304 From 5273ce7e776a0738b9612004829acf538aaabe5e Mon Sep 17 00:00:00 2001 From: Golinth Date: Fri, 16 Feb 2024 09:58:28 -0600 Subject: [PATCH 150/200] Kill Seperated Mindshield Icons (#25303) * Unghettoify mindshield icons Adds support for layers in status icons, through the StatusIconLayer enum and the new "layer" datafield. Defaults to the Base layer where functionally remains unchanged. * TG icon for shield probably better than the shitty one I made in paint * forgor meta.json I forgor * Emo review Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> --------- Co-authored-by: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> (cherry picked from commit bced73f67657246bc167531414ea0be5a5bba6bf) --- Content.Client/StatusIcon/StatusIconOverlay.cs | 14 ++++++++++---- .../StatusIcon/StatusIconPrototype.cs | 12 ++++++++++++ Resources/Prototypes/StatusIcon/antag.yml | 5 +++-- .../Misc/job_icons.rsi/MindShield.png | Bin 198 -> 4452 bytes .../Interface/Misc/job_icons.rsi/meta.json | 2 +- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Content.Client/StatusIcon/StatusIconOverlay.cs b/Content.Client/StatusIcon/StatusIconOverlay.cs index 3e7161b1fb5..0d13baef936 100644 --- a/Content.Client/StatusIcon/StatusIconOverlay.cs +++ b/Content.Client/StatusIcon/StatusIconOverlay.cs @@ -84,21 +84,27 @@ protected override void Draw(in OverlayDrawArgs args) { if (accOffsetL + texture.Height > sprite.Bounds.Height * EyeManager.PixelsPerMeter) break; - accOffsetL += texture.Height; + if (proto.Layer == StatusIconLayer.Base) + { + accOffsetL += texture.Height; + countL++; + } yOffset = (bounds.Height + sprite.Offset.Y) / 2f - (float) accOffsetL / EyeManager.PixelsPerMeter; xOffset = -(bounds.Width + sprite.Offset.X) / 2f; - countL++; } else { if (accOffsetR + texture.Height > sprite.Bounds.Height * EyeManager.PixelsPerMeter) break; - accOffsetR += texture.Height; + if (proto.Layer == StatusIconLayer.Base) + { + accOffsetR += texture.Height; + countR++; + } yOffset = (bounds.Height + sprite.Offset.Y) / 2f - (float) accOffsetR / EyeManager.PixelsPerMeter; xOffset = (bounds.Width + sprite.Offset.X) / 2f - (float) texture.Width / EyeManager.PixelsPerMeter; - countR++; } var position = new Vector2(xOffset, yOffset); diff --git a/Content.Shared/StatusIcon/StatusIconPrototype.cs b/Content.Shared/StatusIcon/StatusIconPrototype.cs index 1523ff4e0ad..a313f55c057 100644 --- a/Content.Shared/StatusIcon/StatusIconPrototype.cs +++ b/Content.Shared/StatusIcon/StatusIconPrototype.cs @@ -34,6 +34,12 @@ public int CompareTo(StatusIconData? other) { return Priority.CompareTo(other?.Priority ?? int.MaxValue); } + + /// + /// The layer the icon is displayed on. Mod is drawn above Base. Base | Mod + /// + [DataField] + public StatusIconLayer Layer = StatusIconLayer.Base; } /// @@ -63,3 +69,9 @@ public enum StatusIconLocationPreference : byte Left, Right, } + +public enum StatusIconLayer : byte +{ + Base, + Mod, +} diff --git a/Resources/Prototypes/StatusIcon/antag.yml b/Resources/Prototypes/StatusIcon/antag.yml index a3fb0727227..0a052ce16da 100644 --- a/Resources/Prototypes/StatusIcon/antag.yml +++ b/Resources/Prototypes/StatusIcon/antag.yml @@ -23,14 +23,15 @@ id: MindShieldIcon priority: 2 locationPreference: Right + layer: Mod icon: sprite: Interface/Misc/job_icons.rsi state: MindShield - + - type: statusIcon id: SyndicateFaction priority: 0 - locationPreference: Left + locationPreference: Left icon: sprite: Interface/Misc/job_icons.rsi state: Syndicate diff --git a/Resources/Textures/Interface/Misc/job_icons.rsi/MindShield.png b/Resources/Textures/Interface/Misc/job_icons.rsi/MindShield.png index 3049f3e50fb191c57f2e998cce388e598b871158..d3df5fe6277177f5106ca40b1fa39ad7349548a0 100644 GIT binary patch literal 4452 zcmeHKeQXqE8sD}`YgtPvEkP8WZV~8(+4EX0HU`k00BucVzDIu6A!P?%PP+K>DxkIX6CDpURe9&l^MRyRmxGRwIJgb z(%U%FQFht6`Kbll|H|)}eM93wQ!ldR+1jDMyjZ{V%y3(xU`c7g%C&dA-1*7RrTdT6 z6xu7kkEi<;us^;?l&3 z);)9#>B#BtS)6}&im~iE{pjb`L+`MK5C8d={X);1a%_OvHe(_OKt)+>d#q;@y%-OzcVQE&L@iQP!uI@(i_*+dE8o97-_^uOnuteEEtb4` z5w=%D=pKfb<91e%Ibcu571(zci?=MPuzWMn5e`H}$!8lrango}g3tCxX9y1|ey~xj zZdbvY_S!nWy_u&4TiLQ)Z<2ukaiFtEG9HsOCh4=8xC~qyV$6n^Dtfce)({FKepv+w zWvA>oTA37EN!zkq#H$JsW_4i2C+(*XZiz}hfIJ~5dvHvTnz|UdM%JX*j2$zbiGe`#aokDTW4W8kP%9K-0y5uXgcl6> zY=(bEkajsGEy8P|D?^P&PulP|6K=I8tzNlrRA*C}}z?@xXwB;C2z> zxB$*MSQ?--?eL%!PdZVS766LVgb=}5+U1Pk6ChTqBJ4^wHZdv#N`O#ogrZpr5UAS& zD3szT4&`W)MtQ;ooPZ`N7fqW`0?(|F)i?{wDaP3-z!WKJZWx3!<>8>uM%vR}O-VS$ z>JexFXF!w$IiX!st`p;6jm{c;5^mgsJ4vU5AUuSdc3o3i3sepEqJc`_b_Zqd7=>YA zI*?k{=u`+`%3(H)Uj?i#t97y*^Vy6L5W{kOI|K(xV0AXY>Hvb`B*ow)LpbY5!dT#L z6n8QB1btZ$BW?dr+ZZ3jn=X2_s6qd2rYJpAYruW!xAbdFG=~X6%&}ltKAnQbwt{rU zAy#^e-^fZ)0MC!nh8>fOztIdF=@K}a$59V(aVRBtSk&W+kSOJF2t4cHIj7rgvM`RW z$q_xls-Qdyd4ycS1~s`tmW-CFbh3V8BQWX!DMN7*H7LUwie{Xo4ZHs70h)si4JXCP zQvytiBv20z1eA<$B=02P#CXzO^E;+zb_79;rRT+r197aFUhG%pPAg0}K_M+^89bTc zL641}^rL*iSg+@2w9T%k3j~>VG9`Ye>6)f%N(@X%dAhr%>6#J)Q&OJpuHTKW+-rA5 zAi+O)33w9>esENUx5ydX-BkheK56;hf1(SnZc?h(Y4Ga#n(@sTc&zygD9qM_p~~#f zGV`-CXPy`!FF+9y43yW+`xoEWF*GvrTy`zdl=WU-#A?0iXzkUJk&&`2S06rfv1`$c g%qDzE)541(%fH(ff_IBE<{9pSm9>E*6-^KP0-}Z?FaQ7m delta 170 zcmaE&bc}I=NGZx^prw85kH?(j9#r85lP9bN@+X1@buyJR*x382Ao@Fyrz3 z6)8Z$Xipc%5RKsE6b7c*AJ+X>kdl>&4L!&-t);OgQvIL=n?sRLz|jN)`>Q-X!s+vy zx(o~!XfQCQcnTZ{Xy7}*b)i%-n%SIDt>GP;o12@mTH5Okef9x%To$`l&EaI=n`IbK T^}L1!Xb*#@tDnm{r-UW|>(Mr! diff --git a/Resources/Textures/Interface/Misc/job_icons.rsi/meta.json b/Resources/Textures/Interface/Misc/job_icons.rsi/meta.json index bf919198f59..df37d244cfe 100644 --- a/Resources/Textures/Interface/Misc/job_icons.rsi/meta.json +++ b/Resources/Textures/Interface/Misc/job_icons.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from https://github.com/vgstation-coders/vgstation13/blob/e71d6c4fba5a51f99b81c295dcaec4fc2f58fb19/icons/mob/screen1.dmi | Brigmedic icon made by PuroSlavKing (Github) | Zombie icon made by RamZ | Zookeper by netwy (discort) | Rev and Head Rev icon taken from https://tgstation13.org/wiki/HUD and edited by coolmankid12345 (Discord) | Mindshield icon made by Psychpsyo (Github)", + "copyright": "Taken from https://github.com/vgstation-coders/vgstation13/blob/e71d6c4fba5a51f99b81c295dcaec4fc2f58fb19/icons/mob/screen1.dmi | Brigmedic icon made by PuroSlavKing (Github) | Zombie icon made by RamZ | Zookeper by netwy (discort) | Rev and Head Rev icon taken from https://tgstation13.org/wiki/HUD and edited by coolmankid12345 (Discord) | Mindshield icon taken from https://github.com/tgstation/tgstation/blob/master/icons/mob/huds/hud.dmi and edited by Golinth (Github)", "size": { "x": 8, From 379be3aa9fbe1cfd72f07bc68b6f49685483d488 Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 16 Feb 2024 15:59:34 +0000 Subject: [PATCH 151/200] Automatic changelog update (cherry picked from commit 16c1beda5c6c85964e0f8f18001db2d10f3a2374) --- 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 c5ca13405a6..d551320d2fd 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Emisse - changes: - - message: Nukies don't start with agent ID anymore - type: Tweak - id: 5446 - time: '2023-12-21T09:59:06.0000000+00:00' - url: null - author: Repo changes: - message: Mice can no longer spill containers. @@ -3878,3 +3871,11 @@ Order: 1 id: 5945 time: '2024-02-16T04:03:51.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25304 +- author: Golinth + changes: + - message: Mindshields are no longer separate and appear as a border around job + icons on the SecHUD + type: Tweak + id: 5946 + time: '2024-02-16T15:58:29.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25303 From c6756528d87cced13654636648f149fcf0c64357 Mon Sep 17 00:00:00 2001 From: Velcroboy <107660393+IamVelcroboy@users.noreply.github.com> Date: Fri, 16 Feb 2024 11:31:11 -0600 Subject: [PATCH 152/200] MORE SUFFIXES (#25314) Co-authored-by: Jeff (cherry picked from commit b5aa1e497f17fa5da4e1548be2797bb0ee4027ff) --- .../Entities/Objects/Specific/Medical/healing.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml index b7da58fb414..18d6f19bb11 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/healing.yml @@ -69,6 +69,7 @@ description: Used to treat even the nastiest burns. Also effective against caustic burns. parent: BaseHealingItem id: RegenerativeMesh + suffix: Full components: - type: Tag tags: @@ -99,6 +100,7 @@ - type: entity id: OintmentAdvanced1 parent: RegenerativeMesh + suffix: Single components: - type: Stack stackType: RegenerativeMesh @@ -155,6 +157,7 @@ description: A suture soaked in medicine, treats blunt-force trauma effectively and closes wounds. parent: BaseHealingItem id: MedicatedSuture + suffix: Full components: - type: Tag tags: @@ -183,6 +186,7 @@ - type: entity id: BrutepackAdvanced1 parent: MedicatedSuture + suffix: Single components: - type: Stack stackType: MedicatedSuture @@ -249,7 +253,7 @@ path: "/Audio/Items/Medical/brutepack_begin.ogg" healingEndSound: path: "/Audio/Items/Medical/brutepack_end.ogg" - + - type: entity name: roll of gauze description: Some sterile gauze to wrap around bloody stumps. From dd92fe87861e3e3cbebe52c5bcff30a2df2f5565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20M=C4=99drek?= Date: Fri, 16 Feb 2024 18:42:43 +0000 Subject: [PATCH 153/200] Fix spawning glass shard for each glass sheet in stack (#25308) * fix: SpawnEntitiesBehavior now works with stacks Fixed the issue of SpawnEntitiesBehavior not executing multiple times on entities with stack conponent. Fixes #25287 * fix: reduced dictionary iterations (cherry picked from commit 53270be66c9aca763b4bfc68e119d0692cd03fd7) --- .../Behaviors/SpawnEntitiesBehavior.cs | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs b/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs index 5b9b7596efb..ed5777c42aa 100644 --- a/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs +++ b/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs @@ -31,29 +31,38 @@ public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause var getRandomVector = () => new Vector2(system.Random.NextFloat(-Offset, Offset), system.Random.NextFloat(-Offset, Offset)); - foreach (var (entityId, minMax) in Spawn) + var executions = 1; + if (system.EntityManager.TryGetComponent(owner, out var stack)) { - var count = minMax.Min >= minMax.Max - ? minMax.Min - : system.Random.Next(minMax.Min, minMax.Max + 1); - - if (count == 0) continue; + executions = stack.Count; + } - if (EntityPrototypeHelpers.HasComponent(entityId, system.PrototypeManager, system.ComponentFactory)) + foreach (var (entityId, minMax) in Spawn) + { + for (var execution = 0; execution < executions; execution++) { - var spawned = system.EntityManager.SpawnEntity(entityId, position.Offset(getRandomVector())); - system.StackSystem.SetCount(spawned, count); + var count = minMax.Min >= minMax.Max + ? minMax.Min + : system.Random.Next(minMax.Min, minMax.Max + 1); - TransferForensics(spawned, system, owner); - } - else - { - for (var i = 0; i < count; i++) + if (count == 0) continue; + + if (EntityPrototypeHelpers.HasComponent(entityId, system.PrototypeManager, system.ComponentFactory)) { var spawned = system.EntityManager.SpawnEntity(entityId, position.Offset(getRandomVector())); + system.StackSystem.SetCount(spawned, count); TransferForensics(spawned, system, owner); } + else + { + for (var i = 0; i < count; i++) + { + var spawned = system.EntityManager.SpawnEntity(entityId, position.Offset(getRandomVector())); + + TransferForensics(spawned, system, owner); + } + } } } } From faf26c501713ceb80572fddc25d6860ff155d42b Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 16 Feb 2024 18:43:49 +0000 Subject: [PATCH 154/200] Automatic changelog update (cherry picked from commit 1019b3aeeecbbd0b8850e04c7c293fa1e2946ff4) --- 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 d551320d2fd..663a74eed58 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Repo - changes: - - message: Mice can no longer spill containers. - type: Tweak - id: 5447 - time: '2023-12-21T10:23:01.0000000+00:00' - url: null - author: Lukasz825700516 changes: - message: Gas tanks no longer predict insertion of random items. @@ -3879,3 +3872,10 @@ Order: 1 id: 5946 time: '2024-02-16T15:58:29.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25303 +- author: Lukasz825700516 + changes: + - message: Damaging stacked glass sheets now gives appropriate amount of glass shards + type: Fix + id: 5947 + time: '2024-02-16T18:42:43.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25308 From 5060e0614589c8c2b795693ac6a7a05832dfa509 Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Fri, 16 Feb 2024 10:50:51 -0800 Subject: [PATCH 155/200] =?UTF-8?q?Adds=20atmospherics=20access=20to=20the?= =?UTF-8?q?=20fire=20fighting=20door=20remote.=20Feels=20like=E2=80=A6=20(?= =?UTF-8?q?#25097)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds atmospherics access to the fire fighting door remote. Feels like an oversight for the atmos door remote to not have atmos access. Co-authored-by: Plykiya (cherry picked from commit 2ee73d54e838a6c119f7cb0413a2b2d8a5cf5402) --- Resources/Prototypes/Access/engineering.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Access/engineering.yml b/Resources/Prototypes/Access/engineering.yml index ce08b3910a4..94901fdf7af 100644 --- a/Resources/Prototypes/Access/engineering.yml +++ b/Resources/Prototypes/Access/engineering.yml @@ -21,3 +21,4 @@ id: FireFight tags: - Engineering + - Atmospherics From 02fd28b29c2cb8fa5b1ffb338bd572e58e75a6ae Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 16 Feb 2024 18:51:56 +0000 Subject: [PATCH 156/200] Automatic changelog update (cherry picked from commit 7461091af0eeef4adcd337354dc57a496a7bf7fd) --- 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 663a74eed58..69f01ae5f86 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Lukasz825700516 - changes: - - message: Gas tanks no longer predict insertion of random items. - type: Fix - id: 5448 - time: '2023-12-21T10:37:35.0000000+00:00' - url: null - author: mirrorcult changes: - message: Smart equipping now works with item slots @@ -3879,3 +3872,10 @@ Order: 1 id: 5947 time: '2024-02-16T18:42:43.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25308 +- author: Plykiya + changes: + - message: The firefighting door remote now has access to atmos doors. + type: Tweak + id: 5948 + time: '2024-02-16T18:50:51.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25097 From 0d8558335bde780e4330d8b002f2995024847e36 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Fri, 16 Feb 2024 19:55:42 +0100 Subject: [PATCH 157/200] Re-organise main menu screen (#25173) - The dummy control of 2px size has annoyed me for almost 5 years. - Why is it in the top-right. - Why is the server address not labelled. (cherry picked from commit 1a438e644f17f1352cec29d90fa755f37e120f34) --- .../MainMenu/UI/MainMenuControl.xaml | 74 +++++++++---------- .../Locale/en-US/main-menu/main-menu.ftl | 5 +- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/Content.Client/MainMenu/UI/MainMenuControl.xaml b/Content.Client/MainMenu/UI/MainMenuControl.xaml index e1d0652b933..d6c3f4b9415 100644 --- a/Content.Client/MainMenu/UI/MainMenuControl.xaml +++ b/Content.Client/MainMenu/UI/MainMenuControl.xaml @@ -2,46 +2,46 @@ xmlns:pllax="clr-namespace:Content.Client.Parallax" xmlns:clog="clr-namespace:Content.Client.Changelog"> - - - - - - + + + + [DataField("visibleLayers")] public HashSet VisibleLayers = new() { SubfloorLayers.FirstLayer }; + + /// + /// This is used for storing the original draw depth of a t-ray revealed entity. + /// e.g. when a t-ray revealed cable is drawn above a carpet. + /// + [DataField] + public int? OriginalDrawDepth; } } From 0af6ccb1c0020145d0547017acd39f74188ec5e6 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 17 Feb 2024 00:39:01 +0100 Subject: [PATCH 160/200] Automatic changelog update (cherry picked from commit b2e8c2e3aa3cc4a9e93b0fb9258217bfd7355600) --- 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 206b626085a..e424312cbd0 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,14 +1,5 @@ Order: 1 Entries: -- author: mirrorcult - changes: - - message: Smart equipping now works with item slots - type: Add - - message: Smart equipping is now predicted - type: Tweak - id: 5449 - time: '2023-12-21T14:17:09.0000000+00:00' - url: null - author: DrMelon changes: - message: Mice and other small creatures can no longer hurt Pun Pun or the Clown @@ -3879,3 +3870,10 @@ Entries: id: 5948 time: '2024-02-16T18:50:51.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25097 +- author: themias + changes: + - message: t-ray scanners can now penetrate carpets and puddles + type: Tweak + id: 5949 + time: '2024-02-16T23:37:56.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25276 From b1e1ec66eae5a2b7ff8a011b629bcb816c4e2d57 Mon Sep 17 00:00:00 2001 From: Krunklehorn <42424291+Krunklehorn@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:48:18 -0500 Subject: [PATCH 161/200] Add sfx for writing on paper (#25257) * Initial commit * Moved params to sound * Removed type tag * Removed null check * Forced default (cherry picked from commit 1de3f24f16733521d22543708a59e72a6b396c71) --- Content.Server/Paper/PaperSystem.cs | 2 ++ Content.Shared/Paper/SharedPaperComponent.cs | 7 +++++++ Resources/Audio/Items/Paper/attributions.yml | 4 ++++ Resources/Audio/Items/Paper/paper_scribble1.ogg | Bin 0 -> 35141 bytes Resources/Audio/Items/Paper/paper_scribble2.ogg | Bin 0 -> 28130 bytes Resources/Audio/Items/Paper/paper_scribble3.ogg | Bin 0 -> 23070 bytes Resources/Audio/Items/Paper/paper_scribble4.ogg | Bin 0 -> 22240 bytes Resources/Audio/Items/Paper/paper_scribble5.ogg | Bin 0 -> 35926 bytes .../Prototypes/SoundCollections/bureaucracy.yml | 8 ++++++++ 9 files changed, 21 insertions(+) create mode 100644 Resources/Audio/Items/Paper/attributions.yml create mode 100644 Resources/Audio/Items/Paper/paper_scribble1.ogg create mode 100644 Resources/Audio/Items/Paper/paper_scribble2.ogg create mode 100644 Resources/Audio/Items/Paper/paper_scribble3.ogg create mode 100644 Resources/Audio/Items/Paper/paper_scribble4.ogg create mode 100644 Resources/Audio/Items/Paper/paper_scribble5.ogg create mode 100644 Resources/Prototypes/SoundCollections/bureaucracy.yml diff --git a/Content.Server/Paper/PaperSystem.cs b/Content.Server/Paper/PaperSystem.cs index 80cc8fa4aed..27c94313b21 100644 --- a/Content.Server/Paper/PaperSystem.cs +++ b/Content.Server/Paper/PaperSystem.cs @@ -160,6 +160,8 @@ private void OnInputTextMessage(EntityUid uid, PaperComponent paperComp, PaperIn if (args.Session.AttachedEntity != null) _adminLogger.Add(LogType.Chat, LogImpact.Low, $"{ToPrettyString(args.Session.AttachedEntity.Value):player} has written on {ToPrettyString(uid):entity} the following text: {args.Text}"); + + _audio.PlayPvs(paperComp.Sound, uid); } paperComp.Mode = PaperAction.Read; diff --git a/Content.Shared/Paper/SharedPaperComponent.cs b/Content.Shared/Paper/SharedPaperComponent.cs index 1e654cc68ae..dd87f9f907a 100644 --- a/Content.Shared/Paper/SharedPaperComponent.cs +++ b/Content.Shared/Paper/SharedPaperComponent.cs @@ -1,9 +1,16 @@ +using Robust.Shared.Audio; using Robust.Shared.Serialization; namespace Content.Shared.Paper; public abstract partial class SharedPaperComponent : Component { + /// + /// Sound played after writing to the paper. + /// + [DataField("sound")] + public SoundSpecifier? Sound { get; private set; } = new SoundCollectionSpecifier("PaperScribbles", AudioParams.Default.WithVariation(0.1f)); + [Serializable, NetSerializable] public sealed class PaperBoundUserInterfaceState : BoundUserInterfaceState { diff --git a/Resources/Audio/Items/Paper/attributions.yml b/Resources/Audio/Items/Paper/attributions.yml new file mode 100644 index 00000000000..42c973c67fa --- /dev/null +++ b/Resources/Audio/Items/Paper/attributions.yml @@ -0,0 +1,4 @@ +- files: ["paper_scribble1.ogg", "paper_scribble2.ogg", "paper_scribble3.ogg", "paper_scribble4.ogg", "paper_scribble5.ogg"] + license: "CC0-1.0" + copyright: "Originally 'Pen Clicks and Writing on Paper' created by PDaefaul. Cut, spliced and converted by Krunklehorn." + source: "https://freesound.org/people/PDaefaul/sounds/631971/" diff --git a/Resources/Audio/Items/Paper/paper_scribble1.ogg b/Resources/Audio/Items/Paper/paper_scribble1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..982bad95c4df19182fde3bdc90a6b030388a1b08 GIT binary patch literal 35141 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
yZEcwGWeqc22~wpr)E1(?OhzjVg1mItdgM0#4Bi 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 k3CT3Y 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 biMW)QOM4;|+XYfqUjF#IK>*g_5m*rbT@tmS literal 0 HcmV?d00001 diff --git a/Resources/Audio/Items/Paper/paper_scribble4.ogg b/Resources/Audio/Items/Paper/paper_scribble4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1d9980133dba6a5016205af47bd3e3ee737e7b3d GIT binary patch literal 22240 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 literal 0 HcmV?d00001 diff --git a/Resources/Audio/Items/Paper/paper_scribble5.ogg b/Resources/Audio/Items/Paper/paper_scribble5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8e155e5fd62fc6669db25082f23a473b9e122431 GIT binary patch literal 35926 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 Date: Sat, 17 Feb 2024 00:49:24 +0100 Subject: [PATCH 162/200] Automatic changelog update (cherry picked from commit 25c658fdcafb3a3efd0d9cd9f27294c08a185c9d) --- 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 e424312cbd0..282eacc3582 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,5 @@ Order: 1 Entries: -- author: DrMelon - changes: - - message: Mice and other small creatures can no longer hurt Pun Pun or the Clown - by smashing them into tables. - type: Fix - id: 5450 - time: '2023-12-21T15:18:26.0000000+00:00' - url: null - author: Boaz1111 changes: - message: Added uranium munitions, a new T1 arsenal research. @@ -3877,3 +3869,10 @@ Entries: id: 5949 time: '2024-02-16T23:37:56.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25276 +- author: Krunk + changes: + - message: Sound effects have been added for writing on paper. + type: Add + id: 5950 + time: '2024-02-16T23:48:18.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25257 From f4e2bef3d2e395c874677cb7aec91a633ebef9c5 Mon Sep 17 00:00:00 2001 From: PotentiallyTom <67602105+PotentiallyTom@users.noreply.github.com> Date: Fri, 16 Feb 2024 23:50:49 +0000 Subject: [PATCH 163/200] New sprites for guidebooks (#25232) * added books to roles * First pass * removed yaml to split pull requests into resprite first, then giving the books to assistants * new science (cherry picked from commit 561e8088426f163f1a38dcabf495c56e5e8fc8ce) --- .../Prototypes/Entities/Objects/Misc/books.yml | 6 +++--- .../Objects/Misc/books.rsi/book_medical.png | Bin 0 -> 361 bytes .../Objects/Misc/books.rsi/book_science.png | Bin 0 -> 291 bytes .../Objects/Misc/books.rsi/book_security.png | Bin 0 -> 319 bytes .../Textures/Objects/Misc/books.rsi/meta.json | 11 ++++++++++- 5 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_medical.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_science.png create mode 100644 Resources/Textures/Objects/Misc/books.rsi/book_security.png diff --git a/Resources/Prototypes/Entities/Objects/Misc/books.yml b/Resources/Prototypes/Entities/Objects/Misc/books.yml index 7a0e76552fc..44d84118a4b 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/books.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/books.yml @@ -143,7 +143,7 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book0 # no science book sprite so this is a placeholder + - state: book_science - type: Tag tags: - Book @@ -161,7 +161,7 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book_detective # maybe a proper sprite is needed + - state: book_security - type: Tag tags: - Book @@ -220,7 +220,7 @@ - type: Sprite sprite: Objects/Misc/books.rsi layers: - - state: book0 # no medical book sprite so this is a placeholder + - state: book_medical - type: Tag tags: - Book diff --git a/Resources/Textures/Objects/Misc/books.rsi/book_medical.png b/Resources/Textures/Objects/Misc/books.rsi/book_medical.png new file mode 100644 index 0000000000000000000000000000000000000000..7152cfe51c66abaa4c126785ec02931af6b2259d GIT binary patch literal 361 zcmV-v0ha!WP)`!9YcKQxUFKd&Q!}%!00000NkvXX Hu0mjf;R~1k literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/book_science.png b/Resources/Textures/Objects/Misc/books.rsi/book_science.png new file mode 100644 index 0000000000000000000000000000000000000000..47047c958a032b1709baf9936c6b06fe55b7cc34 GIT binary patch literal 291 zcmV+;0o?wHP)@Tc5e_}9eN`-LBZJrXi1iW5SLc!VDn2-|A6_RL+ESY z*U*pvk;uQpD4`s=QBYn51&Yp&gj&8iOpv5A4EglwJ{yl-KD%UFtDsdtL4ku~HLn2d z>&wpCEJ!)4KtqO%8byhcoFxkYK#J6w(a?1KqW52xD37jfv&L&PP?JYPFJaOzXC3MJOJGE psUHCj4xjVjai^{4!ARsMxC7sySvz04@h1QP002ovPDHLkV1obPdglND literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/book_security.png b/Resources/Textures/Objects/Misc/books.rsi/book_security.png new file mode 100644 index 0000000000000000000000000000000000000000..fb1a4028e8f4ac3c83683d1b1415d0157179d872 GIT binary patch literal 319 zcmV-F0l@x=P)(BbLBOZci<*>0_6T?8(n}*&Ve1EQ_c?1 zEoTSlma_wN%h>@@!1@nxPP)@>p*MhY#sk24KhqRI1eN>X)LTjKg9gJ-Z~^5CS}WMb literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/books.rsi/meta.json b/Resources/Textures/Objects/Misc/books.rsi/meta.json index daa28bac2aa..514e4075822 100644 --- a/Resources/Textures/Objects/Misc/books.rsi/meta.json +++ b/Resources/Textures/Objects/Misc/books.rsi/meta.json @@ -101,6 +101,15 @@ }, { "name": "book_fish" + }, + { + "name": "book_science" + }, + { + "name": "book_medical" + }, + { + "name": "book_security" } ] -} \ No newline at end of file +} From d4a889d9aa84ecadd30fb29b9febb8f4761b0168 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 17 Feb 2024 00:51:55 +0100 Subject: [PATCH 164/200] Automatic changelog update (cherry picked from commit 19a7b0592cfd0bf360ad24eebb8196312c56b8e3) --- 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 282eacc3582..d59b19d4807 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,14 +1,5 @@ Order: 1 Entries: -- author: Boaz1111 - changes: - - message: Added uranium munitions, a new T1 arsenal research. - type: Add - - message: Made practice munitions and weapons roundstart - type: Tweak - id: 5451 - time: '2023-12-21T17:19:45.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/22824 - author: Admiral-Obvious-001 changes: - message: Reduced per pellet damage of shotguns slightly. @@ -3876,3 +3867,10 @@ Entries: id: 5950 time: '2024-02-16T23:48:18.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25257 +- author: PotentiallyTom + changes: + - message: Added new covers for the medical, security, and science guidebooks + type: Add + id: 5951 + time: '2024-02-16T23:50:49.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25232 From cb0fdb47d12bc2d03e198cc68f5cb43a2d223f81 Mon Sep 17 00:00:00 2001 From: MilenVolf <63782763+MilenVolf@users.noreply.github.com> Date: Sat, 17 Feb 2024 02:52:31 +0300 Subject: [PATCH 165/200] LockVisualizer (#25224) * LockVisualizer * Fix state * Clean some code * Make it component, fix tests fail * Fix for StateUnlocked Now it is possible to manually set the unlocked state and it will work! * Optimize LockVisualizer, add check for unlocked state * No todo I guess (cherry picked from commit c7870882f6f956eea07cbb4738ae45c8805c8ce6) --- .../Lock/Visualizers/LockVisualizerSystem.cs | 38 ++++++++++++++++++ .../Lock/Visualizers/LockVisualsComponent.cs | 20 +++++++++ .../Singularity/Systems/EmitterSystem.cs | 12 +----- .../EntityStorageVisualizerSystem.cs | 16 +------- .../EntityStorageVisualsComponent.cs | 14 ------- .../Unary/EntitySystems/GasCanisterSystem.cs | 12 ------ .../Components/SharedGasCanisterComponent.cs | 3 +- Content.Shared/Lock/LockComponent.cs | 7 ++++ Content.Shared/Lock/LockSystem.cs | 11 ++--- .../Security/DeployableBarrierVisuals.cs | 18 --------- .../Systems/DeployableBarrierSystem.cs | 4 -- Content.Shared/Storage/StorageComponent.cs | 2 - .../Objects/Specific/Security/barrier.yml | 12 ++---- .../Xenoarchaeology/artifact_equipment.yml | 3 +- .../Structures/Machines/anomaly_equipment.yml | 3 +- .../Power/Generation/Singularity/emitter.yml | 5 ++- .../Storage/Canisters/gas_canisters.yml | 6 +-- .../Closets/Lockers/base_structurelockers.yml | 3 +- .../Storage/Closets/base_structureclosets.yml | 8 ++-- .../Storage/Crates/base_structurecrates.yml | 3 +- .../barrier.rsi/{deployed.png => locked.png} | Bin .../Specific/Security/barrier.rsi/meta.json | 2 +- .../emitter.rsi/{lock.png => locked.png} | Bin .../Singularity/emitter.rsi/meta.json | 2 +- .../{can-locked.png => locked.png} | Bin .../Structures/Storage/canister.rsi/meta.json | 4 +- .../{can-unlocked.png => unlocked.png} | Bin 27 files changed, 98 insertions(+), 110 deletions(-) create mode 100644 Content.Client/Lock/Visualizers/LockVisualizerSystem.cs create mode 100644 Content.Client/Lock/Visualizers/LockVisualsComponent.cs delete mode 100644 Content.Shared/Security/DeployableBarrierVisuals.cs rename Resources/Textures/Objects/Specific/Security/barrier.rsi/{deployed.png => locked.png} (100%) rename Resources/Textures/Structures/Power/Generation/Singularity/emitter.rsi/{lock.png => locked.png} (100%) rename Resources/Textures/Structures/Storage/canister.rsi/{can-locked.png => locked.png} (100%) rename Resources/Textures/Structures/Storage/canister.rsi/{can-unlocked.png => unlocked.png} (100%) diff --git a/Content.Client/Lock/Visualizers/LockVisualizerSystem.cs b/Content.Client/Lock/Visualizers/LockVisualizerSystem.cs new file mode 100644 index 00000000000..1329a69ad25 --- /dev/null +++ b/Content.Client/Lock/Visualizers/LockVisualizerSystem.cs @@ -0,0 +1,38 @@ +using Content.Shared.Storage; +using Content.Shared.Lock; +using Robust.Client.GameObjects; + +namespace Content.Client.Lock.Visualizers; + +public sealed class LockVisualizerSystem : VisualizerSystem +{ + protected override void OnAppearanceChange(EntityUid uid, LockVisualsComponent comp, ref AppearanceChangeEvent args) + { + if (args.Sprite == null + || !AppearanceSystem.TryGetData(uid, LockVisuals.Locked, out _, args.Component)) + return; + + // Lock state for the entity. + if (!AppearanceSystem.TryGetData(uid, LockVisuals.Locked, out var locked, args.Component)) + locked = true; + + var unlockedStateExist = args.Sprite.BaseRSI?.TryGetState(comp.StateUnlocked, out _); + + if (AppearanceSystem.TryGetData(uid, StorageVisuals.Open, out var open, args.Component)) + { + args.Sprite.LayerSetVisible(LockVisualLayers.Lock, !open); + } + else if (!(bool) unlockedStateExist!) + args.Sprite.LayerSetVisible(LockVisualLayers.Lock, locked); + + if (!open && (bool) unlockedStateExist!) + { + args.Sprite.LayerSetState(LockVisualLayers.Lock, locked ? comp.StateLocked : comp.StateUnlocked); + } + } +} + +public enum LockVisualLayers : byte +{ + Lock +} diff --git a/Content.Client/Lock/Visualizers/LockVisualsComponent.cs b/Content.Client/Lock/Visualizers/LockVisualsComponent.cs new file mode 100644 index 00000000000..93844d6d823 --- /dev/null +++ b/Content.Client/Lock/Visualizers/LockVisualsComponent.cs @@ -0,0 +1,20 @@ +namespace Content.Client.Lock.Visualizers; + +[RegisterComponent] +[Access(typeof(LockVisualizerSystem))] +public sealed partial class LockVisualsComponent : Component +{ + /// + /// The RSI state used for the lock indicator while the entity is locked. + /// + [DataField("stateLocked")] + [ViewVariables(VVAccess.ReadWrite)] + public string? StateLocked = "locked"; + + /// + /// The RSI state used for the lock indicator entity is unlocked. + /// + [DataField("stateUnlocked")] + [ViewVariables(VVAccess.ReadWrite)] + public string? StateUnlocked = "unlocked"; +} diff --git a/Content.Client/Singularity/Systems/EmitterSystem.cs b/Content.Client/Singularity/Systems/EmitterSystem.cs index 5eb80928d88..e3396d74a29 100644 --- a/Content.Client/Singularity/Systems/EmitterSystem.cs +++ b/Content.Client/Singularity/Systems/EmitterSystem.cs @@ -1,7 +1,5 @@ -using Content.Client.Storage.Visualizers; -using Content.Shared.Singularity.Components; +using Content.Shared.Singularity.Components; using Content.Shared.Singularity.EntitySystems; -using Content.Shared.Storage; using Robust.Client.GameObjects; namespace Content.Client.Singularity.Systems; @@ -21,14 +19,6 @@ private void OnAppearanceChange(EntityUid uid, EmitterComponent component, ref A if (args.Sprite == null) return; - if (args.Sprite.LayerMapTryGet(StorageVisualLayers.Lock, out var lockLayer)) - { - if (!_appearance.TryGetData(uid, StorageVisuals.Locked, out var locked, args.Component)) - locked = false; - - args.Sprite.LayerSetVisible(lockLayer, locked); - } - if (!_appearance.TryGetData(uid, EmitterVisuals.VisualState, out var state, args.Component)) state = EmitterVisualState.Off; diff --git a/Content.Client/Storage/Visualizers/EntityStorageVisualizerSystem.cs b/Content.Client/Storage/Visualizers/EntityStorageVisualizerSystem.cs index 772f516a692..ee4f2fdfd6c 100644 --- a/Content.Client/Storage/Visualizers/EntityStorageVisualizerSystem.cs +++ b/Content.Client/Storage/Visualizers/EntityStorageVisualizerSystem.cs @@ -70,25 +70,11 @@ protected override void OnAppearanceChange(EntityUid uid, EntityStorageVisualsCo args.Sprite.LayerSetState(StorageVisualLayers.Base, comp.StateBaseClosed); } } - - // Lock state for the storage entity. TODO: Split into its own visualizer. - if (AppearanceSystem.TryGetData(uid, StorageVisuals.CanLock, out var canLock, args.Component) && canLock) - { - if (!AppearanceSystem.TryGetData(uid, StorageVisuals.Locked, out var locked, args.Component)) - locked = true; - - args.Sprite.LayerSetVisible(StorageVisualLayers.Lock, !open); - if (!open) - { - args.Sprite.LayerSetState(StorageVisualLayers.Lock, locked ? comp.StateLocked : comp.StateUnlocked); - } - } } } public enum StorageVisualLayers : byte { Base, - Door, - Lock + Door } diff --git a/Content.Client/Storage/Visualizers/EntityStorageVisualsComponent.cs b/Content.Client/Storage/Visualizers/EntityStorageVisualsComponent.cs index dc171d6c54e..2215d8cd70d 100644 --- a/Content.Client/Storage/Visualizers/EntityStorageVisualsComponent.cs +++ b/Content.Client/Storage/Visualizers/EntityStorageVisualsComponent.cs @@ -32,20 +32,6 @@ public sealed partial class EntityStorageVisualsComponent : Component [ViewVariables(VVAccess.ReadWrite)] public string? StateDoorClosed; - /// - /// The RSI state used for the lock indicator while the storage is locked. - /// - [DataField("stateLocked")] - [ViewVariables(VVAccess.ReadWrite)] - public string? StateLocked = "locked"; - - /// - /// The RSI state used for the lock indicator while the storage is unlocked. - /// - [DataField("stateUnlocked")] - [ViewVariables(VVAccess.ReadWrite)] - public string? StateUnlocked = "unlocked"; - /// /// The drawdepth the object has when it's open /// diff --git a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs index e1e7b2a7013..64d02d793bc 100644 --- a/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs +++ b/Content.Server/Atmos/Piping/Unary/EntitySystems/GasCanisterSystem.cs @@ -17,7 +17,6 @@ using Content.Shared.Interaction; using Content.Shared.Lock; using Robust.Server.GameObjects; -using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; using Robust.Shared.Player; @@ -54,7 +53,6 @@ public override void Initialize() SubscribeLocalEvent(OnHoldingTankEjectMessage); SubscribeLocalEvent(OnCanisterChangeReleasePressure); SubscribeLocalEvent(OnCanisterChangeReleaseValve); - SubscribeLocalEvent(OnLockToggled); } /// @@ -78,11 +76,6 @@ private void OnCanisterStartup(EntityUid uid, GasCanisterComponent comp, Compone { // Ensure container _slots.AddItemSlot(uid, comp.ContainerName, comp.GasTankSlot); - - if (TryComp(uid, out var lockComp)) - { - _appearance.SetData(uid, GasCanisterVisuals.Locked, lockComp.Locked); - } } private void DirtyUI(EntityUid uid, @@ -309,11 +302,6 @@ private void OnAnalyzed(EntityUid uid, GasCanisterComponent component, GasAnalyz args.GasMixtures = new Dictionary { {Name(uid), component.Air} }; } - private void OnLockToggled(EntityUid uid, GasCanisterComponent component, ref LockToggledEvent args) - { - _appearance.SetData(uid, GasCanisterVisuals.Locked, args.Locked); - } - /// /// Check if the canister is locked, playing its sound and popup if so. /// diff --git a/Content.Shared/Atmos/Piping/Binary/Components/SharedGasCanisterComponent.cs b/Content.Shared/Atmos/Piping/Binary/Components/SharedGasCanisterComponent.cs index 23300cb2a01..1203639e092 100644 --- a/Content.Shared/Atmos/Piping/Binary/Components/SharedGasCanisterComponent.cs +++ b/Content.Shared/Atmos/Piping/Binary/Components/SharedGasCanisterComponent.cs @@ -21,8 +21,7 @@ public enum GasCanisterUiKey public enum GasCanisterVisuals { PressureState, - TankInserted, - Locked + TankInserted } #endregion diff --git a/Content.Shared/Lock/LockComponent.cs b/Content.Shared/Lock/LockComponent.cs index b3c46597498..5587fc2698b 100644 --- a/Content.Shared/Lock/LockComponent.cs +++ b/Content.Shared/Lock/LockComponent.cs @@ -113,3 +113,10 @@ public override DoAfterEvent Clone() return this; } } + +[NetSerializable] +[Serializable] +public enum LockVisuals : byte +{ + Locked +} diff --git a/Content.Shared/Lock/LockSystem.cs b/Content.Shared/Lock/LockSystem.cs index e5f53b4080e..a01c5ace4d4 100644 --- a/Content.Shared/Lock/LockSystem.cs +++ b/Content.Shared/Lock/LockSystem.cs @@ -7,11 +7,9 @@ using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Popups; -using Content.Shared.Storage; using Content.Shared.Storage.Components; using Content.Shared.Verbs; using JetBrains.Annotations; -using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Utility; @@ -46,8 +44,7 @@ public override void Initialize() private void OnStartup(EntityUid uid, LockComponent lockComp, ComponentStartup args) { - _appearanceSystem.SetData(uid, StorageVisuals.CanLock, true); - _appearanceSystem.SetData(uid, StorageVisuals.Locked, lockComp.Locked); + _appearanceSystem.SetData(uid, LockVisuals.Locked, lockComp.Locked); } private void OnActivated(EntityUid uid, LockComponent lockComp, ActivateInWorldEvent args) @@ -124,7 +121,7 @@ public bool TryLock(EntityUid uid, EntityUid user, LockComponent? lockComp = nul _audio.PlayPredicted(lockComp.LockSound, uid, user); lockComp.Locked = true; - _appearanceSystem.SetData(uid, StorageVisuals.Locked, true); + _appearanceSystem.SetData(uid, LockVisuals.Locked, true); Dirty(uid, lockComp); var ev = new LockToggledEvent(true); @@ -155,7 +152,7 @@ public void Unlock(EntityUid uid, EntityUid? user, LockComponent? lockComp = nul _audio.PlayPredicted(lockComp.UnlockSound, uid, user); lockComp.Locked = false; - _appearanceSystem.SetData(uid, StorageVisuals.Locked, false); + _appearanceSystem.SetData(uid, LockVisuals.Locked, false); Dirty(uid, lockComp); var ev = new LockToggledEvent(false); @@ -250,7 +247,7 @@ private void OnEmagged(EntityUid uid, LockComponent component, ref GotEmaggedEve if (!component.Locked || !component.BreakOnEmag) return; _audio.PlayPredicted(component.UnlockSound, uid, null); - _appearanceSystem.SetData(uid, StorageVisuals.Locked, false); + _appearanceSystem.SetData(uid, LockVisuals.Locked, false); RemComp(uid); //Literally destroys the lock as a tell it was emagged args.Handled = true; } diff --git a/Content.Shared/Security/DeployableBarrierVisuals.cs b/Content.Shared/Security/DeployableBarrierVisuals.cs deleted file mode 100644 index 147ae23bac0..00000000000 --- a/Content.Shared/Security/DeployableBarrierVisuals.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Robust.Shared.Serialization; - -namespace Content.Shared.Security -{ - [Serializable, NetSerializable] - public enum DeployableBarrierVisuals : byte - { - State - } - - - [Serializable, NetSerializable] - public enum DeployableBarrierState : byte - { - Idle, - Deployed - } -} diff --git a/Content.Shared/Security/Systems/DeployableBarrierSystem.cs b/Content.Shared/Security/Systems/DeployableBarrierSystem.cs index 9d021c52194..7b9ce841a99 100644 --- a/Content.Shared/Security/Systems/DeployableBarrierSystem.cs +++ b/Content.Shared/Security/Systems/DeployableBarrierSystem.cs @@ -8,7 +8,6 @@ namespace Content.Shared.Security.Systems; public sealed class DeployableBarrierSystem : EntitySystem { - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly FixtureSystem _fixtures = default!; [Dependency] private readonly SharedPointLightSystem _pointLight = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; @@ -55,9 +54,6 @@ private void ToggleBarrierDeploy(EntityUid uid, bool isDeployed, DeployableBarri _physics.SetHard(uid, fixture, false); } - var state = isDeployed ? DeployableBarrierState.Deployed : DeployableBarrierState.Idle; - _appearance.SetData(uid, DeployableBarrierVisuals.State, state); - if (TryComp(uid, out SharedPullableComponent? pullable)) _pulling.TryStopPull(pullable); diff --git a/Content.Shared/Storage/StorageComponent.cs b/Content.Shared/Storage/StorageComponent.cs index fa06e333e80..35f7955349c 100644 --- a/Content.Shared/Storage/StorageComponent.cs +++ b/Content.Shared/Storage/StorageComponent.cs @@ -207,8 +207,6 @@ public enum StorageVisuals : byte { Open, HasContents, - CanLock, - Locked, StorageUsed, Capacity } diff --git a/Resources/Prototypes/Entities/Objects/Specific/Security/barrier.yml b/Resources/Prototypes/Entities/Objects/Specific/Security/barrier.yml index 3a31edf7f14..9277497e4f4 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Security/barrier.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Security/barrier.yml @@ -10,15 +10,11 @@ - type: Sprite sprite: Objects/Specific/Security/barrier.rsi layers: - - state: "idle" - map: ["deployableBarrierBase"] + - state: idle + - state: locked + map: ["enum.LockVisualLayers.Lock"] - type: Appearance - - type: GenericVisualizer - visuals: - enum.DeployableBarrierVisuals.State: - deployableBarrierBase: - enum.DeployableBarrierState.Idle: {state: "idle"} - enum.DeployableBarrierState.Deployed: {state: "deployed"} + - type: LockVisuals - type: InteractionOutline - type: Physics bodyType: Dynamic diff --git a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifact_equipment.yml b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifact_equipment.yml index 659145562f5..531a5304415 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifact_equipment.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Xenoarchaeology/artifact_equipment.yml @@ -22,7 +22,7 @@ visible: false map: ["enum.WeldableLayers.BaseWelded"] - state: locked - map: ["enum.StorageVisualLayers.Lock"] + map: ["enum.LockVisualLayers.Lock"] shader: unshaded - type: InteractionOutline - type: Physics @@ -73,6 +73,7 @@ - type: EntityStorageVisuals stateDoorOpen: artifact_container_open stateDoorClosed: artifact_container_door + - type: LockVisuals - type: ItemSlots - type: ContainerContainer containers: diff --git a/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml b/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml index 2697e00a700..cc9f8035fe7 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml @@ -140,7 +140,7 @@ - state: locked shader: unshaded visible: false - map: ["enum.StorageVisualLayers.Lock"] + map: ["enum.LockVisualLayers.Lock"] - type: Transform noRot: false - type: Fixtures @@ -203,6 +203,7 @@ enum.PowerDeviceVisualLayers.Powered: True: { visible: true } False: { visible: false } + - type: LockVisuals - type: DeviceNetwork deviceNetId: Wireless receiveFrequencyId: BasicDevice diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml index e5604bea080..52698f62cc0 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml @@ -31,10 +31,10 @@ shader: unshaded visible: false map: ["enum.EmitterVisualLayers.Lights"] - - state: lock + - state: locked shader: unshaded visible: false - map: ["enum.StorageVisualLayers.Lock"] + map: ["enum.LockVisualLayers.Lock"] - type: Emitter - type: Gun showExamineText: false @@ -83,6 +83,7 @@ - type: Appearance - type: Lock locked: false + - type: LockVisuals - type: AccessReader access: [[ "Engineering" ]] - type: Machine diff --git a/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml b/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml index 760eb31755b..897b7be6ffb 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml @@ -24,10 +24,10 @@ tankInserted: False: { state: can-open, visible: false } True: { state: can-open, visible: true } - enum.GasCanisterVisuals.Locked: + enum.LockVisuals.Locked: locked: - False: { state: can-unlocked, shader: "unshaded" } - True: { state: can-locked, shader: "unshaded" } + False: { state: unlocked, shader: "unshaded" } + True: { state: locked, shader: "unshaded" } enum.GasCanisterVisuals.PressureState: pressureLight: 0: { state: can-o0, shader: "unshaded" } diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml index 4448d551e33..7ab24f6b5ca 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml @@ -5,6 +5,7 @@ components: - type: AccessReader - type: Lock + - type: LockVisuals - type: Sprite sprite: Structures/Storage/closet.rsi noRot: true @@ -14,7 +15,7 @@ - state: generic_door map: ["enum.StorageVisualLayers.Door"] - state: locked - map: ["enum.StorageVisualLayers.Lock"] + map: ["enum.LockVisualLayers.Lock"] shader: unshaded - state: welded visible: false diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml index d1a60566d4e..46ec7cbf6aa 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml @@ -180,6 +180,7 @@ components: - type: AccessReader - type: Lock + - type: LockVisuals - type: Sprite sprite: Structures/Storage/wall_locker.rsi layers: @@ -188,7 +189,7 @@ - state: generic_door map: ["enum.StorageVisualLayers.Door"] - state: locked - map: ["enum.StorageVisualLayers.Lock"] + map: ["enum.LockVisualLayers.Lock"] shader: unshaded - state: welded visible: false @@ -222,7 +223,7 @@ visible: false map: ["enum.WeldableLayers.BaseWelded"] - state: locked - map: ["enum.StorageVisualLayers.Lock"] + map: ["enum.LockVisualLayers.Lock"] shader: unshaded - type: MovedByPressure - type: DamageOnHighSpeedImpact @@ -282,7 +283,6 @@ - type: Appearance - type: EntityStorageVisuals stateBase: base - stateLocked: locked - stateUnlocked: unlocked stateDoorOpen: base stateDoorClosed: door + - type: LockVisuals diff --git a/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml b/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml index 76a88e7858f..acf4fd2149e 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml @@ -87,6 +87,7 @@ id: CrateBaseSecure components: - type: Lock + - type: LockVisuals - type: AccessReader - type: Icon sprite: Structures/Storage/Crates/secure.rsi @@ -101,7 +102,7 @@ visible: false map: ["enum.WeldableLayers.BaseWelded"] - state: locked - map: ["enum.StorageVisualLayers.Lock"] + map: ["enum.LockVisualLayers.Lock"] shader: unshaded - type: Damageable damageContainer: StructuralInorganic diff --git a/Resources/Textures/Objects/Specific/Security/barrier.rsi/deployed.png b/Resources/Textures/Objects/Specific/Security/barrier.rsi/locked.png similarity index 100% rename from Resources/Textures/Objects/Specific/Security/barrier.rsi/deployed.png rename to Resources/Textures/Objects/Specific/Security/barrier.rsi/locked.png diff --git a/Resources/Textures/Objects/Specific/Security/barrier.rsi/meta.json b/Resources/Textures/Objects/Specific/Security/barrier.rsi/meta.json index 8142924b683..5cd7cffb035 100644 --- a/Resources/Textures/Objects/Specific/Security/barrier.rsi/meta.json +++ b/Resources/Textures/Objects/Specific/Security/barrier.rsi/meta.json @@ -11,7 +11,7 @@ "name": "idle" }, { - "name": "deployed", + "name": "locked", "delays": [ [ 0.1, diff --git a/Resources/Textures/Structures/Power/Generation/Singularity/emitter.rsi/lock.png b/Resources/Textures/Structures/Power/Generation/Singularity/emitter.rsi/locked.png similarity index 100% rename from Resources/Textures/Structures/Power/Generation/Singularity/emitter.rsi/lock.png rename to Resources/Textures/Structures/Power/Generation/Singularity/emitter.rsi/locked.png diff --git a/Resources/Textures/Structures/Power/Generation/Singularity/emitter.rsi/meta.json b/Resources/Textures/Structures/Power/Generation/Singularity/emitter.rsi/meta.json index 0456b99ffab..5b5b51257ac 100644 --- a/Resources/Textures/Structures/Power/Generation/Singularity/emitter.rsi/meta.json +++ b/Resources/Textures/Structures/Power/Generation/Singularity/emitter.rsi/meta.json @@ -34,7 +34,7 @@ ] }, { - "name": "lock", + "name": "locked", "directions": 4 }, { diff --git a/Resources/Textures/Structures/Storage/canister.rsi/can-locked.png b/Resources/Textures/Structures/Storage/canister.rsi/locked.png similarity index 100% rename from Resources/Textures/Structures/Storage/canister.rsi/can-locked.png rename to Resources/Textures/Structures/Storage/canister.rsi/locked.png diff --git a/Resources/Textures/Structures/Storage/canister.rsi/meta.json b/Resources/Textures/Structures/Storage/canister.rsi/meta.json index 7f9dfe23402..95d67cc8ae1 100644 --- a/Resources/Textures/Structures/Storage/canister.rsi/meta.json +++ b/Resources/Textures/Structures/Storage/canister.rsi/meta.json @@ -23,10 +23,10 @@ "name": "can-connector" }, { - "name": "can-locked" + "name": "locked" }, { - "name": "can-unlocked" + "name": "unlocked" }, { "name": "can-o0", diff --git a/Resources/Textures/Structures/Storage/canister.rsi/can-unlocked.png b/Resources/Textures/Structures/Storage/canister.rsi/unlocked.png similarity index 100% rename from Resources/Textures/Structures/Storage/canister.rsi/can-unlocked.png rename to Resources/Textures/Structures/Storage/canister.rsi/unlocked.png From 589c55a6fcc05cf6d4cc8b768b1b6e7d28f55456 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Sat, 17 Feb 2024 00:54:27 +0100 Subject: [PATCH 166/200] Solution precision fixes (#25199) * Add test for two chemistry issues 1. rounding issue with reaction processing when making chloral hydrate 2. reliable assert trip due to the ValidateSolution() heat capacity issue. * Fix FixedPoint2 arithmetic Fix internal floating point arithmetic in places where it could be avoided. Fix incorrect rounding mode used in other places (it should always floor, like regular int arithmetic). I had to add an explicit epsilon value for float -> FixedPoint2 because something like 1.05 is actually like 1.04999 and that'd cause it to be rounded down to 1.04. This fixes reaction reagent processing in cases where the reagent inputs can't cleanly divide. Previously, when making 30u chloral hydrate by adding the chlorine in 10u increments you'd end up with 0.04 chlorine left over. This was caused by division in the reaction code rounding up in some cases. Changing division here to always round down fixes it. * Attempt to fix heat capacity precision assert issues. Fixes #22126 First, we just increase the tolerance of the assert. It was way too low. Second, actually put a cap on float drift from one-off _heatCapacity changes. * Fix float -> FixedPoint2 epsilon for negative number, fix tests. * Fix DamageableTest * Oh yeah I need to call CleanReturnAsync (cherry picked from commit 33611b7094ba9540326a6f0f6edd2017640e61db) --- .../Tests/Chemistry/SolutionRoundingTest.cs | 122 ++++++++++++++++++ .../Tests/Damageable/DamageableTest.cs | 20 +-- .../Chemistry/Components/Solution.cs | 24 +++- Content.Shared/FixedPoint/FixedPoint2.cs | 38 +++--- .../Shared/Chemistry/FixedPoint2_Tests.cs | 71 +++++++--- Content.Tests/Shared/DamageTest.cs | 6 +- 6 files changed, 232 insertions(+), 49 deletions(-) create mode 100644 Content.IntegrationTests/Tests/Chemistry/SolutionRoundingTest.cs diff --git a/Content.IntegrationTests/Tests/Chemistry/SolutionRoundingTest.cs b/Content.IntegrationTests/Tests/Chemistry/SolutionRoundingTest.cs new file mode 100644 index 00000000000..4d19a96d9e7 --- /dev/null +++ b/Content.IntegrationTests/Tests/Chemistry/SolutionRoundingTest.cs @@ -0,0 +1,122 @@ +using Content.Server.Chemistry.Containers.EntitySystems; +using Content.Shared.Chemistry.Components; +using Content.Shared.Chemistry.Reaction; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.FixedPoint; +using Robust.Shared.GameObjects; + +namespace Content.IntegrationTests.Tests.Chemistry; + +[TestFixture] +[TestOf(typeof(ChemicalReactionSystem))] +public sealed class SolutionRoundingTest +{ + // This test tests two things: + // * A rounding error in reaction code while I was making chloral hydrate + // * An assert with solution heat capacity calculations that I found a repro for while testing the above. + + [TestPrototypes] + private const string Prototypes = @" +- type: entity + id: SolutionRoundingTestContainer + components: + - type: SolutionContainerManager + solutions: + beaker: + maxVol: 100 + +# This is the Chloral Hydrate recipe fyi. +- type: reagent + id: SolutionRoundingTestReagentA + name: reagent-name-nothing + desc: reagent-desc-nothing + physicalDesc: reagent-physical-desc-nothing + +- type: reagent + id: SolutionRoundingTestReagentB + name: reagent-name-nothing + desc: reagent-desc-nothing + physicalDesc: reagent-physical-desc-nothing + +- type: reagent + id: SolutionRoundingTestReagentC + name: reagent-name-nothing + desc: reagent-desc-nothing + physicalDesc: reagent-physical-desc-nothing + +- type: reagent + id: SolutionRoundingTestReagentD + name: reagent-name-nothing + desc: reagent-desc-nothing + physicalDesc: reagent-physical-desc-nothing + +- type: reaction + id: SolutionRoundingTestReaction + impact: Medium + reactants: + SolutionRoundingTestReagentA: + amount: 3 + SolutionRoundingTestReagentB: + amount: 1 + SolutionRoundingTestReagentC: + amount: 1 + products: + SolutionRoundingTestReagentD: 1 +"; + + [Test] + public async Task Test() + { + await using var pair = await PoolManager.GetServerClient(); + var server = pair.Server; + var testMap = await pair.CreateTestMap(); + + Solution solution = default; + Entity solutionEnt = default; + + await server.WaitPost(() => + { + var system = server.System(); + var beaker = server.EntMan.SpawnEntity("SolutionRoundingTestContainer", testMap.GridCoords); + + system.TryGetSolution(beaker, "beaker", out var newSolutionEnt, out var newSolution); + + solutionEnt = newSolutionEnt!.Value; + solution = newSolution!; + + system.TryAddSolution(solutionEnt, new Solution("SolutionRoundingTestReagentC", 50)); + system.TryAddSolution(solutionEnt, new Solution("SolutionRoundingTestReagentB", 30)); + + for (var i = 0; i < 9; i++) + { + system.TryAddSolution(solutionEnt, new Solution("SolutionRoundingTestReagentA", 10)); + } + }); + + await server.WaitAssertion(() => + { + Assert.Multiple(() => + { + Assert.That( + solution.ContainsReagent("SolutionRoundingTestReagentA", null), + Is.False, + "Solution should not contain reagent A"); + + Assert.That( + solution.ContainsReagent("SolutionRoundingTestReagentB", null), + Is.False, + "Solution should not contain reagent B"); + + Assert.That( + solution![new ReagentId("SolutionRoundingTestReagentC", null)].Quantity, + Is.EqualTo((FixedPoint2) 20)); + + Assert.That( + solution![new ReagentId("SolutionRoundingTestReagentD", null)].Quantity, + Is.EqualTo((FixedPoint2) 30)); + }); + }); + + await pair.CleanReturnAsync(); + } +} diff --git a/Content.IntegrationTests/Tests/Damageable/DamageableTest.cs b/Content.IntegrationTests/Tests/Damageable/DamageableTest.cs index 3ab90b07ebc..16744d83dce 100644 --- a/Content.IntegrationTests/Tests/Damageable/DamageableTest.cs +++ b/Content.IntegrationTests/Tests/Damageable/DamageableTest.cs @@ -170,19 +170,19 @@ await server.WaitAssertion(() => // Check that damage works properly if it is NOT perfectly divisible among group members types = group3.DamageTypes; - damageToDeal = FixedPoint2.New(types.Count * 5 - 1); - damage = new DamageSpecifier(group3, damageToDeal); + + Assert.That(types, Has.Count.EqualTo(3)); + + damage = new DamageSpecifier(group3, 14); sDamageableSystem.TryChangeDamage(uid, damage, true); Assert.Multiple(() => { - Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(damageToDeal)); - Assert.That(sDamageableComponent.DamagePerGroup[group3.ID], Is.EqualTo(damageToDeal)); - Assert.That(sDamageableComponent.Damage.DamageDict[type3a.ID], Is.EqualTo(damageToDeal / types.Count)); - Assert.That(sDamageableComponent.Damage.DamageDict[type3b.ID], Is.EqualTo(damageToDeal / types.Count)); - - // last one will get 0.01 less, since its not perfectly divisble by 3 - Assert.That(sDamageableComponent.Damage.DamageDict[type3c.ID], Is.EqualTo(damageToDeal / types.Count - 0.01)); + Assert.That(sDamageableComponent.TotalDamage, Is.EqualTo(FixedPoint2.New(14))); + Assert.That(sDamageableComponent.DamagePerGroup[group3.ID], Is.EqualTo(FixedPoint2.New(14))); + Assert.That(sDamageableComponent.Damage.DamageDict[type3a.ID], Is.EqualTo(FixedPoint2.New(4.66f))); + Assert.That(sDamageableComponent.Damage.DamageDict[type3b.ID], Is.EqualTo(FixedPoint2.New(4.67f))); + Assert.That(sDamageableComponent.Damage.DamageDict[type3c.ID], Is.EqualTo(FixedPoint2.New(4.67f))); }); // Heal @@ -224,7 +224,7 @@ await server.WaitAssertion(() => Assert.Multiple(() => { - Assert.That(sDamageableComponent.Damage.DamageDict[type3a.ID], Is.EqualTo(FixedPoint2.New(1.33))); + Assert.That(sDamageableComponent.Damage.DamageDict[type3a.ID], Is.EqualTo(FixedPoint2.New(1.34))); Assert.That(sDamageableComponent.Damage.DamageDict[type3b.ID], Is.EqualTo(FixedPoint2.New(3.33))); Assert.That(sDamageableComponent.Damage.DamageDict[type3c.ID], Is.EqualTo(FixedPoint2.New(0))); }); diff --git a/Content.Shared/Chemistry/Components/Solution.cs b/Content.Shared/Chemistry/Components/Solution.cs index f8e48213199..1c24c860dd0 100644 --- a/Content.Shared/Chemistry/Components/Solution.cs +++ b/Content.Shared/Chemistry/Components/Solution.cs @@ -92,6 +92,12 @@ public bool CanAddSolution(Solution solution) /// [ViewVariables] private bool _heatCapacityDirty = true; + [ViewVariables(VVAccess.ReadWrite)] + private int _heatCapacityUpdateCounter; + + // This value is arbitrary btw. + private const int HeatCapacityUpdateInterval = 15; + public void UpdateHeatCapacity(IPrototypeManager? protoMan) { IoCManager.Resolve(ref protoMan); @@ -103,6 +109,8 @@ public void UpdateHeatCapacity(IPrototypeManager? protoMan) _heatCapacity += (float) quantity * protoMan.Index(reagent.Prototype).SpecificHeat; } + + _heatCapacityUpdateCounter = 0; } public float GetHeatCapacity(IPrototypeManager? protoMan) @@ -112,6 +120,15 @@ public float GetHeatCapacity(IPrototypeManager? protoMan) return _heatCapacity; } + public void CheckRecalculateHeatCapacity() + { + // For performance, we have a few ways for heat capacity to get modified without a full recalculation. + // To avoid these drifting too much due to float error, we mark it as dirty after N such operations, + // so it will be recalculated. + if (++_heatCapacityUpdateCounter >= HeatCapacityUpdateInterval) + _heatCapacityDirty = true; + } + public float GetThermalEnergy(IPrototypeManager? protoMan) { return GetHeatCapacity(protoMan) * Temperature; @@ -165,6 +182,7 @@ public Solution(Solution solution) Temperature = solution.Temperature; _heatCapacity = solution._heatCapacity; _heatCapacityDirty = solution._heatCapacityDirty; + _heatCapacityUpdateCounter = solution._heatCapacityUpdateCounter; ValidateSolution(); } @@ -193,7 +211,7 @@ public void ValidateSolution() var cur = _heatCapacity; _heatCapacityDirty = true; UpdateHeatCapacity(null); - DebugTools.Assert(MathHelper.CloseTo(_heatCapacity, cur)); + DebugTools.Assert(MathHelper.CloseTo(_heatCapacity, cur, tolerance: 0.01)); } #endif } @@ -380,7 +398,9 @@ public void AddReagent(ReagentId id, FixedPoint2 quantity, bool dirtyHeatCap = t public void AddReagent(ReagentPrototype proto, ReagentId reagentId, FixedPoint2 quantity) { AddReagent(reagentId, quantity, false); + _heatCapacity += quantity.Float() * proto.SpecificHeat; + CheckRecalculateHeatCapacity(); } public void AddReagent(ReagentQuantity reagentQuantity) @@ -419,6 +439,7 @@ public void ScaleSolution(int scale) _heatCapacity *= scale; Volume *= scale; + CheckRecalculateHeatCapacity(); for (int i = 0; i < Contents.Count; i++) { @@ -752,6 +773,7 @@ public void AddSolution(Solution otherSolution, IPrototypeManager? protoMan) } _heatCapacity += otherSolution._heatCapacity; + CheckRecalculateHeatCapacity(); if (closeTemps) _heatCapacityDirty |= otherSolution._heatCapacityDirty; else diff --git a/Content.Shared/FixedPoint/FixedPoint2.cs b/Content.Shared/FixedPoint/FixedPoint2.cs index eb0e75e7ab9..33a9d25bc27 100644 --- a/Content.Shared/FixedPoint/FixedPoint2.cs +++ b/Content.Shared/FixedPoint/FixedPoint2.cs @@ -20,6 +20,9 @@ public struct FixedPoint2 : ISelfSerialize, IComparable, IEquatable public static FixedPoint2 Epsilon { get; } = new(1); public static FixedPoint2 Zero { get; } = new(0); + // This value isn't picked by any proper testing, don't @ me. + private const float FloatEpsilon = 0.00001f; + #if DEBUG static FixedPoint2() { @@ -47,7 +50,17 @@ public static FixedPoint2 New(int value) public static FixedPoint2 New(float value) { - return new((int) MathF.Round(value * ShiftConstant, MidpointRounding.AwayFromZero)); + return new((int) ApplyFloatEpsilon(value * ShiftConstant)); + } + + private static float ApplyFloatEpsilon(float value) + { + return value + FloatEpsilon * Math.Sign(value); + } + + private static double ApplyFloatEpsilon(double value) + { + return value + FloatEpsilon * Math.Sign(value); } /// @@ -60,17 +73,12 @@ public static FixedPoint2 NewCeiling(float value) public static FixedPoint2 New(double value) { - return new((int) Math.Round(value * ShiftConstant, MidpointRounding.AwayFromZero)); + return new((int) ApplyFloatEpsilon(value * ShiftConstant)); } public static FixedPoint2 New(string value) { - return New(FloatFromString(value)); - } - - private static float FloatFromString(string value) - { - return float.Parse(value, CultureInfo.InvariantCulture); + return New(Parse.Float(value)); } public static FixedPoint2 operator +(FixedPoint2 a) => a; @@ -85,17 +93,17 @@ private static float FloatFromString(string value) public static FixedPoint2 operator *(FixedPoint2 a, FixedPoint2 b) { - return new((int) MathF.Round(b.Value * a.Value / (float) ShiftConstant, MidpointRounding.AwayFromZero)); + return new(b.Value * a.Value / ShiftConstant); } public static FixedPoint2 operator *(FixedPoint2 a, float b) { - return new((int) MathF.Round(a.Value * b, MidpointRounding.AwayFromZero)); + return new((int) ApplyFloatEpsilon(a.Value * b)); } public static FixedPoint2 operator *(FixedPoint2 a, double b) { - return new((int) Math.Round(a.Value * b, MidpointRounding.AwayFromZero)); + return new((int) ApplyFloatEpsilon(a.Value * b)); } public static FixedPoint2 operator *(FixedPoint2 a, int b) @@ -105,12 +113,12 @@ private static float FloatFromString(string value) public static FixedPoint2 operator /(FixedPoint2 a, FixedPoint2 b) { - return new((int) MathF.Round((ShiftConstant * a.Value) / (float) b.Value, MidpointRounding.AwayFromZero)); + return new((int) (ShiftConstant * (long) a.Value / b.Value)); } public static FixedPoint2 operator /(FixedPoint2 a, float b) { - return new((int) MathF.Round(a.Value / b, MidpointRounding.AwayFromZero)); + return new((int) ApplyFloatEpsilon(a.Value / b)); } public static bool operator <=(FixedPoint2 a, int b) @@ -185,7 +193,7 @@ public readonly double Double() public readonly int Int() { - return (int) ShiftDown(); + return Value / ShiftConstant; } // Implicit operators ftw @@ -266,7 +274,7 @@ public void Deserialize(string value) if (value == "MaxValue") Value = int.MaxValue; else - this = New(FloatFromString(value)); + this = New(Parse.Float(value)); } public override readonly string ToString() => $"{ShiftDown().ToString(CultureInfo.InvariantCulture)}"; diff --git a/Content.Tests/Shared/Chemistry/FixedPoint2_Tests.cs b/Content.Tests/Shared/Chemistry/FixedPoint2_Tests.cs index 5ad157c747c..8f9de2c2f82 100644 --- a/Content.Tests/Shared/Chemistry/FixedPoint2_Tests.cs +++ b/Content.Tests/Shared/Chemistry/FixedPoint2_Tests.cs @@ -4,7 +4,7 @@ namespace Content.Tests.Shared.Chemistry { - [TestFixture, TestOf(typeof(FixedPoint2))] + [TestFixture, TestOf(typeof(FixedPoint2)), Parallelizable] public sealed class FixedPoint2_Tests { [Test] @@ -18,8 +18,11 @@ public void FixedPoint2IntegerTests(int value, string expected) } [Test] - [TestCase(1.001f, "1")] - [TestCase(0.999f, "1")] + [TestCase(0.999f, "0.99")] + [TestCase(1.005f, "1")] + [TestCase(1.015f, "1.01")] + [TestCase(1.05f, "1.05")] + [TestCase(-1.05f, "-1.05")] public void FixedPoint2FloatTests(float value, string expected) { var result = FixedPoint2.New(value); @@ -27,8 +30,10 @@ public void FixedPoint2FloatTests(float value, string expected) } [Test] - [TestCase(1.001d, "1")] - [TestCase(0.999d, "1")] + [TestCase(0.999, "0.99")] + [TestCase(1.005, "1")] + [TestCase(1.015, "1.01")] + [TestCase(1.05, "1.05")] public void FixedPoint2DoubleTests(double value, string expected) { var result = FixedPoint2.New(value); @@ -36,8 +41,10 @@ public void FixedPoint2DoubleTests(double value, string expected) } [Test] - [TestCase("1.005", "1.01")] - [TestCase("0.999", "1")] + [TestCase("0.999", "0.99")] + [TestCase("1.005", "1")] + [TestCase("1.015", "1.01")] + [TestCase("1.05", "1.05")] public void FixedPoint2StringTests(string value, string expected) { var result = FixedPoint2.New(value); @@ -45,11 +52,9 @@ public void FixedPoint2StringTests(string value, string expected) } [Test] - [TestCase(1.001f, 1.001f, "2")] - [TestCase(1.001f, 1.004f, "2")] - [TestCase(1f, 1.005f, "2.01")] - [TestCase(1f, 2.005f, "3.01")] - public void CalculusPlus(float aFloat, float bFloat, string expected) + [TestCase(1, 1, "2")] + [TestCase(1.05f, 1, "2.05")] + public void ArithmeticAddition(float aFloat, float bFloat, string expected) { var a = FixedPoint2.New(aFloat); var b = FixedPoint2.New(bFloat); @@ -60,10 +65,9 @@ public void CalculusPlus(float aFloat, float bFloat, string expected) } [Test] - [TestCase(1.001f, 1.001f, "0")] - [TestCase(1.001f, 1.004f, "0")] - [TestCase(1f, 2.005f, "-1.01")] - public void CalculusMinus(float aFloat, float bFloat, string expected) + [TestCase(1, 1, "0")] + [TestCase(1f, 2.5f, "-1.5")] + public void ArithmeticSubtraction(float aFloat, float bFloat, string expected) { var a = FixedPoint2.New(aFloat); var b = FixedPoint2.New(bFloat); @@ -77,7 +81,8 @@ public void CalculusMinus(float aFloat, float bFloat, string expected) [TestCase(1.001f, 3f, "0.33")] [TestCase(0.999f, 3f, "0.33")] [TestCase(2.1f, 3f, "0.7")] - public void CalculusDivision(float aFloat, float bFloat, string expected) + [TestCase(0.03f, 2f, "0.01")] + public void ArithmeticDivision(float aFloat, float bFloat, string expected) { var a = FixedPoint2.New(aFloat); var b = FixedPoint2.New(bFloat); @@ -88,9 +93,24 @@ public void CalculusDivision(float aFloat, float bFloat, string expected) } [Test] - [TestCase(1.001f, 0.999f, "1")] - [TestCase(0.999f, 3f, "3")] - public void CalculusMultiplication(float aFloat, float bFloat, string expected) + [TestCase(1.001f, 3f, "0.33")] + [TestCase(0.999f, 3f, "0.33")] + [TestCase(2.1f, 3f, "0.7")] + [TestCase(0.03f, 2f, "0.01")] + [TestCase(1f, 1 / 1.05f, "1.05")] + public void ArithmeticDivisionFloat(float aFloat, float b, string expected) + { + var a = FixedPoint2.New(aFloat); + + var result = a / b; + + Assert.That($"{result}", Is.EqualTo(expected)); + } + + [Test] + [TestCase(1, 1, "1")] + [TestCase(1, 3f, "3")] + public void ArithmeticMultiplication(float aFloat, float bFloat, string expected) { var a = FixedPoint2.New(aFloat); var b = FixedPoint2.New(bFloat); @@ -100,6 +120,17 @@ public void CalculusMultiplication(float aFloat, float bFloat, string expected) Assert.That($"{result}", Is.EqualTo(expected)); } + [Test] + [TestCase(1, 1, "1")] + [TestCase(1, 1.05f, "1.05")] + public void ArithmeticMultiplicationFloat(float aFloat, float b, string expected) + { + var a = FixedPoint2.New(aFloat); + var result = a * b; + + Assert.That($"{result}", Is.EqualTo(expected)); + } + [Test] [TestCase(0.995f, 100)] [TestCase(1.005f, 101)] diff --git a/Content.Tests/Shared/DamageTest.cs b/Content.Tests/Shared/DamageTest.cs index b06b8368a90..11b810bf36a 100644 --- a/Content.Tests/Shared/DamageTest.cs +++ b/Content.Tests/Shared/DamageTest.cs @@ -121,9 +121,9 @@ public void DamageSpecifierTest() damageSpec = new(_prototypeManager.Index("Brute"), 4); Assert.That(damageSpec.DamageDict.TryGetValue("Blunt", out damage)); Assert.That(damage, Is.EqualTo(FixedPoint2.New(1.33))); - Assert.That(damageSpec.DamageDict.TryGetValue("Piercing", out damage)); - Assert.That(damage, Is.EqualTo(FixedPoint2.New(1.33))); Assert.That(damageSpec.DamageDict.TryGetValue("Slash", out damage)); + Assert.That(damage, Is.EqualTo(FixedPoint2.New(1.33))); + Assert.That(damageSpec.DamageDict.TryGetValue("Piercing", out damage)); Assert.That(damage, Is.EqualTo(FixedPoint2.New(1.34))); // doesn't divide evenly, so the 0.01 goes to the last one damageSpec = new(_prototypeManager.Index("Piercing"), 4); @@ -161,7 +161,7 @@ public void ModifierSetTest() Assert.That(damageSpec.DamageDict["Blunt"], Is.EqualTo(FixedPoint2.New(30))); Assert.That(damageSpec.DamageDict["Piercing"], Is.EqualTo(FixedPoint2.New(-40))); // resistances don't apply to healing Assert.That(!damageSpec.DamageDict.ContainsKey("Slash")); // Reduction reduced to 0, and removed from specifier - Assert.That(damageSpec.DamageDict["Radiation"], Is.EqualTo(FixedPoint2.New(65.63))); + Assert.That(damageSpec.DamageDict["Radiation"], Is.EqualTo(FixedPoint2.New(65.62))); } // Default damage Yaml From 97b113c5805ec0efa6a9366e47a5e54fcbdde5fb Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 17 Feb 2024 00:55:32 +0100 Subject: [PATCH 167/200] Automatic changelog update (cherry picked from commit 9e5261e2ce35c42b74295f5de945ff8a69945114) --- 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 d59b19d4807..a1c3da0d634 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,5 @@ Order: 1 Entries: -- author: Admiral-Obvious-001 - changes: - - message: Reduced per pellet damage of shotguns slightly. - type: Tweak - id: 5452 - time: '2023-12-27T09:26:42.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/23042 - author: mirrorcult changes: - message: Pacifists can now attack in general, but are still forbidden from hurting @@ -3874,3 +3867,10 @@ Entries: id: 5951 time: '2024-02-16T23:50:49.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25232 +- author: PJB3005 + changes: + - message: Fix some rounding issues with complex chemical reactions. + type: Fix + id: 5952 + time: '2024-02-16T23:54:27.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25199 From 93503d9fd1cf9923917550b6f41b499efd2b5bbb Mon Sep 17 00:00:00 2001 From: Debug <49997488+DebugOk@users.noreply.github.com> Date: Sun, 18 Feb 2024 23:32:45 +0100 Subject: [PATCH 168/200] WebP lobby images (#25184) --- Content.Server/GameTicking/GameTicker.LobbyBackground.cs | 2 +- Resources/Textures/LobbyScreens/PutLobbyScreensHere.txt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Content.Server/GameTicking/GameTicker.LobbyBackground.cs b/Content.Server/GameTicking/GameTicker.LobbyBackground.cs index 7f2ccfe235b..2090e3e31f0 100644 --- a/Content.Server/GameTicking/GameTicker.LobbyBackground.cs +++ b/Content.Server/GameTicking/GameTicker.LobbyBackground.cs @@ -13,7 +13,7 @@ public sealed partial class GameTicker [ViewVariables] private List? _lobbyBackgrounds; - private static readonly string[] WhitelistedBackgroundExtensions = new string[] {"png", "jpg", "jpeg"}; + private static readonly string[] WhitelistedBackgroundExtensions = new string[] {"png", "jpg", "jpeg", "webp"}; private void InitializeLobbyBackground() { diff --git a/Resources/Textures/LobbyScreens/PutLobbyScreensHere.txt b/Resources/Textures/LobbyScreens/PutLobbyScreensHere.txt index 52cb3f1dc90..7d7777fa101 100644 --- a/Resources/Textures/LobbyScreens/PutLobbyScreensHere.txt +++ b/Resources/Textures/LobbyScreens/PutLobbyScreensHere.txt @@ -1,2 +1,3 @@ Note: -Only png and jpgs files are supported, and you need a prototype in Resources/Prototypes/lobbyscreens.yml +PNG, JPEG and WebP is supported. Please prefer a lossy WebP compression since lobby art is big. +You also need to put a prototype in Resources/Prototypes/lobbyscreens.yml From 2dc1db35a6f7d3e05ad0bc8eb866f4165caa52ed Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 17 Feb 2024 03:53:23 +0100 Subject: [PATCH 169/200] Automatic changelog update (cherry picked from commit 699ee6e0c84a3205ca92bd2134c4c3bbdd5be414) --- Resources/Changelog/Changelog.yml | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index a1c3da0d634..eab4e3ab84d 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,17 +1,5 @@ Order: 1 Entries: -- author: mirrorcult - changes: - - message: Pacifists can now attack in general, but are still forbidden from hurting - living creatures or dangerous things. - type: Tweak - - message: Pacifists can now disarm people. They are pacifist, after all. - type: Tweak - - message: Pacifists can now use flashes (and zero-damaging melee weapons, in general) - type: Tweak - id: 5453 - time: '2023-12-27T09:55:48.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/23037 - author: snebl changes: - message: Fixed emergency and extended nitrogen tanks having the same volume. @@ -3874,3 +3862,10 @@ Entries: id: 5952 time: '2024-02-16T23:54:27.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25199 +- author: data_redacted + changes: + - message: New lobby art (of an Air Alarm blueprint). + type: Add + id: 5953 + time: '2024-02-17T02:52:17.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25179 From e7d8f5e0805412595bd2048d8178b99bc91b0654 Mon Sep 17 00:00:00 2001 From: LankLTE <135308300+lanklte@users.noreply.github.com> Date: Sat, 17 Feb 2024 03:54:44 +0100 Subject: [PATCH 170/200] Diona Nymphs & Splitting (#24630) * Porting & implementation * Fix two stupid errors * Human not humans * fix audio path * Fix test fails & update cooldown * Work on reviews & test fail * Rework nymph organ system. * Make the nymph organs nospawn. * IsDeadIC (cherry picked from commit 407d4aed586a5143dc1dd0d31e7898f6df07a411) --- .../Atmos/EntitySystems/FlammableSystem.cs | 29 +++++ .../Components/IgniteOnHeatDamageComponent.cs | 15 +++ .../Silicons/Borgs/BorgSystem.Modules.cs | 2 +- .../Mind/Components/IsDeadICComponent.cs | 8 ++ Content.Shared/Mind/IsDeadICSystem.cs | 21 ++++ .../Species/Components/GibActionComponent.cs | 30 +++++ .../Species/Components/NymphComponent.cs | 24 ++++ .../Species/Components/ReformComponent.cs | 48 ++++++++ .../Species/Systems/GibActionSystem.cs | 61 ++++++++++ Content.Shared/Species/Systems/NymphSystem.cs | 41 +++++++ .../Species/Systems/ReformSystem.cs | 108 +++++++++++++++++ Resources/Audio/Animals/attributions.yml | 8 +- Resources/Audio/Animals/nymph_chirp.ogg | Bin 0 -> 6270 bytes .../Locale/en-US/actions/actions/diona.ftl | 3 + .../interaction-popup-component.ftl | 2 + Resources/Prototypes/Actions/diona.yml | 21 ++++ Resources/Prototypes/Body/Organs/diona.yml | 113 ++++++++++++++++-- .../Body/Prototypes/Animal/nymph.yml | 66 ++++++++++ .../Prototypes/Body/Prototypes/diona.yml | 6 +- .../Prototypes/Entities/Mobs/NPCs/animals.yml | 74 ++++++++++++ .../Prototypes/Entities/Mobs/Player/diona.yml | 12 +- .../Entities/Mobs/Species/diona.yml | 7 ++ .../Textures/Mobs/Animals/nymph.rsi/icon.png | Bin 0 -> 611 bytes .../Textures/Mobs/Animals/nymph.rsi/meta.json | 63 ++++++++++ .../Textures/Mobs/Animals/nymph.rsi/nymph.png | Bin 0 -> 3891 bytes .../Mobs/Animals/nymph.rsi/nymph_dead.png | Bin 0 -> 655 bytes .../Mobs/Animals/nymph.rsi/nymph_sleep.png | Bin 0 -> 1306 bytes 27 files changed, 744 insertions(+), 18 deletions(-) create mode 100644 Content.Server/Damage/Components/IgniteOnHeatDamageComponent.cs create mode 100644 Content.Shared/Mind/Components/IsDeadICComponent.cs create mode 100644 Content.Shared/Mind/IsDeadICSystem.cs create mode 100644 Content.Shared/Species/Components/GibActionComponent.cs create mode 100644 Content.Shared/Species/Components/NymphComponent.cs create mode 100644 Content.Shared/Species/Components/ReformComponent.cs create mode 100644 Content.Shared/Species/Systems/GibActionSystem.cs create mode 100644 Content.Shared/Species/Systems/NymphSystem.cs create mode 100644 Content.Shared/Species/Systems/ReformSystem.cs create mode 100644 Resources/Audio/Animals/nymph_chirp.ogg create mode 100644 Resources/Locale/en-US/actions/actions/diona.ftl create mode 100644 Resources/Prototypes/Actions/diona.yml create mode 100644 Resources/Prototypes/Body/Prototypes/Animal/nymph.yml create mode 100644 Resources/Textures/Mobs/Animals/nymph.rsi/icon.png create mode 100644 Resources/Textures/Mobs/Animals/nymph.rsi/meta.json create mode 100644 Resources/Textures/Mobs/Animals/nymph.rsi/nymph.png create mode 100644 Resources/Textures/Mobs/Animals/nymph.rsi/nymph_dead.png create mode 100644 Resources/Textures/Mobs/Animals/nymph.rsi/nymph_sleep.png diff --git a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs index cb1cb9bc150..53fcb720766 100644 --- a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs +++ b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs @@ -4,6 +4,7 @@ using Content.Server.Stunnable; using Content.Server.Temperature.Components; using Content.Server.Temperature.Systems; +using Content.Server.Damage.Components; using Content.Shared.ActionBlocker; using Content.Shared.Alert; using Content.Shared.Atmos; @@ -20,6 +21,7 @@ using Content.Shared.Timing; using Content.Shared.Toggleable; using Content.Shared.Weapons.Melee.Events; +using Content.Shared.FixedPoint; using Robust.Server.Audio; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Events; @@ -73,6 +75,8 @@ public override void Initialize() SubscribeLocalEvent(OnMeleeHit); SubscribeLocalEvent(OnExtinguishActivateInWorld); + + SubscribeLocalEvent(OnDamageChanged); } private void OnMeleeHit(EntityUid uid, IgniteOnMeleeHitComponent component, MeleeHitEvent args) @@ -318,6 +322,31 @@ public void Ignite(EntityUid uid, EntityUid ignitionSource, FlammableComponent? UpdateAppearance(uid, flammable); } + private void OnDamageChanged(EntityUid uid, IgniteOnHeatDamageComponent component, DamageChangedEvent args) + { + // Make sure the entity is flammable + if (!TryComp(uid, out var flammable)) + return; + + // Make sure the damage delta isn't null + if (args.DamageDelta == null) + return; + + // Check if its' taken any heat damage, and give the value + if (args.DamageDelta.DamageDict.TryGetValue("Heat", out FixedPoint2 value)) + { + // Make sure the value is greater than the threshold + if(value <= component.Threshold) + return; + + // Ignite that sucker + flammable.FireStacks += component.FireStacks; + Ignite(uid, uid, flammable); + } + + + } + public void Resist(EntityUid uid, FlammableComponent? flammable = null) { diff --git a/Content.Server/Damage/Components/IgniteOnHeatDamageComponent.cs b/Content.Server/Damage/Components/IgniteOnHeatDamageComponent.cs new file mode 100644 index 00000000000..81018f539c9 --- /dev/null +++ b/Content.Server/Damage/Components/IgniteOnHeatDamageComponent.cs @@ -0,0 +1,15 @@ +using Content.Shared.Damage; +using Content.Shared.FixedPoint; + +namespace Content.Server.Damage.Components; + +[RegisterComponent] +public sealed partial class IgniteOnHeatDamageComponent : Component +{ + [DataField("fireStacks")] + public float FireStacks = 1f; + + // The minimum amount of damage taken to apply fire stacks + [DataField("threshold")] + public FixedPoint2 Threshold = 15; +} diff --git a/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs b/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs index a89a101845c..cc57c34c475 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.Modules.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using Content.Shared.Hands.Components; using Content.Shared.Interaction.Components; using Content.Shared.Silicons.Borgs.Components; diff --git a/Content.Shared/Mind/Components/IsDeadICComponent.cs b/Content.Shared/Mind/Components/IsDeadICComponent.cs new file mode 100644 index 00000000000..d62743d912c --- /dev/null +++ b/Content.Shared/Mind/Components/IsDeadICComponent.cs @@ -0,0 +1,8 @@ +namespace Content.Shared.Mind.Components; + +[RegisterComponent] +public sealed partial class IsDeadICComponent : Component +{ +} + + diff --git a/Content.Shared/Mind/IsDeadICSystem.cs b/Content.Shared/Mind/IsDeadICSystem.cs new file mode 100644 index 00000000000..6716f381152 --- /dev/null +++ b/Content.Shared/Mind/IsDeadICSystem.cs @@ -0,0 +1,21 @@ +using Content.Shared.Mind.Components; + +namespace Content.Shared.Mind; + +/// +/// This marks any entity with the component as dead +/// for stuff like objectives & round-end +/// used for nymphs & reformed diona. +/// +public sealed class IsDeadICSystem : EntitySystem +{ + public override void Initialize() + { + SubscribeLocalEvent(OnGetDeadIC); + } + + private void OnGetDeadIC(EntityUid uid, IsDeadICComponent component, ref GetCharactedDeadIcEvent args) + { + args.Dead = true; + } +} diff --git a/Content.Shared/Species/Components/GibActionComponent.cs b/Content.Shared/Species/Components/GibActionComponent.cs new file mode 100644 index 00000000000..bed94f047ec --- /dev/null +++ b/Content.Shared/Species/Components/GibActionComponent.cs @@ -0,0 +1,30 @@ +using Content.Shared.Mobs; +using Robust.Shared.Prototypes; +using Robust.Shared.GameStates; + +namespace Content.Shared.Species.Components; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class GibActionComponent : Component +{ + /// + /// The action to use. + /// + [DataField("actionPrototype", required: true)] + public EntProtoId ActionPrototype; + + [DataField, AutoNetworkedField] + public EntityUid? ActionEntity; + + /// + /// What mob states the action will appear in + /// + [DataField("allowedStates"), ViewVariables(VVAccess.ReadWrite)] + public List AllowedStates = new(); + + /// + /// The text that appears when attempting to split. + /// + [DataField("popupText")] + public string PopupText = "diona-gib-action-use"; +} diff --git a/Content.Shared/Species/Components/NymphComponent.cs b/Content.Shared/Species/Components/NymphComponent.cs new file mode 100644 index 00000000000..e8fe2f367e2 --- /dev/null +++ b/Content.Shared/Species/Components/NymphComponent.cs @@ -0,0 +1,24 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.GameStates; + +namespace Content.Shared.Species.Components; +/// +/// This will replace one entity with another entity when it is removed from a body part. +/// Obviously hyper-specific. If you somehow find another use for this, good on you. +/// + +[RegisterComponent, NetworkedComponent] +public sealed partial class NymphComponent : Component +{ + /// + /// The entity to replace the organ with. + /// + [DataField(required: true)] + public EntProtoId EntityPrototype = default!; + + /// + /// Whether to transfer the mind to this new entity. + /// + [DataField] + public bool TransferMind = false; +} diff --git a/Content.Shared/Species/Components/ReformComponent.cs b/Content.Shared/Species/Components/ReformComponent.cs new file mode 100644 index 00000000000..724c9dc3302 --- /dev/null +++ b/Content.Shared/Species/Components/ReformComponent.cs @@ -0,0 +1,48 @@ + using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; +using Robust.Shared.GameStates; + +namespace Content.Shared.Species.Components; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class ReformComponent : Component +{ + /// + /// The action to use. + /// + [DataField(required: true)] + public EntProtoId ActionPrototype = default!; + + [DataField, AutoNetworkedField] + public EntityUid? ActionEntity; + + /// + /// How long it will take to reform + /// + [DataField(required: true)] + public float ReformTime = 0; + + /// + /// Whether or not the entity should start with a cooldown + /// + [DataField] + public bool StartDelayed = true; + + /// + /// Whether or not the entity should be stunned when reforming at all + /// + [DataField] + public bool ShouldStun = true; + + /// + /// The text that appears when attempting to reform + /// + [DataField(required: true)] + public string PopupText; + + /// + /// The mob that our entity will reform into + /// + [DataField(required: true)] + public EntProtoId ReformPrototype { get; private set; } +} diff --git a/Content.Shared/Species/Systems/GibActionSystem.cs b/Content.Shared/Species/Systems/GibActionSystem.cs new file mode 100644 index 00000000000..bd7cb6baffa --- /dev/null +++ b/Content.Shared/Species/Systems/GibActionSystem.cs @@ -0,0 +1,61 @@ +using Content.Shared.Species.Components; +using Content.Shared.Actions; +using Content.Shared.Body.Systems; +using Content.Shared.Mobs; +using Content.Shared.Mobs.Components; +using Content.Shared.Popups; +using Robust.Shared.Prototypes; + + +namespace Content.Shared.Species; + +public sealed partial class GibActionSystem : EntitySystem +{ + [Dependency] private readonly SharedActionsSystem _actionsSystem = default!; + [Dependency] private readonly SharedBodySystem _bodySystem = default!; + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMobStateChanged); + SubscribeLocalEvent(OnGibAction); + } + + private void OnMobStateChanged(EntityUid uid, GibActionComponent comp, MobStateChangedEvent args) + { + // When the mob changes state, check if they're dead and give them the action if so. + if (!TryComp(uid, out var mobState)) + return; + + if (!_protoManager.TryIndex(comp.ActionPrototype, out var actionProto)) + return; + + + foreach (var allowedState in comp.AllowedStates) + { + if(allowedState == mobState.CurrentState) + { + // The mob should never have more than 1 state so I don't see this being an issue + _actionsSystem.AddAction(uid, ref comp.ActionEntity, comp.ActionPrototype); + return; + } + } + + // If they aren't given the action, remove it. + _actionsSystem.RemoveAction(uid, comp.ActionEntity); + } + + private void OnGibAction(EntityUid uid, GibActionComponent comp, GibActionEvent args) + { + // When they use the action, gib them. + _popupSystem.PopupClient(Loc.GetString(comp.PopupText, ("name", uid)), uid, uid); + _bodySystem.GibBody(uid, true); + } + + + + public sealed partial class GibActionEvent : InstantActionEvent { } +} diff --git a/Content.Shared/Species/Systems/NymphSystem.cs b/Content.Shared/Species/Systems/NymphSystem.cs new file mode 100644 index 00000000000..7acbf2e1528 --- /dev/null +++ b/Content.Shared/Species/Systems/NymphSystem.cs @@ -0,0 +1,41 @@ +using Content.Shared.Species.Components; +using Content.Shared.Body.Events; +using Content.Shared.Mind; +using Robust.Shared.Prototypes; +using Robust.Shared.Timing; + +namespace Content.Shared.Species; + +public sealed partial class NymphSystem : EntitySystem +{ + [Dependency] protected readonly IPrototypeManager _protoManager = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; + [Dependency] private readonly IGameTiming _timing = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnRemovedFromPart); + } + + private void OnRemovedFromPart(EntityUid uid, NymphComponent comp, RemovedFromPartInBodyEvent args) + { + if (!_timing.IsFirstTimePredicted) + return; + + if (TerminatingOrDeleted(uid) || TerminatingOrDeleted(args.OldBody)) + return; + + if (!_protoManager.TryIndex(comp.EntityPrototype, out var entityProto)) + return; + + var coords = Transform(uid).Coordinates; + var nymph = EntityManager.SpawnEntity(entityProto.ID, coords); + + if (comp.TransferMind == true && _mindSystem.TryGetMind(args.OldBody, out var mindId, out var mind)) + _mindSystem.TransferTo(mindId, nymph, mind: mind); + + EntityManager.QueueDeleteEntity(uid); + } +} diff --git a/Content.Shared/Species/Systems/ReformSystem.cs b/Content.Shared/Species/Systems/ReformSystem.cs new file mode 100644 index 00000000000..a013a7f8864 --- /dev/null +++ b/Content.Shared/Species/Systems/ReformSystem.cs @@ -0,0 +1,108 @@ +using Content.Shared.Species.Components; +using Content.Shared.Actions; +using Content.Shared.DoAfter; +using Content.Shared.Popups; +using Content.Shared.Stunnable; +using Content.Shared.Mind; +using Content.Shared.Humanoid; +using Robust.Shared.Network; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; +using Robust.Shared.Timing; +using Robust.Shared.Serialization.Manager; + +namespace Content.Shared.Species; + +public sealed partial class ReformSystem : EntitySystem +{ + [Dependency] private readonly SharedActionsSystem _actionsSystem = default!; + [Dependency] private readonly INetManager _netMan = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; + [Dependency] private readonly SharedPopupSystem _popupSystem = default!; + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [Dependency] private readonly SharedStunSystem _stunSystem = default!; + [Dependency] private readonly IGameTiming _gameTiming = default!; + [Dependency] private readonly SharedMindSystem _mindSystem = default!; + [Dependency] private readonly MetaDataSystem _metaData = default!; + [Dependency] private readonly ISerializationManager _serializationManager = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnCompRemove); + + SubscribeLocalEvent(OnReform); + SubscribeLocalEvent(OnDoAfter); + } + + private void OnMapInit(EntityUid uid, ReformComponent comp, MapInitEvent args) + { + // When the map is initialized, give them the action + if (comp.ActionPrototype != default && !_protoManager.TryIndex(comp.ActionPrototype, out var actionProto)) + return; + + _actionsSystem.AddAction(uid, ref comp.ActionEntity, out var reformAction, comp.ActionPrototype); + + // See if the action should start with a delay, and give it that starting delay if so. + if (comp.StartDelayed && reformAction != null && reformAction.UseDelay != null) + { + var start = _gameTiming.CurTime; + var end = _gameTiming.CurTime + reformAction.UseDelay.Value; + + _actionsSystem.SetCooldown(comp.ActionEntity!.Value, start, end); + } + } + + private void OnCompRemove(EntityUid uid, ReformComponent comp, ComponentShutdown args) + { + _actionsSystem.RemoveAction(uid, comp.ActionEntity); + } + + private void OnReform(EntityUid uid, ReformComponent comp, ReformEvent args) + { + // Stun them when they use the action for the amount of reform time. + if (comp.ShouldStun) + _stunSystem.TryStun(uid, TimeSpan.FromSeconds(comp.ReformTime), true); + _popupSystem.PopupClient(Loc.GetString(comp.PopupText, ("name", uid)), uid, uid); + + // Create a doafter & start it + var doAfter = new DoAfterArgs(EntityManager, uid, comp.ReformTime, new ReformDoAfterEvent(), uid) + { + BreakOnUserMove = true, + BlockDuplicate = true, + BreakOnDamage = true, + CancelDuplicate = true, + RequireCanInteract = false, + }; + + _doAfterSystem.TryStartDoAfter(doAfter); + args.Handled = true; + } + + private void OnDoAfter(EntityUid uid, ReformComponent comp, ReformDoAfterEvent args) + { + if (args.Cancelled || args.Handled || comp.Deleted) + return; + + if (_netMan.IsClient) + return; + + // Spawn a new entity + // This is, to an extent, taken from polymorph. I don't use polymorph for various reasons- most notably that this is permanent. + var child = Spawn(comp.ReformPrototype, Transform(uid).Coordinates); + + // This transfers the mind to the new entity + if (_mindSystem.TryGetMind(uid, out var mindId, out var mind)) + _mindSystem.TransferTo(mindId, child, mind: mind); + + // Delete the old entity + QueueDel(uid); + } + + public sealed partial class ReformEvent : InstantActionEvent { } + + [Serializable, NetSerializable] + public sealed partial class ReformDoAfterEvent : SimpleDoAfterEvent { } +} diff --git a/Resources/Audio/Animals/attributions.yml b/Resources/Audio/Animals/attributions.yml index c9c20473c21..c34832a807a 100644 --- a/Resources/Audio/Animals/attributions.yml +++ b/Resources/Audio/Animals/attributions.yml @@ -131,4 +131,10 @@ - files: ["dog_bark3.ogg"] license: "CC0-1.0" copyright: "Audio is recorded/created by KFerentchak 'FreeSound.org'. The original audio was trimmed and renamed" - source: "https://freesound.org/people/KFerentchak/sounds/235912/" \ No newline at end of file + source: "https://freesound.org/people/KFerentchak/sounds/235912/" + +- files: ["nymph_chirp.ogg"] + license: "CC-BY-SA-3.0" + copyright: "Taken from ParadiseSS13" + source: "https://github.com/ParadiseSS13/Paradise/commit/a34f1054cef5a44a67fdac3b67b811137c6071dd" + \ No newline at end of file diff --git a/Resources/Audio/Animals/nymph_chirp.ogg b/Resources/Audio/Animals/nymph_chirp.ogg new file mode 100644 index 0000000000000000000000000000000000000000..e0e573d497d649c7ede71d0d75470356e86f46f9 GIT binary patch literal 6270 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 literal 0 HcmV?d00001 diff --git a/Resources/Locale/en-US/actions/actions/diona.ftl b/Resources/Locale/en-US/actions/actions/diona.ftl new file mode 100644 index 00000000000..3745e6fe49b --- /dev/null +++ b/Resources/Locale/en-US/actions/actions/diona.ftl @@ -0,0 +1,3 @@ +diona-gib-action-use = {$name} splits apart in an instant! + +diona-reform-attempt = {$name} attempts to reform! \ No newline at end of file diff --git a/Resources/Locale/en-US/interaction/interaction-popup-component.ftl b/Resources/Locale/en-US/interaction/interaction-popup-component.ftl index e18d85df2eb..bb56233ff14 100644 --- a/Resources/Locale/en-US/interaction/interaction-popup-component.ftl +++ b/Resources/Locale/en-US/interaction/interaction-popup-component.ftl @@ -31,6 +31,7 @@ petting-success-bear = You reluctantly pet {THE($target)} on {POSS-ADJ($target)} petting-success-slimes = You pet {THE($target)} on {POSS-ADJ($target)} mucous surface. petting-success-snake = You pet {THE($target)} on {POSS-ADJ($target)} scaly large head. petting-success-monkey = You pet {THE($target)} on {POSS-ADJ($target)} mischevious little head. +petting-success-nymph = You pet {THE($target)} on {POSS-ADJ($target)} wooden little head. petting-failure-generic = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} aloof towards you. @@ -51,6 +52,7 @@ petting-failure-dragon = You raise your hand, but as {THE($target)} roars, you d petting-failure-hamster = You reach out to pet {THE($target)}, but {SUBJECT($target)} attempts to bite your finger and only your quick reflexes save you from an almost fatal injury. petting-failure-bear = You reach out to pet {THE($target)}, but {SUBJECT($target)} growls, making you think twice. petting-failure-monkey = You reach out to pet {THE($target)}, but {SUBJECT($target)} almost bites your fingers! +petting-failure-nymph = You reach out to pet {THE($target)}, but {POSS-ADJ($target)} moves their branches away. petting-failure-shadow = You're trying to pet {THE($target)}, but your hand passes through the cold darkness of his body. ## Petting silicons diff --git a/Resources/Prototypes/Actions/diona.yml b/Resources/Prototypes/Actions/diona.yml new file mode 100644 index 00000000000..ac65d6861d4 --- /dev/null +++ b/Resources/Prototypes/Actions/diona.yml @@ -0,0 +1,21 @@ +- type: entity + id: DionaGibAction + name: Gib Yourself! + description: Split apart into 3 nymphs. + noSpawn: true + components: + - type: InstantAction + icon: Mobs/Species/Diona/organs.rsi/brain.png + event: !type:GibActionEvent {} + checkCanInteract: false + +- type: entity + id: DionaReformAction + name: Reform + description: Reform back into a whole Diona. + noSpawn: true + components: + - type: InstantAction + icon: Mobs/Species/Diona/parts.rsi/full.png + event: !type:ReformEvent {} + useDelay: 300 # Once every 10 minutes. Keep them dead for a fair bit before reforming diff --git a/Resources/Prototypes/Body/Organs/diona.yml b/Resources/Prototypes/Body/Organs/diona.yml index 282bb224d81..23df396dd1e 100644 --- a/Resources/Prototypes/Body/Organs/diona.yml +++ b/Resources/Prototypes/Body/Organs/diona.yml @@ -48,18 +48,6 @@ reagents: - ReagentId: UncookedAnimalProteins Quantity: 5 - - type: Brain - - type: InputMover - - type: Examiner - - type: Lung #lungs in they head. why they there tho? - - type: Metabolizer - removeEmpty: true - solutionOnBody: false - solution: "Lung" - metabolizerTypes: [ Plant ] - groups: - - id: Gas - rateModifier: 100.0 - type: entity id: OrganDionaEyes @@ -102,3 +90,104 @@ - id: Narcotic - id: Alcohol rateModifier: 0.1 + +- type: entity + id: OrganDionaLungs + parent: BaseDionaOrgan + name: lungs + description: "Filters oxygen from an atmosphere, which is then sent into the bloodstream to be used as an electron carrier." + components: + - type: Sprite + sprite: Mobs/Species/Human/organs.rsi + layers: + - state: lung-l + - state: lung-r + - type: Lung + - type: Metabolizer + removeEmpty: true + solutionOnBody: false + solution: "Lung" + metabolizerTypes: [ Plant ] + groups: + - id: Gas + rateModifier: 100.0 + - type: SolutionContainerManager + solutions: + organ: + maxVol: 10 + reagents: + - ReagentId: Nutriment + Quantity: 10 + Lung: + maxVol: 100 + canReact: False + +# Organs that turn into nymphs on removal +- type: entity + id: OrganDionaBrainNymph + parent: OrganDionaBrain + noSpawn: true + name: brain + description: "The source of incredible, unending intelligence. Honk." + components: + - type: Brain + - type: Nymph # This will make the organs turn into a nymph when they're removed. + entityPrototype: OrganDionaNymphBrain + transferMind: true + +- type: entity + id: OrganDionaStomachNymph + parent: OrganDionaStomach + noSpawn: true + name: stomach + description: "Gross. This is hard to stomach." + components: + - type: Nymph + entityPrototype: OrganDionaNymphStomach + +- type: entity + id: OrganDionaLungsNymph + parent: OrganDionaLungs + noSpawn: true + name: lungs + description: "Filters oxygen from an atmosphere, which is then sent into the bloodstream to be used as an electron carrier." + components: + - type: Nymph + entityPrototype: OrganDionaNymphLungs + +# Nymphs that the organs will turn into +- type: entity + id: OrganDionaNymphBrain + parent: MobDionaNymph + noSpawn: true + name: diona nymph + suffix: Brain + description: Contains the brain of a formerly fully-formed Diona. Killing this would kill the Diona forever. You monster. + components: + - type: IsDeadIC + - type: Body + prototype: AnimalNymphBrain + +- type: entity + id: OrganDionaNymphStomach + parent: MobDionaNymph + noSpawn: true + name: diona nymph + suffix: Stomach + description: Contains the stomach of a formerly fully-formed Diona. It doesn't taste any better for it. + components: + - type: IsDeadIC + - type: Body + prototype: AnimalNymphStomach + +- type: entity + id: OrganDionaNymphLungs + parent: MobDionaNymph + noSpawn: true + name: diona nymph + suffix: Lungs + description: Contains the lungs of a formerly fully-formed Diona. Breathtaking. + components: + - type: IsDeadIC + - type: Body + prototype: AnimalNymphLungs diff --git a/Resources/Prototypes/Body/Prototypes/Animal/nymph.yml b/Resources/Prototypes/Body/Prototypes/Animal/nymph.yml new file mode 100644 index 00000000000..21aafe291c9 --- /dev/null +++ b/Resources/Prototypes/Body/Prototypes/Animal/nymph.yml @@ -0,0 +1,66 @@ +- type: body + id: AnimalNymphBrain + name: "nymph" + root: torso + slots: + torso: + part: TorsoAnimal + connections: + - legs + organs: + brain: OrganDionaBrain + lungs: OrganAnimalLungs + stomach: OrganAnimalStomach + liver: OrganAnimalLiver + heart: OrganAnimalHeart + kidneys: OrganAnimalKidneys + legs: + part: LegsAnimal + connections: + - feet + feet: + part: FeetAnimal + +- type: body + id: AnimalNymphLungs + name: "nymph" + root: torso + slots: + torso: + part: TorsoAnimal + connections: + - legs + organs: + lungs: OrganDionaLungs + stomach: OrganAnimalStomach + liver: OrganAnimalLiver + heart: OrganAnimalHeart + kidneys: OrganAnimalKidneys + legs: + part: LegsAnimal + connections: + - feet + feet: + part: FeetAnimal + +- type: body + id: AnimalNymphStomach + name: "nymph" + root: torso + slots: + torso: + part: TorsoAnimal + connections: + - legs + organs: + lungs: OrganAnimalLungs + stomach: OrganDionaStomach + liver: OrganAnimalLiver + heart: OrganAnimalHeart + kidneys: OrganAnimalKidneys + legs: + part: LegsAnimal + connections: + - feet + feet: + part: FeetAnimal \ No newline at end of file diff --git a/Resources/Prototypes/Body/Prototypes/diona.yml b/Resources/Prototypes/Body/Prototypes/diona.yml index f364d0f800f..12ca203988c 100644 --- a/Resources/Prototypes/Body/Prototypes/diona.yml +++ b/Resources/Prototypes/Body/Prototypes/diona.yml @@ -8,8 +8,7 @@ connections: - torso organs: - brain: OrganDionaBrain - eyes: OrganDionaEyes + brain: OrganDionaBrainNymph torso: part: TorsoDiona connections: @@ -18,7 +17,8 @@ - right leg - left leg organs: - stomach: OrganDionaStomach + stomach: OrganDionaStomachNymph + lungs: OrganDionaLungsNymph right arm: part: RightArmDiona connections: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index a343f63ba58..b55ec81c665 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -3114,3 +3114,77 @@ factions: - Passive +- type: entity + name: diona nymph + parent: SimpleMobBase + id: MobDionaNymph + description: It's like a cat, only.... branch-ier. + components: + - type: Sprite + drawdepth: Mobs + layers: + - map: ["enum.DamageStateVisualLayers.Base"] + state: nymph + sprite: Mobs/Animals/nymph.rsi + - type: Physics + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.35 + density: 100 # High, because wood is heavy. + mask: + - MobMask + layer: + - MobLayer + - type: Inventory + speciesId: cat + templateId: pet + - type: InventorySlots + - type: Strippable + - type: Bloodstream + bloodReagent: Water + bloodMaxVolume: 60 + - type: UserInterface + interfaces: + - key: enum.StrippingUiKey.Key + type: StrippableBoundUserInterface + - type: DamageStateVisuals + states: + Alive: + Base: nymph + Critical: + Base: nymph_sleep + Dead: + Base: nymph_dead + - type: Butcherable + spawned: + - id: MaterialWoodPlank1 + amount: 2 + - type: InteractionPopup + successChance: 0.7 + interactSuccessString: petting-success-nymph + interactFailureString: petting-failure-nymph + interactSuccessSound: + path: /Audio/Animals/nymph_chirp.ogg + - type: MobThresholds + thresholds: + 0: Alive + 30: Critical + 60: Dead + - type: MovementSpeedModifier + baseWalkSpeed : 2.5 + baseSprintSpeed : 4.5 + - type: Grammar + attributes: + gender: epicene + - type: Speech + - type: Tag + tags: + - VimPilot + - type: Reform + actionPrototype: DionaReformAction + reformTime: 10 + popupText: diona-reform-attempt + reformPrototype: MobDionaReformed diff --git a/Resources/Prototypes/Entities/Mobs/Player/diona.yml b/Resources/Prototypes/Entities/Mobs/Player/diona.yml index 7fbe0453b3f..28687c68bfc 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/diona.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/diona.yml @@ -11,4 +11,14 @@ damageRecovery: types: Asphyxiation: -1.0 - - type: PotentialPsionic #Nyano - Summary: makes potentially psionic. + - type: PotentialPsionic #Nyano - Summary: makes potentially psionic. + +# Reformed Diona +- type: entity + parent: MobDiona + noSpawn: true + id: MobDionaReformed + name: Reformed Diona + components: + - type: IsDeadIC + - type: RandomHumanoidAppearance diff --git a/Resources/Prototypes/Entities/Mobs/Species/diona.yml b/Resources/Prototypes/Entities/Mobs/Species/diona.yml index 3f46005635c..3d405c4dd91 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/diona.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/diona.yml @@ -95,6 +95,13 @@ - type: BodyEmotes soundsId: DionaBodyEmotes - type: IgnoreKudzu + - type: IgniteOnHeatDamage + fireStacks: 1 + threshold: 12 + - type: GibAction + actionPrototype: DionaGibAction + allowedStates: + - Dead - type: entity parent: BaseSpeciesDummy diff --git a/Resources/Textures/Mobs/Animals/nymph.rsi/icon.png b/Resources/Textures/Mobs/Animals/nymph.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f1b6a7923075b987efa37b2f7cfabef4c49d09dd GIT binary patch literal 611 zcmV-p0-XJcP)*Ap64!l>oaW}{-l}qIxzF;xr}y+czw@5= zepKO~7d1J|FVA3cK7sR# z8~Xuh-Wv3aTxqF9Y<37I>9`h$kyzRVwn_ltqB7syxpEbnNApmV7oFh{)=!dHS=z^7 z3?e??zZQfy1(4;G_cX_55PEYe`q#fI-Yium=mv_`MVJOV3P-@$=jmLivr*xytU+G zmC`qzG^S`y6>Dw^;I65_=s-8q{0l^X9Qx98_dM_VfEzjG4O!KN#>@wPBGU@+{3L|& z8t?P|zOZOG?wsaCs=6V>}l!YSa xv1z~i8Y&221w$E|)2vy|#w7#TDF?s-_ymH4ANCr&imm_v002ovPDHLkV1gH$8K?jN literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Animals/nymph.rsi/meta.json b/Resources/Textures/Mobs/Animals/nymph.rsi/meta.json new file mode 100644 index 00000000000..c6bb6e0ac4e --- /dev/null +++ b/Resources/Textures/Mobs/Animals/nymph.rsi/meta.json @@ -0,0 +1,63 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "https://github.com/ParadiseSS13/Paradise/commit/f367d7de199969a5fb5054de44faa5618092f487", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "nymph", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ], + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + }, + { + "name": "nymph_dead" + }, + { + "name": "nymph_sleep", + "directions": 4 + }, + { + "name": "icon" + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Mobs/Animals/nymph.rsi/nymph.png b/Resources/Textures/Mobs/Animals/nymph.rsi/nymph.png new file mode 100644 index 0000000000000000000000000000000000000000..fe79c893d1496a32576414a61219f289877dcaed GIT binary patch literal 3891 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Animals/nymph.rsi/nymph_sleep.png b/Resources/Textures/Mobs/Animals/nymph.rsi/nymph_sleep.png new file mode 100644 index 0000000000000000000000000000000000000000..4e2055d74adad40e2daf239d3420a573044d114b GIT binary patch literal 1306 zcmV+#1?BpQP)?W~f8_AYp6H>5nBB-Gy6z3F34~0N4 zz6A=s7efAp_K^Gwq0oCEkee@sLJu{xJ=7#70VkDe|AOgFN$ zo84^>Gas1Qo!xzJ-ZyV%SN`4z42LBEhQks7!(j=4;jje2a99FhI4l7$9F_pT4}AOe z=g#TWIBxv#YfSpSzxIVwY3$?2JNIIU7-9SOMF5@C3EOX$@{aV2bGeR)p!?@v^Y8$P zv1B0so(N#Dx0eesIwaWU&dm0%m!5C+`t|z}68hPruPc{7#m_4b6$!)cKMtMbSa?SLqlf z2@HPw#Q`>-msR=~OV!>oaN;w_WRq62VLm@SItI z?stJ7cqV|amZdLq&WVrWsQpn!YI5>lEx|qD_Hr~ILiEoKmVpWp1cTSlBl!>#EdNr9 zUHxiaEi|U$-JdpM`WGRuBSP@)qWhOuvwq#LP2ax-7_@s(_zw}bfBS0?hQks7!(j=4 z;jje2a99FhI4l7$9F_nW4od(Gha~`p!x9jtF$$A%EYfvQxm=gQ1z}3?fe8>TP*ho- zE9pEnu7pY!FX+V#e!ypGL!@{fyM6ud{}kl_s27yC8xZxFB4%o0Oesl!J$d%Qw)re| z2TJkO04t58@mdX*YWXSe~sJ{r6P2NEDDNJA`2pz~}hiF3J5I&u(2=Md?Ild4EUTBkevVSKPi z{U5VnhlLrMuiv+-NYx!h1Yf%>kzol93F4T&EWx2mKuD0yjAbZX-|>Z0>Nq`n^1Wh- zR(&$i=I4eir+A;jj8^?69*^vzwOa1oTi@O3jeVGHPkVrF=)3Ee9hRfal{>XM$F)H= zzkdFi*28= Date: Sat, 17 Feb 2024 03:55:50 +0100 Subject: [PATCH 171/200] Automatic changelog update (cherry picked from commit 8dbf3f9ebf7f5c7d8a3ec99f288e6d86c6339480) --- Resources/Changelog/Changelog.yml | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index eab4e3ab84d..883cee87eff 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ -Order: 1 -Entries: -- author: snebl - changes: - - message: Fixed emergency and extended nitrogen tanks having the same volume. - type: Fix - id: 5454 - time: '2023-12-27T09:56:00.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/23040 +Entries: - author: Blazeror changes: - message: You can now pry open windoors by hand when they are unpowered. @@ -3869,3 +3861,16 @@ Entries: id: 5953 time: '2024-02-17T02:52:17.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25179 +- author: Lank + changes: + - message: Diona nymphs, small cat-like creatures, several of which make up a Diona. + type: Add + - message: Diona are now able to split into three nymphs on death, and will control + one of them. The controlled nymph is able to reform into a new diona after some + time. + type: Add + - message: Diona now combust into flames upon being hit with significant heat damage. + type: Tweak + id: 5954 + time: '2024-02-17T02:54:45.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/24630 From 8515da41b7478b82550fcbec99e3d1c505e59340 Mon Sep 17 00:00:00 2001 From: LankLTE <135308300+LankLTE@users.noreply.github.com> Date: Fri, 16 Feb 2024 19:45:43 -0800 Subject: [PATCH 172/200] reform cooldown 10 minutes (#25328) (cherry picked from commit 95c95006302f6d76ce9c862954723664c0850a69) --- Resources/Prototypes/Actions/diona.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Actions/diona.yml b/Resources/Prototypes/Actions/diona.yml index ac65d6861d4..73bc1ba5290 100644 --- a/Resources/Prototypes/Actions/diona.yml +++ b/Resources/Prototypes/Actions/diona.yml @@ -18,4 +18,4 @@ - type: InstantAction icon: Mobs/Species/Diona/parts.rsi/full.png event: !type:ReformEvent {} - useDelay: 300 # Once every 10 minutes. Keep them dead for a fair bit before reforming + useDelay: 600 # Once every 10 minutes. Keep them dead for a fair bit before reforming From e44942d3417934254c13352172133fdecce84f8f Mon Sep 17 00:00:00 2001 From: Flesh <62557990+PolterTzi@users.noreply.github.com> Date: Sat, 17 Feb 2024 06:02:12 +0100 Subject: [PATCH 173/200] Change plant clipping mechanics (#25326) Make seeds from clipped plants inherit the decreased health from parents. Also require one growth stage before clipping. (cherry picked from commit dab2c4884928eae42e5dbd16237d7b0624b86c68) --- .../Botany/Components/SeedComponent.cs | 6 ++++ .../Botany/Systems/BotanySystem.Seed.cs | 3 +- .../Botany/Systems/PlantHolderSystem.cs | 32 +++++++++++++++---- .../components/plant-holder-component.ftl | 2 +- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/Content.Server/Botany/Components/SeedComponent.cs b/Content.Server/Botany/Components/SeedComponent.cs index 3e729dc9060..f475ec3cfc4 100644 --- a/Content.Server/Botany/Components/SeedComponent.cs +++ b/Content.Server/Botany/Components/SeedComponent.cs @@ -15,6 +15,12 @@ public sealed partial class SeedComponent : SharedSeedComponent [DataField("seed")] public SeedData? Seed; + /// + /// If not null, overrides the plant's initial health. Otherwise, the plant's initial health is set to the Endurance value. + /// + [DataField] + public float? HealthOverride = null; + /// /// Name of a base seed prototype that is used if is null. /// diff --git a/Content.Server/Botany/Systems/BotanySystem.Seed.cs b/Content.Server/Botany/Systems/BotanySystem.Seed.cs index c9389f832e7..f64fcb3c43d 100644 --- a/Content.Server/Botany/Systems/BotanySystem.Seed.cs +++ b/Content.Server/Botany/Systems/BotanySystem.Seed.cs @@ -104,11 +104,12 @@ private void OnExamined(EntityUid uid, SeedComponent component, ExaminedEvent ar /// /// Spawns a new seed packet on the floor at a position, then tries to put it in the user's hands if possible. /// - public EntityUid SpawnSeedPacket(SeedData proto, EntityCoordinates coords, EntityUid user) + public EntityUid SpawnSeedPacket(SeedData proto, EntityCoordinates coords, EntityUid user, float? healthOverride = null) { var seed = Spawn(proto.PacketPrototype, coords); var seedComp = EnsureComp(seed); seedComp.Seed = proto; + seedComp.HealthOverride = healthOverride; var name = Loc.GetString(proto.Name); var noun = Loc.GetString(proto.Noun); diff --git a/Content.Server/Botany/Systems/PlantHolderSystem.cs b/Content.Server/Botany/Systems/PlantHolderSystem.cs index 601dca36856..86f7be6d7b0 100644 --- a/Content.Server/Botany/Systems/PlantHolderSystem.cs +++ b/Content.Server/Botany/Systems/PlantHolderSystem.cs @@ -71,6 +71,17 @@ public override void Update(float frameTime) } } + private int GetCurrentGrowthStage(Entity entity) + { + var (uid, component) = entity; + + if (component.Seed == null) + return 0; + + var result = Math.Max(1, (int) (component.Age * component.Seed.GrowthStages / component.Seed.Maturation)); + return result; + } + private void OnExamine(Entity entity, ref ExaminedEvent args) { if (!args.IsInDetailsRange) @@ -148,6 +159,7 @@ private void OnInteractUsing(Entity entity, ref InteractUs if (!_botany.TryGetSeed(seeds, out var seed)) return; + float? seedHealth = seeds.HealthOverride; var name = Loc.GetString(seed.Name); var noun = Loc.GetString(seed.Noun); _popup.PopupCursor(Loc.GetString("plant-holder-component-plant-success-message", @@ -157,7 +169,14 @@ private void OnInteractUsing(Entity entity, ref InteractUs component.Seed = seed; component.Dead = false; component.Age = 1; - component.Health = component.Seed.Endurance; + if (seedHealth is float realSeedHealth) + { + component.Health = realSeedHealth; + } + else + { + component.Health = component.Seed.Endurance; + } component.LastCycle = _gameTiming.CurTime; QueueDel(args.Used); @@ -262,16 +281,15 @@ private void OnInteractUsing(Entity entity, ref InteractUs return; } - component.Health -= (_random.Next(3, 5) * 10); - - if (!component.Harvest) + if (GetCurrentGrowthStage(entity) <= 1) { - _popup.PopupCursor(Loc.GetString("plant-holder-component-early-sample"), args.User); + _popup.PopupCursor(Loc.GetString("plant-holder-component-early-sample-message"), args.User); return; } + component.Health -= (_random.Next(3, 5) * 10); component.Seed.Unique = false; - var seed = _botany.SpawnSeedPacket(component.Seed, Transform(args.User).Coordinates, args.User); + var seed = _botany.SpawnSeedPacket(component.Seed, Transform(args.User).Coordinates, args.User, component.Health); _randomHelper.RandomOffset(seed, 0.25f); var displayName = Loc.GetString(component.Seed.DisplayName); _popup.PopupCursor(Loc.GetString("plant-holder-component-take-sample-message", @@ -904,7 +922,7 @@ public void UpdateSprite(EntityUid uid, PlantHolderComponent? component = null) } else if (component.Age < component.Seed.Maturation) { - var growthStage = Math.Max(1, (int) (component.Age * component.Seed.GrowthStages / component.Seed.Maturation)); + var growthStage = GetCurrentGrowthStage((uid, component)); _appearance.SetData(uid, PlantHolderVisuals.PlantRsi, component.Seed.PlantRsi.ToString(), app); _appearance.SetData(uid, PlantHolderVisuals.PlantState, $"stage-{growthStage}", app); diff --git a/Resources/Locale/en-US/botany/components/plant-holder-component.ftl b/Resources/Locale/en-US/botany/components/plant-holder-component.ftl index 01d713ab34e..0e8c4137f4e 100644 --- a/Resources/Locale/en-US/botany/components/plant-holder-component.ftl +++ b/Resources/Locale/en-US/botany/components/plant-holder-component.ftl @@ -32,4 +32,4 @@ plant-holder-component-light-improper-warning = The [color=yellow]improper light plant-holder-component-heat-improper-warning = The [color=orange]improper temperature level alert[/color] is blinking. plant-holder-component-pressure-improper-warning = The [color=lightblue]improper environment pressure alert[/color] is blinking. plant-holder-component-gas-missing-warning = The [color=cyan]improper gas environment alert[/color] is blinking. -plant-holder-component-early-sample = It is not ready to sample, but you cut a bit of the plant anyway. +plant-holder-component-early-sample-message = The plant hasn't grown enough to take a sample yet. From df73df41970907cf73bd95d6a026b77f06472b2f Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 17 Feb 2024 05:03:17 +0000 Subject: [PATCH 174/200] Automatic changelog update (cherry picked from commit 74b5b72d81bde06052f61e9d7c42b5e45218f2e2) --- Resources/Changelog/Changelog.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 883cee87eff..d24496ce4ab 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Blazeror - changes: - - message: You can now pry open windoors by hand when they are unpowered. - type: Fix - id: 5455 - time: '2023-12-27T12:28:29.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/23047 - author: Emisse changes: - message: The Grand Lottery now has much more prizes in store! @@ -3874,3 +3867,13 @@ id: 5954 time: '2024-02-17T02:54:45.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/24630 +- author: PolterTzi + changes: + - message: Seeds from sampled plants now inherit the sampled plant's health to discourage + excessive sampling. + type: Tweak + - message: Plants need to grow a bit before being sampled. + type: Tweak + id: 5955 + time: '2024-02-17T05:02:12.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25326 From c9a6019f9708f65015f3c4bf2322a2ab69e1f40a Mon Sep 17 00:00:00 2001 From: Arendian <137322659+Arendian@users.noreply.github.com> Date: Sat, 17 Feb 2024 17:38:21 +0100 Subject: [PATCH 175/200] Fix nymphs being deleted immediatly after spawning (#25344) * nymphs now don't get deleted together with the body of the diona * moved nymph system to server (cherry picked from commit 9969bd25841b5162d80125c9a2fc000a94c3b558) --- .../Species/Systems/NymphSystem.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) rename {Content.Shared => Content.Server}/Species/Systems/NymphSystem.cs (75%) diff --git a/Content.Shared/Species/Systems/NymphSystem.cs b/Content.Server/Species/Systems/NymphSystem.cs similarity index 75% rename from Content.Shared/Species/Systems/NymphSystem.cs rename to Content.Server/Species/Systems/NymphSystem.cs index 7acbf2e1528..8d0646ae8e4 100644 --- a/Content.Shared/Species/Systems/NymphSystem.cs +++ b/Content.Server/Species/Systems/NymphSystem.cs @@ -1,15 +1,15 @@ +using Content.Server.Mind; using Content.Shared.Species.Components; using Content.Shared.Body.Events; -using Content.Shared.Mind; using Robust.Shared.Prototypes; using Robust.Shared.Timing; -namespace Content.Shared.Species; +namespace Content.Server.Species.Systems; public sealed partial class NymphSystem : EntitySystem { - [Dependency] protected readonly IPrototypeManager _protoManager = default!; - [Dependency] private readonly SharedMindSystem _mindSystem = default!; + [Dependency] private readonly IPrototypeManager _protoManager= default!; + [Dependency] private readonly MindSystem _mindSystem = default!; [Dependency] private readonly IGameTiming _timing = default!; public override void Initialize() @@ -31,11 +31,11 @@ private void OnRemovedFromPart(EntityUid uid, NymphComponent comp, RemovedFromPa return; var coords = Transform(uid).Coordinates; - var nymph = EntityManager.SpawnEntity(entityProto.ID, coords); + var nymph = EntityManager.SpawnAtPosition(entityProto.ID, coords); if (comp.TransferMind == true && _mindSystem.TryGetMind(args.OldBody, out var mindId, out var mind)) _mindSystem.TransferTo(mindId, nymph, mind: mind); - EntityManager.QueueDeleteEntity(uid); + QueueDel(uid); } } From 33b647a4dae6da7fc0d22f6f8248222d780efaf8 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 17 Feb 2024 16:39:26 +0000 Subject: [PATCH 176/200] Automatic changelog update (cherry picked from commit f27d78c2710cd1680dcf36290b794a64244d4c90) --- 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 d24496ce4ab..e700e7f24a3 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Emisse - changes: - - message: The Grand Lottery now has much more prizes in store! - type: Tweak - id: 5456 - time: '2023-12-27T12:31:03.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/23048 - author: TheShuEd changes: - message: The thief will temporarily not steal structures for the time being, as @@ -3877,3 +3870,10 @@ id: 5955 time: '2024-02-17T05:02:12.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25326 +- author: Dygon + changes: + - message: Diona nymphs aren't deleted immediately after spawning anymore. + type: Fix + id: 5956 + time: '2024-02-17T16:38:21.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25344 From afcae40a0a82bfa4cb9c88cb2492468b075f326a Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Sat, 17 Feb 2024 08:54:58 -0800 Subject: [PATCH 177/200] Fix: Grenades don't make trigger sound (#25321) * Fix: Grenades don't make trigger sound * transform instead of trycomp transform --------- Co-authored-by: Plykiya (cherry picked from commit 7d94cc719c4c7c6cbffbe4b7aad72f36ed689621) --- .../Explosion/EntitySystems/TriggerSystem.cs | 14 +++++++++++--- .../Objects/Weapons/Throwable/grenades.yml | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs index 5830018c488..9b9a042641f 100644 --- a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs +++ b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs @@ -29,6 +29,8 @@ using Robust.Shared.Physics.Systems; using Robust.Shared.Prototypes; using Robust.Shared.Random; +using Robust.Shared.Player; +using Content.Shared.Coordinates; namespace Content.Server.Explosion.EntitySystems { @@ -103,9 +105,15 @@ public override void Initialize() private void OnSoundTrigger(EntityUid uid, SoundOnTriggerComponent component, TriggerEvent args) { - _audio.PlayPvs(component.Sound, uid); - if (component.RemoveOnTrigger) - RemCompDeferred(uid); + if (component.RemoveOnTrigger) // if the component gets removed when it's triggered + { + var xform = Transform(uid); + _audio.PlayPvs(component.Sound, xform.Coordinates); // play the sound at its last known coordinates + } + else // if the component doesn't get removed when triggered + { + _audio.PlayPvs(component.Sound, uid); // have the sound follow the entity itself + } } private void OnAnchorTrigger(EntityUid uid, AnchorOnTriggerComponent component, TriggerEvent args) diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml index 90cb751e40a..0b1a7ecb77a 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml @@ -67,7 +67,7 @@ sprite: Objects/Weapons/Grenades/flashbang.rsi - type: FlashOnTrigger range: 7 - - type: EmitSoundOnTrigger + - type: SoundOnTrigger sound: path: "/Audio/Effects/flash_bang.ogg" - type: DeleteOnTrigger From 194c9d77555cec81d488ca858e068275ac1acbc7 Mon Sep 17 00:00:00 2001 From: Flesh <62557990+PolterTzi@users.noreply.github.com> Date: Sat, 17 Feb 2024 18:08:59 +0100 Subject: [PATCH 178/200] fixed the specific if statement called when plant age is under 0 (#25346) (cherry picked from commit 5b485fedbd6f41ffb82343f1f6cbb7113ce6284f) --- Content.Server/Botany/Systems/PlantHolderSystem.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Content.Server/Botany/Systems/PlantHolderSystem.cs b/Content.Server/Botany/Systems/PlantHolderSystem.cs index 86f7be6d7b0..0f54fd0da50 100644 --- a/Content.Server/Botany/Systems/PlantHolderSystem.cs +++ b/Content.Server/Botany/Systems/PlantHolderSystem.cs @@ -621,6 +621,7 @@ public void Update(EntityUid uid, PlantHolderComponent? component = null) RemovePlant(uid, component); component.ForceUpdate = true; Update(uid, component); + return; } CheckHealth(uid, component); From df79ac49b966abc10e8ac1c6a4e1938214b6fd06 Mon Sep 17 00:00:00 2001 From: Vasilis Date: Sat, 17 Feb 2024 21:30:54 +0100 Subject: [PATCH 179/200] Save round information into replay_final.yml (#23013) * Save round information into the replay * Add round end text too * This is way better * Get actual job * oop * OK THERE * Fake line endings to make life easier * I was told this yaml is legal * I just realised this will make my life easier * REVIEWS BABY IM A PROGRAMMER MOMMY * Live pjb reaction * Live pjb reaction 2 * Reviews 2 * Dont need this * Please no more have mercy on my soul * Oh frick (cherry picked from commit cb999d23f4b15e1c182e1ae4bf2e414306822f89) --- .../GameTicking/GameTicker.Replays.cs | 21 ++++++++++++++ .../GameTicking/GameTicker.RoundFlow.cs | 10 +++++++ .../GameTicking/SharedGameTicker.cs | 28 ++++++++++++++++--- Content.Shared/Roles/MindGetAllRolesEvent.cs | 3 +- Content.Shared/Roles/SharedRoleSystem.cs | 8 ++++-- 5 files changed, 63 insertions(+), 7 deletions(-) diff --git a/Content.Server/GameTicking/GameTicker.Replays.cs b/Content.Server/GameTicking/GameTicker.Replays.cs index 7e1a553a856..f23482585cc 100644 --- a/Content.Server/GameTicking/GameTicker.Replays.cs +++ b/Content.Server/GameTicking/GameTicker.Replays.cs @@ -2,6 +2,10 @@ using Robust.Shared; using Robust.Shared.ContentPack; using Robust.Shared.Replays; +using Robust.Shared.Serialization.Manager; +using Robust.Shared.Serialization.Markdown; +using Robust.Shared.Serialization.Markdown.Mapping; +using Robust.Shared.Serialization.Markdown.Value; using Robust.Shared.Utility; namespace Content.Server.GameTicking; @@ -10,12 +14,15 @@ public sealed partial class GameTicker { [Dependency] private readonly IReplayRecordingManager _replays = default!; [Dependency] private readonly IResourceManager _resourceManager = default!; + [Dependency] private readonly ISerializationManager _serialman = default!; + private ISawmill _sawmillReplays = default!; private void InitializeReplays() { _replays.RecordingFinished += ReplaysOnRecordingFinished; + _replays.RecordingStopped += ReplaysOnRecordingStopped; } /// @@ -108,6 +115,20 @@ private void ReplaysOnRecordingFinished(ReplayRecordingFinished data) data.Directory.Rename(data.Path, state.MoveToPath.Value); } + private void ReplaysOnRecordingStopped(MappingDataNode metadata) + { + // Write round info like map and round end summery into the replay_final.yml file. Useful for external parsers. + + metadata["map"] = new ValueDataNode(_gameMapManager.GetSelectedMap()?.MapName); + metadata["gamemode"] = new ValueDataNode(CurrentPreset != null ? Loc.GetString(CurrentPreset.ModeTitle) : string.Empty); + metadata["roundEndPlayers"] = _serialman.WriteValue(_replayRoundPlayerInfo); + metadata["roundEndText"] = new ValueDataNode(_replayRoundText); + metadata["server_id"] = new ValueDataNode(_configurationManager.GetCVar(CCVars.ServerId)); + // These should be set to null to prepare them for the next round. + _replayRoundPlayerInfo = null; + _replayRoundText = null; + } + private ResPath GetAutoReplayPath() { var cfgValue = _cfg.GetCVar(CCVars.ReplayAutoRecordName); diff --git a/Content.Server/GameTicking/GameTicker.RoundFlow.cs b/Content.Server/GameTicking/GameTicker.RoundFlow.cs index 6f0463aaf8f..ffe26aeb346 100644 --- a/Content.Server/GameTicking/GameTicker.RoundFlow.cs +++ b/Content.Server/GameTicking/GameTicker.RoundFlow.cs @@ -46,6 +46,10 @@ public sealed partial class GameTicker [ViewVariables] private GameRunLevel _runLevel; + private RoundEndMessageEvent.RoundEndPlayerInfo[]? _replayRoundPlayerInfo; + + private string? _replayRoundText; + [ViewVariables] public GameRunLevel RunLevel { @@ -372,11 +376,14 @@ public void ShowRoundEndScoreboard(string text = "") PlayerOOCName = contentPlayerData?.Name ?? "(IMPOSSIBLE: REGISTERED MIND WITH NO OWNER)", // Character name takes precedence over current entity name PlayerICName = playerIcName, + PlayerGuid = userId, PlayerNetEntity = GetNetEntity(entity), Role = antag ? roles.First(role => role.Antagonist).Name : roles.FirstOrDefault().Name ?? Loc.GetString("game-ticker-unknown-role"), Antag = antag, + JobPrototypes = roles.Where(role => !role.Antagonist).Select(role => role.Prototype).ToArray(), + AntagPrototypes = roles.Where(role => role.Antagonist).Select(role => role.Prototype).ToArray(), Observer = observer, Connected = connected }; @@ -389,6 +396,9 @@ public void ShowRoundEndScoreboard(string text = "") RaiseNetworkEvent(new RoundEndMessageEvent(gamemodeTitle, roundEndText, roundDuration, RoundId, listOfPlayerInfoFinal.Length, listOfPlayerInfoFinal, LobbySong, sound)); + + _replayRoundPlayerInfo = listOfPlayerInfoFinal; + _replayRoundText = roundEndText; } private async void SendRoundEndDiscordMessage() diff --git a/Content.Shared/GameTicking/SharedGameTicker.cs b/Content.Shared/GameTicking/SharedGameTicker.cs index 7778588f97c..2677d499c2f 100644 --- a/Content.Shared/GameTicking/SharedGameTicker.cs +++ b/Content.Shared/GameTicking/SharedGameTicker.cs @@ -1,4 +1,5 @@ using Content.Shared.Roles; +using Robust.Shared.Network; using Robust.Shared.Replays; using Robust.Shared.Serialization; using Robust.Shared.Serialization.Markdown.Mapping; @@ -144,18 +145,37 @@ public TickerJobsAvailableEvent(Dictionary stationNames, Dict } } - [Serializable, NetSerializable] - public sealed class RoundEndMessageEvent : EntityEventArgs + [Serializable, NetSerializable, DataDefinition] + public sealed partial class RoundEndMessageEvent : EntityEventArgs { - [Serializable, NetSerializable] - public struct RoundEndPlayerInfo + [Serializable, NetSerializable, DataDefinition] + public partial struct RoundEndPlayerInfo { + [DataField] public string PlayerOOCName; + + [DataField] public string? PlayerICName; + + [DataField, NonSerialized] + public NetUserId? PlayerGuid; + public string Role; + + [DataField, NonSerialized] + public string[] JobPrototypes; + + [DataField, NonSerialized] + public string[] AntagPrototypes; + public NetEntity? PlayerNetEntity; + + [DataField] public bool Antag; + + [DataField] public bool Observer; + public bool Connected; } diff --git a/Content.Shared/Roles/MindGetAllRolesEvent.cs b/Content.Shared/Roles/MindGetAllRolesEvent.cs index 9313d94edfd..69878739084 100644 --- a/Content.Shared/Roles/MindGetAllRolesEvent.cs +++ b/Content.Shared/Roles/MindGetAllRolesEvent.cs @@ -16,4 +16,5 @@ namespace Content.Shared.Roles; /// Name of the role. /// Whether or not this role makes this player an antagonist. /// The id associated with the role. -public readonly record struct RoleInfo(Component Component, string Name, bool Antagonist, string? PlayTimeTrackerId); +/// The prototype ID of the role +public readonly record struct RoleInfo(Component Component, string Name, bool Antagonist, string? PlayTimeTrackerId, string Prototype); diff --git a/Content.Shared/Roles/SharedRoleSystem.cs b/Content.Shared/Roles/SharedRoleSystem.cs index 05d6ab9f37f..24db1d56774 100644 --- a/Content.Shared/Roles/SharedRoleSystem.cs +++ b/Content.Shared/Roles/SharedRoleSystem.cs @@ -27,16 +27,18 @@ public override void Initialize() private void OnJobGetAllRoles(EntityUid uid, JobComponent component, ref MindGetAllRolesEvent args) { var name = "game-ticker-unknown-role"; + var prototype = ""; string? playTimeTracker = null; if (component.Prototype != null && _prototypes.TryIndex(component.Prototype, out JobPrototype? job)) { name = job.Name; + prototype = job.ID; playTimeTracker = job.PlayTimeTracker; } name = Loc.GetString(name); - args.Roles.Add(new RoleInfo(component, name, false, playTimeTracker)); + args.Roles.Add(new RoleInfo(component, name, false, playTimeTracker, prototype)); } protected void SubscribeAntagEvents() where T : AntagonistRoleComponent @@ -44,13 +46,15 @@ protected void SubscribeAntagEvents() where T : AntagonistRoleComponent SubscribeLocalEvent((EntityUid _, T component, ref MindGetAllRolesEvent args) => { var name = "game-ticker-unknown-role"; + var prototype = ""; if (component.PrototypeId != null && _prototypes.TryIndex(component.PrototypeId, out AntagPrototype? antag)) { name = antag.Name; + prototype = antag.ID; } name = Loc.GetString(name); - args.Roles.Add(new RoleInfo(component, name, true, null)); + args.Roles.Add(new RoleInfo(component, name, true, null, prototype)); }); SubscribeLocalEvent((EntityUid _, T _, ref MindIsAntagonistEvent args) => args.IsAntagonist = true); From 5b158b8296edc875421aca58e184754d357c7419 Mon Sep 17 00:00:00 2001 From: Geekyhobo <66805063+geekyhobo@users.noreply.github.com> Date: Sat, 17 Feb 2024 21:32:21 +0100 Subject: [PATCH 180/200] Adds a massban flag to the admin flags (#25327) Adds a massban flag to the admin flags used on ss14 to ban large amounts of players rom a .tsv file Co-authored-by: Geekyhobo <66805063+Ahlytlex@users.noreply.github.com> (cherry picked from commit dbf2c64cfd5a47088f5b20e850862a202795d5c8) --- Content.Shared/Administration/AdminFlags.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Content.Shared/Administration/AdminFlags.cs b/Content.Shared/Administration/AdminFlags.cs index c33a6be86f3..64cf522faaf 100644 --- a/Content.Shared/Administration/AdminFlags.cs +++ b/Content.Shared/Administration/AdminFlags.cs @@ -89,10 +89,16 @@ public enum AdminFlags : uint /// EditNotes = 1 << 14, + + /// + /// Lets you Massban, on SS14.Admin + /// + MassBan = 1 << 15, + /// /// DeltaV - The ability to whitelist people. Either this permission or +BAN is required for remove. /// - Whitelist = 1 << 15, + Whitelist = 1 << 20, /// /// Dangerous host permissions like scsi. From 712435b4d02347049f7d7b1df52bbe06699d590d Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 17 Feb 2024 20:33:27 +0000 Subject: [PATCH 181/200] Automatic changelog update (cherry picked from commit 3beb01b5b05785e50434cfaf6b2d9c6821a68351) --- Resources/Changelog/Changelog.yml | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index e700e7f24a3..c416884aa9f 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,20 +1,4 @@ Entries: -- author: TheShuEd - changes: - - message: The thief will temporarily not steal structures for the time being, as - this task seems too difficult. - type: Tweak - - message: Added Emag into thief's syndie kit - type: Add - - message: Added 3 smoke grenades into thief's smuggler kit - type: Add - - message: Replaced radio jammer to cyber pen into thief's communicator kit - type: Tweak - - message: Replaced omnizine bottle to omega soap into thief's chemistry kit - type: Tweak - id: 5457 - time: '2023-12-27T20:42:16.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/22976 - author: Alekshhh changes: - message: Changed brown fedora and inspector's coat palette and minor adjustments @@ -3877,3 +3861,10 @@ id: 5956 time: '2024-02-17T16:38:21.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25344 +- author: Geekyhobo + changes: + - message: Massban Flag has been added to admin ranks + type: Add + id: 5957 + time: '2024-02-17T20:32:21.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25327 From 25bc39b2f97e0456c9dd7fe3ccc4bf8aaccb6f8f Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Sat, 17 Feb 2024 21:46:38 +0100 Subject: [PATCH 182/200] Fix missing line in nuke exploding sprite (#25351) I could've sworn I corrected this before committing but guess not ??? (cherry picked from commit 71713fdebf9d27da7d02ea2d31ae0c92b2d9eaa0) --- .../Devices/nuke.rsi/nuclearbomb_exploding.png | Bin 366 -> 372 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Resources/Textures/Objects/Devices/nuke.rsi/nuclearbomb_exploding.png b/Resources/Textures/Objects/Devices/nuke.rsi/nuclearbomb_exploding.png index c5861c43bcbb07bb152b4d475afe9b9cb180b53b..d7e07d888029139670ca053aedad9f334da493ad 100644 GIT binary patch delta 332 zcmV-S0ki(@0`vlqF@G*eL_t(&f$f-0Zp0uAMn9@K82j8LJx_8I_T0=}FsPGa!jD`z z5`NKa0@yEu;sAiLI*z?deh08IEdef`k^--4au-Vh@&Ulf_HV<=Uj^=x-z9DJPh$ee zZ#9t=G(BM}NNDzJ$Job{=fM&b5>kOjB~%4c-u-K896$t+fPca^B_M{2TUiHs#?=bg z1iJsg69g8Ae6T4`F$ZP(UUw6mY|T33Op*IDvwg6}dB{>5 zRrlMne;JUccz|Mi%f)TnkAEZl_CMB=UxTdg3q^^M Date: Sat, 17 Feb 2024 12:49:16 -0800 Subject: [PATCH 183/200] Added Evidence Markers for the Detective! (#25255) * added evidence markers * box tweak * fixed a spelling mistake * new sprites, tweaked yml too (cherry picked from commit 07b796d6d20b190916182e9ab4bcf32b85fe1b92) --- .../Catalog/Fills/Lockers/security.yml | 1 + .../Specific/Security/evidence-marker.yml | 110 ++++++++++++++++++ .../Detective/evidence_marker.rsi/eight.png | Bin 0 -> 6539 bytes .../Detective/evidence_marker.rsi/five.png | Bin 0 -> 6549 bytes .../Detective/evidence_marker.rsi/four.png | Bin 0 -> 6537 bytes .../evidence_marker.rsi/inhand-left.png | Bin 0 -> 7379 bytes .../evidence_marker.rsi/inhand-right.png | Bin 0 -> 7395 bytes .../Detective/evidence_marker.rsi/meta.json | 46 ++++++++ .../Detective/evidence_marker.rsi/nine.png | Bin 0 -> 6549 bytes .../Detective/evidence_marker.rsi/one.png | Bin 0 -> 6494 bytes .../Detective/evidence_marker.rsi/seven.png | Bin 0 -> 6499 bytes .../Detective/evidence_marker.rsi/six.png | Bin 0 -> 6536 bytes .../Detective/evidence_marker.rsi/three.png | Bin 0 -> 6555 bytes .../Detective/evidence_marker.rsi/two.png | Bin 0 -> 6554 bytes .../Storage/boxes.rsi/evidence_markers.png | Bin 0 -> 160 bytes .../Objects/Storage/boxes.rsi/meta.json | 5 +- 16 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 Resources/Prototypes/Entities/Objects/Specific/Security/evidence-marker.yml create mode 100644 Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/eight.png create mode 100644 Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/five.png create mode 100644 Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/four.png create mode 100644 Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/inhand-left.png create mode 100644 Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/inhand-right.png create mode 100644 Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/meta.json create mode 100644 Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/nine.png create mode 100644 Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/one.png create mode 100644 Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/seven.png create mode 100644 Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/six.png create mode 100644 Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/three.png create mode 100644 Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/two.png create mode 100644 Resources/Textures/Objects/Storage/boxes.rsi/evidence_markers.png diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/security.yml b/Resources/Prototypes/Catalog/Fills/Lockers/security.yml index c0e50f8df53..dc7c1a51bfe 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/security.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/security.yml @@ -181,6 +181,7 @@ - id: DrinkDetFlask - id: ClothingHandsGlovesForensic - id: HoloprojectorSecurity + - id: BoxEvidenceMarkers - type: entity id: ClosetBombFilled diff --git a/Resources/Prototypes/Entities/Objects/Specific/Security/evidence-marker.yml b/Resources/Prototypes/Entities/Objects/Specific/Security/evidence-marker.yml new file mode 100644 index 00000000000..35b99573d09 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Specific/Security/evidence-marker.yml @@ -0,0 +1,110 @@ +- type: entity + abstract: true + parent: BaseItem + id: EvidenceMarker + name: evidence marker + description: A numbered yellow marker, useful for labeling evidence on a crime scene. + components: + - type: Sprite + sprite: Objects/Specific/Detective/evidence_marker.rsi + - type: Item + sprite: Objects/Specific/Detective/evidence_marker.rsi + size: Tiny + +- type: entity + parent: EvidenceMarker + id: EvidenceMarkerOne + name: evidence marker + components: + - type: Sprite + state: one + +- type: entity + parent: EvidenceMarker + id: EvidenceMarkerTwo + name: evidence marker + components: + - type: Sprite + state: two + +- type: entity + parent: EvidenceMarker + id: EvidenceMarkerThree + name: evidence marker + components: + - type: Sprite + state: three + +- type: entity + parent: EvidenceMarker + id: EvidenceMarkerFour + name: evidence marker + components: + - type: Sprite + state: four + +- type: entity + parent: EvidenceMarker + id: EvidenceMarkerFive + name: evidence marker + components: + - type: Sprite + state: five + +- type: entity + parent: EvidenceMarker + id: EvidenceMarkerSix + name: evidence marker + components: + - type: Sprite + state: six + +- type: entity + parent: EvidenceMarker + id: EvidenceMarkerSeven + name: evidence marker + components: + - type: Sprite + state: seven + +- type: entity + parent: EvidenceMarker + id: EvidenceMarkerEight + name: evidence marker + components: + - type: Sprite + state: eight + +- type: entity + parent: EvidenceMarker + id: EvidenceMarkerNine + name: evidence marker + components: + - type: Sprite + state: nine + +- type: entity + name: evidence marker box + parent: BoxCardboard + id: BoxEvidenceMarkers + description: A pack of numbered yellow markers, useful for labeling evidence on a crime scene. + components: + - type: Item + shape: + - 0,0,1,1 + - type: StorageFill + contents: + - id: EvidenceMarkerOne + - id: EvidenceMarkerTwo + - id: EvidenceMarkerThree + - id: EvidenceMarkerFour + - id: EvidenceMarkerFive + - id: EvidenceMarkerSix + - id: EvidenceMarkerSeven + - id: EvidenceMarkerEight + - id: EvidenceMarkerNine + - type: Sprite + layers: + - state: box_security + - state: evidence_markers + \ No newline at end of file diff --git a/Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/eight.png b/Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/eight.png new file mode 100644 index 0000000000000000000000000000000000000000..71c38d8d78aeb3e0aae9b18a6e7d9f388b1e1b90 GIT binary patch literal 6539 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/four.png b/Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/four.png new file mode 100644 index 0000000000000000000000000000000000000000..b8d7147896b42a9685c0a70f76ac430b5e95d82b GIT binary patch literal 6537 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/meta.json b/Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/meta.json new file mode 100644 index 00000000000..4beec91793c --- /dev/null +++ b/Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/meta.json @@ -0,0 +1,46 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Modified sprites made originally by tgstation @ https://github.com/tgstation/tgstation/commit/da42afcbaeaa04e5ba288ade027c011efb3ef0ab, Skarlet and Psychosyo. Modified by moomoobeef.", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "one" + }, + { + "name": "two" + }, + { + "name": "three" + }, + { + "name": "four" + }, + { + "name": "five" + }, + { + "name": "six" + }, + { + "name": "seven" + }, + { + "name": "eight" + }, + { + "name": "nine" + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/nine.png b/Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/nine.png new file mode 100644 index 0000000000000000000000000000000000000000..a81db9fae746c0cb726809ca6357e391b8bb226f GIT binary patch literal 6549 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 a|0UC(`TDg)=H-CoAgN@2$l;msIsXOw`v=?r literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/one.png b/Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/one.png new file mode 100644 index 0000000000000000000000000000000000000000..22967c91b800a151abb15cf14c159290a5a49039 GIT binary patch literal 6494 zcmeHMc~leE8lMot52tOaV-Dpsjhlv=yE6v0w03RGDn?@q#I+tVlSwEr&u$T zoxx&1@9*my5H$07zCa`rO`ai>OW|OyPy~}86jxVQw=r%$?(RPD6yGWEh%f7B5W|J6 ziArHZ4h#yFL9w2MCWAU@6x(H|LK3Aq(wv-KTOTcbXO&09Y;-EMBV^Yi@& z?H!%JJ$%&FP4Xgn4qSF-zvIOKyc`@IsgBMhFN#AZNu1$Gn<8);9}?w^uJB~TYh9Rg zx9vT0+|^$g-R7mXT%>zX72TM2pQL7E_H@M7{a?%mi4F1k7ILFfz~oUG&}^uyuOQ%E zhf(``HK^HCvAeaUpzAv;)VH+P3Wb(zj4Y|v6+ANCU3f2dcH7ujC#e)U=b3rS^YHst zXpML9u7b{850n#Sex5F6;Z<)YE^hqpesOP=75cdLw@dGg zYY40>zmi&4-VE1%{NV9|4aDVhjjAQ*Gj4RhHm|-TN|9TXeO$qeq&$r!hQ-x)b|_Ze z%df5LoTc%RrqPV)piRbRzMwSQeEP1`W zYoh>&s_;6DtSW3!eHT!%yQQM6?=ve@R=ly-v-n!q2onBPF{6Edn5@axtB})-%pbs? z$MyQq&`4!yD9day>GWwB1Z5Si-X@PYF~|2*;-vz%7h~1|srJBvj3~zG#rf=5m&&>2 zW2YD9hV0ld_0*{-Ge`R9NPN0^#g)s)7kN0&o>Syk#9X@Xq;*=pw_uX*!&~21pZF9#=&b(_$g311XVeee3LntP1vtxLBgcNO>G9S5^t zrBJp>>)kF*|ADpV>PPPNJtrA2Z(np1zv;Sz8_|0v{nV|XdPN~^&jf++PWDZgBk{i^ zy|+H0u3=Nz=F&s^V`{c`#y5R>Dxtg~zI9J;{*6y-J~)@Yt29E*n7{RaKTZ5b)Y^af z97bk(fBjK$+x^$8ayKubA3dA&Q~VsSiQ2|-ea^MVD(NvhmPJb`M76a3w9kd=F{0Mj z+E@P~J@3hSO)>3;Kesf z9~)1^t6oAhCIc7Mn$#FK%V4&>5CqT8GNYPQj9{s;WW7<&{`FWbo2A#v*>PeOUu6!( zQuGly7Az)bL98YxRU^}~XTLxX&O!iy0V7aWmLbiEBUy5`4Hp4E+00|JY#~IdoE;Bd zUPDb5j3wfVxO|QxOP>L=U!b#sEm|EC9TwgX0e;EZDFk6gc)ZNaOm3!-YqBKs1TvY7 z$A@_^%mEP`Jlja1SsWwoPeRx+!Z2K8(VGdq$;cuxQMDsaQQrgfj4{vPAD<}NPj_pIs%W)He=IR>2b~$=CeB5u^mkdV|?E3W)tgB%#+0iSRkIh)LnXiXZu7O}ZOe34M9mB=_^SR&wvWT=dTinJIC_w0WQ=DvCfhnl!I6+irJN0O`9m#{X(*us1LW+N^v3k8p^jL+0gE9}QcXb+ zUn&quVVO)I6N-eQp`e#B3l3HyiD^5q*?P!nK>!&bEK06Z0AOneT#!%;h7u-AtjUxn zXAd6r2D??@anhm$8io=W03AI1#SR?)ID9G4Vkq9E)$6kVS2X$Xu!8MV9-+rU{%l*5 z{fUafR@i^pf2Qeej}nVzdngc8W2bA;~~TpcPo2wqr3Xz&24c zpN!5-!N^$vf^qmTMwZ*gC@bYfMJ^q7-w$-n-|y%d4ro_zh>mN z^ABGAbMX&m0MMgJMx^hkT%&T0NP!UrkFKs!xkjYGh=NB~*WV@=edsua8NpjnCO9n3 zuS+5Sui&JfKQ9b=p8WJZKI8{lT+I;)I0TLHB#i>?D)Ir1&V*8>aBgv6(58DfxksJ^ zO&gS9A+hl%G)X?R(j?}Vb=$`JD5E}2LQdqZ(oNHDzXy3oi%)8k3OGBDe+I6$;@EKl zKDgWo=GMCqb*Ue-=C$d^14{N#FL26Mx-6+$gC6GR;m@Pt!uze&6qY zzu&!cnR{53ICZiQa}*PTARl!?Y%;iW2=n#=-`3*dP6%R5!qe1xwfaTK8?=E)iYG)N zVt`Qw_#PB0Lps#l4W#?7M z_my~cJQ#?e0lu79pcu&8%Zu(s^QP1342Cz8<>$j1GK4j9_=sVC!J|S(2agI0;)L;E z;Ba3G4GIdEkAF!hf?+u11*J+Mj^s;VF#$qhFc_>MtUw>1K=GKMG2&;woJS$HH&GLn z!i7B86e^qIJPCz>I%yR0a#10OQax#2bZ-W82neY1C6uCicv5LJPfyUh2=qgqY})WK zqG+!XNhqB=&riH`%~tQwNe7PkC!cQ*lV~j^3}(P{fg?wa9rr@`_!nWROs-HOF|l#+ zlM~dhq@+%NZAM!9OiYLCv$73yt+xF61%*Y$%l=Wie8tLDjuyVi95r{)_sTUvj<{d-5} zoxAt$cXboI2%deHi`gG|u>mg+Pfw~Ro!~|BC?JTlJ!xY^Uc;l4=;*u=T=7zGze#Jh z9yrDbl_anHYz*LM($N&%BcWkXR=SFa;{i^rh- zwHnl}tlZSr;^_L`3H8o?;Dll-RwP!`=pFY>zfQZgII4Z<8>2OG#b^EObM4mKPH0I$ zWVz!``R{YvjyKiRbXF~ixLMrItu3hBe>$r9<`;LAZJo^UirSSo!S|A@6aw)sQ@!)7H6O>q0S+?(1p`>??6S`8@GwD{l-$x~#CYfJ&TM=I2fS$%8z?%4xp#PNQa_H&`M>teDt}-3i>k&P6LE{u+ka9=su9UKFzl#leupGdI7Wc50^=2%r zOL@0$A|T%KmYGQWGb1wz;$V8$+oR64Y;A1ayirUw;De{yi&I%{pu?ue?b8lo< zRPCBp*1hUTseea}f2R|=9Maj*?u1ILJ$BC1kN9U54fa1aYgFgA(1+_z-UfdfmlEaj$pS54YCblm#I z(QB87)z>GPd5Zf7((=voE?qn}-Pbc};>O^OezUiqbdD_z5RDGHcm0Q&Q$I|Yn4S8b zzO-q{&MSIkgYU=H(+~9cdwBVltVB1Yf3`7f$JGh7x7b(PX1|%$^?r}Fb5GG56v`S! z1M9-LA32-9J?PWWbCUg9+4LrB6Jsqu;lb(r`s?zBxb?KnBSn(dq9*SHX}@IdSeAaK zapkU6+xG5Esa<_1t@+dX^nHzKZJQsIUi-B6qc8Kzw7ocHX~Ua{5dG;#Gmy63XOgZO6x7eRQbjXPflw?E zi+Lb|XDu??&_bTk8cIO8Fk*2lW-*v;29uFPV4_-6zD>pDf__e4eR*b$rXSvDb*ljM z5EP{@;^8tvvpeJTnQ;W>FAQ`us@+}x1Hy=0JLI*O2=z9pBW zqr(JvE}jQMtzcBqV?z?J`287#1X+eWGnoa%ek{^v&_5FEvD%0plFqJiP+Pv{J25 zC&EPopwvdI4K-po0R_PM27m)gQ=m3am z76Vw7XzswO2q+zZ66;~1NQYuPSb`~euuvl5DKL?ihr%!}RqBKyOd%wpbQltEvgDy) zIt_Vf7A`Owv&arYa3nfWt>TLLu28ZiF&DMzL4t}q#bC@Yd=#2$$iq`?D50iEE>wtM zg#_G%GPz9tDCjlZVg)Oaz$6cAWDhYd2p|K5MTvC^0LXU01&OiXsLfZuG$x%vU-W0u#KXgh1o2?X6AV@`ei7N^ zdZJSBd9GispScF|QQ~mOhXO${7X>RiAJ>s}0xVY-mW>*-aIky0mup|U;R#DYq=j`d zg+$E5<*=3qD`6Q=D^X~9a##=JVoWTSp?^TPn)J2;)PhH60Ud!>V0n^9Voo?YQR5%4 zr63z8W&sGs14~UL>k~}w7EItKEFkubKE{!P|Is9p3>dJs=i+Z10YDE9@=W>;$~7q0Gb!*)!Go)7P_AcE;F*F4SJz)A7xU3^3O9ncpaO7M zg6H&oOF*z6DQ zd;yx?R>wxCrk%ht18Lhb{oX8DGc-`0^l2t?!oE;HR#$cl3P_fo)MYw&8;%_XSNr>^ z!$d-G`PlqcH$&9f!HVUSU`~1J5+Ba`!S`tMg5(k0 z=`j;0uN_J|U%KpaedVkb=NKEd`^Se(fb?vHbFnE&$c#T09!L{{|Cq3XD;Fu%6`(Xo N9XB<0|D?>4{{l#+?Wap2Cxjp`1*ZFzYe5agjpla+d>7{>#1o+rSU$jd1}!kK_V*gL^43KJXdfz7LpT zgR@pG@V^B{B|g!>!;$;$vy`e>CZEHDIf77-5A%gmm@nmpGWk5IKr9sqK{V-uff0dJ z$OGzuoY**0A155Pj}z|qahd^qa_@L?W!wk(KD|E9o#f)gjK*_&{Xkqca5=~B_`%Tx zjhsDGITIAZX@D=s6-W+I-Q6kfZd3||;^9H1c`>}bJUzX}j2itCBVg>fz<{y-{>%xS zNlex&LH_}?;?d``O??0aZ!k6O$9>}J?@thDtgAg}zW?wWGd6hQq>#x|grd+eu|z75 zQp}tct(+a7koa0s^85u_9jZ@DH!QJXSa`V=#UAKP2#!ZD=w!Zz&yW8F?E~(h@ z;m%#V_w3#G$)UqlpMG}a=;tR+o;v;InX~7<`mW*9<;L%S`0=N!&DXBqxY^Qr>-K|( z?H!$uetX>Y1m}hG?7N)Ie#eUrc)7T`l3gh{FOo|(PMq%QHlF7`DpE~BmX2oeS5X-= zipmcj_XrZi-S^R0>uJ6dgja(f;M53a&qr+a|HZ7I*Z{AeATKfrOdgpIML=CWg&`lf z4BKC;LG8xM?QN}vUH@@FJ&T?>AbG`x*oqo`;bZfid3OsU?vHpQP^HMbz_2f|+a5Te zmA>I6g`Fi2m$aQ|uBqv$S~;~P?+L3myYj%i{~w|9>y445~+qOfa9tswZE{cu-z&*ImyntOK94~;ux=A`FmC|10qSYCHKtvkX2 zowGmHazDx)x8VD&Ngn~bh}z9Jo^1ER2le^Uk|*Jn!Y6eRN0(oztSs6-dqv}=u3rj6 zDvyXyJnt&{19jpXGp_G@(pWpYa?+ZJ8xE+u+5vs$9#r1>vCqRqhJ9~YhXZmz!4Bxo znzq1MjaAn#w~4M_ZZA%`(p9iqE?sgnW7h$FwWWJjP)lA&MO{pIQ$=A2^gLDxR3gL% z%(vMizHKeP)L8#^gNbS@6%qB zPfwXv=77GgD{IAKZ-b?xPI)h2yn+!+TC7@p2-v4dk9tz}6yrriJ`FLugF7bgFTJqh zUP@Hb#m+}#D9?@oW!MF)6pW;L|EqZ7pBa(ap;&PjQ0Da5%j@NP8`KLg_&l^HwM%o~ zDk;2~zTn|jLu{X61T%T)*D+VZF;^7$+N*@%Ywhs+wq z@#Dm)F#dwI#vqr+D&=yf#cI|YGEoT1Da|jEMW3ARe>$b1kmW<4wnwbn6SGWBKeJ#R zD}h=yWB-VW+X^DLuAgxFwA#WJKR%e8Wm(#I`FP?;*NEw*0i}#ZAD(gquk+;v`u}$A z=bAG=Pn({e@Sc8M^U7UU^wQ#yhmIy5eCp%kK63R&qIfY~@5hJDYX-TG&O!Hn;c3@C3JV zo2dtre@)%FX8yTL8+UKov2Ry=?dHzp8^=!1-+w8&?fqx#t{$uXi&gMNq zZlbrcYobDbd|MS zv(G0Iycp*g5|XiG)m*98Y~&z1vj*kl7%jvLLwH1v1<_`p7*m6$8B8+Pz3Ms^)1Z^F zl0+(4Ws#%lhUh#i8lM-Fpv}wBN_4D3OPa!%vR(WmhoAy(wN~^on9IjHM182{F1TKG0Y<6aY+~Y=h{l|S$yhAV&+HqY z(V|lI!<%fqDgZsWIf#YJv1jUdzps`7@E#E${}8Mp*#2BU?@0%8w|#0>fYv4)Hd?;+?6 z9tcS9#~l*g$DIfUQ7V-*%B;=8ho_8^vGDp*omp$pNeLGb!Z3&M+ZSEO*RZMX;B;sfO8B02ZqBW8ZpdcOEfUb7KR}bwpfTFY$3qV z3I%!;6$l4G%(EK6szfpej|zv<;ZR{HU!*}o*)STaVGBbw8UPxGvcnLKFjUJ6)#^1) zD4kY1(`+>&U^)#(Bn{Frx7o zf~(03gT*|dSilp8g-HZ_(Lm5^sMQ8mB92KM=!hPCTBLvs5EjALDF7ha0T-#R03<?-_lJ!@2*XNjMQOXp;eX&Ni@lfxVF1zZv#w zhHpE6XFjLL$hsD!&e3Io8f? zJ`|LAsQj&o0W+FTME=^GbU>aSw_@JA z)YeL|R;*O8Eyq?`P=WeDrB$p|u-0pf2%_QxD^@`vcXk7ay`FRNp7uW`=iB{u=9}Mq zzu(MGb~Z#uMYuY7J3$cSDv1n>1$P>5j`rYc%*pA7AW9aNAW=yquR)HW4n&e{Arc+~ zj5N%*A(0_6s9Otc9PsfN+`LJ4#C;?1Cl2^qfgdmsV*`8+$p&%-_hMjN;Jbr+IWYA) z>sYnG{}GrY@rwi=jy!mekVvCxTqcLja*f`Q4CmeQ=6YdXknge|DK)$##_QQOS0Uzg1vaw=D;(Z5v7A_ko*4!;WTUwy8 z^X5wCf`M=v;9|K9g+h+@_73)Tjt&kE6pEvhi@U3fv$M;DapT?GeZ417^7Z!dp-o}F zN~6E-@8c67nEpDO1H}dU5@H{J1Y&EZ;#?M?5Do zi4NINNn|R?avYir^0Xrn#YzPyO18DLcW|UQIfH=8vA9xX8(XrSovkfsT?N`9TdLhS zKTe4K_!!iIzTBO=rf`>||D63tJYvsvP2tH6c@!tlSG*>8Po4H^!1UK(exN`oLPEpB z=SD zPw8iS%gVp{`atD3-&R#0JbLVS{fU#O8ovMO{Dr3Gi$7obqlCKD%4wYBr(*pCZ|aX^=kr*qdhy3Z-x zwf_jkpBLNZAvc_J@|*%+oq8XqMlc&0vAq9_*$}a3yncaP$Rsd%WGWO4_4F46d}1?d zf2{_!>nnD2-YDq#w*~57`qTo2maK~|sZkX?*4=sIZfpa?8Q`23!dPYZ1FTFOi;>%OP?HxZn6m@nx1(ejT?*P};BQm0Q$&3!8 z1?tIs&^M;Q_l-p*1wF6T@}@SJ5A^i)zx5AO%{?>!=jJ_8^HWx(hOc}-d_~=@z9?OCCgW=Fdl8M@G2ywz*+;_N zqe&yN#IX3rhuz^T@0u+Tv){byTxeM*9FsUT{)Doc^~cWOx*vYfZmYR>{gC&CvIczU zw(@|AYLN5oMzi^&qAQHl#50dX<+6@%)-_kQHFfganz|+=Uhc{LOo1%Bo?7~)>X5!K z!oMRYprkG;sHLPJ02+x^fQcm51DKp`=HMT1?7Hx<2tcrrIk@D9i)vKB(kkvet&8D- zK@KjPQMw~){*AbJQBlvYgxa^cZavvRp2dAOV6I9;M@KSOFPf*)lIo%vZT%J3O%Hte z9;eSmG(A1`;mv*9OA4BI%$k2|+Fkef#_ss@7AVPl{_L@S%Go^5&)^3&+|9&o1^Yc3=AGam&~G;_16TA;oIy!p1|SV z%x-nupKv>A&)bU{F0B7-!|w9ZxY|t*6WR~gFWPq@q4VRX`Bx9ueswy%Xm_NXI)Bq% ze>?uxm^J_O`U08m`O|@&UHAW0mAheyQ}y>rZ3(kIypi=; zyxb!Md@5(DWeKJP=>kNd(=bt`PL46NGbKy+d_$np!EQ z$MdCZsXi1-QAg$&u(+HknIb1uAyU$VXE_CBApk&wnNV7mCQWNZvcz-(7XdzA&7#wY z5L2p{o&Y{~Lv;p>1~XwMn-QL+&fwB#Inja)N)-|tHg^C5Jc;QkCX*gvu`)9=nVCGM z&XCOFh(sb5o6F*I86bjT%+{LFEQZ$Tk3(27!Z4%4pw^qzIxP*yMCH14lbB8i?XAlo4T&ENhI-%H8) zI>QqI-G^|Wiyq`o1cNB46baKQ((&{pVPZNyKBCkq)JlYK=E03|IgvV6IZ25^;t>Nwh{2s#Rb(6aZ(c0S=do%DF}ViQGA^O0HPjnK|&1} zYSI~GI$fHWK6E%7YLbN zT7l(B9HeOh#6(ShJ~}f6!)E~q#sEu=6ZmJrSObJv_?|JyIEeLMngkI6!!{Yv&sqmI zFR&M~hBm_i%|O0?XBn7_zjFv0ZFG>A(sxv@QMq19ftLy%U0tJcy_5nk6+F7S{xZ3o zo*kz!E%*w`1c#+%^QcwesAVso9}xz?!+t*-by^3;@BGh_J^Z>9X?XUp_C&dhB`-kDbaNGXC;RD{;l8pC#)dnCZijtxOu X^Zm@6E!K literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/two.png b/Resources/Textures/Objects/Specific/Detective/evidence_marker.rsi/two.png new file mode 100644 index 0000000000000000000000000000000000000000..7309c2ff9b91996c037339709334dcde7a411f8b GIT binary patch literal 6554 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 Date: Sun, 18 Feb 2024 07:49:48 +1100 Subject: [PATCH 184/200] Add "tailed" hair (#25216) * add * yes (cherry picked from commit 22244b3055ab1c6319073fb654017476659ef41f) --- .../Locale/en-US/accessories/human-hair.ftl | 3 ++- .../Mobs/Customization/Markings/human_hair.yml | 7 +++++++ .../Mobs/Customization/human_hair.rsi/meta.json | 6 +++++- .../Mobs/Customization/human_hair.rsi/tailed.png | Bin 0 -> 2164 bytes 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 Resources/Textures/Mobs/Customization/human_hair.rsi/tailed.png diff --git a/Resources/Locale/en-US/accessories/human-hair.ftl b/Resources/Locale/en-US/accessories/human-hair.ftl index 2d66537d368..1f10b363f8a 100644 --- a/Resources/Locale/en-US/accessories/human-hair.ftl +++ b/Resources/Locale/en-US/accessories/human-hair.ftl @@ -163,6 +163,7 @@ marking-HumanHairSpiky = Spiky 2 marking-HumanHairSpiky2 = Spiky 3 marking-HumanHairSwept = Swept Back Hair marking-HumanHairSwept2 = Swept Back Hair 2 +marking-HumanHairTailed = Tailed marking-HumanHairThinning = Thinning marking-HumanHairThinningfront = Thinning (Front) marking-HumanHairThinningrear = Thinning (Rear) @@ -175,6 +176,7 @@ marking-HumanHairTwoStrands = Two Strands marking-HumanHairUndercut = Undercut marking-HumanHairUndercutleft = Undercut Left marking-HumanHairUndercutright = Undercut Right +marking-HumanHairUneven = Uneven marking-HumanHairUnkept = Unkept marking-HumanHairUpdo = Updo marking-HumanHairVlong = Very Long Hair @@ -184,4 +186,3 @@ marking-HumanHairVeryshortovereyealternate = Very Short Over Eye marking-HumanHairVlongfringe = Very Long with Fringe marking-HumanHairVolaju = Volaju marking-HumanHairWisp = Wisp -marking-HumanHairUneven = Uneven diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/human_hair.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/human_hair.yml index bb9d6d2b295..92943a7af4b 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/human_hair.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/human_hair.yml @@ -1307,3 +1307,10 @@ sprites: - sprite: Mobs/Customization/human_hair.rsi state: uneven +- type: marking + id: HumanHairTailed + bodyPart: Hair + markingCategory: Hair + sprites: + - sprite: Mobs/Customization/human_hair.rsi + state: tailed diff --git a/Resources/Textures/Mobs/Customization/human_hair.rsi/meta.json b/Resources/Textures/Mobs/Customization/human_hair.rsi/meta.json index 927d2ec6e44..c0bf805c386 100644 --- a/Resources/Textures/Mobs/Customization/human_hair.rsi/meta.json +++ b/Resources/Textures/Mobs/Customization/human_hair.rsi/meta.json @@ -4,7 +4,7 @@ "x": 32, "y": 32 }, - "copyright": "Taken from https://github.com/tgstation/tgstation/blob/05ec94e46349c35e29ca91e5e97d0c88ae26ad44/icons/mob/species/human/human_face.dmi ,resprited by Alekshhh, a modified by potato1234x, uneven is drawn by Ubaser, doublebun_long by Emisse", + "copyright": "Taken from https://github.com/tgstation/tgstation/blob/05ec94e46349c35e29ca91e5e97d0c88ae26ad44/icons/mob/species/human/human_face.dmi ,resprited by Alekshhh, a modified by potato1234x, uneven and tailed is drawn by Ubaser, doublebun_long by Emisse", "license": "CC-BY-SA-3.0", "states": [ { @@ -758,6 +758,10 @@ { "name": "uneven", "directions": 4 + }, + { + "name": "tailed", + "directions": 4 } ] } diff --git a/Resources/Textures/Mobs/Customization/human_hair.rsi/tailed.png b/Resources/Textures/Mobs/Customization/human_hair.rsi/tailed.png new file mode 100644 index 0000000000000000000000000000000000000000..f24abb81e320e65fb535f5930fd908f77c546deb GIT binary patch literal 2164 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|_);T0(|mmy zw18|5AO?X;!IOa`XMsm#F;KxA5N2eb5`33|fjK8LB%&n3*T*V3KUXg?B|j-uuOhbq ztjngt3dqb&ElE_U$j!+swyLmI0;{kBvO&W7N(x{lCE2!05xxNm&iO^D3TAo+dIm~% zTnY*bHbp6ERzWUqQ0+jTtx`rwNr9EVetCJhUb(Seeo?xG?W zUP)qwZeFo6#1NP{E~&-IMVSR9nfZANAafIw@=Hr>m6Sjh!2!gbDamkq3QCJ|z_z3$ z>!;?V=BDPA6zd!68R}!xSCW~AaA96CG&q0(qYsh+YBRv9&9k5+*#sC;t`$J{K>Y`F zXfoK|;*u17BnA3L1_l&2TID3>rQ0f1=%%EmC6?xtDA{@Xy2l%uT3XuZLsX&ahKQmXYNL{p zmyJF=C)sg{E@QD~U|?zYba4!+V0;^8?V;@`vR67z`G= zDkQQsFk}sjcA)oBFP%%#Q5uirb+!m?2@!N<{r;3^&W1H7PoGH>o>F1j>w%_ON z{GPXIvr^Q*e6~Fr&-{ISe#pzqU%GNdMOj(--mhP~>Z_}@ySuw5KH2%oz|{1qx)A5g z`SZW0rKkTrf8PJ2jlY79N(2REEP?cMm1mzVd` zuU}eIr%t{1@ZrM!TeqqL0o&$)c??295ls2n+1cK=%ZrMVZk3jnUb=TrPgGR&TG`Vt z4G;2|M2=m*e%(7VawhxZ#yb};K0JH&?990y*`W=`E?%5yIB!v=#qWLZPhYwuwA*RD zCx1%D6O{(TzSv{y9tX$8{p(F^SbXK$wX}xL^cT;b9phNFYSpCn_Vz8uFG?54K4duj z@#K>9h{qjf*&ztvW{d)b#xHz*%-@bqM?R|6q>ebX+U+i*bNN)J?E7?%pmUa8yOP4N{*xzu- zbMRS~=gPWMR%xRmPv_2EyRypUA8y#aJG*V7j3?9cr>oXFDd?!I;8>UVJ#i2B=fs(2 zwQ9Ccq*an6`mHidoG-Y=EwSu)tH79{KKbOAb1p)!He}@Ho<07a_kq#PM9X7~p3L=- z6S(&M-#kPUW8c0a6{Ir~++*xi&G)_FWgy0&=nVzq;^^77IV*A5yKTs%Ir!QiyL zCmYY&b?eN&wS6s8RD8cPFiAf?;0e<|yA$ryHnTrr7JGhc<3>Y$iT{PC{+Vui!1`0` zceX74(-uzu)8N%kb0k^=noUyh7CN=CtgroA$-i- z%xukkQLEMi&z>!-udCzZ30}a!C2BNRsqSM3U;gq9TefUDapA&*t+9T~4_nMT#%UPK zdxoE%Ke{>ascVKM=4> zrs0Rz8Gm7h8mWG>QkUDyECd;*KiBO)6f4Ac{YYs0#)ZKsCOntDnm{r-UW|V=PtA literal 0 HcmV?d00001 From a3f01a1c5cca52626180d88148c5a0919ddf34c3 Mon Sep 17 00:00:00 2001 From: Ubaser <134914314+ubaserb@users.noreply.github.com> Date: Sat, 17 Feb 2024 21:50:39 +0100 Subject: [PATCH 185/200] Clean up scars.yml and add a new chest scar (#25215) add (cherry picked from commit f72a1a0edb5f28bc9c83e5fe484b77cce0b7d8a0) --- Resources/Locale/en-US/markings/scars.ftl | 3 ++ .../Mobs/Customization/Markings/scars.yml | 26 ++++++++++-------- .../Mobs/Customization/scars.rsi/meta.json | 4 +++ .../Customization/scars.rsi/scar_chest.png | Bin 0 -> 1410 bytes 4 files changed, 21 insertions(+), 12 deletions(-) create mode 100644 Resources/Textures/Mobs/Customization/scars.rsi/scar_chest.png diff --git a/Resources/Locale/en-US/markings/scars.ftl b/Resources/Locale/en-US/markings/scars.ftl index 57047731d1a..fae2ffe8873 100644 --- a/Resources/Locale/en-US/markings/scars.ftl +++ b/Resources/Locale/en-US/markings/scars.ftl @@ -9,3 +9,6 @@ marking-ScarTopSurgeryShort = Top Surgery Scar (Short) marking-ScarTopSurgeryLong-scar_top_surgery_long = Top Surgery Scar marking-ScarTopSurgeryLong = Top Surgery Scar (Long) + +marking-ScarChest-scar_chest = Chest Scar +marking-ScarChest = Chest Scar diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/scars.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/scars.yml index cca16443e2c..f4186295900 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/scars.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/scars.yml @@ -3,11 +3,7 @@ bodyPart: Head markingCategory: Head speciesRestriction: [Human, Dwarf, Felinid, Harpy, Oni] # Delta V - Felinid, Oni, Harpy - coloring: - default: - type: - !type:TattooColoring - fallbackColor: "#FFFFFF" + followSkinColor: true sprites: - sprite: Mobs/Customization/scars.rsi state: scar_eye_right @@ -17,11 +13,7 @@ bodyPart: Head markingCategory: Head speciesRestriction: [Human, Dwarf, Felinid, Harpy, Oni] # Delta V - Felinid, Oni, Harpy - coloring: - default: - type: - !type:TattooColoring - fallbackColor: "#FFFFFF" + followSkinColor: true sprites: - sprite: Mobs/Customization/scars.rsi state: scar_eye_left @@ -30,7 +22,7 @@ id: ScarTopSurgeryShort bodyPart: Chest markingCategory: Chest - speciesRestriction: [Human] + speciesRestriction: [Human, Dwarf] sexRestriction: [Male] followSkinColor: true sprites: @@ -41,9 +33,19 @@ id: ScarTopSurgeryLong bodyPart: Chest markingCategory: Chest - speciesRestriction: [Human] + speciesRestriction: [Human, Dwarf] sexRestriction: [Male] followSkinColor: true sprites: - sprite: Mobs/Customization/scars.rsi state: scar_top_surgery_long + +- type: marking + id: ScarChest + bodyPart: Chest + markingCategory: Chest + speciesRestriction: [Human, Dwarf] + followSkinColor: true + sprites: + - sprite: Mobs/Customization/scars.rsi + state: scar_chest diff --git a/Resources/Textures/Mobs/Customization/scars.rsi/meta.json b/Resources/Textures/Mobs/Customization/scars.rsi/meta.json index c3bfd498d69..0a323f7f65d 100644 --- a/Resources/Textures/Mobs/Customization/scars.rsi/meta.json +++ b/Resources/Textures/Mobs/Customization/scars.rsi/meta.json @@ -22,6 +22,10 @@ { "name": "scar_top_surgery_long", "directions": 4 + }, + { + "name": "scar_chest", + "directions": 4 } ] } diff --git a/Resources/Textures/Mobs/Customization/scars.rsi/scar_chest.png b/Resources/Textures/Mobs/Customization/scars.rsi/scar_chest.png new file mode 100644 index 0000000000000000000000000000000000000000..9a1cc56c5eaaefd41a959e81287b35d6c1f8ebe4 GIT binary patch literal 1410 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|_);T0(|mmy zw18|5AO?X;!IOa`XMsm#F;KxA5N2eb5`33|fjK8LB%&n3*T*V3KUXg?B|j-uuOhbq ztjngt3dqb&ElE_U$j!+swyLmI0;{kBvO&W7N(x{lCE2!05xxNm&iO^D3TAo+dIm~% zTnY*bHbp6ERzWUqQ0+jTtx`rwNr9EVetCJhUb(Seeo?xG?W zUP)qwZeFo6#1NP{E~&-IMVSR9nfZANAafIw@=Hr>m6Sjh!2!gbDamkq3QCJ|z_z3$ z>!;?V=BDPA6zd!68R}!xSCW~AaA96CG&q0(qYsh+YBRv9&9k5+*#sC;t`$J{K>Y`F zXfoK|;*u17BnA3L1_l&2TID3>rQ0f1=%%EmC6?xtDA{@Xy2l%uT3XuZLsX&ahKQmXYNL{p zmyJF=C)sg{E@QCayJOdMOgS5JQx87CEVT&?u8^1_I&x6i*@e*BcgW6vVsz`zJ18uPfm zBrW-CA{RaPdEwSBqvhwG#|IzT`H8t@OMIGf_1*WWkIm z`d61Z947s@kh^=Q{qDJ~$>#6els_BH|E|(@ITaB$H`z zs&%3NpL{pT-1%zJB=)aNTLdq+UM~+=w^r}ST8%Y=HEeIT-!@vbr(4ti--a!(`nlLH zFt5Ln^UD3VzHPL9jgk|aE#urfUprp-v@$SpC^TRr9K4xM+NJFXu?w1g#b|EG>LR_% ze{cD4Z~1p%4)@kNx%AuXyIZe*`g8M~sBDv0vgqg7C)3{iS*Wq-$SFRDN&DyfoZ9TI zeZ^O06LUrU`qMS}Y|R?%ab*nG>gvUo2>6!Szuq|4^6ln(s$%`fme+?p;I_Em!PqUO R@eNe|dAj Date: Sat, 17 Feb 2024 20:51:45 +0000 Subject: [PATCH 186/200] Automatic changelog update (cherry picked from commit cb32a8470f7e4c1cc0cdfe487a1fb6b73af006fe) --- Resources/Changelog/Changelog.yml | 43 ++++++++++++++++--------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index c416884aa9f..e6c389d8cd0 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,25 +1,4 @@ Entries: -- author: Alekshhh - changes: - - message: Changed brown fedora and inspector's coat palette and minor adjustments - type: Tweak - id: 5458 - time: '2023-12-27T22:53:10.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/23065 -- author: Velcroboy - changes: - - message: Added melee dmg to salami logs! - type: Add - id: 5459 - time: '2023-12-28T02:59:14.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/23041 -- author: Emisse - changes: - - message: Ion Storm is silent now - type: Tweak - id: 5460 - time: '2023-12-28T03:03:00.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/23045 - author: Alekshhh changes: - message: Changed wall lockers visually to match regular lockers and sit on walls @@ -3868,3 +3847,25 @@ id: 5957 time: '2024-02-17T20:32:21.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25327 +- author: Moomoobeef + changes: + - message: Detectives are now supplied with a box of evidence markers, useful for + marking evidence at a crime scene. + type: Add + id: 5958 + time: '2024-02-17T20:49:16.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25255 +- author: Ubaser + changes: + - message: New "tailed" hair. + type: Add + id: 5959 + time: '2024-02-17T20:49:48.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25216 +- author: Ubaser + changes: + - message: A new chest scar marking is now available to humans and dwarves. + type: Add + id: 5960 + time: '2024-02-17T20:50:40.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25215 From 5da6086a0283b774d4d447327b277b294eb84ca8 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Sat, 17 Feb 2024 21:52:11 +0100 Subject: [PATCH 187/200] Add new "OptionsVisualizer" (#25128) This is a visualizer somewhat similar to the Generic. It allows configuring appearance info based on specific CVars the user has set. This allows YAML to easily configure alternatives for accessibility CVars like reduced motion. (cherry picked from commit 1ce21553152199e3d97a8d02c11922fb8db5fd52) --- .../Options/OptionsVisualizerComponent.cs | 84 +++++++++++++++ .../Options/OptionsVisualizerSystem.cs | 97 ++++++++++++++++++ Content.Server/Entry/IgnoredComponents.cs | 1 + Content.Shared/CCVar/CCVars.cs | 10 ++ .../Entities/Debugging/options_visualizer.yml | 24 +++++ .../optionsvisualizertest.rsi/both.png | Bin 0 -> 316 bytes .../optionsvisualizertest.rsi/meta.json | 1 + .../optionsvisualizertest.rsi/motion.png | Bin 0 -> 336 bytes .../optionsvisualizertest.rsi/none.png | Bin 0 -> 251 bytes .../optionsvisualizertest.rsi/test.png | Bin 0 -> 317 bytes 10 files changed, 217 insertions(+) create mode 100644 Content.Client/Options/OptionsVisualizerComponent.cs create mode 100644 Content.Client/Options/OptionsVisualizerSystem.cs create mode 100644 Resources/Prototypes/Entities/Debugging/options_visualizer.yml create mode 100644 Resources/Textures/Effects/optionsvisualizertest.rsi/both.png create mode 100644 Resources/Textures/Effects/optionsvisualizertest.rsi/meta.json create mode 100644 Resources/Textures/Effects/optionsvisualizertest.rsi/motion.png create mode 100644 Resources/Textures/Effects/optionsvisualizertest.rsi/none.png create mode 100644 Resources/Textures/Effects/optionsvisualizertest.rsi/test.png diff --git a/Content.Client/Options/OptionsVisualizerComponent.cs b/Content.Client/Options/OptionsVisualizerComponent.cs new file mode 100644 index 00000000000..87999f381c1 --- /dev/null +++ b/Content.Client/Options/OptionsVisualizerComponent.cs @@ -0,0 +1,84 @@ +using Content.Shared.CCVar; + +namespace Content.Client.Options; + +/// +/// Allows specifying sprite alternatives depending on the client's accessibility options. +/// +/// +/// A list of layer mappings is given that the component applies to, +/// and it will pick one entry to apply based on the settings configuration. Example: +/// +/// +/// - type: Sprite +/// sprite: Effects/optionsvisualizertest.rsi +/// layers: +/// - state: none +/// map: [ "layer" ] +/// - type: OptionsVisualizer +/// visuals: +/// layer: +/// - options: Default +/// data: { state: none } +/// - options: Test +/// data: { state: test } +/// - options: ReducedMotion +/// data: { state: motion } +/// - options: [Test, ReducedMotion] +/// data: { state: both } +/// +/// +/// +/// +[RegisterComponent] +public sealed partial class OptionsVisualizerComponent : Component +{ + /// + /// A mapping storing data about which sprite layer keys should be controlled. + /// + /// + /// Each layer stores an array of possible options. The last entry with a + /// matching the active user preferences will be picked. + /// This allows choosing a priority if multiple entries are matched. + /// + [DataField(required: true)] + public Dictionary Visuals = default!; + + /// + /// A single option for a layer to be selected. + /// + [DataDefinition] + public sealed partial class LayerDatum + { + /// + /// Which options must be set by the user to make this datum match. + /// + [DataField] + public OptionVisualizerOptions Options { get; set; } + + /// + /// The sprite layer data to set on the sprite when this datum matches. + /// + [DataField] + public PrototypeLayerData Data { get; set; } + } +} + +[Flags] +public enum OptionVisualizerOptions +{ + /// + /// Corresponds to no special options being set, can be used as a "default" state. + /// + Default = 0, + + /// + /// Corresponds to the CVar being set. + /// + Test = 1 << 0, + + /// + /// Corresponds to the CVar being set. + /// + ReducedMotion = 1 << 1, +} diff --git a/Content.Client/Options/OptionsVisualizerSystem.cs b/Content.Client/Options/OptionsVisualizerSystem.cs new file mode 100644 index 00000000000..2a297e3802a --- /dev/null +++ b/Content.Client/Options/OptionsVisualizerSystem.cs @@ -0,0 +1,97 @@ +using Content.Shared.CCVar; +using Robust.Client.GameObjects; +using Robust.Shared.Configuration; +using Robust.Shared.Reflection; + +namespace Content.Client.Options; + +/// +/// Implements . +/// +public sealed class OptionsVisualizerSystem : EntitySystem +{ + private static readonly (OptionVisualizerOptions, CVarDef)[] OptionVars = + { + (OptionVisualizerOptions.Test, CCVars.DebugOptionVisualizerTest), + (OptionVisualizerOptions.ReducedMotion, CCVars.ReducedMotion), + }; + + [Dependency] private readonly IConfigurationManager _cfg = default!; + [Dependency] private readonly IReflectionManager _reflection = default!; + + private OptionVisualizerOptions _currentOptions; + + public override void Initialize() + { + base.Initialize(); + + foreach (var (_, cvar) in OptionVars) + { + Subs.CVar(_cfg, cvar, _ => CVarChanged()); + } + + UpdateActiveOptions(); + + SubscribeLocalEvent(OnComponentStartup); + } + + private void CVarChanged() + { + UpdateActiveOptions(); + UpdateAllComponents(); + } + + private void UpdateActiveOptions() + { + _currentOptions = OptionVisualizerOptions.Default; + + foreach (var (value, cVar) in OptionVars) + { + if (_cfg.GetCVar(cVar)) + _currentOptions |= value; + } + } + + private void UpdateAllComponents() + { + var query = EntityQueryEnumerator(); + while (query.MoveNext(out _, out var component, out var sprite)) + { + UpdateComponent(component, sprite); + } + } + + private void OnComponentStartup(EntityUid uid, OptionsVisualizerComponent component, ComponentStartup args) + { + if (!TryComp(uid, out SpriteComponent? sprite)) + return; + + UpdateComponent(component, sprite); + } + + private void UpdateComponent(OptionsVisualizerComponent component, SpriteComponent sprite) + { + foreach (var (layerKeyRaw, layerData) in component.Visuals) + { + object layerKey = _reflection.TryParseEnumReference(layerKeyRaw, out var @enum) + ? @enum + : layerKeyRaw; + + OptionsVisualizerComponent.LayerDatum? matchedDatum = null; + foreach (var datum in layerData) + { + if ((datum.Options & _currentOptions) != datum.Options) + continue; + + matchedDatum = datum; + } + + if (matchedDatum == null) + continue; + + var layerIndex = sprite.LayerMapReserveBlank(layerKey); + sprite.LayerSetData(layerIndex, matchedDatum.Data); + } + } +} + diff --git a/Content.Server/Entry/IgnoredComponents.cs b/Content.Server/Entry/IgnoredComponents.cs index c1b646ec4f9..fe073da7a49 100644 --- a/Content.Server/Entry/IgnoredComponents.cs +++ b/Content.Server/Entry/IgnoredComponents.cs @@ -19,6 +19,7 @@ public static class IgnoredComponents "InventorySlots", "LightFade", "HolidayRsiSwap", + "OptionsVisualizer", }; } } diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 2bf612c7ed3..32e3ae6e1d4 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -2012,6 +2012,16 @@ public static readonly CVarDef public static readonly CVarDef GatewayGeneratorEnabled = CVarDef.Create("gateway.generator_enabled", true); + /* + * DEBUG + */ + + /// + /// A simple toggle to test OptionsVisualizerComponent. + /// + public static readonly CVarDef DebugOptionVisualizerTest = + CVarDef.Create("debug.option_visualizer_test", false, CVar.CLIENTONLY); + /// DELTA-V CCVARS /* * Glimmer diff --git a/Resources/Prototypes/Entities/Debugging/options_visualizer.yml b/Resources/Prototypes/Entities/Debugging/options_visualizer.yml new file mode 100644 index 00000000000..229ffa00ccb --- /dev/null +++ b/Resources/Prototypes/Entities/Debugging/options_visualizer.yml @@ -0,0 +1,24 @@ +- type: entity + id: OptionsVisualizerTest + suffix: DEBUG + components: + - type: Tag + tags: + - Debug + - type: Sprite + sprite: Effects/optionsvisualizertest.rsi + layers: + - state: none + map: [ "layer" ] + - type: OptionsVisualizer + visuals: + layer: + - options: Default + data: { state: none } + - options: Test + data: { state: test } + - options: ReducedMotion + data: { state: motion } + - options: [Test, ReducedMotion] + data: { state: both } + diff --git a/Resources/Textures/Effects/optionsvisualizertest.rsi/both.png b/Resources/Textures/Effects/optionsvisualizertest.rsi/both.png new file mode 100644 index 0000000000000000000000000000000000000000..76237f5076fffb9e3de2965a2285eaa0b0b9862b GIT binary patch literal 316 zcmV-C0mJ@@P)Px#_DMuRR9J=WR_zLaFbGuX{U2HTWti!{+K6BWQCYj)P8~xL5%>`F<>Xrc0Kj2i zqH;jQG(H122b44-N5tZH5ebEM33!VUSMV2YIBM^Z0L`_v6A^)k9x=T{5X1-#~eBCu>ooaRMh=N3PktqDL7iY(5-2WTS6$QNmmaqhM$)Yx{T7XVD%bOQcnl$Q;W&yL%BH&g7E3|0JGVY=S*2>4gq|I7ZZBgukZ0C!F zj-n_aBJMdeycUolJ1;Cf57hd2 O0000F@hKX literal 0 HcmV?d00001 diff --git a/Resources/Textures/Effects/optionsvisualizertest.rsi/meta.json b/Resources/Textures/Effects/optionsvisualizertest.rsi/meta.json new file mode 100644 index 00000000000..e7f749513dc --- /dev/null +++ b/Resources/Textures/Effects/optionsvisualizertest.rsi/meta.json @@ -0,0 +1 @@ +{"version":1,"size":{"x":32,"y":32},"license":"CC-BY-SA-4.0","copyright":"Discord pjb","states":[{"name":"none"},{"name":"both"},{"name":"motion"},{"name":"test"}]} diff --git a/Resources/Textures/Effects/optionsvisualizertest.rsi/motion.png b/Resources/Textures/Effects/optionsvisualizertest.rsi/motion.png new file mode 100644 index 0000000000000000000000000000000000000000..edbbd52636503deb3774b71419aa34dd44acc367 GIT binary patch literal 336 zcmV-W0k8gvP)Px$3Q0skR9J=WmeCHwAP7Z;^#4DZyC*tI0jo3XlJzEgP*yz1)s_ID-6+0u@du!_ z);2qc>_9~6{0bd*K$AwviKvVN2tkJcKGn>w(9a#iXe(#8cM9O!3IUjTuNc6=d^)eD zw0*a8K9*_A0?gb*WKY8UX0;#+C?b2Sv;g0_2qe_oiUE5@ z&0;42PpXyo`kBRhV5tYJ`E;xcWw8;k5+E~^{crAxSH5rSfff$!Kf-dyWqQI4~(%#`8UzJNP_0`J)~9}-SXKFiI((DzL_ihWXMoqLJ! zhed&flP(tPx#_en%SR9J=WmO&20AP7aJ>HUxFpA`)vsOXrciGS6>4m?1t1OVwpU2g_I04b$( z%OBQuAR^cP4;2+)r6CZZxJ0Q0{+RRHXqoyx3qE4V5WDyq;J$}IU=LwcEe zb`wBnSiOjQ|ua*ui3*D^kr0a0acfq1BGaG&H9`kDxw$ zWYAeP0W8OnJHs-7C-1(n^*+%1B1U`9GLK@GcIaik0`ZLt$pJV32Vkdu2Jp)efnPl^ P00000NkvXXu0mjfSu%kU literal 0 HcmV?d00001 From e7a5ca84cb3aed4f856f1a2a158c4bbf7e4fea92 Mon Sep 17 00:00:00 2001 From: Peptide90 <78795277+Peptide90@users.noreply.github.com> Date: Sat, 17 Feb 2024 20:55:01 +0000 Subject: [PATCH 188/200] Suffix spelling mistake on seed vendor (#25352) spelling error (cherry picked from commit d4c68a9ab9df3dda9ad3b2b355074bacffbc223d) --- .../Entities/Structures/Machines/vending_machines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml b/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml index d1c6079a5bf..ee40012bbeb 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml @@ -888,7 +888,7 @@ - type: entity parent: VendingMachineSeedsUnlocked id: VendingMachineSeeds - suffix: Hyroponics + suffix: Hydroponics components: - type: AccessReader access: [["Hydroponics"]] From 094a94d62b81eda106b97d31eb7310770eb32b5f Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Sat, 17 Feb 2024 22:26:27 +0100 Subject: [PATCH 189/200] Update engine to v210.1.1 (#25354) Important fixes from the UI PR (cherry picked from commit e4930078aba424288c36e258390c8b24892d904c) --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index f8cb1729a3e..ef0bc1a2e48 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit f8cb1729a3e0f790fe1b72f060fed0b27b1eefc2 +Subproject commit ef0bc1a2e4878eedc24dd6fedc0631be56aca072 From 783284ab0f68aeaead518a86f196fd229eb3544b Mon Sep 17 00:00:00 2001 From: ArchPigeon Date: Sat, 17 Feb 2024 16:33:10 -0500 Subject: [PATCH 190/200] Stop wagging tails on crit (#25323) * Add Flammable Touch Reaction for liquid tritium * Stop tail wagging action on crit * Revert "Add Flammable Touch Reaction for liquid tritium" This reverts commit 41be57b058a0cdee0cecfc51eb1c4a25631e62f3. (cherry picked from commit e8eddf57f64daca19054f0e3dfbe73dd6af8c342) --- Content.Server/Wagging/WaggingSystem.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/Content.Server/Wagging/WaggingSystem.cs b/Content.Server/Wagging/WaggingSystem.cs index 7e9ffbbc8f4..7ccc19e20c6 100644 --- a/Content.Server/Wagging/WaggingSystem.cs +++ b/Content.Server/Wagging/WaggingSystem.cs @@ -48,9 +48,6 @@ private void OnWaggingToggle(EntityUid uid, WaggingComponent component, ref Togg private void OnMobStateChanged(EntityUid uid, WaggingComponent component, MobStateChangedEvent args) { - if (args.NewMobState != MobState.Dead) - return; - if (component.Wagging) TryToggleWagging(uid, wagging: component); } From 4c09d15fc5e181b204b956a5a00f5cd7f5be26dd Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 17 Feb 2024 21:34:15 +0000 Subject: [PATCH 191/200] Automatic changelog update (cherry picked from commit fa09f7aaa1f21fe9e8f3a9dfd66dab5f189bdc6c) --- 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 e6c389d8cd0..831cdda18f1 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Alekshhh - changes: - - message: Changed wall lockers visually to match regular lockers and sit on walls - better - type: Tweak - id: 5461 - time: '2023-12-28T03:05:05.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/23060 - author: EmoGarbage404 changes: - message: Added the clerical error station event, which causes a small amount of @@ -3869,3 +3861,10 @@ id: 5960 time: '2024-02-17T20:50:40.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25215 +- author: ArchPigeon + changes: + - message: Tails now stop wagging on crit + type: Fix + id: 5961 + time: '2024-02-17T21:33:10.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25323 From 2cc5b2b3ef094626ee355a6383f859c0876e9e4e Mon Sep 17 00:00:00 2001 From: Killerqu00 <47712032+Killerqu00@users.noreply.github.com> Date: Sat, 17 Feb 2024 23:34:38 +0100 Subject: [PATCH 192/200] EVA suit helmets now have (un)equip sounds (#25349) add (un)equip sounds to EVA helms (cherry picked from commit aadf7492f44d9cdf654898e64dc4f73c13927815) --- .../Prototypes/Entities/Clothing/Head/base_clothinghead.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml index 813888fb6b4..e34208e9ca1 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml @@ -128,6 +128,12 @@ - type: TemperatureProtection coefficient: 0.2 - type: IngestionBlocker + - type: Clothing + #Copies ClothingHeadHardsuitBase behavior + equipSound: /Audio/Mecha/mechmove03.ogg + unequipSound: /Audio/Mecha/mechmove03.ogg + quickEquip: false + slots: [ HEAD ] - type: Tag tags: - HidesHair From 16a2283e45874c17203ea79169c4225fb1f8e4cd Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 17 Feb 2024 22:35:44 +0000 Subject: [PATCH 193/200] Automatic changelog update (cherry picked from commit a361e6aee55b083fd22b600d408b7123c54ea2b5) --- 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 831cdda18f1..67225918922 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: EmoGarbage404 - changes: - - message: Added the clerical error station event, which causes a small amount of - station records to be destroyed. - type: Add - id: 5462 - time: '2023-12-28T03:09:05.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/23091 - author: EmoGarbage404 changes: - message: Added the GORILLA gauntlet. When powered with an anomaly core, a single @@ -3868,3 +3860,10 @@ id: 5961 time: '2024-02-17T21:33:10.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25323 +- author: Killerqu00 + changes: + - message: EVA and paramedic suits now play sound when putting helmet on. + type: Fix + id: 5962 + time: '2024-02-17T22:34:39.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25349 From 5eac70cd7faa384c866778d8df11c5d0a1dcf801 Mon Sep 17 00:00:00 2001 From: Firewatch <54725557+musicmanvr@users.noreply.github.com> Date: Sat, 17 Feb 2024 18:55:58 -0500 Subject: [PATCH 194/200] Newton Cradle Fix + Addition to Bureaucracy Crate (#25357) fixes makes the newton cradle not able to decimate ears while also adding it to the bureaucracy crate and lowering its volume and range a little bit (cherry picked from commit 110437cc7f9b912093ec53560df6026c7873de51) --- Resources/Audio/Items/newton_cradle.ogg | Bin 10019 -> 11276 bytes .../Catalog/Fills/Crates/service.yml | 3 ++- .../Prototypes/Entities/Objects/Fun/toys.yml | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Resources/Audio/Items/newton_cradle.ogg b/Resources/Audio/Items/newton_cradle.ogg index 6dfe528feb56f22afa59ad09dd953901f266a6e4..875841ee848987260aecf618cfef6f4d0921ff4c 100644 GIT binary patch literal 11276 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 literal 10019 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 Date: Sat, 17 Feb 2024 23:57:04 +0000 Subject: [PATCH 195/200] Automatic changelog update (cherry picked from commit 8ea30cae34a5f3fabf8c27ef49e464be28919a92) --- 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 67225918922..3e82a672e9e 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,16 +1,4 @@ Entries: -- author: EmoGarbage404 - changes: - - message: Added the GORILLA gauntlet. When powered with an anomaly core, a single - blow from this is able to send anomalies flying through the air. Just try not - to let it out on the clown. - type: Add - - message: Added Anomaly Core Harnessing technology to the Experimental discipline, - which contains the GORILLA gauntlet. - type: Add - id: 5463 - time: '2023-12-28T03:11:13.0000000+00:00' - url: https://api.github.com/repos/space-wizards/space-station-14/pulls/23012 - author: Ubaser changes: - message: You can now purchase kobolds from cargo as an alternative to monkeys! @@ -3867,3 +3855,11 @@ id: 5962 time: '2024-02-17T22:34:39.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/25349 +- author: musicmanvr + changes: + - message: Toned down the newton cradle and added it to the bureaucracy crate for + bored accountants. + type: Fix + id: 5963 + time: '2024-02-17T23:55:58.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/25357 From 074fea218e70ebeb820bdb3dde1433211e090cc0 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Sun, 18 Feb 2024 04:26:19 +0100 Subject: [PATCH 196/200] Shadow anomaly respects "reduced motion" (#25355) Enabling "reduced motion" now makes the smoke effects not animate. This helps some people with vision issues. (cherry picked from commit 0c8e61757278715cb7a065c6cf8bf5d8ac24142f) --- .../Prototypes/Entities/Objects/Misc/kudzu.yml | 15 ++++++++++++--- .../Textures/Effects/spookysmoke.rsi/meta.json | 5 ++++- .../spookysmoke.rsi/spookysmoke_static.png | Bin 0 -> 9787 bytes 3 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 Resources/Textures/Effects/spookysmoke.rsi/spookysmoke_static.png diff --git a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml index 9727f2125d0..6ebf0951174 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml @@ -271,8 +271,10 @@ - type: Sprite drawdepth: Effects sprite: Effects/spookysmoke.rsi - state: spookysmoke - color: "#793a80dd" + layers: + - state: spookysmoke + color: "#793a80dd" + map: [base] - type: Kudzu growthTickChance: 0.2 spreadChance: 0.99 @@ -290,6 +292,13 @@ tags: - HideContextMenu - SpookyFog + - type: OptionsVisualizer + visuals: + base: + - options: Default + data: { state: spookysmoke } + - options: ReducedMotion + data: { state: spookysmoke_static } - type: entity name: Haze @@ -297,4 +306,4 @@ parent: ShadowKudzu components: - type: Kudzu - spreadChance: 0 #appears during pulsation. It shouldnt spreading. \ No newline at end of file + spreadChance: 0 #appears during pulsation. It shouldnt spreading. diff --git a/Resources/Textures/Effects/spookysmoke.rsi/meta.json b/Resources/Textures/Effects/spookysmoke.rsi/meta.json index c6655bdba21..13da3020fce 100644 --- a/Resources/Textures/Effects/spookysmoke.rsi/meta.json +++ b/Resources/Textures/Effects/spookysmoke.rsi/meta.json @@ -25,6 +25,9 @@ 0.2 ] ] + }, + { + "name": "spookysmoke_static" } ] -} \ No newline at end of file +} diff --git a/Resources/Textures/Effects/spookysmoke.rsi/spookysmoke_static.png b/Resources/Textures/Effects/spookysmoke.rsi/spookysmoke_static.png new file mode 100644 index 0000000000000000000000000000000000000000..a817fe76e297dd9d0754d6e91edf6639d1aa7221 GIT binary patch literal 9787 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 Date: Sun, 18 Feb 2024 16:06:09 +0200 Subject: [PATCH 197/200] Fixed directional window durability (#25259) shit (cherry picked from commit 8542c718c0ad6b0c77f35e3df47fa8d47f3340f0) --- .../Entities/Structures/Windows/reinforced.yml | 13 +++++++++++-- .../Entities/Structures/Windows/window.yml | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml b/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml index 26d9da0745b..18da78f1b5b 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml @@ -18,7 +18,7 @@ thresholds: - trigger: !type:DamageTrigger - damage: 150 + damage: 150 #excess damage (nuke?). avoid computational cost of spawning entities. behaviors: - !type:DoActsBehavior acts: [ "Destruction" ] @@ -103,7 +103,16 @@ thresholds: - trigger: !type:DamageTrigger - damage: 150 + damage: 150 #excess damage (nuke?). avoid computational cost of spawning entities. + behaviors: + - !type:PlaySoundBehavior + sound: + collection: WindowShatter + - !type:DoActsBehavior + acts: [ "Destruction" ] + - trigger: + !type:DamageTrigger + damage: 50 behaviors: - !type:PlaySoundBehavior sound: diff --git a/Resources/Prototypes/Entities/Structures/Windows/window.yml b/Resources/Prototypes/Entities/Structures/Windows/window.yml index 3ae2707f461..faae8b004b7 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/window.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/window.yml @@ -46,7 +46,7 @@ thresholds: - trigger: !type:DamageTrigger - damage: 100 + damage: 150 #excess damage (nuke?). avoid computational cost of spawning entities. behaviors: - !type:PlaySoundBehavior sound: @@ -152,7 +152,7 @@ collection: WindowShatter - trigger: !type:DamageTrigger - damage: 50 + damage: 25 behaviors: - !type:PlaySoundBehavior sound: From 61083c268e925d46af72df9cbedc6dc68290848f Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Sun, 18 Feb 2024 17:52:44 +0100 Subject: [PATCH 198/200] Very little cleanup (#25364) (cherry picked from commit 0dd381ae37a1ae40e23c98d7310388b425bbe2a6) --- .../Objects/Specific/Security/evidence-marker.yml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Specific/Security/evidence-marker.yml b/Resources/Prototypes/Entities/Objects/Specific/Security/evidence-marker.yml index 35b99573d09..0773813461c 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Security/evidence-marker.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Security/evidence-marker.yml @@ -10,11 +10,10 @@ - type: Item sprite: Objects/Specific/Detective/evidence_marker.rsi size: Tiny - + - type: entity parent: EvidenceMarker id: EvidenceMarkerOne - name: evidence marker components: - type: Sprite state: one @@ -22,7 +21,6 @@ - type: entity parent: EvidenceMarker id: EvidenceMarkerTwo - name: evidence marker components: - type: Sprite state: two @@ -30,7 +28,6 @@ - type: entity parent: EvidenceMarker id: EvidenceMarkerThree - name: evidence marker components: - type: Sprite state: three @@ -38,7 +35,6 @@ - type: entity parent: EvidenceMarker id: EvidenceMarkerFour - name: evidence marker components: - type: Sprite state: four @@ -46,7 +42,6 @@ - type: entity parent: EvidenceMarker id: EvidenceMarkerFive - name: evidence marker components: - type: Sprite state: five @@ -54,7 +49,6 @@ - type: entity parent: EvidenceMarker id: EvidenceMarkerSix - name: evidence marker components: - type: Sprite state: six @@ -62,7 +56,6 @@ - type: entity parent: EvidenceMarker id: EvidenceMarkerSeven - name: evidence marker components: - type: Sprite state: seven @@ -70,7 +63,6 @@ - type: entity parent: EvidenceMarker id: EvidenceMarkerEight - name: evidence marker components: - type: Sprite state: eight @@ -78,7 +70,6 @@ - type: entity parent: EvidenceMarker id: EvidenceMarkerNine - name: evidence marker components: - type: Sprite state: nine @@ -107,4 +98,3 @@ layers: - state: box_security - state: evidence_markers - \ No newline at end of file From 89383ab646d6c6a00c4cd8e08964e0036c23901a Mon Sep 17 00:00:00 2001 From: Debug <49997488+DebugOk@users.noreply.github.com> Date: Sun, 18 Feb 2024 23:53:52 +0100 Subject: [PATCH 199/200] Fix felinid sprite shit --- .../Prototypes/DeltaV/typing_indicator.yml | 6 ++++ .../Entities/Mobs/Species/felinid.yml | 2 ++ .../DeltaV/Effects/speech.rsi/felinid0.png | Bin 0 -> 899 bytes .../DeltaV/Effects/speech.rsi/felinid1.png | Bin 0 -> 721 bytes .../DeltaV/Effects/speech.rsi/felinid2.png | Bin 0 -> 712 bytes .../DeltaV/Effects/speech.rsi/meta.json | 28 ++++++++++++++++++ 6 files changed, 36 insertions(+) create mode 100644 Resources/Prototypes/DeltaV/typing_indicator.yml create mode 100644 Resources/Textures/DeltaV/Effects/speech.rsi/felinid0.png create mode 100644 Resources/Textures/DeltaV/Effects/speech.rsi/felinid1.png create mode 100644 Resources/Textures/DeltaV/Effects/speech.rsi/felinid2.png create mode 100644 Resources/Textures/DeltaV/Effects/speech.rsi/meta.json diff --git a/Resources/Prototypes/DeltaV/typing_indicator.yml b/Resources/Prototypes/DeltaV/typing_indicator.yml new file mode 100644 index 00000000000..7cfca9cc95f --- /dev/null +++ b/Resources/Prototypes/DeltaV/typing_indicator.yml @@ -0,0 +1,6 @@ +- type: typingIndicator + id: felinid + spritePath: /Textures/DeltaV/Effects/speech.rsi + typingState: felinid0 + offset: 0, 0.2 # 0625 + diff --git a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/felinid.yml b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/felinid.yml index 406a2c698bf..d9b25c5dd1b 100644 --- a/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/felinid.yml +++ b/Resources/Prototypes/Nyanotrasen/Entities/Mobs/Species/felinid.yml @@ -48,6 +48,8 @@ Blunt: 1 - type: Stamina critThreshold: 85 + - type: TypingIndicator + proto: felinid - type: PseudoItem storedOffset: 0,17 shape: diff --git a/Resources/Textures/DeltaV/Effects/speech.rsi/felinid0.png b/Resources/Textures/DeltaV/Effects/speech.rsi/felinid0.png new file mode 100644 index 0000000000000000000000000000000000000000..586d1e6a343b2f9ed7f295291819c9f9905d7dc6 GIT binary patch literal 899 zcmV-}1AP36P)l(9dr-<1J{FO{Ay^ONFincozR8K8i!|56}a;_!ZCmgf#1*0;L`jS@Do}H1} zCA%AsBnjeZq$#jM9-jfJwq*9VZ}7)A&8m0|c{>zw#gQc^-hNRF($$oj5#5w0Pf_Lm zJ5Mh&JXG%98i&TmAb9P8@HTvvg5dKo2)>S>{sGSIs()2-8hsbNRMlep5Z!>&i>j91 zfwN8Mymxe0|B>othcX#>If1r$XupQYVmYhIImdU9T9;pR1-pCDEBB*I-_bc|^xxnq zzyJUM32;bRa{vGf5&!@T5&_cPe*6Fc0lY~>K~#8N?V7(!12Gteds5KNy_5JCh>MGx z|F45?Lig$-xC-JZZcc&<*EcnhnETOdxvwASb8y^|qbv=YZxT50R^W zKHr{XEbR69XsmVwP0R2{#xfXcrG@Bzn>ov(qw|^cus$`>)kNr2b52%I2!o@F+&*#1MdzTpU1FTkH`h@@lAOHafKmY;|fB*y_009U<00Izz00eeU ZUzcsbCj%Xe(HCX<|QwriLU%imTw_P;d}k z{2KfRx(coef}jW@j?R89QsTK*sEFQha~|G%-^0lp@J|&C(`g(Bv*_CKSX7%!&1=n1 z_z4iCow2mxSksBgB>%4W8+@u>M^vx>@BO)2mokn4z82vT!?ImrnTDxV*HXMG+-2m` zOTzoYVOs_izEHYe<44808ow&Glko}gtDai!2kSrB$lIpyfN;nxl#K6r)RzP^#o2_^ z9@)J(#EB6_L#M;4tVY4lC>N?i->LB~3roYysd z8%{T%`_4++=`X24wm+MN=VNF~LFW|&7HV02pL28z$u;>!m$0)7{c^u!@e>~qXc(-W zx)}ff010qNS#tmY3labT3lag+-G2N4009X}L_t(oN9~g_3&JoEg&QgAP;htj7l?y8 zxcPq_bQ9cL7eR0moQty{6rsM;JE3}%5Hw2wM9D-C;V zMg&8coXMC5<`c?TUyu&S5%yBd+uod6NC?b|!eop{U>aG5qox`t=@JDd;M?;}PY9GA zp2OAqH#9KXBF1bO%R4AG02;KM^4 zBuyQgYT%P@)%Wp>-qceGC;=s)1eAahPy$Ne4+z`=g0EB#V{wto00000NkvXXu0mjf DP!vS` literal 0 HcmV?d00001 diff --git a/Resources/Textures/DeltaV/Effects/speech.rsi/felinid2.png b/Resources/Textures/DeltaV/Effects/speech.rsi/felinid2.png new file mode 100644 index 0000000000000000000000000000000000000000..abb5f04373eeaeb41d4e7946340372195b52cfb1 GIT binary patch literal 712 zcmV;(0yq7MP)zcsbCj%Xe(HCX<|QwriLU%imTw_P;d}k z{2KfRx(coef}jW@j?R89QsTK*sEFQha~|G%-^0lp@J|&C(`g(Bv*_CKSX7%!&1=n1 z_z4iCow2mxSksBgB>%4W8+@u>M^vx>@BO)2mokn4z82vT!?ImrnTDxV*HXMG+-2m` zOTzoYVOs_izEHYe<44808ow&Glko}gtDai!2kSrB$lIpyfN;nxl#K6r)RzP^#o2_^ z9@)J(#EB6_L#M;4tVY4lC>N?i->LB~3roYysd z8%{T%`_4++=`X24wm+MN=VNF~LFW|&7HV02pL28z$u;>!m$0)7{c^u!@e>~qXc(-W zx)}ff010qNS#tmY3labT3lag+-G2N40096=L_t(oN9|KF3IZ_@yvTtTg1x0L5DT@i z^S>6_3HGOrU@KUQA2>LLIEz^c3DF!R2(k+yo9t$0ZZ0W`SL`uXCJ#+p6pmkdT9-TK zgwk3MkZ%GAYt%=r(IXC&rl-L?1WB!ws@!wfr+SuP2OdE0g1iA);SSnIoy4->WMWuA z36dKTb6`E=9Q%E&uUOxcF&iKju!sbnMD|6uu>kJ?zM5V}_Fw_t#j}5br6Tz=Q~*C< zObtn8-vjGDP&zm39p+^!Ye)dc1qr?Nw;L=5ZctATW1NcE#W@9l$q^F7qRzPle8Tna u$1g+(r#K)Ehy&t)I3Ny)1LDB{I`9Oll1NI}FYCwv0000 Date: Sun, 18 Feb 2024 23:06:04 +0000 Subject: [PATCH 200/200] Automatic Changelog Update (#857) --- Resources/Changelog/DeltaVChangelog.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Resources/Changelog/DeltaVChangelog.yml b/Resources/Changelog/DeltaVChangelog.yml index 03752eaef15..7e3b668d939 100644 --- a/Resources/Changelog/DeltaVChangelog.yml +++ b/Resources/Changelog/DeltaVChangelog.yml @@ -1666,3 +1666,11 @@ Entries: message: 'Metempsychosis machines have been added to the game. ' id: 248 time: '2024-02-18T02:36:16.0000000+00:00' +- author: DebugOk + changes: + - type: Add + message: Merged upstream + - type: Fix + message: Fixed the upstream changelog not rendering + id: 249 + time: '2024-02-18T23:05:48.0000000+00:00'