diff --git a/Content.Server/Abilities/Borgs/FabricateActionsComponent.cs b/Content.Server/Abilities/Borgs/FabricateActionsComponent.cs new file mode 100644 index 0000000000..c9a693562f --- /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 0000000000..c73b46c0b8 --- /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 d0a399c1fe..0000000000 --- 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 6451c7cbb2..0000000000 --- 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 0000000000..7483cb04d9 --- /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 3c9371d27e..0000000000 --- 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 22f16bd956..f55f59daaa 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 6191e61250..5056fda4c0 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 e6e4bdc5a7..04002f5755 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