Wizard Item Recall Spell (#34411)
This commit is contained in:
@@ -137,6 +137,7 @@ namespace Content.Client.Actions
|
|||||||
component.Priority = state.Priority;
|
component.Priority = state.Priority;
|
||||||
component.AttachedEntity = EnsureEntity<T>(state.AttachedEntity, uid);
|
component.AttachedEntity = EnsureEntity<T>(state.AttachedEntity, uid);
|
||||||
component.RaiseOnUser = state.RaiseOnUser;
|
component.RaiseOnUser = state.RaiseOnUser;
|
||||||
|
component.RaiseOnAction = state.RaiseOnAction;
|
||||||
component.AutoPopulate = state.AutoPopulate;
|
component.AutoPopulate = state.AutoPopulate;
|
||||||
component.Temporary = state.Temporary;
|
component.Temporary = state.Temporary;
|
||||||
component.ItemIconStyle = state.ItemIconStyle;
|
component.ItemIconStyle = state.ItemIconStyle;
|
||||||
|
|||||||
11
Content.Client/ItemRecall/ItemRecallSystem.cs
Normal file
11
Content.Client/ItemRecall/ItemRecallSystem.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Content.Shared.ItemRecall;
|
||||||
|
|
||||||
|
namespace Content.Client.ItemRecall;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// System for handling the ItemRecall ability for wizards.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class ItemRecallSystem : SharedItemRecallSystem
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
11
Content.Server/ItemRecall/ItemRecallSystem.cs
Normal file
11
Content.Server/ItemRecall/ItemRecallSystem.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Content.Shared.ItemRecall;
|
||||||
|
|
||||||
|
namespace Content.Server.ItemRecall;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// System for handling the ItemRecall ability for wizards.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class ItemRecallSystem : SharedItemRecallSystem
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -167,6 +167,14 @@ public abstract partial class BaseActionComponent : Component
|
|||||||
[DataField]
|
[DataField]
|
||||||
public bool RaiseOnUser;
|
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.
|
||||||
|
/// Takes priority over RaiseOnUser.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
[Obsolete("This datafield will be reworked in an upcoming action refactor")]
|
||||||
|
public bool RaiseOnAction;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether or not to automatically add this action to the action bar when it becomes available.
|
/// Whether or not to automatically add this action to the action bar when it becomes available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -212,6 +220,7 @@ public abstract class BaseActionComponentState : ComponentState
|
|||||||
public int Priority;
|
public int Priority;
|
||||||
public NetEntity? AttachedEntity;
|
public NetEntity? AttachedEntity;
|
||||||
public bool RaiseOnUser;
|
public bool RaiseOnUser;
|
||||||
|
public bool RaiseOnAction;
|
||||||
public bool AutoPopulate;
|
public bool AutoPopulate;
|
||||||
public bool Temporary;
|
public bool Temporary;
|
||||||
public ItemActionIconStyle ItemIconStyle;
|
public ItemActionIconStyle ItemIconStyle;
|
||||||
@@ -223,6 +232,7 @@ public abstract class BaseActionComponentState : ComponentState
|
|||||||
EntityIcon = entManager.GetNetEntity(component.EntIcon);
|
EntityIcon = entManager.GetNetEntity(component.EntIcon);
|
||||||
AttachedEntity = entManager.GetNetEntity(component.AttachedEntity);
|
AttachedEntity = entManager.GetNetEntity(component.AttachedEntity);
|
||||||
RaiseOnUser = component.RaiseOnUser;
|
RaiseOnUser = component.RaiseOnUser;
|
||||||
|
RaiseOnAction = component.RaiseOnAction;
|
||||||
Icon = component.Icon;
|
Icon = component.Icon;
|
||||||
IconOn = component.IconOn;
|
IconOn = component.IconOn;
|
||||||
IconColor = component.IconColor;
|
IconColor = component.IconColor;
|
||||||
|
|||||||
@@ -679,6 +679,9 @@ public abstract class SharedActionsSystem : EntitySystem
|
|||||||
if (!action.RaiseOnUser && action.Container != null && !HasComp<MindComponent>(action.Container))
|
if (!action.RaiseOnUser && action.Container != null && !HasComp<MindComponent>(action.Container))
|
||||||
target = action.Container.Value;
|
target = action.Container.Value;
|
||||||
|
|
||||||
|
if (action.RaiseOnAction)
|
||||||
|
target = actionId;
|
||||||
|
|
||||||
RaiseLocalEvent(target, (object) actionEvent, broadcast: true);
|
RaiseLocalEvent(target, (object) actionEvent, broadcast: true);
|
||||||
handled = actionEvent.Handled;
|
handled = actionEvent.Handled;
|
||||||
}
|
}
|
||||||
|
|||||||
43
Content.Shared/ItemRecall/ItemRecallComponent.cs
Normal file
43
Content.Shared/ItemRecall/ItemRecallComponent.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.ItemRecall;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Component for the ItemRecall action.
|
||||||
|
/// Used for marking a held item and recalling it back into your hand with second action use.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedItemRecallSystem))]
|
||||||
|
public sealed partial class ItemRecallComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The name the action should have while an entity is marked.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public LocId? WhileMarkedName = "item-recall-marked-name";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The description the action should have while an entity is marked.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public LocId? WhileMarkedDescription = "item-recall-marked-description";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name the action starts with.
|
||||||
|
/// This shouldn't be set in yaml.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public string? InitialName;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The description the action starts with.
|
||||||
|
/// This shouldn't be set in yaml.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public string? InitialDescription;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The entity currently marked to be recalled by this action.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public EntityUid? MarkedEntity;
|
||||||
|
}
|
||||||
9
Content.Shared/ItemRecall/ItemRecallEvents.cs
Normal file
9
Content.Shared/ItemRecall/ItemRecallEvents.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using Content.Shared.Actions;
|
||||||
|
|
||||||
|
namespace Content.Shared.ItemRecall;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised when using the ItemRecall action.
|
||||||
|
/// </summary>
|
||||||
|
[ByRefEvent]
|
||||||
|
public sealed partial class OnItemRecallActionEvent : InstantActionEvent;
|
||||||
18
Content.Shared/ItemRecall/RecallMarkerComponent.cs
Normal file
18
Content.Shared/ItemRecall/RecallMarkerComponent.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Shared.ItemRecall;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Component used as a marker for an item marked by the ItemRecall ability.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedItemRecallSystem))]
|
||||||
|
public sealed partial class RecallMarkerComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The action that marked this item.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public EntityUid? MarkedByAction;
|
||||||
|
}
|
||||||
187
Content.Shared/ItemRecall/SharedItemRecallSystem.cs
Normal file
187
Content.Shared/ItemRecall/SharedItemRecallSystem.cs
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
using Content.Shared.Actions;
|
||||||
|
using Content.Shared.Hands.Components;
|
||||||
|
using Content.Shared.Hands.EntitySystems;
|
||||||
|
using Content.Shared.Popups;
|
||||||
|
using Content.Shared.Projectiles;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
|
||||||
|
namespace Content.Shared.ItemRecall;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// System for handling the ItemRecall ability for wizards.
|
||||||
|
/// </summary>
|
||||||
|
public abstract partial class SharedItemRecallSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly ISharedPlayerManager _player = default!;
|
||||||
|
[Dependency] private readonly SharedPvsOverrideSystem _pvs = default!;
|
||||||
|
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||||
|
[Dependency] private readonly SharedHandsSystem _hands = default!;
|
||||||
|
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||||
|
[Dependency] private readonly SharedPopupSystem _popups = default!;
|
||||||
|
[Dependency] private readonly SharedProjectileSystem _proj = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<ItemRecallComponent, MapInitEvent>(OnMapInit);
|
||||||
|
SubscribeLocalEvent<ItemRecallComponent, OnItemRecallActionEvent>(OnItemRecallActionUse);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<RecallMarkerComponent, ComponentShutdown>(OnRecallMarkerShutdown);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnMapInit(Entity<ItemRecallComponent> ent, ref MapInitEvent args)
|
||||||
|
{
|
||||||
|
ent.Comp.InitialName = Name(ent);
|
||||||
|
ent.Comp.InitialDescription = Description(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnItemRecallActionUse(Entity<ItemRecallComponent> ent, ref OnItemRecallActionEvent args)
|
||||||
|
{
|
||||||
|
if (ent.Comp.MarkedEntity == null)
|
||||||
|
{
|
||||||
|
if (!TryComp<HandsComponent>(args.Performer, out var hands))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var markItem = _hands.GetActiveItem((args.Performer, hands));
|
||||||
|
|
||||||
|
if (markItem == null)
|
||||||
|
{
|
||||||
|
_popups.PopupClient(Loc.GetString("item-recall-item-mark-empty"), args.Performer, args.Performer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasComp<RecallMarkerComponent>(markItem))
|
||||||
|
{
|
||||||
|
_popups.PopupClient(Loc.GetString("item-recall-item-already-marked", ("item", markItem)), args.Performer, args.Performer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_popups.PopupClient(Loc.GetString("item-recall-item-marked", ("item", markItem.Value)), args.Performer, args.Performer);
|
||||||
|
TryMarkItem(ent, markItem.Value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RecallItem(ent.Comp.MarkedEntity.Value);
|
||||||
|
args.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RecallItem(Entity<RecallMarkerComponent?> ent)
|
||||||
|
{
|
||||||
|
if (!Resolve(ent.Owner, ref ent.Comp, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!TryComp<InstantActionComponent>(ent.Comp.MarkedByAction, out var instantAction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var actionOwner = instantAction.AttachedEntity;
|
||||||
|
|
||||||
|
if (actionOwner == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (TryComp<EmbeddableProjectileComponent>(ent, out var projectile))
|
||||||
|
_proj.UnEmbed(ent, projectile, actionOwner.Value);
|
||||||
|
|
||||||
|
_popups.PopupPredicted(Loc.GetString("item-recall-item-summon", ("item", ent)), actionOwner.Value, actionOwner.Value);
|
||||||
|
|
||||||
|
_hands.TryForcePickupAnyHand(actionOwner.Value, ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnRecallMarkerShutdown(Entity<RecallMarkerComponent> ent, ref ComponentShutdown args)
|
||||||
|
{
|
||||||
|
TryUnmarkItem(ent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TryMarkItem(Entity<ItemRecallComponent> ent, EntityUid item)
|
||||||
|
{
|
||||||
|
if (!TryComp<InstantActionComponent>(ent, out var instantAction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var actionOwner = instantAction.AttachedEntity;
|
||||||
|
|
||||||
|
if (actionOwner == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
AddToPvsOverride(item, actionOwner.Value);
|
||||||
|
|
||||||
|
var marker = AddComp<RecallMarkerComponent>(item);
|
||||||
|
ent.Comp.MarkedEntity = item;
|
||||||
|
Dirty(ent);
|
||||||
|
|
||||||
|
marker.MarkedByAction = ent.Owner;
|
||||||
|
|
||||||
|
UpdateActionAppearance(ent);
|
||||||
|
Dirty(item, marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TryUnmarkItem(EntityUid item)
|
||||||
|
{
|
||||||
|
if (!TryComp<RecallMarkerComponent>(item, out var marker))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!TryComp<InstantActionComponent>(marker.MarkedByAction, out var instantAction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (TryComp<ItemRecallComponent>(marker.MarkedByAction, out var action))
|
||||||
|
{
|
||||||
|
// For some reason client thinks the station grid owns the action on client and this doesn't work. It doesn't work in PopupEntity(mispredicts) and PopupPredicted either(doesnt show).
|
||||||
|
// I don't have the heart to move this code to server because of this small thing.
|
||||||
|
// This line will only do something once that is fixed.
|
||||||
|
if (instantAction.AttachedEntity != null)
|
||||||
|
{
|
||||||
|
_popups.PopupClient(Loc.GetString("item-recall-item-unmark", ("item", item)), instantAction.AttachedEntity.Value, instantAction.AttachedEntity.Value, PopupType.MediumCaution);
|
||||||
|
RemoveFromPvsOverride(item, instantAction.AttachedEntity.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
action.MarkedEntity = null;
|
||||||
|
UpdateActionAppearance((marker.MarkedByAction.Value, action));
|
||||||
|
Dirty(marker.MarkedByAction.Value, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
RemCompDeferred<RecallMarkerComponent>(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateActionAppearance(Entity<ItemRecallComponent> action)
|
||||||
|
{
|
||||||
|
if (!TryComp<InstantActionComponent>(action, out var instantAction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (action.Comp.MarkedEntity == null)
|
||||||
|
{
|
||||||
|
if (action.Comp.InitialName != null)
|
||||||
|
_metaData.SetEntityName(action, action.Comp.InitialName);
|
||||||
|
if (action.Comp.InitialDescription != null)
|
||||||
|
_metaData.SetEntityDescription(action, action.Comp.InitialDescription);
|
||||||
|
_actions.SetEntityIcon(action, null, instantAction);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (action.Comp.WhileMarkedName != null)
|
||||||
|
_metaData.SetEntityName(action, Loc.GetString(action.Comp.WhileMarkedName,
|
||||||
|
("item", action.Comp.MarkedEntity.Value)));
|
||||||
|
|
||||||
|
if (action.Comp.WhileMarkedDescription != null)
|
||||||
|
_metaData.SetEntityDescription(action, Loc.GetString(action.Comp.WhileMarkedDescription,
|
||||||
|
("item", action.Comp.MarkedEntity.Value)));
|
||||||
|
|
||||||
|
_actions.SetEntityIcon(action, action.Comp.MarkedEntity, instantAction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddToPvsOverride(EntityUid uid, EntityUid user)
|
||||||
|
{
|
||||||
|
if (!_player.TryGetSessionByEntity(user, out var mindSession))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_pvs.AddSessionOverride(uid, mindSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveFromPvsOverride(EntityUid uid, EntityUid user)
|
||||||
|
{
|
||||||
|
if (!_player.TryGetSessionByEntity(user, out var mindSession))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_pvs.RemoveSessionOverride(uid, mindSession);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -67,25 +67,7 @@ public abstract partial class SharedProjectileSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var xform = Transform(uid);
|
UnEmbed(uid, component, args.User);
|
||||||
TryComp<PhysicsComponent>(uid, out var physics);
|
|
||||||
_physics.SetBodyType(uid, BodyType.Dynamic, body: physics, xform: xform);
|
|
||||||
_transform.AttachToGridOrMap(uid, xform);
|
|
||||||
component.EmbeddedIntoUid = null;
|
|
||||||
Dirty(uid, component);
|
|
||||||
|
|
||||||
// Reset whether the projectile has damaged anything if it successfully was removed
|
|
||||||
if (TryComp<ProjectileComponent>(uid, out var projectile))
|
|
||||||
{
|
|
||||||
projectile.Shooter = null;
|
|
||||||
projectile.Weapon = null;
|
|
||||||
projectile.ProjectileSpent = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Land it just coz uhhh yeah
|
|
||||||
var landEv = new LandEvent(args.User, true);
|
|
||||||
RaiseLocalEvent(uid, ref landEv);
|
|
||||||
_physics.WakeBody(uid, body: physics);
|
|
||||||
|
|
||||||
// try place it in the user's hand
|
// try place it in the user's hand
|
||||||
_hands.TryPickupAnyHand(args.User, uid);
|
_hands.TryPickupAnyHand(args.User, uid);
|
||||||
@@ -135,6 +117,38 @@ public abstract partial class SharedProjectileSystem : EntitySystem
|
|||||||
Dirty(uid, component);
|
Dirty(uid, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UnEmbed(EntityUid uid, EmbeddableProjectileComponent? component, EntityUid? user = null)
|
||||||
|
{
|
||||||
|
if (!Resolve(uid, ref component))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var xform = Transform(uid);
|
||||||
|
TryComp<PhysicsComponent>(uid, out var physics);
|
||||||
|
_physics.SetBodyType(uid, BodyType.Dynamic, body: physics, xform: xform);
|
||||||
|
_transform.AttachToGridOrMap(uid, xform);
|
||||||
|
component.EmbeddedIntoUid = null;
|
||||||
|
Dirty(uid, component);
|
||||||
|
|
||||||
|
// Reset whether the projectile has damaged anything if it successfully was removed
|
||||||
|
if (TryComp<ProjectileComponent>(uid, out var projectile))
|
||||||
|
{
|
||||||
|
projectile.Shooter = null;
|
||||||
|
projectile.Weapon = null;
|
||||||
|
projectile.ProjectileSpent = false;
|
||||||
|
|
||||||
|
Dirty(uid, projectile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
// Land it just coz uhhh yeah
|
||||||
|
var landEv = new LandEvent(user, true);
|
||||||
|
RaiseLocalEvent(uid, ref landEv);
|
||||||
|
}
|
||||||
|
|
||||||
|
_physics.WakeBody(uid, body: physics);
|
||||||
|
}
|
||||||
|
|
||||||
private void PreventCollision(EntityUid uid, ProjectileComponent component, ref PreventCollideEvent args)
|
private void PreventCollision(EntityUid uid, ProjectileComponent component, ref PreventCollideEvent args)
|
||||||
{
|
{
|
||||||
if (component.IgnoreShooter && (args.OtherEntity == component.Shooter || args.OtherEntity == component.Weapon))
|
if (component.IgnoreShooter && (args.OtherEntity == component.Shooter || args.OtherEntity == component.Weapon))
|
||||||
|
|||||||
9
Resources/Locale/en-US/item-recall/item-recall.ftl
Normal file
9
Resources/Locale/en-US/item-recall/item-recall.ftl
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
item-recall-marked-name = Recall {CAPITALIZE($item)}
|
||||||
|
item-recall-marked-description = Recall {THE($item)} back into your hand.
|
||||||
|
|
||||||
|
item-recall-item-marked = You draw a magical sigil on {THE($item)}.
|
||||||
|
item-recall-item-already-marked = {CAPITALIZE(THE($item))} is already marked!
|
||||||
|
item-recall-item-mark-empty = You must be holding an item!
|
||||||
|
item-recall-item-summon = {CAPITALIZE(THE($item))} appears in your hand!
|
||||||
|
item-recall-item-unmark = You feel your connection with {THE($item)} sever.
|
||||||
|
|
||||||
@@ -35,6 +35,9 @@ spellbook-cluwne-desc = For when you really hate someone and Smite isn't enough.
|
|||||||
spellbook-slip-name = Slippery Slope
|
spellbook-slip-name = Slippery Slope
|
||||||
spellbook-slip-desc = Learn the ancient ways of the Janitor and curse your target to be slippery. Requires Wizard Robe & Hat.
|
spellbook-slip-desc = Learn the ancient ways of the Janitor and curse your target to be slippery. Requires Wizard Robe & Hat.
|
||||||
|
|
||||||
|
spellbook-item-recall-name = Item Recall
|
||||||
|
spellbook-item-recall-description = Mark a held item and summon it back at any time with just a snap of your fingers!
|
||||||
|
|
||||||
# Equipment
|
# Equipment
|
||||||
|
|
||||||
spellbook-wand-polymorph-door-name = Wand of Entrance
|
spellbook-wand-polymorph-door-name = Wand of Entrance
|
||||||
|
|||||||
@@ -278,3 +278,16 @@
|
|||||||
- SpellbookJaunt
|
- SpellbookJaunt
|
||||||
- !type:ListingLimitedStockCondition
|
- !type:ListingLimitedStockCondition
|
||||||
stock: 2
|
stock: 2
|
||||||
|
|
||||||
|
- type: listing
|
||||||
|
id: SpellbookItemRecallSwap
|
||||||
|
name: spellbook-item-recall-name
|
||||||
|
description: spellbook-item-recall-description
|
||||||
|
productAction: ActionItemRecall
|
||||||
|
cost:
|
||||||
|
WizCoin: 1
|
||||||
|
categories:
|
||||||
|
- SpellbookUtility
|
||||||
|
conditions:
|
||||||
|
- !type:ListingLimitedStockCondition
|
||||||
|
stock: 1
|
||||||
|
|||||||
21
Resources/Prototypes/Magic/recall_spell.yml
Normal file
21
Resources/Prototypes/Magic/recall_spell.yml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
- type: entity
|
||||||
|
id: ActionItemRecall
|
||||||
|
name: Mark Item
|
||||||
|
description: Mark a held item to later summon into your hand.
|
||||||
|
components:
|
||||||
|
- type: InstantAction
|
||||||
|
useDelay: 10
|
||||||
|
raiseOnAction: true
|
||||||
|
itemIconStyle: BigAction
|
||||||
|
sound: !type:SoundPathSpecifier
|
||||||
|
path: /Audio/Magic/forcewall.ogg
|
||||||
|
params:
|
||||||
|
volume: -5
|
||||||
|
pitch: 1.2
|
||||||
|
maxDistance: 5
|
||||||
|
variation: 0.2
|
||||||
|
icon:
|
||||||
|
sprite: Objects/Magic/magicactions.rsi
|
||||||
|
state: item_recall
|
||||||
|
event: !type:OnItemRecallActionEvent
|
||||||
|
- type: ItemRecall
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"license": "CC-BY-SA-3.0",
|
"license": "CC-BY-SA-3.0",
|
||||||
"copyright": "https://github.com/Citadel-Station-13/Citadel-Station-13/commit/78db6bd5c2b2b3d1f5cd8fd75be3a39d5d929943 andhttps://github.com/tgstation/tgstation/commit/906fb0682bab6a0975b45036001c54f021f58ae7 ",
|
"copyright": "https://github.com/Citadel-Station-13/Citadel-Station-13/commit/78db6bd5c2b2b3d1f5cd8fd75be3a39d5d929943 and https://github.com/tgstation/tgstation/commit/906fb0682bab6a0975b45036001c54f021f58ae7, item_recall by ScarKy0",
|
||||||
"size": {
|
"size": {
|
||||||
"x": 32,
|
"x": 32,
|
||||||
"y": 32
|
"y": 32
|
||||||
@@ -30,6 +30,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "gib"
|
"name": "gib"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "item_recall"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user