From 3eba895fc7a234fdca288a6da3f631886d538afb Mon Sep 17 00:00:00 2001 From: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:47:31 -0700 Subject: [PATCH] Thieves can innately pickpocket - thieving gloves rework (#38123) * Thieves can innately pickpocket (#107) Pickpocketing a skyrim guard's armor off (cherry picked from commit 21b9f1ddb251ea3c7c6803e78871abefcaecbfb4) * this isnt moff * Make predicted, cleanup * !skating-basketball * orks are NOT the best trollface * Implement much more sensible component replication prevention --------- Co-authored-by: DuckManZach <144298822+duckmanzach@users.noreply.github.com> --- .../Strip/Components/ThievingComponent.cs | 32 +++++++++++--- Content.Shared/Strip/ThievingSystem.cs | 39 ++++++++++++++++-- Resources/Locale/en-US/alerts/alerts.ftl | 3 ++ Resources/Prototypes/Alerts/alerts.yml | 14 +++++++ .../Prototypes/Catalog/uplink_catalog.yml | 14 ------- .../Prototypes/GameRules/subgamemodes.yml | 3 ++ Resources/Prototypes/Roles/Antags/thief.yml | 1 - .../Interface/Alerts/stealthy.rsi/meta.json | 17 ++++++++ .../Alerts/stealthy.rsi/stealthy-off.png | Bin 0 -> 636 bytes .../Alerts/stealthy.rsi/stealthy-on.png | Bin 0 -> 685 bytes 10 files changed, 99 insertions(+), 24 deletions(-) create mode 100644 Resources/Textures/Interface/Alerts/stealthy.rsi/meta.json create mode 100644 Resources/Textures/Interface/Alerts/stealthy.rsi/stealthy-off.png create mode 100644 Resources/Textures/Interface/Alerts/stealthy.rsi/stealthy-on.png diff --git a/Content.Shared/Strip/Components/ThievingComponent.cs b/Content.Shared/Strip/Components/ThievingComponent.cs index a851dd5ef6..f40201723b 100644 --- a/Content.Shared/Strip/Components/ThievingComponent.cs +++ b/Content.Shared/Strip/Components/ThievingComponent.cs @@ -1,22 +1,44 @@ +using Content.Shared.Alert; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + namespace Content.Shared.Strip.Components; /// /// Give this to an entity when you want to decrease stripping times /// -[RegisterComponent] +[RegisterComponent, NetworkedComponent] +[AutoGenerateComponentState(fieldDeltas: true)] public sealed partial class ThievingComponent : Component { /// /// How much the strip time should be shortened by /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField("stripTimeReduction")] + [DataField, AutoNetworkedField] public TimeSpan StripTimeReduction = TimeSpan.FromSeconds(0.5f); /// /// Should it notify the user if they're stripping a pocket? /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField("stealthy")] + [DataField, AutoNetworkedField] public bool Stealthy; + + /// + /// Variable pointing at the Alert modal + /// + [DataField] + public ProtoId StealthyAlertProtoId = "Stealthy"; + + /// + /// Prevent component replication to clients other than the owner, + /// doesn't affect prediction. + /// Get mogged. + /// + public override bool SendOnlyToOwner => true; } + +/// +/// Event raised to toggle the thieving component. +/// +public sealed partial class ToggleThievingEvent : BaseAlertEvent; + diff --git a/Content.Shared/Strip/ThievingSystem.cs b/Content.Shared/Strip/ThievingSystem.cs index 2b3d3b38a0..4a76354844 100644 --- a/Content.Shared/Strip/ThievingSystem.cs +++ b/Content.Shared/Strip/ThievingSystem.cs @@ -1,23 +1,54 @@ +using Content.Shared.Alert; using Content.Shared.Inventory; -using Content.Shared.Strip; using Content.Shared.Strip.Components; +using Robust.Shared.GameStates; namespace Content.Shared.Strip; -public sealed class ThievingSystem : EntitySystem +public sealed partial class ThievingSystem : EntitySystem { + [Dependency] private readonly AlertsSystem _alertsSystem = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnBeforeStrip); - SubscribeLocalEvent>((e, c, ev) => OnBeforeStrip(e, c, ev.Args)); + SubscribeLocalEvent>((e, c, ev) => + OnBeforeStrip(e, c, ev.Args)); + SubscribeLocalEvent(OnToggleStealthy); + SubscribeLocalEvent(OnCompInit); + SubscribeLocalEvent(OnCompRemoved); } private void OnBeforeStrip(EntityUid uid, ThievingComponent component, BeforeStripEvent args) { args.Stealth |= component.Stealthy; - args.Additive -= component.StripTimeReduction; + if (args.Stealth) + { + args.Additive -= component.StripTimeReduction; + } + } + + private void OnCompInit(Entity entity, ref ComponentInit args) + { + _alertsSystem.ShowAlert(entity, entity.Comp.StealthyAlertProtoId, 1); + } + + private void OnCompRemoved(Entity entity, ref ComponentRemove args) + { + _alertsSystem.ClearAlert(entity, entity.Comp.StealthyAlertProtoId); + } + + private void OnToggleStealthy(Entity ent, ref ToggleThievingEvent args) + { + if (args.Handled) + return; + + ent.Comp.Stealthy = !ent.Comp.Stealthy; + _alertsSystem.ShowAlert(ent.Owner, ent.Comp.StealthyAlertProtoId, (short)(ent.Comp.Stealthy ? 1 : 0)); + DirtyField(ent.AsNullable(), nameof(ent.Comp.Stealthy), null); + + args.Handled = true; } } diff --git a/Resources/Locale/en-US/alerts/alerts.ftl b/Resources/Locale/en-US/alerts/alerts.ftl index eb6d179027..45c22abcbc 100644 --- a/Resources/Locale/en-US/alerts/alerts.ftl +++ b/Resources/Locale/en-US/alerts/alerts.ftl @@ -116,3 +116,6 @@ alerts-revenant-corporeal-desc = You have manifested physically. People around y alerts-rooted-name = Rooted alerts-rooted-desc = You are attached to the ground. You can't slip, but you absorb fluids under you. + +alerts-stealthy-name = Pickpocketing +alerts-stealthy-desc = Whether you are currently pickpocketing. Click to toggle. diff --git a/Resources/Prototypes/Alerts/alerts.yml b/Resources/Prototypes/Alerts/alerts.yml index 60a23294d3..6710a15fbc 100644 --- a/Resources/Prototypes/Alerts/alerts.yml +++ b/Resources/Prototypes/Alerts/alerts.yml @@ -26,6 +26,7 @@ - alertType: Magboots - alertType: Rooted - alertType: Pacified + - alertType: Stealthy - type: entity id: AlertSpriteView @@ -438,6 +439,19 @@ name: alerts-pacified-name description: alerts-pacified-desc +- type: alert + id: Stealthy + clickEvent: !type:ToggleThievingEvent + icons: + - sprite: /Textures/Interface/Alerts/stealthy.rsi + state: stealthy-off + - sprite: /Textures/Interface/Alerts/stealthy.rsi + state: stealthy-on + name: alerts-stealthy-name + description: alerts-stealthy-desc + minSeverity: 0 + maxSeverity: 1 + - type: alert id: Adrenaline icons: diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index 2371ee2c25..c177baa5d7 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -1593,20 +1593,6 @@ categories: - UplinkWearables -# TODO: Revert back to normal thieving gloves when clothes dyeing is added -- type: listing - id: UplinkgClothingThievingGloves - name: uplink-clothing-chameleon-thieving-gloves-name - description: uplink-clothing-chameleon-thieving-gloves-desc - productEntity: ClothingHandsChameleonThief - discountCategory: veryRareDiscounts - discountDownTo: - Telecrystal: 3 - cost: - Telecrystal: 5 - categories: - - UplinkWearables - - type: listing id: UplinkClothingOuterVestWeb name: uplink-clothing-outer-vest-web-name diff --git a/Resources/Prototypes/GameRules/subgamemodes.yml b/Resources/Prototypes/GameRules/subgamemodes.yml index cb764d9787..2213623c28 100644 --- a/Resources/Prototypes/GameRules/subgamemodes.yml +++ b/Resources/Prototypes/GameRules/subgamemodes.yml @@ -27,6 +27,9 @@ startingGear: ThiefGear components: - type: Pacified + - type: Thieving + stripTimeReduction: 2 + stealthy: true mindRoles: - MindRoleThief briefing: diff --git a/Resources/Prototypes/Roles/Antags/thief.yml b/Resources/Prototypes/Roles/Antags/thief.yml index b8d21d2e83..4b333ac495 100644 --- a/Resources/Prototypes/Roles/Antags/thief.yml +++ b/Resources/Prototypes/Roles/Antags/thief.yml @@ -15,4 +15,3 @@ back: - ThiefBeacon - SatchelThief - - ClothingHandsChameleonThief diff --git a/Resources/Textures/Interface/Alerts/stealthy.rsi/meta.json b/Resources/Textures/Interface/Alerts/stealthy.rsi/meta.json new file mode 100644 index 0000000000..8c00bfef64 --- /dev/null +++ b/Resources/Textures/Interface/Alerts/stealthy.rsi/meta.json @@ -0,0 +1,17 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/4f6190e2895e09116663ef282d3ce1d8b35c032e. Edited by DuckManZach (github)", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "stealthy-off" + }, + { + "name": "stealthy-on" + } + ] +} diff --git a/Resources/Textures/Interface/Alerts/stealthy.rsi/stealthy-off.png b/Resources/Textures/Interface/Alerts/stealthy.rsi/stealthy-off.png new file mode 100644 index 0000000000000000000000000000000000000000..98e35494b2697b2d66ee0fa2c7eb3000224197d3 GIT binary patch literal 636 zcmV-?0)zdDP)z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGi!~g&e!~vBn4jTXf00(qQO+^Rk1QrAU40F<|o&W#= z(n&-?R9M69R!fe9FbsW0+yGGF0%SqB|3%o)3*f5B89a+=G69l6XDZE%RIiX@`#paW z1H9!eZ+Xiv3%x3kQcB$SJkO`&md}ES2#9C}()YczZR_nsM6TB>y_7%-L@6b0+oG;( zr}riRa73g$158A?TrM6Y5Q*vQx(;=+t=K67ecuZJjN|At3$pV7%d((pny;ZEf@>21 zXstbw7>P0k9yog7ZSe4WHQAeU5y3DF(b*_t;Nv*%g1hgSE_uZs=hj+Z4I)}qqKIW~ zjDfXwm3dB#F;V^feupszRaJqRVXeh548FZ90!k^-TEkk4Wm!;F6|A+%;Kmp*Gv;|F zW{#3+n#Kcbt+6Z%thK9zim=ZPd>ls)5Ked)+<|Y2F*BxV^0r!QFf)uX=(=v_=V#zC z9MW|ij4`;~ZhnFtnQ;17cQLpf!AmI4UTckMn$WiG&bEjR4Kwe+bI&Ug?ONqpv#nb8 z7KF@m;9D>e0WSHCN-m_MC;aI@qJ!$J`XB0Z{>4isIRQc^N>H9H^Pjzj+bmQ1lzaf= Wm1jt0qPS!L0000z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGi!~g&e!~vBn4jTXf00(qQO+^Rk1QrAY678{4`2YX{ z14%?dR9M69R&8$MAQT)dU!bv3?F-bF4EI0CQfZS5_(g&C2ycJHU`%l0>_*zE&HF{b z%*^{Fz|)@gw4ZL`Q9zQxeti<#amz=LNCxlvZvK$>yj4Vb5BaX|z|0Ur1QN;Mm+lQs z+synO1AO2u(I~fiy+*R@J2Y*Bx~|XrJO#-Ik3IOol=WC-}Blj2Mu%_VgdeK_RIWuDz z2AC;rv4}E9uC=}Z_v_r=YL8Fn&bbhc_kNj zoO2k40WaNKsIek$F{Kooa~Q`FRaL<`w+e2p1rg!n_Z~!)6(gk##7ZfQ;|S;6!l5G0 zvnSVD2ZFf5V{lKN8WF)56TVeSfrwzOMccOFo=-s;dXx{04rtpJ)><5o$54n~OkDl3 z#oYnmEUcfqMJWYi44S67__oLu4G~?C=e&*YrK$3%Nu&0;KOox$=P2yiE5Ambk})%g z=pwuxFUGh!2Z9Iyrk_2D0ZpG&x=&x`k&5xwMzOdxiqngK`|SSn{{c>`=bU>HpT)n$ zt>JNxfC+H5`s2}?jO?5E#l0a*AEjIu-D3s*vwbfCYtQpT1qdOolC0Iomu