From: Jessica M Date: Thu, 9 Oct 2025 21:14:12 +0000 (-0700) Subject: Migrate revenant and PAI shops to use ActionGrant instead of hardcoding them (#40475) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=0d97699aaeec677736382b8a225414b193a9bf8a;p=space-station-14.git Migrate revenant and PAI shops to use ActionGrant instead of hardcoding them (#40475) * add intrinsic store, replace revenant store with it. * migrate PAI and also move to shared where possible * fix typos and clean up... intrinisic * oops, hopefully fixes test * Move to StoreSystem and ActionGrant * documentation and remove thing * review --------- Co-authored-by: Jessica M Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- diff --git a/Content.Client/PAI/PAISystem.cs b/Content.Client/PAI/PAISystem.cs deleted file mode 100644 index a28cf6a077..0000000000 --- a/Content.Client/PAI/PAISystem.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Content.Shared.PAI; - -namespace Content.Client.PAI -{ - public sealed class PAISystem : SharedPAISystem - { - } -} diff --git a/Content.Server/PAI/PAISystem.cs b/Content.Server/PAI/PAISystem.cs index 289b74b258..7fd58f1572 100644 --- a/Content.Server/PAI/PAISystem.cs +++ b/Content.Server/PAI/PAISystem.cs @@ -2,27 +2,22 @@ using Content.Server.Ghost.Roles; using Content.Server.Ghost.Roles.Components; using Content.Server.Instruments; using Content.Server.Kitchen.Components; -using Content.Server.Store.Systems; using Content.Shared.Interaction.Events; using Content.Shared.Mind.Components; using Content.Shared.PAI; using Content.Shared.Popups; -using Content.Shared.Store; -using Content.Shared.Store.Components; using Content.Shared.Instruments; using Robust.Shared.Random; -using Robust.Shared.Prototypes; using System.Text; namespace Content.Server.PAI; -public sealed class PAISystem : SharedPAISystem +public sealed class PAISystem : EntitySystem { [Dependency] private readonly InstrumentSystem _instrumentSystem = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly MetaDataSystem _metaData = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; - [Dependency] private readonly StoreSystem _store = default!; [Dependency] private readonly ToggleableGhostRoleSystem _toggleableGhostRole = default!; /// @@ -38,8 +33,6 @@ public sealed class PAISystem : SharedPAISystem SubscribeLocalEvent(OnMindAdded); SubscribeLocalEvent(OnMindRemoved); SubscribeLocalEvent(OnMicrowaved); - - SubscribeLocalEvent(OnShop); } private void OnUseInHand(EntityUid uid, PAIComponent component, UseInHandEvent args) @@ -106,15 +99,6 @@ public sealed class PAISystem : SharedPAISystem var val = Loc.GetString("pai-system-pai-name-raw", ("name", name.ToString())); _metaData.SetEntityName(uid, val); } - - private void OnShop(Entity ent, ref PAIShopActionEvent args) - { - if (!TryComp(ent, out var store)) - return; - - _store.ToggleUi(args.Performer, ent, store); - } - public void PAITurningOff(EntityUid uid) { // Close the instrument interface if it was open diff --git a/Content.Server/Revenant/EntitySystems/RevenantSystem.cs b/Content.Server/Revenant/EntitySystems/RevenantSystem.cs index b89f10934d..6c8972be58 100644 --- a/Content.Server/Revenant/EntitySystems/RevenantSystem.cs +++ b/Content.Server/Revenant/EntitySystems/RevenantSystem.cs @@ -1,7 +1,6 @@ using System.Numerics; using Content.Server.Actions; using Content.Server.GameTicking; -using Content.Server.Store.Components; using Content.Server.Store.Systems; using Content.Shared.Alert; using Content.Shared.Damage; @@ -21,7 +20,6 @@ using Content.Shared.Store.Components; using Content.Shared.Stunnable; using Content.Shared.Tag; using Robust.Server.GameObjects; -using Robust.Shared.Prototypes; using Robust.Shared.Random; namespace Content.Server.Revenant.EntitySystems; @@ -46,17 +44,12 @@ public sealed partial class RevenantSystem : EntitySystem [Dependency] private readonly TagSystem _tag = default!; [Dependency] private readonly VisibilitySystem _visibility = default!; [Dependency] private readonly TurfSystem _turf = default!; - - private static readonly EntProtoId RevenantShopId = "ActionRevenantShop"; - public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnStartup); - SubscribeLocalEvent(OnMapInit); - SubscribeLocalEvent(OnShop); SubscribeLocalEvent(OnDamage); SubscribeLocalEvent(OnExamine); SubscribeLocalEvent(OnStatusAdded); @@ -94,11 +87,6 @@ public sealed partial class RevenantSystem : EntitySystem _eye.RefreshVisibilityMask(uid); } - private void OnMapInit(EntityUid uid, RevenantComponent component, MapInitEvent args) - { - _action.AddAction(uid, ref component.Action, RevenantShopId); - } - private void OnStatusAdded(EntityUid uid, RevenantComponent component, StatusEffectAddedEvent args) { if (args.Key == "Stun") @@ -182,13 +170,6 @@ public sealed partial class RevenantSystem : EntitySystem return true; } - private void OnShop(EntityUid uid, RevenantComponent component, RevenantShopActionEvent args) - { - if (!TryComp(uid, out var store)) - return; - _store.ToggleUi(uid, uid, store); - } - public void MakeVisible(bool visible) { var query = EntityQueryEnumerator(); diff --git a/Content.Server/Store/Systems/StoreSystem.cs b/Content.Server/Store/Systems/StoreSystem.cs index 0625ced087..10060dc7d3 100644 --- a/Content.Server/Store/Systems/StoreSystem.cs +++ b/Content.Server/Store/Systems/StoreSystem.cs @@ -1,17 +1,16 @@ +using System.Linq; using Content.Server.Store.Components; -using Content.Shared.UserInterface; using Content.Shared.FixedPoint; using Content.Shared.Implants.Components; using Content.Shared.Interaction; using Content.Shared.Popups; using Content.Shared.Stacks; using Content.Shared.Store.Components; -using JetBrains.Annotations; +using Content.Shared.Store.Events; +using Content.Shared.UserInterface; using Robust.Shared.Prototypes; -using Robust.Shared.Utility; -using System.Linq; using Robust.Shared.Timing; -using Content.Shared.Mind; +using Robust.Shared.Utility; namespace Content.Server.Store.Systems; @@ -37,6 +36,7 @@ public sealed partial class StoreSystem : EntitySystem SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnShutdown); SubscribeLocalEvent(OnImplantActivate); + SubscribeLocalEvent(OnIntrinsicStoreAction); InitializeUi(); InitializeCommand(); @@ -187,6 +187,12 @@ public sealed partial class StoreSystem : EntitySystem UpdateUserInterface(null, uid, store); return true; } + + private void OnIntrinsicStoreAction(Entity ent, ref IntrinsicStoreActionEvent args) + { + ToggleUi(args.Performer, ent.Owner, ent.Comp); + } + } public sealed class CurrencyInsertAttemptEvent : CancellableEntityEventArgs diff --git a/Content.Shared/PAI/PAIComponent.cs b/Content.Shared/PAI/PAIComponent.cs index fb9d7150e3..541172ffe0 100644 --- a/Content.Shared/PAI/PAIComponent.cs +++ b/Content.Shared/PAI/PAIComponent.cs @@ -1,8 +1,4 @@ -using Content.Shared.FixedPoint; -using Content.Shared.Store; using Robust.Shared.GameStates; -using Robust.Shared.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Shared.PAI; @@ -16,7 +12,7 @@ namespace Content.Shared.PAI; /// and there's not always enough players and ghost roles to justify it. /// All logic in PAISystem. /// -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[RegisterComponent, NetworkedComponent] public sealed partial class PAIComponent : Component { /// @@ -26,12 +22,6 @@ public sealed partial class PAIComponent : Component [DataField, ViewVariables(VVAccess.ReadWrite)] public EntityUid? LastUser; - [DataField] - public EntProtoId ShopActionId = "ActionPAIOpenShop"; - - [DataField, AutoNetworkedField] - public EntityUid? ShopAction; - /// /// When microwaved there is this chance to brick the pai, kicking out its player and preventing it from being used again. /// diff --git a/Content.Shared/PAI/SharedPAISystem.cs b/Content.Shared/PAI/SharedPAISystem.cs deleted file mode 100644 index 00d3e23cef..0000000000 --- a/Content.Shared/PAI/SharedPAISystem.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Content.Shared.Actions; - -namespace Content.Shared.PAI; - -/// -/// pAIs, or Personal AIs, are essentially portable ghost role generators. -/// In their current implementation, they create a ghost role anyone can access, -/// and that a player can also "wipe" (reset/kick out player). -/// Theoretically speaking pAIs are supposed to use a dedicated "offer and select" system, -/// with the player holding the pAI being able to choose one of the ghosts in the round. -/// This seems too complicated for an initial implementation, though, -/// and there's not always enough players and ghost roles to justify it. -/// -public abstract class SharedPAISystem : EntitySystem -{ - [Dependency] private readonly SharedActionsSystem _actions = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnMapInit); - SubscribeLocalEvent(OnShutdown); - } - - private void OnMapInit(Entity ent, ref MapInitEvent args) - { - _actions.AddAction(ent, ent.Comp.ShopActionId); - } - - private void OnShutdown(Entity ent, ref ComponentShutdown args) - { - _actions.RemoveAction(ent.Owner, ent.Comp.ShopAction); - } -} -public sealed partial class PAIShopActionEvent : InstantActionEvent -{ -} diff --git a/Content.Shared/Revenant/Components/RevenantComponent.cs b/Content.Shared/Revenant/Components/RevenantComponent.cs index e6543f1906..e434bba1d9 100644 --- a/Content.Shared/Revenant/Components/RevenantComponent.cs +++ b/Content.Shared/Revenant/Components/RevenantComponent.cs @@ -214,6 +214,4 @@ public sealed partial class RevenantComponent : Component [DataField("harvestingState")] public string HarvestingState = "harvesting"; #endregion - - [DataField] public EntityUid? Action; } diff --git a/Content.Shared/Revenant/SharedRevenant.cs b/Content.Shared/Revenant/SharedRevenant.cs index c44e4408aa..b1023f43e2 100644 --- a/Content.Shared/Revenant/SharedRevenant.cs +++ b/Content.Shared/Revenant/SharedRevenant.cs @@ -42,10 +42,6 @@ public sealed class HarvestDoAfterCancelled : EntityEventArgs { } -public sealed partial class RevenantShopActionEvent : InstantActionEvent -{ -} - public sealed partial class RevenantDefileActionEvent : InstantActionEvent { } diff --git a/Content.Shared/Store/Events/IntrinsicStoreActionEvent.cs b/Content.Shared/Store/Events/IntrinsicStoreActionEvent.cs new file mode 100644 index 0000000000..dea2c25e6e --- /dev/null +++ b/Content.Shared/Store/Events/IntrinsicStoreActionEvent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Actions; + +namespace Content.Shared.Store.Events; + +/// +/// Opens a store specified by +/// Used for entities with a store built into themselves like Revenant or PAI +/// +public sealed partial class IntrinsicStoreActionEvent : InstantActionEvent +{ +} diff --git a/Resources/Prototypes/Actions/revenant.yml b/Resources/Prototypes/Actions/revenant.yml index 5904908a75..3ac425a567 100644 --- a/Resources/Prototypes/Actions/revenant.yml +++ b/Resources/Prototypes/Actions/revenant.yml @@ -1,13 +1,8 @@ - type: entity - parent: BaseAction + parent: ActionIntrinsicStore id: ActionRevenantShop name: Shop description: Opens the ability shop. - components: - - type: Action - icon: Interface/Actions/shop.png - - type: InstantAction - event: !type:RevenantShopActionEvent - type: entity parent: BaseAction diff --git a/Resources/Prototypes/Actions/types.yml b/Resources/Prototypes/Actions/types.yml index 61babbfcea..752aeb13f8 100644 --- a/Resources/Prototypes/Actions/types.yml +++ b/Resources/Prototypes/Actions/types.yml @@ -466,3 +466,14 @@ itemIconStyle: BigAction - type: InstantAction event: !type:ChameleonControllerOpenMenuEvent + +- type: entity + parent: BaseMentalAction + id: ActionIntrinsicStore + name: Store + description: Opens the store + components: + - type: Action + icon: Interface/Actions/shop.png + - type: InstantAction + event: !type:IntrinsicStoreActionEvent diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml index 9b0bfb05ca..04b1554cef 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml @@ -66,6 +66,9 @@ type: StoreBoundUserInterface - type: Visibility layer: 2 #ghost vis layer + - type: ActionGrant + actions: + - ActionRevenantShop - type: Store categories: - RevenantAbilities diff --git a/Resources/Prototypes/Entities/Objects/Fun/pai.yml b/Resources/Prototypes/Entities/Objects/Fun/pai.yml index 6aec812b77..2ba5acfbf1 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/pai.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/pai.yml @@ -58,6 +58,9 @@ - Common - type: DoAfter - type: Actions + - type: ActionGrant + actions: + - ActionPAIOpenShop - type: Store categories: - PAIAbilities @@ -188,15 +191,10 @@ node: potatoai - type: entity - parent: BaseMentalAction + parent: ActionIntrinsicStore id: ActionPAIOpenShop name: Software Catalog description: Install new software to assist your owner. - components: - - type: Action - icon: Interface/Actions/shop.png - - type: InstantAction - event: !type:PAIShopActionEvent - type: entity parent: BaseMentalAction