]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Improve `vv /c/enthover` and add keybind (#20127)
authorLeon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Sat, 16 Sep 2023 04:09:51 +0000 (16:09 +1200)
committerGitHub <noreply@github.com>
Sat, 16 Sep 2023 04:09:51 +0000 (14:09 +1000)
Content.Client/ContextMenu/UI/EntityMenuElement.cs
Content.Client/Gameplay/GameplayStateBase.cs
Content.Client/Input/ContentContexts.cs
Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs
Content.Client/UserInterface/Controls/ListContainer.cs
Content.Client/UserInterface/Controls/SlotControl.cs
Content.Client/UserInterface/IEntityControl.cs [new file with mode: 0644]
Content.Client/UserInterface/Systems/Actions/Controls/ActionButton.cs
Content.Shared/Input/ContentKeyFunctions.cs
Resources/Locale/en-US/escape-menu/ui/options-menu.ftl
Resources/keybinds.yml

index cdd171a6e7d7240015c4bcb57a0cb4d7dd0a7462..8a8070aeccd7de2d3e857db5638f4b8d37c52961 100644 (file)
@@ -1,6 +1,7 @@
 using System.Linq;
 using Content.Client.Administration.Managers;
 using Content.Client.Administration.Systems;
+using Content.Client.UserInterface;
 using Content.Shared.Administration;
 using Content.Shared.IdentityManagement;
 using Robust.Client.GameObjects;
@@ -8,7 +9,7 @@ using Robust.Client.Player;
 
 namespace Content.Client.ContextMenu.UI
 {
-    public sealed partial class EntityMenuElement : ContextMenuElement
+    public sealed partial class EntityMenuElement : ContextMenuElement, IEntityControl
     {
         [Dependency] private readonly IClientAdminManager _adminManager = default!;
         [Dependency] private readonly IEntityManager _entityManager = default!;
@@ -117,5 +118,7 @@ namespace Content.Client.ContextMenu.UI
                 Text = GetEntityDescription(entity.Value);
             }
         }
+
+        EntityUid? IEntityControl.UiEntity => Entity;
     }
 }
index 87fe257cd0837122baaad1401dce2e97d14c17ac..788a4e5dfff93a3e238d537f28a9d37f90a60530 100644 (file)
@@ -1,9 +1,8 @@
-using System;
-using System.Collections.Generic;
 using System.Linq;
 using System.Numerics;
 using Content.Client.Clickable;
-using Content.Client.ContextMenu.UI;
+using Content.Client.UserInterface;
+using Content.Shared.Input;
 using Robust.Client.ComponentTrees;
 using Robust.Client.GameObjects;
 using Robust.Client.Graphics;
@@ -11,10 +10,13 @@ using Robust.Client.Input;
 using Robust.Client.Player;
 using Robust.Client.State;
 using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
 using Robust.Client.UserInterface.CustomControls;
-using Robust.Shared.Containers;
+using Robust.Shared.Console;
 using Robust.Shared.Input;
+using Robust.Shared.Input.Binding;
 using Robust.Shared.Map;
+using Robust.Shared.Players;
 using Robust.Shared.Timing;
 
 namespace Content.Client.Gameplay
@@ -34,28 +36,36 @@ namespace Content.Client.Gameplay
         [Dependency] protected readonly IUserInterfaceManager UserInterfaceManager = default!;
         [Dependency] private readonly IEntityManager _entityManager = default!;
         [Dependency] private readonly IViewVariablesManager _vvm = default!;
+        [Dependency] private readonly IConsoleHost _conHost = default!;
 
         private ClickableEntityComparer _comparer = default!;
 
-        private (ViewVariablesPath? path, string[] segments) ResolveVVHoverObject(string path)
+        private (ViewVariablesPath? path, string[] segments) ResolveVvHoverObject(string path)
         {
-            // VVs the currently hovered entity. For a nifty vv keybinding you can use:
-            //
-            // /bind v command "vv /c/enthover"
-            // /svbind
-            //
-            // Though you probably want to include a modifier like alt, as otherwise this would open VV even when typing
-            // a message into chat containing the letter v.
-
             var segments = path.Split('/');
+            var uid = RecursivelyFindUiEntity(UserInterfaceManager.CurrentlyHovered);
+            var netUid = _entityManager.GetNetEntity(uid);
+            return (netUid != null ? new ViewVariablesInstancePath(netUid) : null, segments);
+        }
 
