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