Re-add action prototypes (#7508)
Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
This commit is contained in:
@@ -183,7 +183,7 @@ public sealed class DecalPlacementSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class PlaceDecalActionEvent : PerformWorldTargetActionEvent
|
public sealed class PlaceDecalActionEvent : WorldTargetActionEvent
|
||||||
{
|
{
|
||||||
[DataField("decalId", customTypeSerializer:typeof(PrototypeIdSerializer<DecalPrototype>))]
|
[DataField("decalId", customTypeSerializer:typeof(PrototypeIdSerializer<DecalPrototype>))]
|
||||||
public string DecalId = string.Empty;
|
public string DecalId = string.Empty;
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ public sealed partial class MappingSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class StartPlacementActionEvent : PerformActionEvent
|
public sealed class StartPlacementActionEvent : InstantActionEvent
|
||||||
{
|
{
|
||||||
[DataField("entityType")]
|
[DataField("entityType")]
|
||||||
public string? EntityType;
|
public string? EntityType;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
SubscribeLocalEvent<GasTankComponent, BeforeActivatableUIOpenEvent>(BeforeUiOpen);
|
SubscribeLocalEvent<GasTankComponent, BeforeActivatableUIOpenEvent>(BeforeUiOpen);
|
||||||
SubscribeLocalEvent<GasTankComponent, GetActionsEvent>(OnGetActions);
|
SubscribeLocalEvent<GasTankComponent, GetItemActionsEvent>(OnGetActions);
|
||||||
SubscribeLocalEvent<GasTankComponent, ExaminedEvent>(OnExamined);
|
SubscribeLocalEvent<GasTankComponent, ExaminedEvent>(OnExamined);
|
||||||
SubscribeLocalEvent<GasTankComponent, ToggleActionEvent>(OnActionToggle);
|
SubscribeLocalEvent<GasTankComponent, ToggleActionEvent>(OnActionToggle);
|
||||||
SubscribeLocalEvent<GasTankComponent, DroppedEvent>(OnDropped);
|
SubscribeLocalEvent<GasTankComponent, DroppedEvent>(OnDropped);
|
||||||
@@ -37,7 +37,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
component.DisconnectFromInternals(args.User);
|
component.DisconnectFromInternals(args.User);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGetActions(EntityUid uid, GasTankComponent component, GetActionsEvent args)
|
private void OnGetActions(EntityUid uid, GasTankComponent component, GetItemActionsEvent args)
|
||||||
{
|
{
|
||||||
args.Actions.Add(component.ToggleAction);
|
args.Actions.Add(component.ToggleAction);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,5 +29,5 @@ namespace Content.Server.Ghost.Components
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class BooActionEvent : PerformActionEvent { }
|
public sealed class BooActionEvent : InstantActionEvent { }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,5 +36,5 @@ namespace Content.Server.Guardian
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class GuardianToggleActionEvent : PerformActionEvent { };
|
public sealed class GuardianToggleActionEvent : InstantActionEvent { };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Content.Server.Light.Components;
|
|||||||
using Content.Server.Popups;
|
using Content.Server.Popups;
|
||||||
using Content.Server.PowerCell;
|
using Content.Server.PowerCell;
|
||||||
using Content.Shared.Actions;
|
using Content.Shared.Actions;
|
||||||
|
using Content.Shared.Actions.ActionTypes;
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Light.Component;
|
using Content.Shared.Light.Component;
|
||||||
@@ -14,6 +15,7 @@ using Robust.Server.GameObjects;
|
|||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Server.Light.EntitySystems
|
namespace Content.Server.Light.EntitySystems
|
||||||
@@ -24,6 +26,7 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
[Dependency] private readonly PopupSystem _popup = default!;
|
[Dependency] private readonly PopupSystem _popup = default!;
|
||||||
[Dependency] private readonly PowerCellSystem _powerCell = default!;
|
[Dependency] private readonly PowerCellSystem _powerCell = default!;
|
||||||
[Dependency] private readonly ActionsSystem _actionSystem = default!;
|
[Dependency] private readonly ActionsSystem _actionSystem = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||||
|
|
||||||
// TODO: Ideally you'd be able to subscribe to power stuff to get events at certain percentages.. or something?
|
// TODO: Ideally you'd be able to subscribe to power stuff to get events at certain percentages.. or something?
|
||||||
// But for now this will be better anyway.
|
// But for now this will be better anyway.
|
||||||
@@ -42,13 +45,20 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
|
|
||||||
SubscribeLocalEvent<HandheldLightComponent, ActivateInWorldEvent>(OnActivate);
|
SubscribeLocalEvent<HandheldLightComponent, ActivateInWorldEvent>(OnActivate);
|
||||||
|
|
||||||
SubscribeLocalEvent<HandheldLightComponent, GetActionsEvent>(OnGetActions);
|
SubscribeLocalEvent<HandheldLightComponent, GetItemActionsEvent>(OnGetActions);
|
||||||
SubscribeLocalEvent<HandheldLightComponent, ToggleActionEvent>(OnToggleAction);
|
SubscribeLocalEvent<HandheldLightComponent, ToggleActionEvent>(OnToggleAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGetActions(EntityUid uid, HandheldLightComponent component, GetActionsEvent args)
|
private void OnGetActions(EntityUid uid, HandheldLightComponent component, GetItemActionsEvent args)
|
||||||
{
|
{
|
||||||
args.Actions.Add(component.ToggleAction);
|
if (component.ToggleAction == null
|
||||||
|
&& _proto.TryIndex(component.ToggleActionId, out InstantActionPrototype? act))
|
||||||
|
{
|
||||||
|
component.ToggleAction = new(act);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.ToggleAction != null)
|
||||||
|
args.Actions.Add(component.ToggleAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnToggleAction(EntityUid uid, HandheldLightComponent component, ToggleActionEvent args)
|
private void OnToggleAction(EntityUid uid, HandheldLightComponent component, ToggleActionEvent args)
|
||||||
@@ -169,7 +179,8 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
if (!component.Activated) return false;
|
if (!component.Activated) return false;
|
||||||
|
|
||||||
component.Activated = false;
|
component.Activated = false;
|
||||||
_actionSystem.SetToggled(component.ToggleAction, false);
|
if (component.ToggleAction != null)
|
||||||
|
_actionSystem.SetToggled(component.ToggleAction, false);
|
||||||
_activeLights.Remove(component);
|
_activeLights.Remove(component);
|
||||||
component.LastLevel = null;
|
component.LastLevel = null;
|
||||||
component.Dirty(EntityManager);
|
component.Dirty(EntityManager);
|
||||||
@@ -202,7 +213,8 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
}
|
}
|
||||||
|
|
||||||
component.Activated = true;
|
component.Activated = true;
|
||||||
_actionSystem.SetToggled(component.ToggleAction, true);
|
if (component.ToggleAction != null)
|
||||||
|
_actionSystem.SetToggled(component.ToggleAction, true);
|
||||||
_activeLights.Add(component);
|
_activeLights.Add(component);
|
||||||
component.LastLevel = GetLevel(component);
|
component.LastLevel = GetLevel(component);
|
||||||
Dirty(component);
|
Dirty(component);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<UnpoweredFlashlightComponent, GetVerbsEvent<ActivationVerb>>(AddToggleLightVerbs);
|
SubscribeLocalEvent<UnpoweredFlashlightComponent, GetVerbsEvent<ActivationVerb>>(AddToggleLightVerbs);
|
||||||
SubscribeLocalEvent<UnpoweredFlashlightComponent, GetActionsEvent>(OnGetActions);
|
SubscribeLocalEvent<UnpoweredFlashlightComponent, GetItemActionsEvent>(OnGetActions);
|
||||||
SubscribeLocalEvent<UnpoweredFlashlightComponent, ToggleActionEvent>(OnToggleAction);
|
SubscribeLocalEvent<UnpoweredFlashlightComponent, ToggleActionEvent>(OnToggleAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGetActions(EntityUid uid, UnpoweredFlashlightComponent component, GetActionsEvent args)
|
private void OnGetActions(EntityUid uid, UnpoweredFlashlightComponent component, GetItemActionsEvent args)
|
||||||
{
|
{
|
||||||
args.Actions.Add(component.ToggleAction);
|
args.Actions.Add(component.ToggleAction);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ using Content.Shared.Actions;
|
|||||||
using Content.Shared.Actions.ActionTypes;
|
using Content.Shared.Actions.ActionTypes;
|
||||||
using Content.Shared.Sound;
|
using Content.Shared.Sound;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
|
|
||||||
namespace Content.Server.Speech.Components;
|
namespace Content.Server.Speech.Components;
|
||||||
|
|
||||||
@@ -25,19 +24,16 @@ public sealed class VocalComponent : Component
|
|||||||
[DataField("audioParams")]
|
[DataField("audioParams")]
|
||||||
public AudioParams AudioParams = AudioParams.Default.WithVolume(4f);
|
public AudioParams AudioParams = AudioParams.Default.WithVolume(4f);
|
||||||
|
|
||||||
|
[DataField("wilhelmProbability")]
|
||||||
|
public float WilhelmProbability = 0.01f;
|
||||||
|
|
||||||
public const float Variation = 0.125f;
|
public const float Variation = 0.125f;
|
||||||
|
|
||||||
// Not using the in-build sound support for actions, given that the sound is modified non-prototype specific factors like gender.
|
[DataField("actionId", customTypeSerializer:typeof(PrototypeIdSerializer<InstantActionPrototype>))]
|
||||||
[DataField("action")]
|
public string ActionId = "Scream";
|
||||||
public InstantAction Action = new()
|
|
||||||
{
|
[DataField("action")] // must be a data-field to properly save cooldown when saving game state.
|
||||||
UseDelay = TimeSpan.FromSeconds(10),
|
public InstantAction? ScreamAction = null;
|
||||||
Icon = new SpriteSpecifier.Texture(new ResourcePath("Interface/Actions/scream.png")),
|
|
||||||
Name = "action-name-scream",
|
|
||||||
Description = "AAAAAAAAAAAAAAAAAAAAAAAAA",
|
|
||||||
Event = new ScreamActionEvent(),
|
|
||||||
CheckCanInteract = false, // system checks a speech related action blocker.
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ScreamActionEvent : PerformActionEvent { };
|
public sealed class ScreamActionEvent : InstantActionEvent { };
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using Content.Server.Speech.Components;
|
using Content.Server.Speech.Components;
|
||||||
using Content.Shared.ActionBlocker;
|
using Content.Shared.ActionBlocker;
|
||||||
using Content.Shared.Actions;
|
using Content.Shared.Actions;
|
||||||
|
using Content.Shared.Actions.ActionTypes;
|
||||||
using Content.Shared.CharacterAppearance;
|
using Content.Shared.CharacterAppearance;
|
||||||
using Content.Shared.CharacterAppearance.Components;
|
using Content.Shared.CharacterAppearance.Components;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
|
|
||||||
namespace Content.Server.Speech;
|
namespace Content.Server.Speech;
|
||||||
@@ -18,6 +20,7 @@ namespace Content.Server.Speech;
|
|||||||
public sealed class VocalSystem : EntitySystem
|
public sealed class VocalSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IRobustRandom _random = default!;
|
[Dependency] private readonly IRobustRandom _random = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||||
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
|
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
|
||||||
|
|
||||||
@@ -32,12 +35,20 @@ public sealed class VocalSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnStartup(EntityUid uid, VocalComponent component, ComponentStartup args)
|
private void OnStartup(EntityUid uid, VocalComponent component, ComponentStartup args)
|
||||||
{
|
{
|
||||||
_actions.AddAction(uid, component.Action, null);
|
if (component.ScreamAction == null
|
||||||
|
&& _proto.TryIndex(component.ActionId, out InstantActionPrototype? act))
|
||||||
|
{
|
||||||
|
component.ScreamAction = new(act);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.ScreamAction != null)
|
||||||
|
_actions.AddAction(uid, component.ScreamAction, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnShutdown(EntityUid uid, VocalComponent component, ComponentShutdown args)
|
private void OnShutdown(EntityUid uid, VocalComponent component, ComponentShutdown args)
|
||||||
{
|
{
|
||||||
_actions.RemoveAction(uid, component.Action);
|
if (component.ScreamAction != null)
|
||||||
|
_actions.RemoveAction(uid, component.ScreamAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnActionPerform(EntityUid uid, VocalComponent component, ScreamActionEvent args)
|
private void OnActionPerform(EntityUid uid, VocalComponent component, ScreamActionEvent args)
|
||||||
@@ -60,7 +71,7 @@ public sealed class VocalSystem : EntitySystem
|
|||||||
if (!TryComp(uid, out HumanoidAppearanceComponent? humanoid))
|
if (!TryComp(uid, out HumanoidAppearanceComponent? humanoid))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (_random.Prob(.01f))
|
if (_random.Prob(component.WilhelmProbability))
|
||||||
{
|
{
|
||||||
SoundSystem.Play(Filter.Pvs(uid), component.Wilhelm.GetSound(), uid, component.AudioParams);
|
SoundSystem.Play(Filter.Pvs(uid), component.Wilhelm.GetSound(), uid, component.AudioParams);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public sealed class IntrinsicUISystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public sealed class ToggleIntrinsicUIEvent : PerformActionEvent
|
public sealed class ToggleIntrinsicUIEvent : InstantActionEvent
|
||||||
{
|
{
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public Enum? Key { get; set; }
|
public Enum? Key { get; set; }
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using Robust.Shared.Serialization;
|
|||||||
|
|
||||||
namespace Content.Server.UserInterface;
|
namespace Content.Server.UserInterface;
|
||||||
|
|
||||||
public sealed class OpenUiActionEvent : PerformActionEvent, ISerializationHooks
|
public sealed class OpenUiActionEvent : InstantActionEvent, ISerializationHooks
|
||||||
{
|
{
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public Enum? Key { get; set; }
|
public Enum? Key { get; set; }
|
||||||
|
|||||||
@@ -1,21 +1,44 @@
|
|||||||
using Content.Shared.Actions.ActionTypes;
|
using Content.Shared.Actions.ActionTypes;
|
||||||
|
using Content.Shared.Hands;
|
||||||
|
using Content.Shared.Inventory;
|
||||||
|
using Content.Shared.Inventory.Events;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.Actions;
|
namespace Content.Shared.Actions;
|
||||||
|
|
||||||
public sealed class GetActionsEvent : EntityEventArgs
|
/// <summary>
|
||||||
|
/// Event raised directed at items or clothing when they are equipped or held. In order for an item to grant actions some
|
||||||
|
/// system can subscribe to this event and add actions to the <see cref="Actions"/> list.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Note that a system could also just manually add actions as a result of a <see cref="GotEquippedEvent"/> or <see
|
||||||
|
/// cref="GotEquippedHandEvent"/>. This exists mostly as a convenience event, while also helping to keep
|
||||||
|
/// action-granting logic separate from general equipment behavior.
|
||||||
|
/// </remarks>
|
||||||
|
public sealed class GetItemActionsEvent : EntityEventArgs
|
||||||
{
|
{
|
||||||
public SortedSet<ActionType> Actions = new();
|
public SortedSet<ActionType> Actions = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Slot flags for the inventory slot that this item got equipped to. Null if not in a slot (i.e., if equipped to hands).
|
||||||
|
/// </summary>
|
||||||
|
public SlotFlags? SlotFlags;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, the item was equipped to a users hands.
|
||||||
|
/// </summary>
|
||||||
|
public bool InHands => SlotFlags == null;
|
||||||
|
|
||||||
|
public GetItemActionsEvent(SlotFlags? slotFlags = null)
|
||||||
|
{
|
||||||
|
SlotFlags = slotFlags;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event used to communicate with the client that the user wishes to perform some action.
|
/// Event used to communicate with the server that a client wishes to perform some action.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// Basically a wrapper for <see cref="PerformActionEvent"/> that the action system will validate before performing
|
|
||||||
/// (check cooldown, target, enabling-entity)
|
|
||||||
/// </remarks>
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public sealed class RequestPerformActionEvent : EntityEventArgs
|
public sealed class RequestPerformActionEvent : EntityEventArgs
|
||||||
{
|
{
|
||||||
@@ -41,21 +64,56 @@ public sealed class RequestPerformActionEvent : EntityEventArgs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[ImplicitDataDefinitionForInheritors]
|
/// <summary>
|
||||||
public abstract class PerformActionEvent : HandledEntityEventArgs
|
/// This is the type of event that gets raised when an <see cref="InstantAction"/> is performed. The <see
|
||||||
|
/// cref="Performer"/> field is automatically filled out by the <see cref="SharedActionsSystem"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// To define a new action for some system, you need to create an event that inherits from this class.
|
||||||
|
/// </remarks>
|
||||||
|
public abstract class InstantActionEvent : BaseActionEvent { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is the type of event that gets raised when an <see cref="EntityTargetAction"/> is performed. The <see
|
||||||
|
/// cref="Performer"/> and <see cref="Target"/> fields will automatically be filled out by the <see
|
||||||
|
/// cref="SharedActionsSystem"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// To define a new action for some system, you need to create an event that inherits from this class.
|
||||||
|
/// </remarks>
|
||||||
|
public abstract class EntityTargetActionEvent : BaseActionEvent
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The user performing the action
|
/// The entity that the user targeted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public EntityUid Performer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class PerformEntityTargetActionEvent : PerformActionEvent
|
|
||||||
{
|
|
||||||
public EntityUid Target;
|
public EntityUid Target;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class PerformWorldTargetActionEvent : PerformActionEvent
|
/// <summary>
|
||||||
|
/// This is the type of event that gets raised when an <see cref="WorldTargetAction"/> is performed. The <see
|
||||||
|
/// cref="Performer"/> and <see cref="Target"/> fields will automatically be filled out by the <see
|
||||||
|
/// cref="SharedActionsSystem"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// To define a new action for some system, you need to create an event that inherits from this class.
|
||||||
|
/// </remarks>
|
||||||
|
public abstract class WorldTargetActionEvent : BaseActionEvent
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The coordinates of the location that the user targeted.
|
||||||
|
/// </summary>
|
||||||
public MapCoordinates Target;
|
public MapCoordinates Target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Base class for events that are raised when an action gets performed. This should not generally be used outside of the action
|
||||||
|
/// system.
|
||||||
|
/// </summary>
|
||||||
|
[ImplicitDataDefinitionForInheritors]
|
||||||
|
public abstract class BaseActionEvent : HandledEntityEventArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The user performing the action.
|
||||||
|
/// </summary>
|
||||||
|
public EntityUid Performer;
|
||||||
|
}
|
||||||
|
|||||||
56
Content.Shared/Actions/ActionTypes/ActionPrototypes.cs
Normal file
56
Content.Shared/Actions/ActionTypes/ActionPrototypes.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
|
namespace Content.Shared.Actions.ActionTypes;
|
||||||
|
|
||||||
|
// These are just prototype definitions for actions. Allows actions to be defined once in yaml and re-used elsewhere.
|
||||||
|
// Note that you still need to create a new instance of each action to properly track the state (cooldown, toggled,
|
||||||
|
// enabled, etc). The prototypes should not be modified directly.
|
||||||
|
//
|
||||||
|
// If ever action states data is separated from the rest of the data, this might not be required
|
||||||
|
// anymore.
|
||||||
|
|
||||||
|
[Prototype("worldTargetAction")]
|
||||||
|
public sealed class WorldTargetActionPrototype : WorldTargetAction, IPrototype
|
||||||
|
{
|
||||||
|
[IdDataFieldAttribute]
|
||||||
|
public string ID { get; } = default!;
|
||||||
|
|
||||||
|
// This is a shitty hack to get around the fact that action-prototypes should not in general be sever-exclusive
|
||||||
|
// prototypes, but some actions may need to use server-exclusive events, and there is no way to specify on a
|
||||||
|
// per-prototype basis whether the client should ignore it when validating yaml.
|
||||||
|
[DataField("serverEvent", serverOnly: true)]
|
||||||
|
public WorldTargetActionEvent? ServerEvent
|
||||||
|
{
|
||||||
|
get => Event;
|
||||||
|
set => Event = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Prototype("entityTargetAction")]
|
||||||
|
public sealed class EntityTargetActionPrototype : EntityTargetAction, IPrototype
|
||||||
|
{
|
||||||
|
[IdDataFieldAttribute]
|
||||||
|
public string ID { get; } = default!;
|
||||||
|
|
||||||
|
[DataField("serverEvent", serverOnly: true)]
|
||||||
|
public EntityTargetActionEvent? ServerEvent
|
||||||
|
{
|
||||||
|
get => Event;
|
||||||
|
set => Event = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Prototype("instantAction")]
|
||||||
|
public sealed class InstantActionPrototype : InstantAction, IPrototype
|
||||||
|
{
|
||||||
|
[IdDataFieldAttribute]
|
||||||
|
public string ID { get; } = default!;
|
||||||
|
|
||||||
|
[DataField("serverEvent", serverOnly: true)]
|
||||||
|
public InstantActionEvent? ServerEvent
|
||||||
|
{
|
||||||
|
get => Event;
|
||||||
|
set => Event = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -3,10 +3,9 @@ using Robust.Shared.Serialization;
|
|||||||
namespace Content.Shared.Actions.ActionTypes;
|
namespace Content.Shared.Actions.ActionTypes;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instantaneous action with no extra targeting information. Will result in <see cref="PerformActionEvent"/> being raised.
|
/// Instantaneous action with no extra targeting information. Will result in <see cref="InstantActionEvent"/> being raised.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
[Friend(typeof(SharedActionsSystem))]
|
|
||||||
[Virtual]
|
[Virtual]
|
||||||
public class InstantAction : ActionType
|
public class InstantAction : ActionType
|
||||||
{
|
{
|
||||||
@@ -15,7 +14,7 @@ public class InstantAction : ActionType
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("event")]
|
[DataField("event")]
|
||||||
[NonSerialized]
|
[NonSerialized]
|
||||||
public PerformActionEvent? Event;
|
public InstantActionEvent? Event;
|
||||||
|
|
||||||
public InstantAction() { }
|
public InstantAction() { }
|
||||||
public InstantAction(InstantAction toClone)
|
public InstantAction(InstantAction toClone)
|
||||||
|
|||||||
@@ -67,10 +67,9 @@ public abstract class TargetedAction : ActionType
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Action that targets some entity. Will result in <see cref="PerformEntityTargetActionEvent"/> being raised.
|
/// Action that targets some entity. Will result in <see cref="EntityTargetActionEvent"/> being raised.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
[Friend(typeof(SharedActionsSystem))]
|
|
||||||
[Virtual]
|
[Virtual]
|
||||||
public class EntityTargetAction : TargetedAction
|
public class EntityTargetAction : TargetedAction
|
||||||
{
|
{
|
||||||
@@ -79,7 +78,7 @@ public class EntityTargetAction : TargetedAction
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[NonSerialized]
|
[NonSerialized]
|
||||||
[DataField("event")]
|
[DataField("event")]
|
||||||
public PerformEntityTargetActionEvent? Event;
|
public EntityTargetActionEvent? Event;
|
||||||
|
|
||||||
[DataField("whitelist")]
|
[DataField("whitelist")]
|
||||||
public EntityWhitelist? Whitelist;
|
public EntityWhitelist? Whitelist;
|
||||||
@@ -115,10 +114,9 @@ public class EntityTargetAction : TargetedAction
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Action that targets some map coordinates. Will result in <see cref="PerformWorldTargetActionEvent"/> being raised.
|
/// Action that targets some map coordinates. Will result in <see cref="WorldTargetActionEvent"/> being raised.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
[Friend(typeof(SharedActionsSystem))]
|
|
||||||
[Virtual]
|
[Virtual]
|
||||||
public class WorldTargetAction : TargetedAction
|
public class WorldTargetAction : TargetedAction
|
||||||
{
|
{
|
||||||
@@ -127,7 +125,7 @@ public class WorldTargetAction : TargetedAction
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("event")]
|
[DataField("event")]
|
||||||
[NonSerialized]
|
[NonSerialized]
|
||||||
public PerformWorldTargetActionEvent? Event;
|
public WorldTargetActionEvent? Event;
|
||||||
|
|
||||||
public WorldTargetAction() { }
|
public WorldTargetAction() { }
|
||||||
public WorldTargetAction(WorldTargetAction toClone)
|
public WorldTargetAction(WorldTargetAction toClone)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using Robust.Shared.Containers;
|
|||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@@ -99,7 +100,7 @@ public abstract class SharedActionsSystem : EntitySystem
|
|||||||
#region Execution
|
#region Execution
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When receiving a request to perform an action, this validates whether the action is allowed. If it is, it
|
/// When receiving a request to perform an action, this validates whether the action is allowed. If it is, it
|
||||||
/// will raise the relevant <see cref="PerformActionEvent"/>
|
/// will raise the relevant <see cref="InstantActionEvent"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnActionRequest(RequestPerformActionEvent ev, EntitySessionEventArgs args)
|
private void OnActionRequest(RequestPerformActionEvent ev, EntitySessionEventArgs args)
|
||||||
{
|
{
|
||||||
@@ -124,7 +125,7 @@ public abstract class SharedActionsSystem : EntitySystem
|
|||||||
if (act.Cooldown.HasValue && act.Cooldown.Value.End > curTime)
|
if (act.Cooldown.HasValue && act.Cooldown.Value.End > curTime)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PerformActionEvent? performEvent = null;
|
BaseActionEvent? performEvent = null;
|
||||||
|
|
||||||
// Validate request by checking action blockers and the like:
|
// Validate request by checking action blockers and the like:
|
||||||
var name = Loc.GetString(act.Name);
|
var name = Loc.GetString(act.Name);
|
||||||
@@ -273,7 +274,7 @@ public abstract class SharedActionsSystem : EntitySystem
|
|||||||
return _interactionSystem.InRangeUnobstructed(user, coords, range: action.Range);
|
return _interactionSystem.InRangeUnobstructed(user, coords, range: action.Range);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void PerformAction(ActionsComponent component, ActionType action, PerformActionEvent? actionEvent, TimeSpan curTime)
|
protected void PerformAction(ActionsComponent component, ActionType action, BaseActionEvent? actionEvent, TimeSpan curTime)
|
||||||
{
|
{
|
||||||
var handled = false;
|
var handled = false;
|
||||||
|
|
||||||
@@ -356,6 +357,13 @@ public abstract class SharedActionsSystem : EntitySystem
|
|||||||
/// <param name="provider">The entity that enables these actions (e.g., flashlight). May be null (innate actions).</param>
|
/// <param name="provider">The entity that enables these actions (e.g., flashlight). May be null (innate actions).</param>
|
||||||
public virtual void AddAction(EntityUid uid, ActionType action, EntityUid? provider, ActionsComponent? comp = null, bool dirty = true)
|
public virtual void AddAction(EntityUid uid, ActionType action, EntityUid? provider, ActionsComponent? comp = null, bool dirty = true)
|
||||||
{
|
{
|
||||||
|
// Because action classes have state data, e.g. cooldowns and uses-remaining, people should not be adding prototypes directly
|
||||||
|
if (action is IPrototype)
|
||||||
|
{
|
||||||
|
Logger.Error("Attempted to directly add a prototype action. You need to clone a prototype in order to use it.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
comp ??= EnsureComp<ActionsComponent>(uid);
|
comp ??= EnsureComp<ActionsComponent>(uid);
|
||||||
action.Provider = provider;
|
action.Provider = provider;
|
||||||
action.AttachedEntity = comp.Owner;
|
action.AttachedEntity = comp.Owner;
|
||||||
@@ -426,7 +434,7 @@ public abstract class SharedActionsSystem : EntitySystem
|
|||||||
#region EquipHandlers
|
#region EquipHandlers
|
||||||
private void OnDidEquip(EntityUid uid, ActionsComponent component, DidEquipEvent args)
|
private void OnDidEquip(EntityUid uid, ActionsComponent component, DidEquipEvent args)
|
||||||
{
|
{
|
||||||
var ev = new GetActionsEvent();
|
var ev = new GetItemActionsEvent(args.SlotFlags);
|
||||||
RaiseLocalEvent(args.Equipment, ev, false);
|
RaiseLocalEvent(args.Equipment, ev, false);
|
||||||
|
|
||||||
if (ev.Actions.Count == 0)
|
if (ev.Actions.Count == 0)
|
||||||
@@ -437,7 +445,7 @@ public abstract class SharedActionsSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnHandEquipped(EntityUid uid, ActionsComponent component, DidEquipHandEvent args)
|
private void OnHandEquipped(EntityUid uid, ActionsComponent component, DidEquipHandEvent args)
|
||||||
{
|
{
|
||||||
var ev = new GetActionsEvent();
|
var ev = new GetItemActionsEvent();
|
||||||
RaiseLocalEvent(args.Equipped, ev, false);
|
RaiseLocalEvent(args.Equipped, ev, false);
|
||||||
|
|
||||||
if (ev.Actions.Count == 0)
|
if (ev.Actions.Count == 0)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public abstract class SharedMagbootsSystem : EntitySystem
|
|||||||
|
|
||||||
SubscribeLocalEvent<SharedMagbootsComponent, GetVerbsEvent<ActivationVerb>>(AddToggleVerb);
|
SubscribeLocalEvent<SharedMagbootsComponent, GetVerbsEvent<ActivationVerb>>(AddToggleVerb);
|
||||||
SubscribeLocalEvent<SharedMagbootsComponent, SlipAttemptEvent>(OnSlipAttempt);
|
SubscribeLocalEvent<SharedMagbootsComponent, SlipAttemptEvent>(OnSlipAttempt);
|
||||||
SubscribeLocalEvent<SharedMagbootsComponent, GetActionsEvent>(OnGetActions);
|
SubscribeLocalEvent<SharedMagbootsComponent, GetItemActionsEvent>(OnGetActions);
|
||||||
SubscribeLocalEvent<SharedMagbootsComponent, ToggleActionEvent>(OnToggleAction);
|
SubscribeLocalEvent<SharedMagbootsComponent, ToggleActionEvent>(OnToggleAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ public abstract class SharedMagbootsSystem : EntitySystem
|
|||||||
args.Cancel();
|
args.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGetActions(EntityUid uid, SharedMagbootsComponent component, GetActionsEvent args)
|
private void OnGetActions(EntityUid uid, SharedMagbootsComponent component, GetItemActionsEvent args)
|
||||||
{
|
{
|
||||||
args.Actions.Add(component.ToggleAction);
|
args.Actions.Add(component.ToggleAction);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using Content.Shared.Sound;
|
|||||||
using Content.Shared.Targeting;
|
using Content.Shared.Targeting;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
namespace Content.Shared.CombatMode
|
namespace Content.Shared.CombatMode
|
||||||
{
|
{
|
||||||
@@ -27,22 +27,17 @@ namespace Content.Shared.CombatMode
|
|||||||
[DataField("disarmSuccessSound")]
|
[DataField("disarmSuccessSound")]
|
||||||
public readonly SoundSpecifier DisarmSuccessSound = new SoundPathSpecifier("/Audio/Effects/thudswoosh.ogg");
|
public readonly SoundSpecifier DisarmSuccessSound = new SoundPathSpecifier("/Audio/Effects/thudswoosh.ogg");
|
||||||
|
|
||||||
// These are chonky default definitions for combat actions. But its a pain to add a yaml version of this for
|
[DataField("disarmActionId", customTypeSerializer:typeof(PrototypeIdSerializer<EntityTargetActionPrototype>))]
|
||||||
// every entity that wants combat mode, especially given that they're currently all identical... so ummm.. yeah.
|
public readonly string DisarmActionId = "Disarm";
|
||||||
[DataField("disarmAction")]
|
|
||||||
public readonly EntityTargetAction DisarmAction = new();
|
[DataField("disarmAction")] // must be a data-field to properly save cooldown when saving game state.
|
||||||
|
public EntityTargetAction? DisarmAction;
|
||||||
|
|
||||||
|
[DataField("combatToggleActionId", customTypeSerializer: typeof(PrototypeIdSerializer<InstantActionPrototype>))]
|
||||||
|
public readonly string CombatToggleActionId = "CombatModeToggle";
|
||||||
|
|
||||||
[DataField("combatToggleAction")]
|
[DataField("combatToggleAction")]
|
||||||
public readonly InstantAction CombatToggleAction = new()
|
public InstantAction? CombatToggleAction;
|
||||||
{
|
|
||||||
Icon = new SpriteSpecifier.Texture(new ResourcePath("Interface/Actions/harmOff.png")),
|
|
||||||
IconOn = new SpriteSpecifier.Texture(new ResourcePath("Interface/Actions/harm.png")),
|
|
||||||
UserPopup = "action-popup-combat",
|
|
||||||
PopupToggleSuffix = "-disabling",
|
|
||||||
Name = "action-name-combat",
|
|
||||||
Description = "action-description-combat",
|
|
||||||
Event = new ToggleCombatActionEvent(),
|
|
||||||
};
|
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public virtual bool IsInCombatMode
|
public virtual bool IsInCombatMode
|
||||||
@@ -52,7 +47,8 @@ namespace Content.Shared.CombatMode
|
|||||||
{
|
{
|
||||||
if (_isInCombatMode == value) return;
|
if (_isInCombatMode == value) return;
|
||||||
_isInCombatMode = value;
|
_isInCombatMode = value;
|
||||||
EntitySystem.Get<SharedActionsSystem>().SetToggled(CombatToggleAction, _isInCombatMode);
|
if (CombatToggleAction != null)
|
||||||
|
EntitySystem.Get<SharedActionsSystem>().SetToggled(CombatToggleAction, _isInCombatMode);
|
||||||
Dirty();
|
Dirty();
|
||||||
|
|
||||||
// Regenerate physics contacts -> Can probably just selectively check
|
// Regenerate physics contacts -> Can probably just selectively check
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
using Content.Shared.Actions;
|
using Content.Shared.Actions;
|
||||||
|
using Content.Shared.Actions.ActionTypes;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Shared.CombatMode
|
namespace Content.Shared.CombatMode
|
||||||
{
|
{
|
||||||
public abstract class SharedCombatModeSystem : EntitySystem
|
public abstract class SharedCombatModeSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
|
[Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -20,14 +23,32 @@ namespace Content.Shared.CombatMode
|
|||||||
|
|
||||||
private void OnStartup(EntityUid uid, SharedCombatModeComponent component, ComponentStartup args)
|
private void OnStartup(EntityUid uid, SharedCombatModeComponent component, ComponentStartup args)
|
||||||
{
|
{
|
||||||
_actionsSystem.AddAction(uid, component.CombatToggleAction, null);
|
if (component.CombatToggleAction == null
|
||||||
_actionsSystem.AddAction(uid, component.DisarmAction, null);
|
&& _protoMan.TryIndex(component.CombatToggleActionId, out InstantActionPrototype? toggleProto))
|
||||||
|
{
|
||||||
|
component.CombatToggleAction = new(toggleProto);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.CombatToggleAction != null)
|
||||||
|
_actionsSystem.AddAction(uid, component.CombatToggleAction, null);
|
||||||
|
|
||||||
|
if (component.DisarmAction == null
|
||||||
|
&& _protoMan.TryIndex(component.DisarmActionId, out EntityTargetActionPrototype? disarmProto))
|
||||||
|
{
|
||||||
|
component.DisarmAction = new(disarmProto);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.DisarmAction != null)
|
||||||
|
_actionsSystem.AddAction(uid, component.DisarmAction, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnShutdown(EntityUid uid, SharedCombatModeComponent component, ComponentShutdown args)
|
private void OnShutdown(EntityUid uid, SharedCombatModeComponent component, ComponentShutdown args)
|
||||||
{
|
{
|
||||||
_actionsSystem.RemoveAction(uid, component.CombatToggleAction);
|
if (component.CombatToggleAction != null)
|
||||||
_actionsSystem.RemoveAction(uid, component.DisarmAction);
|
_actionsSystem.RemoveAction(uid, component.CombatToggleAction);
|
||||||
|
|
||||||
|
if (component.DisarmAction != null)
|
||||||
|
_actionsSystem.RemoveAction(uid, component.DisarmAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnActionPerform(EntityUid uid, SharedCombatModeComponent component, ToggleCombatActionEvent args)
|
private void OnActionPerform(EntityUid uid, SharedCombatModeComponent component, ToggleCombatActionEvent args)
|
||||||
@@ -52,6 +73,6 @@ namespace Content.Shared.CombatMode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ToggleCombatActionEvent : PerformActionEvent { }
|
public sealed class ToggleCombatActionEvent : InstantActionEvent { }
|
||||||
public sealed class DisarmActionEvent : PerformEntityTargetActionEvent { }
|
public sealed class DisarmActionEvent : EntityTargetActionEvent { }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
namespace Content.Shared.Inventory.Events;
|
namespace Content.Shared.Inventory.Events;
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
using Content.Shared.Actions.ActionTypes;
|
using Content.Shared.Actions.ActionTypes;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
namespace Content.Shared.Light.Component
|
namespace Content.Shared.Light.Component
|
||||||
{
|
{
|
||||||
[NetworkedComponent]
|
[NetworkedComponent]
|
||||||
public abstract class SharedHandheldLightComponent : Robust.Shared.GameObjects.Component
|
public abstract class SharedHandheldLightComponent : Robust.Shared.GameObjects.Component
|
||||||
{
|
{
|
||||||
[DataField("toggleAction", required: true)]
|
[DataField("toggleActionId", customTypeSerializer:typeof(PrototypeIdSerializer<InstantActionPrototype>))]
|
||||||
public InstantAction ToggleAction = new();
|
public string ToggleActionId = "ToggleLight";
|
||||||
|
|
||||||
|
[DataField("toggleAction")]
|
||||||
|
public InstantAction? ToggleAction;
|
||||||
|
|
||||||
public const int StatusLevels = 6;
|
public const int StatusLevels = 6;
|
||||||
|
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ namespace Content.Shared.Toggleable;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generic action-event for toggle-able components.
|
/// Generic action-event for toggle-able components.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class ToggleActionEvent : PerformActionEvent { }
|
public sealed class ToggleActionEvent : InstantActionEvent { }
|
||||||
|
|||||||
42
Resources/Prototypes/Actions/types.yml
Normal file
42
Resources/Prototypes/Actions/types.yml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
- type: instantAction
|
||||||
|
id: Scream
|
||||||
|
useDelay: 10
|
||||||
|
icon: Interface/Actions/scream.png
|
||||||
|
name: action-name-scream
|
||||||
|
description: AAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
serverEvent: !type:ScreamActionEvent
|
||||||
|
checkCanInteract: false
|
||||||
|
|
||||||
|
- type: instantAction
|
||||||
|
id: ToggleLight
|
||||||
|
name: action-name-toggle-light
|
||||||
|
description: action-description-toggle-light
|
||||||
|
icon: Objects/Tools/flashlight.rsi/flashlight.png
|
||||||
|
iconOn: Objects/Tools/flashlight.rsi/flashlight-on.png
|
||||||
|
event: !type:ToggleActionEvent
|
||||||
|
|
||||||
|
- type: entityTargetAction
|
||||||
|
id: Disarm
|
||||||
|
name: action-name-disarm
|
||||||
|
description: action-description-disarm
|
||||||
|
icon: Interface/Actions/disarmOff.png
|
||||||
|
iconOn: Interface/Actions/disarm.png
|
||||||
|
repeat: true
|
||||||
|
useDelay: 1.5
|
||||||
|
interactOnMiss: true
|
||||||
|
event: !type:DisarmActionEvent
|
||||||
|
canTargetSelf: false
|
||||||
|
whitelist:
|
||||||
|
components:
|
||||||
|
- Hands
|
||||||
|
- StatusEffects
|
||||||
|
|
||||||
|
- type: instantAction
|
||||||
|
id: CombatModeToggle
|
||||||
|
name: action-name-combat
|
||||||
|
description: action-description-combat
|
||||||
|
icon: Interface/Actions/harmOff.png
|
||||||
|
iconOn: Interface/Actions/harm.png
|
||||||
|
userPopup: action-popup-combat
|
||||||
|
popupToggleSuffix: -disabling
|
||||||
|
event: !type:ToggleCombatActionEvent
|
||||||
@@ -98,12 +98,6 @@
|
|||||||
- type: FlashLightVisualizer
|
- type: FlashLightVisualizer
|
||||||
- type: HandheldLight
|
- type: HandheldLight
|
||||||
addPrefix: true
|
addPrefix: true
|
||||||
toggleAction:
|
|
||||||
name: action-name-toggle-light
|
|
||||||
description: action-description-toggle-light
|
|
||||||
icon: Objects/Tools/flashlight.rsi/flashlight.png
|
|
||||||
iconOn: Objects/Tools/flashlight.rsi/flashlight-on.png
|
|
||||||
event: !type:ToggleActionEvent
|
|
||||||
- type: PowerCellSlot
|
- type: PowerCellSlot
|
||||||
cellSlot:
|
cellSlot:
|
||||||
startingItem: PowerCellHardsuitHelmet # self recharging
|
startingItem: PowerCellHardsuitHelmet # self recharging
|
||||||
|
|||||||
@@ -21,12 +21,6 @@
|
|||||||
- type: FlashLightVisualizer
|
- type: FlashLightVisualizer
|
||||||
- type: HandheldLight
|
- type: HandheldLight
|
||||||
addPrefix: true
|
addPrefix: true
|
||||||
toggleAction:
|
|
||||||
name: action-name-toggle-light
|
|
||||||
description: action-description-toggle-light
|
|
||||||
icon: Objects/Tools/flashlight.rsi/flashlight.png
|
|
||||||
iconOn: Objects/Tools/flashlight.rsi/flashlight-on.png
|
|
||||||
event: !type:ToggleActionEvent
|
|
||||||
- type: PowerCellSlot
|
- type: PowerCellSlot
|
||||||
cellSlot:
|
cellSlot:
|
||||||
startingItem: PowerCellSmallHigh
|
startingItem: PowerCellSmallHigh
|
||||||
|
|||||||
@@ -705,6 +705,7 @@
|
|||||||
# mice are gender neutral who cares
|
# mice are gender neutral who cares
|
||||||
maleScream: /Audio/Animals/mouse_squeak.ogg
|
maleScream: /Audio/Animals/mouse_squeak.ogg
|
||||||
femaleScream: /Audio/Animals/mouse_squeak.ogg
|
femaleScream: /Audio/Animals/mouse_squeak.ogg
|
||||||
|
wilhelmProbability: 0.001
|
||||||
# TODO: Remove CombatMode when Prototype Composition is added
|
# TODO: Remove CombatMode when Prototype Composition is added
|
||||||
- type: CombatMode
|
- type: CombatMode
|
||||||
combatToggleAction:
|
combatToggleAction:
|
||||||
|
|||||||
@@ -95,20 +95,6 @@
|
|||||||
100: !type:DeadMobState {}
|
100: !type:DeadMobState {}
|
||||||
- type: HeatResistance
|
- type: HeatResistance
|
||||||
- type: CombatMode
|
- type: CombatMode
|
||||||
disarmAction:
|
|
||||||
name: action-name-disarm
|
|
||||||
description: action-description-disarm
|
|
||||||
icon: Interface/Actions/disarmOff.png
|
|
||||||
iconOn: Interface/Actions/disarm.png
|
|
||||||
repeat: true
|
|
||||||
useDelay: 1.5
|
|
||||||
interactOnMiss: true
|
|
||||||
event: !type:DisarmActionEvent
|
|
||||||
canTargetSelf: false
|
|
||||||
whitelist:
|
|
||||||
components:
|
|
||||||
- Hands
|
|
||||||
- StatusEffects
|
|
||||||
- type: Internals
|
- type: Internals
|
||||||
- type: StatusEffects
|
- type: StatusEffects
|
||||||
allowed:
|
allowed:
|
||||||
|
|||||||
@@ -12,20 +12,6 @@
|
|||||||
- type: Hands
|
- type: Hands
|
||||||
- type: DoAfter
|
- type: DoAfter
|
||||||
- type: CombatMode
|
- type: CombatMode
|
||||||
disarmAction:
|
|
||||||
name: action-name-disarm
|
|
||||||
description: action-description-disarm
|
|
||||||
icon: Interface/Actions/disarmOff.png
|
|
||||||
iconOn: Interface/Actions/disarm.png
|
|
||||||
repeat: true
|
|
||||||
useDelay: 1.5
|
|
||||||
interactOnMiss: true
|
|
||||||
event: !type:DisarmActionEvent
|
|
||||||
canTargetSelf: false
|
|
||||||
whitelist:
|
|
||||||
components:
|
|
||||||
- Hands
|
|
||||||
- StatusEffects
|
|
||||||
- type: Actions
|
- type: Actions
|
||||||
- type: PlayerInputMover
|
- type: PlayerInputMover
|
||||||
- type: MovementSpeedModifier
|
- type: MovementSpeedModifier
|
||||||
|
|||||||
@@ -53,20 +53,6 @@
|
|||||||
0: !type:NormalMobState {}
|
0: !type:NormalMobState {}
|
||||||
- type: HeatResistance
|
- type: HeatResistance
|
||||||
- type: CombatMode
|
- type: CombatMode
|
||||||
disarmAction:
|
|
||||||
name: action-name-disarm
|
|
||||||
description: action-description-disarm
|
|
||||||
icon: Interface/Actions/disarmOff.png
|
|
||||||
iconOn: Interface/Actions/disarm.png
|
|
||||||
repeat: true
|
|
||||||
useDelay: 1.5
|
|
||||||
interactOnMiss: true
|
|
||||||
event: !type:DisarmActionEvent
|
|
||||||
canTargetSelf: false
|
|
||||||
whitelist:
|
|
||||||
components:
|
|
||||||
- Hands
|
|
||||||
- StatusEffects
|
|
||||||
- type: Internals
|
- type: Internals
|
||||||
- type: Examiner
|
- type: Examiner
|
||||||
- type: Speech
|
- type: Speech
|
||||||
|
|||||||
@@ -228,17 +228,3 @@
|
|||||||
normal: onestar_boss
|
normal: onestar_boss
|
||||||
dead: onestar_boss_wrecked
|
dead: onestar_boss_wrecked
|
||||||
- type: CombatMode
|
- type: CombatMode
|
||||||
disarmAction:
|
|
||||||
name: action-name-disarm
|
|
||||||
description: action-description-disarm
|
|
||||||
icon: Interface/Actions/disarmOff.png
|
|
||||||
iconOn: Interface/Actions/disarm.png
|
|
||||||
repeat: true
|
|
||||||
useDelay: 1.5
|
|
||||||
interactOnMiss: true
|
|
||||||
event: !type:DisarmActionEvent
|
|
||||||
canTargetSelf: false
|
|
||||||
whitelist:
|
|
||||||
components:
|
|
||||||
- Hands
|
|
||||||
- StatusEffects
|
|
||||||
|
|||||||
@@ -258,20 +258,6 @@
|
|||||||
Burn:
|
Burn:
|
||||||
sprite: Mobs/Effects/burn_damage.rsi
|
sprite: Mobs/Effects/burn_damage.rsi
|
||||||
- type: CombatMode
|
- type: CombatMode
|
||||||
disarmAction:
|
|
||||||
name: action-name-disarm
|
|
||||||
description: action-description-disarm
|
|
||||||
icon: Interface/Actions/disarmOff.png
|
|
||||||
iconOn: Interface/Actions/disarm.png
|
|
||||||
repeat: true
|
|
||||||
useDelay: 1.5
|
|
||||||
interactOnMiss: true
|
|
||||||
event: !type:DisarmActionEvent
|
|
||||||
canTargetSelf: false
|
|
||||||
whitelist:
|
|
||||||
components:
|
|
||||||
- Hands
|
|
||||||
- StatusEffects
|
|
||||||
- type: Climbing
|
- type: Climbing
|
||||||
- type: Cuffable
|
- type: Cuffable
|
||||||
- type: CharacterInfo
|
- type: CharacterInfo
|
||||||
|
|||||||
@@ -6,12 +6,6 @@
|
|||||||
components:
|
components:
|
||||||
- type: HandheldLight
|
- type: HandheldLight
|
||||||
addPrefix: true
|
addPrefix: true
|
||||||
toggleAction:
|
|
||||||
name: action-name-toggle-light
|
|
||||||
description: action-description-toggle-light
|
|
||||||
icon: Objects/Tools/flashlight.rsi/flashlight.png
|
|
||||||
iconOn: Objects/Tools/flashlight.rsi/flashlight-on.png
|
|
||||||
event: !type:ToggleActionEvent
|
|
||||||
- type: PowerCellSlot
|
- type: PowerCellSlot
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/Lights/lights.rsi
|
sprite: Objects/Misc/Lights/lights.rsi
|
||||||
|
|||||||
@@ -17,12 +17,6 @@
|
|||||||
right:
|
right:
|
||||||
- state: inhand-right-light
|
- state: inhand-right-light
|
||||||
shader: unshaded
|
shader: unshaded
|
||||||
toggleAction:
|
|
||||||
name: action-name-toggle-light
|
|
||||||
description: action-description-toggle-light
|
|
||||||
icon: Objects/Tools/flashlight.rsi/flashlight.png
|
|
||||||
iconOn: Objects/Tools/flashlight.rsi/flashlight-on.png
|
|
||||||
event: !type:ToggleActionEvent
|
|
||||||
- type: PowerCellSlot
|
- type: PowerCellSlot
|
||||||
cellSlot:
|
cellSlot:
|
||||||
startingItem: PowerCellSmallHigh
|
startingItem: PowerCellSmallHigh
|
||||||
|
|||||||
@@ -6,12 +6,6 @@
|
|||||||
components:
|
components:
|
||||||
- type: HandheldLight
|
- type: HandheldLight
|
||||||
addPrefix: true
|
addPrefix: true
|
||||||
toggleAction:
|
|
||||||
name: action-name-toggle-light
|
|
||||||
description: action-description-toggle-light
|
|
||||||
icon: Objects/Tools/flashlight.rsi/flashlight.png
|
|
||||||
iconOn: Objects/Tools/flashlight.rsi/flashlight-on.png
|
|
||||||
event: !type:ToggleActionEvent
|
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Tools/lantern.rsi
|
sprite: Objects/Tools/lantern.rsi
|
||||||
layers:
|
layers:
|
||||||
|
|||||||
Reference in New Issue
Block a user