Small tweak and cleanup of spells and actions (#15943)

This commit is contained in:
AJCM-git
2023-05-01 04:29:18 -04:00
committed by GitHub
parent 2e2cbe1f02
commit d5b3585c09
7 changed files with 60 additions and 51 deletions

View File

@@ -1,16 +1,13 @@
using System.IO;
using System.Linq;
using Content.Client.Popups;
using Content.Shared.Actions;
using Content.Shared.Actions.ActionTypes;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Shared.Audio;
using Robust.Shared.ContentPack;
using Robust.Shared.GameStates;
using Robust.Shared.Input.Binding;
using Robust.Shared.Player;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Serialization.Markdown;
using Robust.Shared.Serialization.Markdown.Mapping;
@@ -28,9 +25,6 @@ namespace Content.Client.Actions
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IResourceManager _resources = default!;
[Dependency] private readonly ISerializationManager _serialization = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
public event Action<ActionType>? ActionAdded;
public event Action<ActionType>? ActionRemoved;

View File

@@ -20,7 +20,6 @@ using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controllers;
using Robust.Client.UserInterface.Controls;
using Robust.Client.Utility;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Timing;
@@ -39,7 +38,6 @@ namespace Content.Client.UserInterface.Systems.Actions;
public sealed class ActionUIController : UIController, IOnStateChanged<GameplayState>, IOnSystemChanged<ActionsSystem>
{
[Dependency] private readonly IEntityManager _entities = default!;
[Dependency] private readonly IOverlayManager _overlays = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
@@ -47,6 +45,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
[UISystemDependency] private readonly ActionsSystem? _actionsSystem = default;
[UISystemDependency] private readonly InteractionOutlineSystem? _interactionOutline = default;
[UISystemDependency] private readonly TargetOutlineSystem? _targetOutline = default;
[UISystemDependency] private readonly SpriteSystem _spriteSystem = default!;
private const int DefaultPageIndex = 0;
private ActionButtonContainer? _container;
@@ -65,7 +64,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
/// <summary>
/// Action slot we are currently selecting a target for.
/// </summary>
public TargetedAction? SelectingTargetFor { get; private set; } = null;
public TargetedAction? SelectingTargetFor { get; private set; }
public ActionUIController()
{
@@ -190,15 +189,15 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
if (!_timing.IsFirstTimePredicted || _actionsSystem == null || SelectingTargetFor is not { } action)
return false;
if (_playerManager.LocalPlayer?.ControlledEntity is not EntityUid user)
if (_playerManager.LocalPlayer?.ControlledEntity is not { } user)
return false;
if (!_entities.TryGetComponent(user, out ActionsComponent? comp))
if (!EntityManager.TryGetComponent(user, out ActionsComponent? comp))
return false;
// Is the action currently valid?
if (!action.Enabled
|| action.Charges != null && action.Charges == 0
|| action.Charges is 0
|| action.Cooldown.HasValue && action.Cooldown.Value.End > _timing.CurTime)
{
// The user is targeting with this action, but it is not valid. Maybe mark this click as
@@ -247,7 +246,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
_actionsSystem.PerformAction(user, actionComp, action, action.Event, _timing.CurTime);
}
else
_entities.RaisePredictiveEvent(new RequestPerformActionEvent(action, coords));
EntityManager.RaisePredictiveEvent(new RequestPerformActionEvent(action, coords));
if (!action.Repeat)
StopTargeting();
@@ -279,7 +278,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
_actionsSystem.PerformAction(user, actionComp, action, action.Event, _timing.CurTime);
}
else
_entities.RaisePredictiveEvent(new RequestPerformActionEvent(action, args.EntityUid));
EntityManager.RaisePredictiveEvent(new RequestPerformActionEvent(action, args.EntityUid));
if (!action.Repeat)
StopTargeting();
@@ -414,6 +413,10 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
private void OnActionAdded(ActionType action)
{
// if the action is toggled when we add it, start targetting
if (action is TargetedAction targetAction && action.Toggled)
StartTargeting(targetAction);
foreach (var page in _pages)
{
for (var i = 0; i < page.Size; i++)
@@ -434,6 +437,10 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
if (_container == null)
return;
// stop targeting if the action is removed
if (action == SelectingTargetFor)
StopTargeting();
foreach (var button in _container.GetButtons())
{
if (button.Action == action)
@@ -520,8 +527,8 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
return filter switch
{
Filters.Enabled => action.Enabled,
Filters.Item => action.Provider != null && action.Provider != _actionsSystem?.PlayerActions?.Owner,
Filters.Innate => action.Provider == null || action.Provider == _actionsSystem?.PlayerActions?.Owner,
Filters.Item => action.Provider != null && action.Provider != _playerManager.LocalPlayer?.ControlledEntity,
Filters.Innate => action.Provider == null || action.Provider == _playerManager.LocalPlayer?.ControlledEntity,
Filters.Instant => action is InstantAction,
Filters.Targeted => action is TargetedAction,
_ => throw new ArgumentOutOfRangeException(nameof(filter), filter, null)
@@ -582,10 +589,10 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
if (action.DisplayName.Contains(search, StringComparison.OrdinalIgnoreCase))
return true;
if (action.Provider == null || action.Provider == _actionsSystem?.PlayerActions?.Owner)
if (action.Provider == null || action.Provider == _playerManager.LocalPlayer?.ControlledEntity)
return false;
var name = _entities.GetComponent<MetaDataComponent>(action.Provider.Value).EntityName;
var name = EntityManager.GetComponent<MetaDataComponent>(action.Provider.Value).EntityName;
return name.Contains(search, StringComparison.OrdinalIgnoreCase);
});
@@ -731,12 +738,12 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
{
if (action.EntityIcon != null)
{
_dragShadow.Texture = _entities.GetComponent<SpriteComponent>(action.EntityIcon.Value).Icon?
_dragShadow.Texture = EntityManager.GetComponent<SpriteComponent>(action.EntityIcon.Value).Icon?
.GetFrame(RSI.State.Direction.South, 0);
}
else if (action.Icon != null)
{
_dragShadow.Texture = action.Icon!.Frame0();
_dragShadow.Texture = _spriteSystem.Frame0(action.Icon);
}
else
{
@@ -761,13 +768,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
_dragShadow.Visible = false;
}
public void ReloadActionContainer()
{
UnloadGui();
LoadGui();
}
public void UnloadGui()
private void UnloadGui()
{
_actionsSystem?.UnlinkAllActions();
@@ -780,7 +781,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
ActionsBar.PageButtons.RightArrow.OnPressed -= OnRightArrowPressed;
}
public void LoadGui()
private void LoadGui()
{
if (ActionsBar == null)
{
@@ -809,7 +810,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
_container.ActionUnpressed += OnActionUnpressed;
}
public void ClearActions()
private void ClearActions()
{
_container?.ClearActionData();
}
@@ -906,7 +907,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
/// If currently targeting with no slot or a different slot, switches to
/// targeting with the specified slot.
/// </summary>
public void ToggleTargeting(TargetedAction action)
private void ToggleTargeting(TargetedAction action)
{
if (SelectingTargetFor == action)
{
@@ -935,9 +936,9 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
handOverlay.EntityOverride = action.Provider;
}
else if (action.Toggled && action.IconOn != null)
handOverlay.IconOverride = action.IconOn.Frame0();
handOverlay.IconOverride = _spriteSystem.Frame0(action.IconOn);
else if (action.Icon != null)
handOverlay.IconOverride = action.Icon.Frame0();
handOverlay.IconOverride = _spriteSystem.Frame0(action.Icon);
}
// TODO: allow world-targets to check valid positions. E.g., maybe:
@@ -962,7 +963,7 @@ public sealed class ActionUIController : UIController, IOnStateChanged<GameplayS
/// <summary>
/// Switch out of targeting mode if currently selecting target for an action
/// </summary>
public void StopTargeting()
private void StopTargeting()
{
if (SelectingTargetFor == null)
return;

View File

@@ -1,7 +1,7 @@
using Content.Shared.Actions.ActionTypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
namespace Content.Server.Magic;
namespace Content.Server.Magic.Components;
/// <summary>
/// Spellbooks for having an entity learn spells as long as they've read the book and it's in their hand.
@@ -19,14 +19,25 @@ public sealed class SpellbookComponent : Component
/// The three fields below is just used for initialization.
/// </summary>
[DataField("worldSpells", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<int, WorldTargetActionPrototype>))]
[ViewVariables(VVAccess.ReadWrite)]
public readonly Dictionary<string, int> WorldSpells = new();
[DataField("entitySpells", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<int, EntityTargetActionPrototype>))]
[ViewVariables(VVAccess.ReadWrite)]
public readonly Dictionary<string, int> EntitySpells = new();
[DataField("instantSpells", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<int, InstantActionPrototype>))]
[ViewVariables(VVAccess.ReadWrite)]
public readonly Dictionary<string, int> InstantSpells = new();
[DataField("learnTime")]
[ViewVariables(VVAccess.ReadWrite)]
public float LearnTime = .75f;
/// <summary>
/// If true, the spell action stays even after the book is removed
/// </summary>
[DataField("learnPermanently")]
[ViewVariables(VVAccess.ReadWrite)]
public bool LearnPermanently;
}

View File

@@ -3,6 +3,7 @@ using Content.Server.Body.Systems;
using Content.Server.Chat.Systems;
using Content.Server.Coordinates.Helpers;
using Content.Server.Doors.Systems;
using Content.Server.Magic.Components;
using Content.Server.Magic.Events;
using Content.Server.Weapons.Ranged.Systems;
using Content.Shared.Actions;
@@ -72,7 +73,7 @@ public sealed class MagicSystem : EntitySystem
if (args.Handled || args.Cancelled)
return;
_actionsSystem.AddActions(args.Args.User, component.Spells, uid);
_actionsSystem.AddActions(args.Args.User, component.Spells, component.LearnPermanently ? null : uid);
args.Handled = true;
}
@@ -166,12 +167,14 @@ public sealed class MagicSystem : EntitySystem
{
// If applicable, this ensures the projectile is parented to grid on spawn, instead of the map.
var mapPos = pos.ToMap(EntityManager);
EntityCoordinates spawnCoords = _mapManager.TryFindGridAt(mapPos, out var grid)
var spawnCoords = _mapManager.TryFindGridAt(mapPos, out var grid)
? pos.WithEntityId(grid.Owner, EntityManager)
: new(_mapManager.GetMapEntityId(mapPos.MapId), mapPos.Position);
var ent = Spawn(ev.Prototype, spawnCoords);
_gunSystem.ShootProjectile(ent, ev.Target.Position - mapPos.Position, userVelocity, ev.Performer);
var direction = ev.Target.ToMapPos(EntityManager, _transformSystem) -
spawnCoords.ToMapPos(EntityManager, _transformSystem);
_gunSystem.ShootProjectile(ent, direction, userVelocity, ev.Performer);
}
}

View File

@@ -10,7 +10,8 @@ namespace Content.Shared.Actions;
public sealed class ActionsComponent : Component
{
[ViewVariables]
[Access(typeof(SharedActionsSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends
[Access(typeof(SharedActionsSystem), Other = AccessPermissions.ReadExecute)]
// FIXME Friends
public SortedSet<ActionType> Actions = new();
public override bool SendOnlyToOwner => true;

View File

@@ -5,12 +5,9 @@ using Content.Shared.Database;
using Content.Shared.Hands;
using Content.Shared.Interaction;
using Content.Shared.Inventory.Events;
using Content.Shared.Popups;
using Robust.Shared.Audio;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using System.Linq;
@@ -25,8 +22,8 @@ public abstract class SharedActionsSystem : EntitySystem
[Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly RotateToFaceSystem _rotateToFaceSystem = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
public override void Initialize()
{
@@ -98,7 +95,7 @@ public abstract class SharedActionsSystem : EntitySystem
/// </summary>
private void OnActionRequest(RequestPerformActionEvent ev, EntitySessionEventArgs args)
{
if (args.SenderSession.AttachedEntity is not EntityUid user)
if (args.SenderSession.AttachedEntity is not { } user)
return;
if (!TryComp(user, out ActionsComponent? component))
@@ -134,7 +131,8 @@ public abstract class SharedActionsSystem : EntitySystem
return;
}
_rotateToFaceSystem.TryFaceCoordinates(user, Transform(entityTarget).WorldPosition);
var targetWorldPos = _transformSystem.GetWorldPosition(entityTarget);
_rotateToFaceSystem.TryFaceCoordinates(user, targetWorldPos);
if (!ValidateEntityTarget(user, entityTarget, entityAction))
return;
@@ -156,7 +154,7 @@ public abstract class SharedActionsSystem : EntitySystem
case WorldTargetAction worldAction:
if (ev.EntityCoordinatesTarget is not EntityCoordinates entityCoordinatesTarget)
if (ev.EntityCoordinatesTarget is not { } entityCoordinatesTarget)
{
Logger.Error($"Attempted to perform a world-targeted action without a target! Action: {worldAction.DisplayName}");
return;
@@ -231,7 +229,8 @@ public abstract class SharedActionsSystem : EntitySystem
if (action.Range <= 0)
return true;
return (xform.WorldPosition - targetXform.WorldPosition).Length <= action.Range;
var distance = (_transformSystem.GetWorldPosition(xform) - _transformSystem.GetWorldPosition(targetXform)).Length;
return distance <= action.Range;
}
if (_interactionSystem.InRangeUnobstructed(user, target, range: action.Range)
@@ -259,7 +258,7 @@ public abstract class SharedActionsSystem : EntitySystem
if (action.Range <= 0)
return true;
return coords.InRange(EntityManager, Transform(user).Coordinates, action.Range);
return coords.InRange(EntityManager, _transformSystem, Transform(user).Coordinates, action.Range);
}
return _interactionSystem.InRangeUnobstructed(user, coords, range: action.Range);
@@ -354,7 +353,7 @@ public abstract class SharedActionsSystem : EntitySystem
{
comp ??= EnsureComp<ActionsComponent>(uid);
bool allClientExclusive = true;
var allClientExclusive = true;
foreach (var action in actions)
{
@@ -400,7 +399,7 @@ public abstract class SharedActionsSystem : EntitySystem
private void OnDidEquip(EntityUid uid, ActionsComponent component, DidEquipEvent args)
{
var ev = new GetItemActionsEvent(args.SlotFlags);
RaiseLocalEvent(args.Equipment, ev, false);
RaiseLocalEvent(args.Equipment, ev);
if (ev.Actions.Count == 0)
return;
@@ -411,7 +410,7 @@ public abstract class SharedActionsSystem : EntitySystem
private void OnHandEquipped(EntityUid uid, ActionsComponent component, DidEquipHandEvent args)
{
var ev = new GetItemActionsEvent();
RaiseLocalEvent(args.Equipped, ev, false);
RaiseLocalEvent(args.Equipped, ev);
if (ev.Actions.Count == 0)
return;