using Content.Shared.Interaction;
using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
namespace Content.Server.Actions;
[RegisterComponent]
public sealed partial class ActionOnInteractComponent : Component
{
- [DataField(required:true)]
+ [DataField(required: true)]
public List<EntProtoId>? Actions;
[DataField] public List<EntityUid>? ActionEntities;
+
+ [DataField] public bool RequiresCharge;
}
using System.Linq;
using Content.Shared.Actions;
+using Content.Shared.Charges.Components;
+using Content.Shared.Charges.Systems;
using Content.Shared.Interaction;
using Robust.Shared.Random;
using Robust.Shared.Timing;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedActionsSystem _actions = default!;
[Dependency] private readonly ActionContainerSystem _actionContainer = default!;
+ [Dependency] private readonly SharedChargesSystem _charges = default!;
public override void Initialize()
{
if (options.Count == 0)
return;
+ if (!TryUseCharge((uid, component)))
+ return;
+
var (actId, act) = _random.Pick(options);
_actions.PerformAction(args.User, null, actId, act, act.Event, _timing.CurTime, false);
args.Handled = true;
if (entOptions.Count > 0)
{
+ if (!TryUseCharge((uid, component)))
+ return;
+
var (entActId, entAct) = _random.Pick(entOptions);
if (entAct.Event != null)
{
if (entWorldOptions.Count > 0)
{
+ if (!TryUseCharge((uid, component)))
+ return;
+
var (entActId, entAct) = _random.Pick(entWorldOptions);
if (entAct.Event != null)
{
if (options.Count == 0)
return;
+ if (!TryUseCharge((uid, component)))
+ return;
+
var (actId, act) = _random.Pick(options);
if (act.Event != null)
{
return valid;
}
+
+ private bool TryUseCharge(Entity<ActionOnInteractComponent> ent)
+ {
+ if (!ent.Comp.RequiresCharge)
+ return true;
+
+ Entity<LimitedChargesComponent?> charges = ent.Owner;
+ if (_charges.IsEmpty(charges))
+ return false;
+
+ _charges.TryUseCharge(charges);
+ return true;
+ }
}
{
if (_container.TryGetContainingContainer(targetUid, out var container))
{
+ if (container.Owner == owner)
+ return 0f;
+
if (TryComp<EntityStorageComponent>(container.Owner, out var storageComponent))
{
if (storageComponent is { Open: false } && _weldable.IsWelded(container.Owner))
_container.AttachParentToContainerOrGrid((ent, xform)); // Items animated inside inventory now exit, they can't be picked up and so can't escape otherwise
var ev = new AnimateSpellEvent();
- RaiseLocalEvent(ref ev);
+ RaiseLocalEvent(ent, ref ev);
}
}
name: Animate
description: Bring an inanimate object to life!
components:
- - type: LimitedCharges
- maxCharges: 5
- type: EntityTargetAction
useDelay: 0
itemIconStyle: BigAction
whitelist:
components:
- - Animateable # Currently on: SeatBase, TableBase, ClosetBase, BaseMachine, ConstructibleMachine, BaseComputer, BaseItem, CrateGeneric, StorageTank, GasCanister, BaseTarget
+ - Animateable # Currently on: SeatBase, TableBase, ClosetBase, BaseMachine, ConstructibleMachine, BaseComputer, BaseItem, CrateGeneric, StorageTank, GasCanister
blacklist:
components:
- MindContainer
- AnomalyGenerator
- TegGenerator
- TegCirculator
- - Artifact
+ - XenoArtifact
canTargetSelf: false
interactOnMiss: false
sound: !type:SoundPathSpecifier
collection: MetalBreak
- type: Hands
- type: CanEscapeInventory
+ - type: MobCollision
toRemove:
- RequireProjectileTarget
- BlockMovement
- Item
+ - MeleeRequiresWield
speech: action-speech-spell-animate
doSpeech: false
name: RGB staff
description: Helps fix the underabundance of RGB gear on the station.
components:
+ - type: LimitedCharges
+ maxCharges: 25
+ - type: AutoRecharge
+ rechargeDuration: 30
- type: Sprite
sprite: Objects/Weapons/Guns/Basic/staves.rsi
layers:
- state: nothing-unshaded
shader: unshaded
- type: ActionOnInteract
+ requiresCharge: true
actions:
- ActionRgbLight
- type: Item
name: staff of animation
description: Brings inanimate objects to life!
components:
+ - type: LimitedCharges
+ maxCharges: 5
+ - type: AutoRecharge
+ rechargeDuration: 30
- type: Sprite
sprite: Objects/Weapons/Guns/Basic/staves.rsi
layers:
- state: animation
- type: ActionOnInteract
+ requiresCharge: true
actions:
- ActionAnimateSpell
- type: Item
- type: entity
id: ActionRgbLight
components:
- - type: LimitedCharges
- maxCharges: 25
- type: EntityTargetAction
whitelist: { components: [ PointLight ] }
sound: /Audio/Magic/blink.ogg