From cf0498e89a40ffca5e68bf3db7146f614684af20 Mon Sep 17 00:00:00 2001 From: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com> Date: Tue, 23 Jul 2024 12:38:55 +0300 Subject: [PATCH] Refactor FabricateCandySystem Into Its Generic Equivalent (#566) # Description Refactors the nyano shitcode responsible for allowing borgs to dispense candies into a more generic variant, that allows to define what action dispenses what entity, and allowing an arbitrary number of such actions on an entity. Requested by @DangerRevolution

Media

https://github.com/user-attachments/assets/b4d643e2-c9b0-4367-8b9c-2d0cd4a228b9

# Changelog No cl no fun --------- Signed-off-by: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com> Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> --- .../Borgs/FabricateActionsComponent.cs | 19 +++++++ .../Abilities/Borgs/FabricateActionsSystem.cs | 53 +++++++++++++++++++ .../Borgs/FabricateCandyComponent.cs | 11 ---- .../Abilities/Borgs/FabricateCandySystem.cs | 37 ------------- .../Actions/Events/FabricateActionEvent.cs | 9 ++++ .../Actions/FabricateCandyEvent.cs | 4 -- Resources/Prototypes/Actions/types.yml | 26 +++++++++ .../Entities/Mobs/Cyborgs/borg_chassis.yml | 7 ++- .../Prototypes/Nyanotrasen/Actions/types.yml | 21 -------- 9 files changed, 112 insertions(+), 75 deletions(-) create mode 100644 Content.Server/Abilities/Borgs/FabricateActionsComponent.cs create mode 100644 Content.Server/Abilities/Borgs/FabricateActionsSystem.cs delete mode 100644 Content.Server/Nyanotrasen/Abilities/Borgs/FabricateCandyComponent.cs delete mode 100644 Content.Server/Nyanotrasen/Abilities/Borgs/FabricateCandySystem.cs create mode 100644 Content.Shared/Actions/Events/FabricateActionEvent.cs delete mode 100644 Content.Shared/Nyanotrasen/Actions/FabricateCandyEvent.cs diff --git a/Content.Server/Abilities/Borgs/FabricateActionsComponent.cs b/Content.Server/Abilities/Borgs/FabricateActionsComponent.cs new file mode 100644 index 00000000000..c9a693562ff --- /dev/null +++ b/Content.Server/Abilities/Borgs/FabricateActionsComponent.cs @@ -0,0 +1,19 @@ +using Robust.Shared.Prototypes; + +namespace Content.Server.Abilities.Borgs; + +[RegisterComponent] +public sealed partial class FabricateActionsComponent : Component +{ + /// + /// IDs of fabrication actions that the entity should receive with this component. + /// + [DataField] + public List> Actions = new(); + + /// + /// Action entities added by this component. + /// + [DataField] + public Dictionary, EntityUid> ActionEntities = new(); +} diff --git a/Content.Server/Abilities/Borgs/FabricateActionsSystem.cs b/Content.Server/Abilities/Borgs/FabricateActionsSystem.cs new file mode 100644 index 00000000000..c73b46c0b8e --- /dev/null +++ b/Content.Server/Abilities/Borgs/FabricateActionsSystem.cs @@ -0,0 +1,53 @@ +using Content.Shared.ActionBlocker; +using Content.Shared.Actions; +using Content.Shared.Actions.Events; + +namespace Content.Server.Abilities.Borgs; + +public sealed partial class FabricateActionsSystem : EntitySystem +{ + [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!; + [Dependency] private readonly SharedActionsSystem _actions = default!; + + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnStartup); + SubscribeLocalEvent(OnShutdown); + SubscribeLocalEvent(OnFabricate); + } + + + private void OnStartup(Entity entity, ref ComponentStartup args) + { + foreach (var actionId in entity.Comp.Actions) + { + EntityUid? actionEntity = null; + if (_actions.AddAction(entity, ref actionEntity, actionId)) + entity.Comp.ActionEntities[actionId] = actionEntity.Value; + } + } + + private void OnShutdown(Entity entity, ref ComponentShutdown args) + { + foreach (var (actionId, actionEntity) in entity.Comp.ActionEntities) + { + if (actionEntity is not { Valid: true }) + continue; + + _actions.RemoveAction(entity, actionEntity); + entity.Comp.ActionEntities.Remove(actionId); + } + } + + private void OnFabricate(Entity entity, ref FabricateActionEvent args) + { + if (args.Handled || !_actionBlocker.CanConsciouslyPerformAction(entity)) + return; + + SpawnNextToOrDrop(args.Fabrication, entity); + args.Handled = true; + } +} diff --git a/Content.Server/Nyanotrasen/Abilities/Borgs/FabricateCandyComponent.cs b/Content.Server/Nyanotrasen/Abilities/Borgs/FabricateCandyComponent.cs deleted file mode 100644 index d0a399c1fea..00000000000 --- a/Content.Server/Nyanotrasen/Abilities/Borgs/FabricateCandyComponent.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Content.Server.Abilities.Borgs; - -[RegisterComponent] -public sealed partial class FabricateCandyComponent : Component -{ - [DataField("lollipopAction")] - public EntityUid? LollipopAction; - - [DataField("gumballAction")] - public EntityUid? GumballAction; -} diff --git a/Content.Server/Nyanotrasen/Abilities/Borgs/FabricateCandySystem.cs b/Content.Server/Nyanotrasen/Abilities/Borgs/FabricateCandySystem.cs deleted file mode 100644 index 6451c7cbb27..00000000000 --- a/Content.Server/Nyanotrasen/Abilities/Borgs/FabricateCandySystem.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Content.Shared.Actions; -using Content.Shared.Actions.Events; - -namespace Content.Server.Abilities.Borgs; - -public sealed partial class FabricateCandySystem : EntitySystem -{ - [Dependency] private readonly SharedActionsSystem _actionsSystem = default!; - public override void Initialize() - { - base.Initialize(); - SubscribeLocalEvent(OnInit); - SubscribeLocalEvent(OnLollipop); - SubscribeLocalEvent(OnGumball); - } - - private void OnInit(EntityUid uid, FabricateCandyComponent component, ComponentInit args) - { - if (component.LollipopAction != null || component.GumballAction != null) - return; - - _actionsSystem.AddAction(uid, ref component.LollipopAction, "ActionFabricateLollipop"); - _actionsSystem.AddAction(uid, ref component.GumballAction, "ActionFabricateGumball"); - } - - private void OnLollipop(FabricateLollipopActionEvent args) - { - Spawn("FoodLollipop", Transform(args.Performer).Coordinates); - args.Handled = true; - } - - private void OnGumball(FabricateGumballActionEvent args) - { - Spawn("FoodGumball", Transform(args.Performer).Coordinates); - args.Handled = true; - } -} diff --git a/Content.Shared/Actions/Events/FabricateActionEvent.cs b/Content.Shared/Actions/Events/FabricateActionEvent.cs new file mode 100644 index 00000000000..7483cb04d98 --- /dev/null +++ b/Content.Shared/Actions/Events/FabricateActionEvent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.Actions.Events; + +public sealed partial class FabricateActionEvent : InstantActionEvent +{ + [DataField(required: true)] + public ProtoId Fabrication; +} diff --git a/Content.Shared/Nyanotrasen/Actions/FabricateCandyEvent.cs b/Content.Shared/Nyanotrasen/Actions/FabricateCandyEvent.cs deleted file mode 100644 index 3c9371d27eb..00000000000 --- a/Content.Shared/Nyanotrasen/Actions/FabricateCandyEvent.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Content.Shared.Actions.Events; - -public sealed partial class FabricateLollipopActionEvent : InstantActionEvent {} -public sealed partial class FabricateGumballActionEvent : InstantActionEvent {} diff --git a/Resources/Prototypes/Actions/types.yml b/Resources/Prototypes/Actions/types.yml index 22f16bd9568..f55f59daaa8 100644 --- a/Resources/Prototypes/Actions/types.yml +++ b/Resources/Prototypes/Actions/types.yml @@ -350,3 +350,29 @@ itemIconStyle: NoItem useDelay: 1 # emote spam event: !type:ToggleActionEvent + +- type: entity + id: ActionFabricateLollipop + name: action-name-fabricate-lollipop + description: action-description-fabricate-lollipop + noSpawn: true + components: + - type: InstantAction + icon: { sprite: Nyanotrasen/Objects/Consumable/Food/candy.rsi, state: lollipop } + useDelay: 120 + event: + !type:FabricateActionEvent + fabrication: FoodLollipop + +- type: entity + id: ActionFabricateGumball + name: action-name-fabricate-gumball + description: action-description-fabricate-gumball + noSpawn: true + components: + - type: InstantAction + icon: { sprite: Nyanotrasen/Objects/Consumable/Food/candy.rsi, state: gumball } + useDelay: 40 + event: + !type:FabricateActionEvent + fabrication: FoodGumball diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml index 6191e612505..5056fda4c06 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/borg_chassis.yml @@ -119,7 +119,7 @@ - type: Inventory templateId: borgShort - type: SiliconLawProvider # Delta-V - Adds custom lawset for Engineering Cyborg - laws: Engineer + laws: Engineer - type: entity id: BorgChassisJanitor @@ -224,7 +224,10 @@ access: [["Medical"], ["Command"], ["Research"]] - type: Inventory templateId: borgDutch - - type: FabricateCandy # Nyanotrasen - The medical cyborg can generate candies filled with medicine. + - type: FabricateActions + actions: + - ActionFabricateLollipop + - ActionFabricateGumball - type: SiliconLawProvider # Delta-V - Adds custom lawset for Medical cyborg laws: Medical diff --git a/Resources/Prototypes/Nyanotrasen/Actions/types.yml b/Resources/Prototypes/Nyanotrasen/Actions/types.yml index e6e4bdc5a75..04002f5755d 100644 --- a/Resources/Prototypes/Nyanotrasen/Actions/types.yml +++ b/Resources/Prototypes/Nyanotrasen/Actions/types.yml @@ -156,24 +156,3 @@ icon: Nyanotrasen/Interface/VerbIcons/psionic_invisibility_off.png event: !type:RemovePsionicInvisibilityOffPowerActionEvent -- type: entity - id: ActionFabricateLollipop - name: action-name-fabricate-lollipop - description: action-description-fabricate-lollipop - noSpawn: true - components: - - type: InstantAction - icon: { sprite: Nyanotrasen/Objects/Consumable/Food/candy.rsi, state: lollipop } - useDelay: 120 - event: !type:FabricateLollipopActionEvent - -- type: entity - id: ActionFabricateGumball - name: action-name-fabricate-gumball - description: action-description-fabricate-gumball - noSpawn: true - components: - - type: InstantAction - icon: { sprite: Nyanotrasen/Objects/Consumable/Food/candy.rsi, state: gumball } - useDelay: 40 - event: !type:FabricateGumballActionEvent