-            EntityUid? uid = null;
-            if (UserInterfaceManager.CurrentlyHovered is IViewportControl vp && _inputManager.MouseScreenPosition.IsValid)
-                uid = GetClickedEntity(vp.PixelToMap(_inputManager.MouseScreenPosition.Position));
-            else if (UserInterfaceManager.CurrentlyHovered is EntityMenuElement element)
-                uid = element.Entity;
+        private EntityUid? RecursivelyFindUiEntity(Control? control)
+        {
+            if (control == null)
+                return null;
 
-            return (uid != null ? new ViewVariablesInstancePath(uid) : null, segments);
+            switch (control)
+            {
+                case IViewportControl vp:
+                    if (_inputManager.MouseScreenPosition.IsValid)
+                        return GetClickedEntity(vp.PixelToMap(_inputManager.MouseScreenPosition.Position));
+                    return null;
+                case SpriteView sprite:
+                    return sprite.Entity;
+                case IEntityControl ui:
+                    return ui.UiEntity;
+            }
+
+            return RecursivelyFindUiEntity(control.Parent);
         }
 
         private IEnumerable<string>? ListVVHoverPaths(string[] segments)
@@ -65,15 +75,25 @@ namespace Content.Client.Gameplay
 
         protected override void Startup()
         {
-            _vvm.RegisterDomain("enthover", ResolveVVHoverObject, ListVVHoverPaths);
+            _vvm.RegisterDomain("enthover", ResolveVvHoverObject, ListVVHoverPaths);
             _inputManager.KeyBindStateChanged += OnKeyBindStateChanged;
             _comparer = new ClickableEntityComparer();
+            CommandBinds.Builder
+                .Bind(ContentKeyFunctions.InspectEntity, new PointerInputCmdHandler(HandleInspect, outsidePrediction: true))
+                .Register<GameplayStateBase>();
         }
 
         protected override void Shutdown()
         {
             _vvm.UnregisterDomain("enthover");
             _inputManager.KeyBindStateChanged -= OnKeyBindStateChanged;
+            CommandBinds.Unregister<GameplayStateBase>();
+        }
+
+        private bool HandleInspect(ICommonSession? session, EntityCoordinates coords, EntityUid uid)
+        {
+            _conHost.ExecuteCommand($"vv /c/enthover");
+            return true;
         }
 
         public EntityUid? GetClickedEntity(MapCoordinates coordinates)
index 963571abe76fc7fb6d8fc8eb0f638c09bd64de16..63809f88c1efbf6f1210ace8faa45ced899bd631 100644 (file)
@@ -33,6 +33,7 @@ namespace Content.Client.Input
             common.AddFunction(ContentKeyFunctions.ZoomOut);
             common.AddFunction(ContentKeyFunctions.ZoomIn);
             common.AddFunction(ContentKeyFunctions.ResetZoom);
+            common.AddFunction(ContentKeyFunctions.InspectEntity);
 
             // Not in engine, because engine cannot check for sanbox/admin status before starting placement.
             common.AddFunction(ContentKeyFunctions.EditorCopyObject);
index d1e4c3bbcddfaff45e7f47436c2db6ee3f0dfdef..ba77c431609facd6754ac062aaf656a582d7d919 100644 (file)
@@ -192,6 +192,7 @@ namespace Content.Client.Options.UI.Tabs
             AddButton(EngineKeyFunctions.ShowDebugConsole);
             AddButton(EngineKeyFunctions.ShowDebugMonitors);
             AddButton(EngineKeyFunctions.HideUI);
+            AddButton(ContentKeyFunctions.InspectEntity);
 
             foreach (var control in _keyControls.Values)
             {
index eefeb19d40def9c98eaba2629eb16372150f1742..d1bb103926f9ebcd5abb38bc5394f5d9c4a05a29 100644 (file)
@@ -344,7 +344,7 @@ public sealed class ListContainer : Control
     }
 }
 
-public sealed class ListContainerButton : ContainerButton
+public sealed class ListContainerButton : ContainerButton, IEntityControl
 {
     public readonly ListData Data;
     // public PanelContainer Background;
@@ -359,6 +359,8 @@ public sealed class ListContainerButton : ContainerButton
         //     PanelOverride = new StyleBoxFlat {BackgroundColor = new Color(55, 55, 68)}
         // });
     }
+
+    public EntityUid? UiEntity => (Data as EntityListData)?.Uid;
 }
 
 #region Data
