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 

<details><summary><h1>Media</h1></summary><p>


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

</p></details>

# 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>
This commit is contained in:
Mnemotechnican
2024-07-23 12:38:55 +03:00
committed by GitHub
parent fe84704eca
commit cf0498e89a
9 changed files with 112 additions and 75 deletions

View File

@@ -0,0 +1,19 @@
using Robust.Shared.Prototypes;
namespace Content.Server.Abilities.Borgs;
[RegisterComponent]
public sealed partial class FabricateActionsComponent : Component
{
/// <summary>
/// IDs of fabrication actions that the entity should receive with this component.
/// </summary>
[DataField]
public List<ProtoId<EntityPrototype>> Actions = new();
/// <summary>
/// Action entities added by this component.
/// </summary>
[DataField]
public Dictionary<ProtoId<EntityPrototype>, EntityUid> ActionEntities = new();
}

View File

@@ -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<FabricateActionsComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<FabricateActionsComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<FabricateActionsComponent, FabricateActionEvent>(OnFabricate);
}
private void OnStartup(Entity<FabricateActionsComponent> 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<FabricateActionsComponent> 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<FabricateActionsComponent> entity, ref FabricateActionEvent args)
{
if (args.Handled || !_actionBlocker.CanConsciouslyPerformAction(entity))
return;
SpawnNextToOrDrop(args.Fabrication, entity);
args.Handled = true;
}
}

View File

@@ -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;
}

View File

@@ -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<FabricateCandyComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<FabricateLollipopActionEvent>(OnLollipop);
SubscribeLocalEvent<FabricateGumballActionEvent>(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;
}
}

View File

@@ -0,0 +1,9 @@
using Robust.Shared.Prototypes;
namespace Content.Shared.Actions.Events;
public sealed partial class FabricateActionEvent : InstantActionEvent
{
[DataField(required: true)]
public ProtoId<EntityPrototype> Fabrication;
}

View File

@@ -1,4 +0,0 @@
namespace Content.Shared.Actions.Events;
public sealed partial class FabricateLollipopActionEvent : InstantActionEvent {}
public sealed partial class FabricateGumballActionEvent : InstantActionEvent {}

View File

@@ -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

View File

@@ -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

View File

@@ -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