Add RGB staff (#13125)
This commit is contained in:
30
Content.Server/Actions/ActionOnInteractComponent.cs
Normal file
30
Content.Server/Actions/ActionOnInteractComponent.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Content.Shared.Actions.ActionTypes;
|
||||
using Content.Shared.Interaction;
|
||||
|
||||
namespace Content.Server.Actions;
|
||||
|
||||
/// <summary>
|
||||
/// This component enables an entity to perform actions when used to interact with the world, without actually
|
||||
/// granting that action to the entity that is using the item.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the entity is used in hand (<see cref="ActivateInWorldEvent"/>), it will perform a random available instant
|
||||
/// action. If the entity is used to interact with another entity (<see cref="InteractUsingEvent"/>), it will
|
||||
/// attempt to perform a random entity target action. Finally, if the entity is used to click somewhere in the world
|
||||
/// and no other interaction takes place (<see cref="AfterInteractEvent"/>), then it will try to perform a random
|
||||
/// available entity or world target action. This component does not bypass standard interaction checks.
|
||||
///
|
||||
/// This component mainly exists as a lazy way to add utility entities that can do things like cast "spells".
|
||||
/// </remarks>
|
||||
[RegisterComponent]
|
||||
public sealed class ActionOnInteractComponent : Component
|
||||
{
|
||||
[DataField("activateActions")]
|
||||
public List<InstantAction>? ActivateActions;
|
||||
|
||||
[DataField("entityActions")]
|
||||
public List<EntityTargetAction>? EntityActions;
|
||||
|
||||
[DataField("worldActions")]
|
||||
public List<WorldTargetAction>? WorldActions;
|
||||
}
|
||||
131
Content.Server/Actions/ActionOnInteractSystem.cs
Normal file
131
Content.Server/Actions/ActionOnInteractSystem.cs
Normal file
@@ -0,0 +1,131 @@
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.ActionTypes;
|
||||
using Content.Shared.Interaction;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server.Actions;
|
||||
|
||||
/// <summary>
|
||||
/// This System handled interactions for the <see cref="ActionOnInteractComponent"/>.
|
||||
/// </summary>
|
||||
public sealed class ActionOnInteractSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ActionOnInteractComponent, ActivateInWorldEvent>(OnActivate);
|
||||
SubscribeLocalEvent<ActionOnInteractComponent, AfterInteractEvent>(OnAfterInteract);
|
||||
}
|
||||
|
||||
private void OnActivate(EntityUid uid, ActionOnInteractComponent component, ActivateInWorldEvent args)
|
||||
{
|
||||
if (args.Handled || component.ActivateActions == null)
|
||||
return;
|
||||
|
||||
var options = new List<InstantAction>();
|
||||
foreach (var action in component.ActivateActions)
|
||||
{
|
||||
if (ValidAction(action))
|
||||
options.Add(action);
|
||||
}
|
||||
|
||||
if (options.Count == 0)
|
||||
return;
|
||||
|
||||
var act = _random.Pick(options);
|
||||
if (act.Event != null)
|
||||
act.Event.Performer = args.User;
|
||||
|
||||
act.Provider = uid;
|
||||
_actions.PerformAction(args.User, null, act, act.Event, _timing.CurTime, false);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void OnAfterInteract(EntityUid uid, ActionOnInteractComponent component, AfterInteractEvent args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
// First, try entity target actions
|
||||
if (args.Target != null && component.EntityActions != null)
|
||||
{
|
||||
var entOptions = new List<EntityTargetAction>();
|
||||
foreach (var action in component.EntityActions)
|
||||
{
|
||||
if (!ValidAction(action, args.CanReach))
|
||||
continue;
|
||||
|
||||
if (!_actions.ValidateEntityTarget(args.User, args.Target.Value, action))
|
||||
continue;
|
||||
|
||||
entOptions.Add(action);
|
||||
}
|
||||
|
||||
if (entOptions.Count > 0)
|
||||
{
|
||||
var entAct = _random.Pick(entOptions);
|
||||
if (entAct.Event != null)
|
||||
{
|
||||
entAct.Event.Performer = args.User;
|
||||
entAct.Event.Target = args.Target.Value;
|
||||
}
|
||||
|
||||
entAct.Provider = uid;
|
||||
_actions.PerformAction(args.User, null, entAct, entAct.Event, _timing.CurTime, false);
|
||||
args.Handled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// else: try world target actions
|
||||
if (component.WorldActions == null)
|
||||
return;
|
||||
|
||||
var options = new List<WorldTargetAction>();
|
||||
foreach (var action in component.WorldActions)
|
||||
{
|
||||
if (!ValidAction(action, args.CanReach))
|
||||
continue;
|
||||
|
||||
if (!_actions.ValidateWorldTarget(args.User, args.ClickLocation, action))
|
||||
continue;
|
||||
|
||||
options.Add(action);
|
||||
}
|
||||
|
||||
if (options.Count == 0)
|
||||
return;
|
||||
|
||||
var act = _random.Pick(options);
|
||||
if (act.Event != null)
|
||||
{
|
||||
act.Event.Performer = args.User;
|
||||
act.Event.Target = args.ClickLocation;
|
||||
}
|
||||
|
||||
act.Provider = uid;
|
||||
_actions.PerformAction(args.User, null, act, act.Event, _timing.CurTime, false);
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private bool ValidAction(ActionType act, bool canReach = true)
|
||||
{
|
||||
if (!act.Enabled)
|
||||
return false;
|
||||
|
||||
if (act.Charges.HasValue && act.Charges <= 0)
|
||||
return false;
|
||||
|
||||
var curTime = _timing.CurTime;
|
||||
if (act.Cooldown.HasValue && act.Cooldown.Value.End > curTime)
|
||||
return false;
|
||||
|
||||
return canReach || act is TargetedAction { CheckCanAccess: false };
|
||||
}
|
||||
}
|
||||
@@ -18,9 +18,9 @@ namespace Content.Server.Actions
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
protected override bool PerformBasicActions(EntityUid user, ActionType action)
|
||||
protected override bool PerformBasicActions(EntityUid user, ActionType action, bool predicted)
|
||||
{
|
||||
var result = base.PerformBasicActions(user, action);
|
||||
var result = base.PerformBasicActions(user, action, predicted);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(action.Speech))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user