index 4caabaa788ee2f3cb385810d66ef4cef2feceb37..b0a2198443b56c4c4ea057c9b8dc68de3d01e9f5 100644 (file)
@@ -8,7 +8,7 @@ using Robust.Shared.Input;
 namespace Content.Client.UserInterface.Controls
 {
     [Virtual]
-    public abstract class SlotControl : Control
+    public abstract class SlotControl : Control, IEntityControl
     {
         public static int DefaultButtonSize = 64;
 
@@ -20,7 +20,7 @@ namespace Content.Client.UserInterface.Controls
         public TextureButton StorageButton { get; }
         public CooldownGraphic CooldownDisplay { get; }
 
-        public EntityUid? Entity => SpriteView.Sprite?.Owner;
+        public EntityUid? Entity => SpriteView.Entity;
 
         private bool _slotNameSet;
 
@@ -232,5 +232,7 @@ namespace Content.Client.UserInterface.Controls
             ButtonRect.Texture = Theme.ResolveTextureOrNull(_buttonTexturePath)?.Texture;
             HighlightRect.Texture = Theme.ResolveTextureOrNull(_highlightTexturePath)?.Texture;
         }
+
+        EntityUid? IEntityControl.UiEntity => Entity;
     }
 }
diff --git a/Content.Client/UserInterface/IEntityControl.cs b/Content.Client/UserInterface/IEntityControl.cs
new file mode 100644 (file)
index 0000000..5bf9976
--- /dev/null
@@ -0,0 +1,10 @@
+namespace Content.Client.UserInterface;
+
+/// <summary>
+/// Simple interface that indicates that the given control is associated with some entity.
+/// This is primarily intended to be used with VV, so that you can easily open the VV window to examine an entity.
+/// </summary>
+public interface IEntityControl
+{
+    EntityUid? UiEntity { get; }
+}
index 2af079ccce4ea049bc1fa239d0a4b0c40ba5d3d7..e4521cecaa99446d434a545accdf50e1ec19478c 100644 (file)
@@ -19,7 +19,7 @@ using Direction = Robust.Shared.Maths.Direction;
 
 namespace Content.Client.UserInterface.Systems.Actions.Controls;
 
-public sealed class ActionButton : Control
+public sealed class ActionButton : Control, IEntityControl
 {
     private IEntityManager? _entities;
 
@@ -197,7 +197,7 @@ public sealed class ActionButton : Control
     private void UpdateItemIcon()
     {
         if (!Actions.TryGetActionData(ActionId, out var action) ||
-            action is not { EntityIcon: { } entity } ||
+            action is not {EntityIcon: { } entity} ||
             !Entities.HasComponent<SpriteComponent>(entity))
         {
             _bigItemSpriteView.Visible = false;
@@ -344,7 +344,7 @@ public sealed class ActionButton : Control
     public void Depress(GUIBoundKeyEventArgs args, bool depress)
     {
         // action can still be toggled if it's allowed to stay selected
-        if (!Actions.TryGetActionData(ActionId, out var action) || action is not { Enabled: true })
+        if (!Actions.TryGetActionData(ActionId, out var action) || action is not {Enabled: true})
             return;
 
         if (_depressed && !depress)
@@ -401,4 +401,6 @@ public sealed class ActionButton : Control
 
         SetOnlyStylePseudoClass(ContainerButton.StylePseudoClassNormal);
     }
+
+    EntityUid? IEntityControl.UiEntity => ActionId;
 }
index 57b0493eb9a6acf1d5fe1934193408d0846f2266..c50531e29588eb790800bb5082347130911d81a2 100644 (file)
@@ -112,5 +112,6 @@ namespace Content.Shared.Input
         public static readonly BoundKeyFunction Vote9 = "Vote9";
         public static readonly BoundKeyFunction EditorCopyObject = "EditorCopyObject";
         public static readonly BoundKeyFunction EditorFlipObject = "EditorFlipObject";
+        public static readonly BoundKeyFunction InspectEntity = "InspectEntity";
     }
 }
index e2ff7bc411aad75a3bce6348b446981468b75baa..10db378ab42af742e40871af8f6c8f0d6a9e5ccb 100644 (file)
@@ -159,6 +159,7 @@ ui-options-function-editor-copy-object = Copy
 ui-options-function-open-abilities-menu = Open action menu
 ui-options-function-show-debug-console = Open Console
 ui-options-function-show-debug-monitors = Show Debug Monitors
+ui-options-function-inspect-entity = Inspect Entity
 ui-options-function-hide-ui = Hide UI
 
 ui-options-function-hotbar1 = Hotbar slot 1
index 4ce5d84e8c810ad8af0faab2aae9256660e971ec..e3e7a09657bf5f166bc4dd958d5c19139d154a54 100644 (file)
@@ -237,6 +237,10 @@ binds:
 - function: ShowDebugConsole
   type: State
   key: Tilde
+- function: InspectEntity
+  type: State
+  key: v
+  mod1: Alt
 - function: MouseMiddle
   type: State
   key: MouseMiddle