From c5045883acbc3362f36fd692c96e96a5274beb0a Mon Sep 17 00:00:00 2001 From: Zachary Higgs Date: Mon, 27 Jan 2025 22:37:46 -0400 Subject: [PATCH] Fake mindshield componentry and Implanter (#34079) * Fake Mindshield (With some bad sprites) - Add FakeMindshield System and Component - Add FakeMindsheildImplantSystem and Component - modify ShowMindShieldIconsSystem to check for FakeMindshields - add all supporting yaml for the Implants, action and uplink - add loc file stuff - add unfinished sprites * Cleanup, add to thief toolbox, remove metagame - Move Implant sameness check to AFTER the implant DoAfter to prevent instant identification of Deception Implants - cleanup the systems and components - add the fake mindshield to the Thief toolbox * part 1 of fixing the folder problem * Make the fakemindshield sprite folder lowercase * CR - Move ImplantCheck into shared, cleanup - Moved ImplantCheck and eventsubscription into Shared - Remove Client/Server extensions of FakeMindshieldImplantSystem and FakeMindShieldSystem and make shared Sealed - make OnToggleMindshield Private, use the event! * CR - Cleanup extra lines, fix some Prototype - cleaned up extra liens in ImplanterSystem and SharedFakeMindshieldSystem from when i was developing - Uplink catalog no longer lists the implant in 2 spots, only implants now, also uses the On state action icon - added a comment about why it's reraising the action event rather than directly interacting with the FakeMindshield Component * Fake Mindshield CR: - Added a comment about IsEnabled - moved OnFakeMindShieldToggle to Entity<> from Uid, Comp - fixed some formatting in uplink_catalog * CR - Add a bit more comment --- .../Overlays/ShowMindShieldIconsSystem.cs | 10 +++++ Content.Server/Implants/ImplanterSystem.cs | 18 --------- .../Implants/SharedImplanterSystem.cs | 17 +++++++++ .../FakeMindShieldImplantComponent.cs | 8 ++++ .../Components/FakeMindshieldComponent.cs | 22 +++++++++++ .../SharedFakeMindShieldImplantSystem.cs | 36 ++++++++++++++++++ .../SharedFakeMindshieldSystem.cs | 21 ++++++++++ Resources/Locale/en-US/implant/implant.ftl | 3 ++ .../Locale/en-US/store/uplink-catalog.ftl | 3 ++ Resources/Prototypes/Actions/types.yml | 12 ++++++ .../Prototypes/Catalog/thief_toolbox_sets.yml | 1 + .../Prototypes/Catalog/uplink_catalog.yml | 14 +++++++ .../Entities/Objects/Misc/implanters.yml | 8 ++++ .../Objects/Misc/subdermal_implants.yml | 11 ++++++ .../actions_fakemindshield.rsi/icon-on.png | Bin 0 -> 5111 bytes .../actions_fakemindshield.rsi/icon.png | Bin 0 -> 5105 bytes .../actions_fakemindshield.rsi/meta.json | 17 +++++++++ 17 files changed, 183 insertions(+), 18 deletions(-) create mode 100644 Content.Shared/Mindshield/Components/FakeMindShieldImplantComponent.cs create mode 100644 Content.Shared/Mindshield/Components/FakeMindshieldComponent.cs create mode 100644 Content.Shared/Mindshield/FakeMindShield/SharedFakeMindShieldImplantSystem.cs create mode 100644 Content.Shared/Mindshield/FakeMindShield/SharedFakeMindshieldSystem.cs create mode 100644 Resources/Textures/Interface/Actions/actions_fakemindshield.rsi/icon-on.png create mode 100644 Resources/Textures/Interface/Actions/actions_fakemindshield.rsi/icon.png create mode 100644 Resources/Textures/Interface/Actions/actions_fakemindshield.rsi/meta.json diff --git a/Content.Client/Overlays/ShowMindShieldIconsSystem.cs b/Content.Client/Overlays/ShowMindShieldIconsSystem.cs index cdb9c54fdf..8f8b8e6407 100644 --- a/Content.Client/Overlays/ShowMindShieldIconsSystem.cs +++ b/Content.Client/Overlays/ShowMindShieldIconsSystem.cs @@ -15,6 +15,16 @@ public sealed class ShowMindShieldIconsSystem : EquipmentHudSystem(OnGetStatusIconsEvent); + SubscribeLocalEvent(OnGetStatusIconsEventFake); + } + // TODO: Probably need to get this OFF of client since this can be read by bad actors rather easily + // ...imagine cheating in a game about silly paper dolls + private void OnGetStatusIconsEventFake(EntityUid uid, FakeMindShieldComponent component, ref GetStatusIconsEvent ev) + { + if(!IsActive) + return; + if (component.IsEnabled && _prototype.TryIndex(component.MindShieldStatusIcon, out var fakeStatusIconPrototype)) + ev.StatusIcons.Add(fakeStatusIconPrototype); } private void OnGetStatusIconsEvent(EntityUid uid, MindShieldComponent component, ref GetStatusIconsEvent ev) diff --git a/Content.Server/Implants/ImplanterSystem.cs b/Content.Server/Implants/ImplanterSystem.cs index e441574213..5efd5dc6fb 100644 --- a/Content.Server/Implants/ImplanterSystem.cs +++ b/Content.Server/Implants/ImplanterSystem.cs @@ -58,17 +58,6 @@ public sealed partial class ImplanterSystem : SharedImplanterSystem return; } - // Check if we are trying to implant a implant which is already implanted - if (implant.HasValue && !component.AllowMultipleImplants && CheckSameImplant(target, implant.Value)) - { - var name = Identity.Name(target, EntityManager, args.User); - var msg = Loc.GetString("implanter-component-implant-already", ("implant", implant), ("target", name)); - _popup.PopupEntity(msg, target, args.User); - args.Handled = true; - return; - } - - //Implant self instantly, otherwise try to inject the target. if (args.User == target) Implant(target, target, uid, component); @@ -79,14 +68,7 @@ public sealed partial class ImplanterSystem : SharedImplanterSystem args.Handled = true; } - public bool CheckSameImplant(EntityUid target, EntityUid implant) - { - if (!TryComp(target, out var implanted)) - return false; - var implantPrototype = Prototype(implant); - return implanted.ImplantContainer.ContainedEntities.Any(entity => Prototype(entity) == implantPrototype); - } /// /// Attempt to implant someone else. diff --git a/Content.Shared/Implants/SharedImplanterSystem.cs b/Content.Shared/Implants/SharedImplanterSystem.cs index 44803e721c..6f394fb932 100644 --- a/Content.Shared/Implants/SharedImplanterSystem.cs +++ b/Content.Shared/Implants/SharedImplanterSystem.cs @@ -52,7 +52,14 @@ public abstract class SharedImplanterSystem : EntitySystem args.PushMarkup(Loc.GetString("implanter-contained-implant-text", ("desc", component.ImplantData.Item2))); } + public bool CheckSameImplant(EntityUid target, EntityUid implant) + { + if (!TryComp(target, out var implanted)) + return false; + var implantPrototype = Prototype(implant); + return implanted.ImplantContainer.ContainedEntities.Any(entity => Prototype(entity) == implantPrototype); + } //Instantly implant something and add all necessary components and containers. //Set to draw mode if not implant only public void Implant(EntityUid user, EntityUid target, EntityUid implanter, ImplanterComponent component) @@ -60,6 +67,16 @@ public abstract class SharedImplanterSystem : EntitySystem if (!CanImplant(user, target, implanter, component, out var implant, out var implantComp)) return; + // Check if we are trying to implant a implant which is already implanted + // Check AFTER the doafter to prevent "is it a fake?" metagaming against deceptive implants + if (!component.AllowMultipleImplants && CheckSameImplant(target, implant.Value)) + { + var name = Identity.Name(target, EntityManager, user); + var msg = Loc.GetString("implanter-component-implant-already", ("implant", implant), ("target", name)); + _popup.PopupEntity(msg, target, user); + return; + } + //If the target doesn't have the implanted component, add it. var implantedComp = EnsureComp(target); var implantContainer = implantedComp.ImplantContainer; diff --git a/Content.Shared/Mindshield/Components/FakeMindShieldImplantComponent.cs b/Content.Shared/Mindshield/Components/FakeMindShieldImplantComponent.cs new file mode 100644 index 0000000000..788de804f4 --- /dev/null +++ b/Content.Shared/Mindshield/Components/FakeMindShieldImplantComponent.cs @@ -0,0 +1,8 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Mindshield.Components; + +[RegisterComponent, NetworkedComponent] +public sealed partial class FakeMindShieldImplantComponent : Component +{ +} diff --git a/Content.Shared/Mindshield/Components/FakeMindshieldComponent.cs b/Content.Shared/Mindshield/Components/FakeMindshieldComponent.cs new file mode 100644 index 0000000000..106f43367e --- /dev/null +++ b/Content.Shared/Mindshield/Components/FakeMindshieldComponent.cs @@ -0,0 +1,22 @@ +using Content.Shared.StatusIcon; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Mindshield.Components; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class FakeMindShieldComponent : Component +{ + + /// + /// The state of the Fake mindshield, if true the owning entity will display a mindshield effect on their job icon + /// + [DataField, AutoNetworkedField] + public bool IsEnabled { get; set; } = false; + + /// + /// The Security status icon displayed to the security officer. Should be a duplicate of the one the mindshield uses since it's spoofing that + /// + [DataField, AutoNetworkedField] + public ProtoId MindShieldStatusIcon = "MindShieldIcon"; +} diff --git a/Content.Shared/Mindshield/FakeMindShield/SharedFakeMindShieldImplantSystem.cs b/Content.Shared/Mindshield/FakeMindShield/SharedFakeMindShieldImplantSystem.cs new file mode 100644 index 0000000000..8887025e3a --- /dev/null +++ b/Content.Shared/Mindshield/FakeMindShield/SharedFakeMindShieldImplantSystem.cs @@ -0,0 +1,36 @@ +using Content.Shared.Actions; +using Content.Shared.Implants; +using Content.Shared.Implants.Components; +using Content.Shared.Mindshield.Components; + +namespace Content.Shared.Mindshield.FakeMindShield; + +public sealed class SharedFakeMindShieldImplantSystem : EntitySystem +{ + [Dependency] private readonly SharedActionsSystem _actionsSystem = default!; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnFakeMindShieldToggle); + SubscribeLocalEvent(ImplantCheck); + } + /// + /// Raise the Action of a Implanted user toggling their implant to the FakeMindshieldComponent on their entity + /// + private void OnFakeMindShieldToggle(Entity entity, ref FakeMindShieldToggleEvent ev) + { + ev.Handled = true; + if (entity.Comp.ImplantedEntity is not { } ent) + return; + + if (!TryComp(ent, out var comp)) + return; + _actionsSystem.SetToggled(ev.Action, !comp.IsEnabled); // Set it to what the Mindshield component WILL be after this + RaiseLocalEvent(ent, ev); //this reraises the action event to support an eventual future Changeling Antag which will also be using this component for it's "mindshield" ability + } + private void ImplantCheck(EntityUid uid, FakeMindShieldImplantComponent component ,ref ImplantImplantedEvent ev) + { + if (ev.Implanted != null) + EnsureComp(ev.Implanted.Value); + } +} diff --git a/Content.Shared/Mindshield/FakeMindShield/SharedFakeMindshieldSystem.cs b/Content.Shared/Mindshield/FakeMindShield/SharedFakeMindshieldSystem.cs new file mode 100644 index 0000000000..0a7c974200 --- /dev/null +++ b/Content.Shared/Mindshield/FakeMindShield/SharedFakeMindshieldSystem.cs @@ -0,0 +1,21 @@ +using Content.Shared.Actions; +using Content.Shared.Mindshield.Components; + +namespace Content.Shared.Mindshield.FakeMindShield; + +public sealed class SharedFakeMindShieldSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnToggleMindshield); + } + + private void OnToggleMindshield(EntityUid uid, FakeMindShieldComponent comp, FakeMindShieldToggleEvent toggleEvent) + { + comp.IsEnabled = !comp.IsEnabled; + Dirty(uid, comp); + } +} + +public sealed partial class FakeMindShieldToggleEvent : InstantActionEvent; diff --git a/Resources/Locale/en-US/implant/implant.ftl b/Resources/Locale/en-US/implant/implant.ftl index 073757f53c..813ed3e7a9 100644 --- a/Resources/Locale/en-US/implant/implant.ftl +++ b/Resources/Locale/en-US/implant/implant.ftl @@ -17,6 +17,9 @@ implanter-label = [color=green]{$implantName}[/color] implanter-contained-implant-text = [color=green]{$desc}[/color] +action-name-toggle-fake-mindshield = [color=green]Toggle Fake Mindshield[/color] +action-description-toggle-fake-mindshield = Turn the Fake Mindshield implants transmission on/off + ## Implant Popups scramble-implant-activated-popup = Your appearance shifts and changes! diff --git a/Resources/Locale/en-US/store/uplink-catalog.ftl b/Resources/Locale/en-US/store/uplink-catalog.ftl index 82c80dab1f..655c620e30 100644 --- a/Resources/Locale/en-US/store/uplink-catalog.ftl +++ b/Resources/Locale/en-US/store/uplink-catalog.ftl @@ -451,3 +451,6 @@ uplink-combat-bakery-desc = A kit of clandestine baked weapons. Contains a bague uplink-business-card-name = Syndicate Business Card uplink-business-card-desc = A business card that you can give to someone to demonstrate your involvement in the syndicate or leave at the crime scene in order to make fun of the detective. You can buy no more than three of them. + +uplink-fake-mindshield-name = Fake Mindshield +uplink-fake-mindshield-desc = A togglable implant capable of mimicking the same transmissions a real mindshield puts out when on, tricking capable Heads-up displays into thinking you have a mindshield (Nanotrasen brand implanter not provided.) diff --git a/Resources/Prototypes/Actions/types.yml b/Resources/Prototypes/Actions/types.yml index a9ac169d3c..89c8e56b78 100644 --- a/Resources/Prototypes/Actions/types.yml +++ b/Resources/Prototypes/Actions/types.yml @@ -328,3 +328,15 @@ itemIconStyle: NoItem useDelay: 1 # emote spam event: !type:ToggleActionEvent + +- type: entity + id: FakeMindShieldToggleAction + name: action-name-toggle-fake-mindshield + description: action-description-toggle-fake-mindshield + components: + - type: InstantAction + icon: { sprite: Interface/Actions/actions_fakemindshield.rsi, state: icon } + iconOn: { sprite: Interface/Actions/actions_fakemindshield.rsi, state: icon-on } + itemIconStyle: NoItem + useDelay: 1 + event: !type:FakeMindShieldToggleEvent diff --git a/Resources/Prototypes/Catalog/thief_toolbox_sets.yml b/Resources/Prototypes/Catalog/thief_toolbox_sets.yml index f9ea34b389..06328870fc 100644 --- a/Resources/Prototypes/Catalog/thief_toolbox_sets.yml +++ b/Resources/Prototypes/Catalog/thief_toolbox_sets.yml @@ -17,6 +17,7 @@ - ClothingShoesChameleon - BarberScissors - ChameleonProjector + - FakeMindShieldImplanter - AgentIDCard - type: thiefBackpackSet diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index f31d85414d..f3ace5b0bb 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -1422,6 +1422,20 @@ components: - SurplusBundle +- type: listing + id: UplinkFakeMindshield + name: uplink-fake-mindshield-name + description: uplink-fake-mindshield-desc + icon: { sprite: Interface/Actions/actions_fakemindshield.rsi, state: icon-on } + productEntity: FakeMindShieldImplanter + discountDownTo: + Telecrystal: 2 + cost: + Telecrystal: 4 + categories: + - UplinkImplants + + # Wearables - type: listing diff --git a/Resources/Prototypes/Entities/Objects/Misc/implanters.yml b/Resources/Prototypes/Entities/Objects/Misc/implanters.yml index beffe8959a..b8ab92e5e9 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/implanters.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/implanters.yml @@ -245,6 +245,14 @@ - type: Implanter implant: DeathAcidifierImplant +- type: entity + id: FakeMindShieldImplanter + suffix: fake mindshield + parent: BaseImplantOnlyImplanterSyndi + components: + - type: Implanter + implant: FakeMindShieldImplant + # Security and Command implanters - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml b/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml index 28788e9a13..5d93cefd5d 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml @@ -311,6 +311,17 @@ - Dead - type: Rattle +- type: entity + parent: BaseSubdermalImplant + id: FakeMindShieldImplant + name: fake mindshield implant + description: This implant allows the implanter to produce a fake signal that NT security huds use to identify individuals implanted with a mindshield. + categories: [ HideSpawnMenu ] + components: + - type: SubdermalImplant + implantAction: FakeMindShieldToggleAction + - type: FakeMindShieldImplant + # Sec and Command implants - type: entity diff --git a/Resources/Textures/Interface/Actions/actions_fakemindshield.rsi/icon-on.png b/Resources/Textures/Interface/Actions/actions_fakemindshield.rsi/icon-on.png new file mode 100644 index 0000000000000000000000000000000000000000..19b4e13ec1de201a8796f0aed015f80c89fac805 GIT binary patch literal 5111 zcmeHKdsGuw8XrJKQ4ti2R;V#Tt6(xSAqgZ9c?Bi1!3Y6CP?*e2U^L0Z$v^_GMHGCY zRtvS_tG+?&tFG3w_(Zfm*cHT9i`ExbS+v&2T1$(M-U%pS*K_uG&h|g%oXOmKzu*0R z_xs)NyOUX@i67tJ?R_^0g8Hjsl?mX<vH={C&&RtyeOT0Gc z#gmag4&ONO+luegE2}(+foFSONe`SNsLd(P`NUfGTU2mhQ;Krg-7nI;r_r^~UHPE{ z`GQOf^t8fhX;HnKXxN}7Xza79-~7VP91HdBozZtks<}khx($Myim2#ljVe0&bx0tP zwX;_!VrwFNPGuze^9Q?zR)!Fj?mF+mGs^k;}=(YSo393C}YUvORBC&kVnQZPpJ*T#CjOQ^}WoHnen{!>$j%-+pw9dQUY@KHdOB)9iUASxtEL=v za(6HMicjuoJAA0(ZwCwN_W$1Iw5^0Ww7vKVNHO<+P$0!p)PIrVv{8r=w2lHf&Xqq8;Vxd@w2x4qhu82R@jTgoc zdU=9!Tn7c{DfrneYnH>X)oK-5gM>7b1*0;V3`Rt-NF)FVfhEtxVm5)vGLoZc=TMRs zoT1DtMVojWC#IuwSOuRC?7Y|OGn&=vH}ob;hYCOs*oK*5REWSvBkVZC!p7tRl8yzv zb%sR?Diuy3Ep!fplQFrZi5=-kLEvxZn{yb0JsbjuNdsvFPz&&ic5yjgrPjQe!AX!s z8O`=tKJ>s%h!w*xIK0joeq3}yfTEJBbF0U{EJWL@U7l)h8!F0pYIyBv;z z0J1mh>Vkf)ogEBNYPDQR<2hV-Dy4$YtzS;iI7P_qO;n;MaZIEa=ny?F5R3JwKo=y% z1bQ43i-LkAx?loxpi-GEEM~$OS z2rk7PC?+x#$ZE{sxGIi{;HVHx8ibP)ft19h0&z$%E|7722%*D7B1woutQXs<2wXmn zW{eonn=)cqBy2Wi*$v!=$s;u?1z#jYI!81HjMak)poSW%Oe@qN;5OG6l)+A{3H|0H3(kEupP?n zp&UdGb^+sx0{H42*JRTy4N8=uaFvNA88ZXQwH+nuL~%)N$l->QOcaRQ!IaWz1H?fN zmejXdfZFnChQwH!(bBX*!RJKdago`*ab`7G0fDiY5@SI~B19yXqawLTqD7_hAViKz z1xTE z<&uPboq(&|glA)>EE1fL9R>AzoO(;L%1|keVR}S>NKu_YOroejh9d;XFjR(%^%9aq zBwg7pw4SwM3>ldPHVsPaz9_;5$CFn1!pjy4Sb zZ#}|5dfSu8L7hkg+f^Oz7?m49j&wM< z!Ibtf@InCZ7x>K!rehu4QT``h9lQT0dH~ejPToo1Zn?VUdM5?m3EZ7s-EzH?0`COw z&aVHPTyCA8sH6$}@3Mjq(0et{AApb7Ub?vPN+_B8j*a&y^a77Q=GasV1bL~s+o|l_ zQWy-nvMP0q>%aO9_5Q%a{Yd&?2y%v1%1CWW&4Xmc#9@&hvvK%nsQ??!ME7+o@Tzmu_p27v$b`>=>yOTQvhV7RIUde)oS?{+N1|Ppj&o7=P+w$j^exTPR_)%Luzka{ zJ-4q4c|}mO&+hxWun%gGe(42Bly&-n)!GWAab>_~6W}9pUZYBheK#S^lwUI^IZaOB zSvPrZoU$w6M%o(ZnB%WheJ;gkewE_oeqQG4`NG%fd>-a}vE^yqP7SXd%p8A6I2rU_n4((%@zE)P4)1{msy-y5{U(o68#m za|)NZjcuJ$m6=rh?AoAlnD&;!-N${X&1#?w|p*))Gn&dT%Lbv z-xz;$OR$GOc2zp2)=l37@3#c?DJUOZ_>t*U>ZN;Z@iF+>bx~O@Ip*^?NOS(MN8zYG zv^GDE@_ZE4BUxpOYr*$E-Z9tv!{rB79$UTRMXzI?{VCyOW)sLJcQQq#SF51_(C!Ux T?rKOZ%(;I6jiy)X literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Actions/actions_fakemindshield.rsi/icon.png b/Resources/Textures/Interface/Actions/actions_fakemindshield.rsi/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9eb33d5350c59302827974286a5bc166c5b62723 GIT binary patch literal 5105 zcmeHKc~BEs8V{#}z~FiSBS;J$1KM;ha!KS0kcd&_P%@y<>Fz*Fk`A4QgfQOMcp;y3;1I^o>4YRjsf|LCgD>-WCz{l548 z-tT*zUX?sO(cAM=PZo>itx_sdK+9(C!S3MKY_mNFO`|O>gHAy#Y!gN52tCfGi%mEi zw-P!Q%X-z2e9gO#JNRAh>e3wZrpvb^>afD4rP+FAd78ZWq|a8Tt5Hw=DwdH<|D%b%kNamwz_6|+`UO$x*zrM&2UpI6y~?{t(W%HFm-Ho=ir7! z|6%JwkNM6U<66X78U5<$hGQqPW@o&j6JI3O?N^$IPT9PW(mb|h9$r{;G9;wJ?c$&s zYwZ1mLz;xcKY1PXzdIQ_ri*H-o*c9T_L`-kpMMoHjm2_WM#RM>tK#CiQv!*6H~%ZS zvMxHXAv<*(XT+e%dnDK%AFbbrg7UDDwXwv+BM)<^2Yy0AnUWRg*1BYA@S5~Nez|jk zvfN_YUFxsYs(y~2`Yt;qZ|JSsf~f2NDEa#-mt_gdiCL|IJ02XXSl#%0y)pfF*+b9x zD%Qr8SKwpMuL*cvda%UxwaxF2rt@BB;QV>lwb9X>ZRiSO80p)hzv_N(ej9gUbJ#QK zvt=s3u?udWXnQv5-uLI6TfDYZT#PK(lo3{R=zQ&dY+n6^`l0C;LbID}`>E?~`_t#` zFPzbNCV6hQ%DnaN;I@odXO%KJIWAztrVm4vpozr)VRwja8d_V=CG4NAH}M8=u=U*91EK z>sn1iVP@*fMdyNY+MCPNSH4~%TpsIWjoL+?b#keUe!96eGe3CuC($cTe16)=$7k_j z4t}uXWYz9JS1xQh^0ve2hc#5y-sQgniTV76020ekPm`gfAsoR-Ego()n1J?JtjH*< z2|@F5nytli38S3zw5poJCNMc?c7&R%HpSt2gwjUgskZ59s4X9rVw|Wco{?4=05IS* z!nPXpMzhQ+=h$&&;F%eQIc&QNoiFEPsFT@oB!#nu;lgk(6mKPp_?#)8>_`gJ$x;*v zT@aur=j73}Ne06fizVD52q&prm?xD=VJ;u$^C92?nTw4yVug(65C+15p}@^3MVM%U zG_n~?L`xRZat;UB+1=|inAGYXc%!+C1;7VvMNBX+oC_NaaNikbI=%>ibS>zEGt6nA zQsETbOcqio9$$nT>5#q<7}_)6R7mOV>0l^~>v02cHG`g1jo3)hQuO70ttm89Fp<`Qb?%NB4Ux0uhoflb|?&$ zC6JT>0elk%Bo~KG#$3CB*)Um5vP#b3hjV*JlJy9!0~0_E5k`!(n0rlWgaJ>b5r$8m zSP;PzNh7#o2`@q{5cfLG!YMP*GK0$Fh6@~&bZxmThN3Mbm7hk?dR)#)H`2@l#_k%n zgD`t21DS(eK$xNcv3kdo^GKQmB}x&f%1Gmsi2~*7@Z$G+F{0KNGQ;Uc0_5Gtl+kMg zz=A#&&4(<2ZCM$nc1T;W;Iv=hR}!tp+QP~E?+3)@n!soG@eK% z;K_s{h%1(H`}mU>p)3Ah-puj9j&#UCNti+WV*8Ne%t*xx96d)@PuLF&HrrnIG6Z!n zVn&K^hnxVG!-VD`##|hnk6i`TJx+W;tO7n)fM|6X#6x*NVSKw-g+hpjAgG9oh*KB7wZ^BI?6VjGpe#4s(pk^dNIki4Z6{q)<SJ&?UmLb^efgm5n?*Lr`bbS;9ALTrtt^v9}ih+-E z9#Gf+jV{mLPgL9p{&!ix2WSi?7y>?C-L*-H3f3&o-7nwr$Su*s8{bR6ncWR7B^Ja#=U(mUFZ)MVfMuYdu(mJl!k(kq(OuXpkk79>2hM(Deefrf+EZ-GlmicaKxz`-3+3S4zX~=3$=oj+9n+HhcxWQu* z&t<=ctX>y{%TL`3kW}gwGhJK$x#Q7^=aY^?#h? zT)HXLG$jPr?_DshoT`3)@JjwW7i#wpoDDJCM*|)C;2A2NTFnXr&x66uT<23aGL0&J Ly5c}=&XRuvnz2Z< literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Actions/actions_fakemindshield.rsi/meta.json b/Resources/Textures/Interface/Actions/actions_fakemindshield.rsi/meta.json new file mode 100644 index 0000000000..31f288131f --- /dev/null +++ b/Resources/Textures/Interface/Actions/actions_fakemindshield.rsi/meta.json @@ -0,0 +1,17 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Created by Ubaser (Discord) for SS14, Modified for purpose by brassicaprime69 (Discord)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "icon-on" + } + ] +} -- 2.51.2