Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wizard Item Recall Spell #34411

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions Content.Client/Actions/ActionsSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ private void BaseHandleState<T>(EntityUid uid, BaseActionComponent component, Ba
component.Priority = state.Priority;
component.AttachedEntity = EnsureEntity<T>(state.AttachedEntity, uid);
component.RaiseOnUser = state.RaiseOnUser;
component.RaiseOnAction = state.RaiseOnAction;
component.AutoPopulate = state.AutoPopulate;
component.Temporary = state.Temporary;
component.ItemIconStyle = state.ItemIconStyle;
Expand Down
8 changes: 8 additions & 0 deletions Content.Shared/Actions/BaseActionComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ public EntityUid? EntityIcon
[DataField]
public bool RaiseOnUser;

/// <summary>
/// If true, this will cause the the action event to always be raised directed at the action itself instead of the action's container/provider.
/// </summary>
[DataField]
public bool RaiseOnAction;
ScarKy0 marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Whether or not to automatically add this action to the action bar when it becomes available.
/// </summary>
Expand Down Expand Up @@ -212,6 +218,7 @@ public abstract class BaseActionComponentState : ComponentState
public int Priority;
public NetEntity? AttachedEntity;
public bool RaiseOnUser;
public bool RaiseOnAction;
public bool AutoPopulate;
public bool Temporary;
public ItemActionIconStyle ItemIconStyle;
Expand All @@ -223,6 +230,7 @@ protected BaseActionComponentState(BaseActionComponent component, IEntityManager
EntityIcon = entManager.GetNetEntity(component.EntIcon);
AttachedEntity = entManager.GetNetEntity(component.AttachedEntity);
RaiseOnUser = component.RaiseOnUser;
RaiseOnAction = component.RaiseOnAction;
Icon = component.Icon;
IconOn = component.IconOn;
IconColor = component.IconColor;
Expand Down
3 changes: 3 additions & 0 deletions Content.Shared/Actions/SharedActionsSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,9 @@ public void PerformAction(EntityUid performer, ActionsComponent? component, Enti
if (!action.RaiseOnUser && action.Container != null && !HasComp<MindComponent>(action.Container))
target = action.Container.Value;

if (action.RaiseOnAction && !HasComp<MindComponent>(actionId))
ScarKy0 marked this conversation as resolved.
Show resolved Hide resolved
target = actionId;

RaiseLocalEvent(target, (object) actionEvent, broadcast: true);
handled = actionEvent.Handled;
}
Expand Down
33 changes: 33 additions & 0 deletions Content.Shared/ItemRecall/ItemRecallComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Robust.Shared.GameStates;
using Robust.Shared.Utility;

namespace Content.Shared.ItemRecall;

[RegisterComponent, NetworkedComponent, Access(typeof(SharedItemRecallSystem))]
public sealed partial class ItemRecallComponent : Component
{
/// <summary>
/// Does this spell require Wizard Robes & Hat?
/// </summary>
[DataField]
public bool RequiresClothes = true;

[DataField]
public LocId WhileMarkedName = "";

[DataField]
public LocId WhileMarkedDescription = "";

[DataField]
public SpriteSpecifier? WhileMarkedSprite;

[ViewVariables]
public EntityUid? MarkedEntity;

/// <summary>
/// Does this spell require the user to speak?
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public bool RequiresSpeech;

ScarKy0 marked this conversation as resolved.
Show resolved Hide resolved
}
ScarKy0 marked this conversation as resolved.
Show resolved Hide resolved
12 changes: 12 additions & 0 deletions Content.Shared/ItemRecall/ItemRecallEvents.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Content.Shared.Actions;

namespace Content.Shared.ItemRecall;

/// <summary>
/// Raised directed on an entity when it embeds in another entity.
/// </summary>
[ByRefEvent]
public sealed partial class OnItemRecallActionEvent : InstantActionEvent
{

}
14 changes: 14 additions & 0 deletions Content.Shared/ItemRecall/RecallMarkerComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Robust.Shared.GameStates;
using Robust.Shared.Utility;

namespace Content.Shared.ItemRecall;

[RegisterComponent, NetworkedComponent, Access(typeof(SharedItemRecallSystem))]
public sealed partial class RecallMarkerComponent : Component
{
/// <summary>
/// Does this spell require Wizard Robes & Hat?
/// </summary>
[DataField]
public EntityUid MarkedByEntity;
}
56 changes: 56 additions & 0 deletions Content.Shared/ItemRecall/SharedItemRecallSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;

namespace Content.Shared.ItemRecall;

/// <summary>
/// uwu
/// </summary>
public sealed partial class SharedItemRecallSystem : EntitySystem
{

[Dependency] private readonly SharedHandsSystem _hands = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<ItemRecallComponent, OnItemRecallActionEvent>(OnItemRecallUse);
}

public void OnItemRecallUse(Entity<ItemRecallComponent> ent, ref OnItemRecallActionEvent args)
{

if (ent.Comp.MarkedEntity == null)
{
Log.Debug("Trying for hands");
if (!TryComp<HandsComponent>(args.Performer, out var hands))
return;

Log.Debug("Marking");
var markItem = _hands.GetActiveItem((args.Performer, hands));
TryMarkItem(ent, markItem, args.Performer);
return;
}

RecallItem(ent.Comp.MarkedEntity);
}

private void TryMarkItem(Entity<ItemRecallComponent> ent, EntityUid? item, EntityUid markedBy)
{
if (item == null)
return;
ScarKy0 marked this conversation as resolved.
Show resolved Hide resolved
Log.Debug("Adding component");
EnsureComp<RecallMarkerComponent>(item.Value, out var marker);
ent.Comp.MarkedEntity = item;
marker.MarkedByEntity = markedBy;
}

private void RecallItem(EntityUid? item)
{
if (!TryComp<RecallMarkerComponent>(item, out var marker))
return;
ScarKy0 marked this conversation as resolved.
Show resolved Hide resolved

_hands.TryForcePickupAnyHand(marker.MarkedByEntity, item.Value);
ScarKy0 marked this conversation as resolved.
Show resolved Hide resolved
}
}
13 changes: 13 additions & 0 deletions Resources/Prototypes/Catalog/spellbook_catalog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,16 @@
- SpellbookJaunt
- !type:ListingLimitedStockCondition
stock: 2

- type: listing
id: SpellbookItemRecallSwap
name: recall
description: recall
productAction: ActionItemRecall
cost:
WizCoin: 1
categories:
- SpellbookUtility
conditions:
- !type:ListingLimitedStockCondition
stock: 1
16 changes: 16 additions & 0 deletions Resources/Prototypes/Magic/recall_spell.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
- type: entity
id: ActionItemRecall
name: item recall
description: Mark and summon an item back into your hand.
components:
- type: InstantAction
useDelay: 5
raiseOnAction: true
itemIconStyle: BigAction
sound: !type:SoundPathSpecifier
path: /Audio/Magic/forcewall.ogg
icon:
sprite: Objects/Magic/magicactions.rsi
state: shield
event: !type:OnItemRecallActionEvent
- type: ItemRecall
Loading