]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Small tweak and cleanup of spells and actions (#15943)
authorAJCM-git <60196617+AJCM-git@users.noreply.github.com>
Mon, 1 May 2023 08:29:18 +0000 (04:29 -0400)
committerGitHub <noreply@github.com>
Mon, 1 May 2023 08:29:18 +0000 (18:29 +1000)
Content.Client/Actions/ActionsSystem.cs
Content.Client/UserInterface/Systems/Actions/ActionUIController.cs
Content.Server/Magic/Components/SpellbookComponent.cs
Content.Server/Magic/MagicSystem.cs
Content.Shared/Actions/ActionsComponent.cs
Content.Shared/Actions/SharedActionsSystem.cs
Resources/Prototypes/Entities/Objects/Magic/books.yml

index 9e594260f3d7610a9085836644712536f4290910..767e7ac3258dc16257e760625860c25cd1d29f79 100644 (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;
index 06a7792f3835ba068091bb5e7519a718bc887a02..472ad49a3f39b16692a74b41385480726b1eaa3e 100644 (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;
index 0432336dfddf175d7abfbf56c8edc24bdfb28dfa..db6c717061026c7fd71ba848d96c71073cf35a53 100644 (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;
 }
index c69243376225e6c6074f352addc8cde35aa56266..48b6a5b8daf640597466cc4bbb3a92c541d6d1fd 100644 (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);
         }
     }
 
index 646dac9d7313896cb979c9ada9968c7a0837e45b..ba2aedb6da81a7d531cd0d76e560d3aabe2f2e0c 100644 (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;
index 324c260a1edfe8b98de7582f50731127d3c93e85..a6c82c217e235113d801336d0338d65d66fdeb61 100644 (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;
index 7b4dc5d535eec893af7ea30a702a817085a20f14..b9208dc669f9cc5aa4e7387b2b322944eeb7c19e 100644 (file)
       FlashRune: -1
       ExplosionRune: -1
       IgniteRune: -1
-      StunRune: -1
\ No newline at end of file
+      StunRune: -1