Add Alt-click functionality (#4497)
* Fix ItemSlot Bug * Add Alt-use Key * Fix TransferAmount window bug * Alt-click functionality * Added AltInteract verbs * Add new verbs * verb icons * Changed Comments * Change Comments * Fix disposal verbs * Changed Get...() to Get...OrNull() * Changed alt-interact combat behaviour * Update verb icons * Inventory interact event * Add Alt+E secondary binding * Add alt-z keybinding * Rename AltUse -> AltActivateItemInWorld
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Content.Client.Resources;
|
||||
using Content.Client.Stylesheets;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
@@ -24,7 +24,7 @@ namespace Content.Client.Chemistry.UI
|
||||
_window.Close();
|
||||
}
|
||||
};
|
||||
|
||||
_window.OnClose += Close;
|
||||
_window.OpenCentered();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Content.Client.Examine;
|
||||
@@ -121,7 +121,7 @@ namespace Content.Client.ContextMenu.UI
|
||||
|
||||
if (firstEntity == null) return;
|
||||
|
||||
if (args.Function == EngineKeyFunctions.Use || args.Function == ContentKeyFunctions.TryPullObject || args.Function == ContentKeyFunctions.MovePulledObject)
|
||||
if (args.Function == EngineKeyFunctions.Use || args.Function == ContentKeyFunctions.AltActivateItemInWorld || args.Function == ContentKeyFunctions.TryPullObject || args.Function == ContentKeyFunctions.MovePulledObject)
|
||||
{
|
||||
var inputSys = _systemManager.GetEntitySystem<InputSystem>();
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace Content.Client.ContextMenu.UI
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Function == EngineKeyFunctions.Use || args.Function == ContentKeyFunctions.Point ||
|
||||
if (args.Function == EngineKeyFunctions.Use || args.Function == ContentKeyFunctions.AltActivateItemInWorld || args.Function == ContentKeyFunctions.Point ||
|
||||
args.Function == ContentKeyFunctions.TryPullObject || args.Function == ContentKeyFunctions.MovePulledObject)
|
||||
{
|
||||
var inputSys = _systemManager.GetEntitySystem<InputSystem>();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Client.Stylesheets;
|
||||
using Content.Shared.Input;
|
||||
@@ -85,7 +85,9 @@ namespace Content.Client.EscapeMenu.UI.Tabs
|
||||
AddButton(EngineKeyFunctions.Use);
|
||||
AddButton(ContentKeyFunctions.WideAttack);
|
||||
AddButton(ContentKeyFunctions.ActivateItemInHand);
|
||||
AddButton(ContentKeyFunctions.AltActivateItemInHand);
|
||||
AddButton(ContentKeyFunctions.ActivateItemInWorld);
|
||||
AddButton(ContentKeyFunctions.AltActivateItemInWorld);
|
||||
AddButton(ContentKeyFunctions.Drop);
|
||||
AddButton(ContentKeyFunctions.ExamineEntity);
|
||||
AddButton(ContentKeyFunctions.SwapHands);
|
||||
|
||||
@@ -31,9 +31,11 @@ namespace Content.Client.Input
|
||||
human.AddFunction(ContentKeyFunctions.SwapHands);
|
||||
human.AddFunction(ContentKeyFunctions.Drop);
|
||||
human.AddFunction(ContentKeyFunctions.ActivateItemInHand);
|
||||
human.AddFunction(ContentKeyFunctions.AltActivateItemInHand);
|
||||
human.AddFunction(ContentKeyFunctions.OpenCharacterMenu);
|
||||
human.AddFunction(ContentKeyFunctions.ActivateItemInWorld);
|
||||
human.AddFunction(ContentKeyFunctions.ThrowItemInHand);
|
||||
human.AddFunction(ContentKeyFunctions.AltActivateItemInWorld);
|
||||
human.AddFunction(ContentKeyFunctions.TryPullObject);
|
||||
human.AddFunction(ContentKeyFunctions.MovePulledObject);
|
||||
human.AddFunction(ContentKeyFunctions.ReleasePulledObject);
|
||||
|
||||
@@ -207,10 +207,9 @@ namespace Content.Client.Inventory
|
||||
return;
|
||||
if (!Owner.TryGetSlot(slot, out var item))
|
||||
return;
|
||||
if (_itemSlotManager.OnButtonPressed(args, item))
|
||||
return;
|
||||
|
||||
base.HandleInventoryKeybind(args, slot);
|
||||
if (!_itemSlotManager.OnButtonPressed(args, item))
|
||||
base.HandleInventoryKeybind(args, slot);
|
||||
}
|
||||
|
||||
private void ClearButton(ItemSlotButton button, Slots slot)
|
||||
|
||||
@@ -7,6 +7,7 @@ using Content.Client.Verbs;
|
||||
using Content.Shared.Cooldown;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Input;
|
||||
using Content.Shared.Interaction;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.Input;
|
||||
@@ -86,26 +87,11 @@ namespace Content.Client.Items.Managers
|
||||
}
|
||||
else if (args.Function == ContentKeyFunctions.ActivateItemInWorld)
|
||||
{
|
||||
var inputSys = _entitySystemManager.GetEntitySystem<InputSystem>();
|
||||
|
||||
var func = args.Function;
|
||||
var funcId = _inputManager.NetworkBindMap.KeyFunctionID(args.Function);
|
||||
|
||||
|
||||
var mousePosWorld = _eyeManager.ScreenToMap(args.PointerLocation);
|
||||
|
||||
var coordinates = _mapManager.TryFindGridAt(mousePosWorld, out var grid) ? grid.MapToGrid(mousePosWorld) :
|
||||
EntityCoordinates.FromMap(_mapManager, mousePosWorld);
|
||||
|
||||
var message = new FullInputCmdMessage(_gameTiming.CurTick, _gameTiming.TickFraction, funcId, BoundKeyState.Down,
|
||||
coordinates, args.PointerLocation, item.Uid);
|
||||
|
||||
// client side command handlers will always be sent the local player session.
|
||||
var session = _playerManager.LocalPlayer?.Session;
|
||||
if (session == null)
|
||||
return false;
|
||||
|
||||
inputSys.HandleInputCommand(session, func, message);
|
||||
_entityManager.EntityNetManager?.SendSystemNetworkMessage(new InteractInventorySlotEvent(item.Uid, altInteract: false));
|
||||
}
|
||||
else if (args.Function == ContentKeyFunctions.AltActivateItemInWorld)
|
||||
{
|
||||
_entityManager.EntityNetManager?.SendSystemNetworkMessage(new InteractInventorySlotEvent(item.Uid, altInteract: true));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -256,6 +256,8 @@ namespace Content.Server.Access.Components
|
||||
[Verb]
|
||||
public sealed class EjectPrivilegedIDVerb : Verb<IdCardConsoleComponent>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, IdCardConsoleComponent component, VerbData data)
|
||||
{
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user))
|
||||
@@ -281,6 +283,8 @@ namespace Content.Server.Access.Components
|
||||
|
||||
public sealed class EjectTargetIDVerb : Verb<IdCardConsoleComponent>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, IdCardConsoleComponent component, VerbData data)
|
||||
{
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user))
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace Content.Server.Administration.Verbs
|
||||
}
|
||||
|
||||
data.Text = Loc.GetString("admin-add-reagent-verb-get-data-text");
|
||||
data.IconTexture = "/Textures/Interface/VerbIcons/spill.svg.192dpi.png";
|
||||
data.CategoryData = VerbCategories.Debug;
|
||||
data.Visibility = VerbVisibility.Invisible;
|
||||
|
||||
|
||||
@@ -75,6 +75,11 @@ namespace Content.Server.Cabinet
|
||||
[Verb]
|
||||
public sealed class ToggleItemCabinetVerb : Verb<ItemCabinetComponent>
|
||||
{
|
||||
// Unlike lockers, you cannot open/close cabinets by clicking on them, as this usually removes their item
|
||||
// instead. So open/close is the alt-interact verb
|
||||
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, ItemCabinetComponent component, VerbData data)
|
||||
{
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user))
|
||||
|
||||
@@ -426,6 +426,8 @@ namespace Content.Server.Chemistry.Components
|
||||
[Verb]
|
||||
public sealed class EjectBeakerVerb : Verb<ChemMasterComponent>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, ChemMasterComponent component, VerbData data)
|
||||
{
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user))
|
||||
@@ -436,6 +438,7 @@ namespace Content.Server.Chemistry.Components
|
||||
|
||||
data.Text = Loc.GetString("eject-beaker-verb-get-data-text");
|
||||
data.Visibility = component.HasBeaker ? VerbVisibility.Visible : VerbVisibility.Invisible;
|
||||
data.IconTexture = "/Textures/Interface/VerbIcons/eject.svg.192dpi.png";
|
||||
}
|
||||
|
||||
protected override void Activate(IEntity user, ChemMasterComponent component)
|
||||
|
||||
@@ -368,6 +368,8 @@ namespace Content.Server.Chemistry.Components
|
||||
[Verb]
|
||||
public sealed class EjectBeakerVerb : Verb<ReagentDispenserComponent>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, ReagentDispenserComponent component, VerbData data)
|
||||
{
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user))
|
||||
@@ -378,6 +380,7 @@ namespace Content.Server.Chemistry.Components
|
||||
|
||||
data.Text = Loc.GetString("eject-beaker-verb-get-data-text");
|
||||
data.Visibility = component.HasBeaker ? VerbVisibility.Visible : VerbVisibility.Invisible;
|
||||
data.IconTexture = "/Textures/Interface/VerbIcons/eject.svg.192dpi.png";
|
||||
}
|
||||
|
||||
protected override void Activate(IEntity user, ReagentDispenserComponent component)
|
||||
|
||||
@@ -282,6 +282,8 @@ namespace Content.Server.Chemistry.Components
|
||||
[Verb]
|
||||
public sealed class CustomTransferVerb : Verb<SolutionTransferComponent>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, SolutionTransferComponent component, VerbData data)
|
||||
{
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user) || !component.CanChangeTransferAmount)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using Content.Server.DoAfter;
|
||||
using Content.Server.Notification;
|
||||
using Content.Shared.ActionBlocker;
|
||||
@@ -242,6 +242,8 @@ namespace Content.Server.Climbing.Components
|
||||
[Verb]
|
||||
private sealed class ClimbVerb : Verb<ClimbableComponent>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, ClimbableComponent component, VerbData data)
|
||||
{
|
||||
if (!component.CanVault(user, component.Owner, out var _))
|
||||
|
||||
@@ -207,7 +207,7 @@ namespace Content.Server.Disposal.Unit.Components
|
||||
}
|
||||
|
||||
data.Visibility = VerbVisibility.Visible;
|
||||
data.Text = Loc.GetString("self-insert-verb-get-data-text");
|
||||
data.Text = Loc.GetString("disposal-self-insert-verb-get-data-text");
|
||||
}
|
||||
|
||||
protected override void Activate(IEntity user, DisposalUnitComponent component)
|
||||
@@ -230,8 +230,8 @@ namespace Content.Server.Disposal.Unit.Components
|
||||
}
|
||||
|
||||
data.Visibility = VerbVisibility.Visible;
|
||||
data.Text = Loc.GetString("flush-verb-get-data-text");
|
||||
data.IconTexture = "/Textures/Interface/VerbIcons/eject.svg.192dpi.png";
|
||||
data.Text = Loc.GetString("disposal-flush-verb-get-data-text");
|
||||
data.IconTexture = "/Textures/Interface/VerbIcons/delete_transparent.svg.192dpi.png";
|
||||
}
|
||||
|
||||
protected override void Activate(IEntity user, DisposalUnitComponent component)
|
||||
@@ -240,6 +240,37 @@ namespace Content.Server.Disposal.Unit.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Verb]
|
||||
private sealed class EjectVerb : Verb<DisposalUnitComponent>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, DisposalUnitComponent component, VerbData data)
|
||||
{
|
||||
data.Visibility = VerbVisibility.Invisible;
|
||||
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user) ||
|
||||
component.ContainedEntities.Contains(user))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Only show verb if actually containing any entities.
|
||||
if (component.ContainedEntities.Count > 0)
|
||||
data.Visibility = VerbVisibility.Visible;
|
||||
else
|
||||
data.Visibility = VerbVisibility.Invisible;
|
||||
|
||||
data.Text = Loc.GetString("disposal-eject-verb-get-data-text");
|
||||
data.IconTexture = "/Textures/Interface/VerbIcons/eject.svg.192dpi.png";
|
||||
}
|
||||
|
||||
protected override void Activate(IEntity user, DisposalUnitComponent component)
|
||||
{
|
||||
EntitySystem.Get<DisposalUnitSystem>().TryEjectContents(component);
|
||||
}
|
||||
}
|
||||
|
||||
void IDestroyAct.OnDestroy(DestructionEventArgs eventArgs)
|
||||
{
|
||||
EntitySystem.Get<DisposalUnitSystem>().TryEjectContents(this);
|
||||
|
||||
@@ -82,10 +82,10 @@ namespace Content.Server.Hands.Components
|
||||
.TryInteractionActivate(Owner, heldEntity);
|
||||
}
|
||||
|
||||
protected override void DoUse(IEntity heldEntity)
|
||||
protected override void DoUse(IEntity heldEntity, bool altInteract = false)
|
||||
{
|
||||
_entitySystemManager.GetEntitySystem<InteractionSystem>()
|
||||
.TryUseInteraction(Owner, heldEntity);
|
||||
.TryUseInteraction(Owner, heldEntity, altInteract);
|
||||
}
|
||||
|
||||
protected override void HandlePickupAnimation(IEntity entity)
|
||||
|
||||
@@ -50,6 +50,7 @@ namespace Content.Server.Hands
|
||||
|
||||
CommandBinds.Builder
|
||||
.Bind(ContentKeyFunctions.ActivateItemInHand, InputCmdHandler.FromDelegate(HandleActivateItem))
|
||||
.Bind(ContentKeyFunctions.AltActivateItemInHand, InputCmdHandler.FromDelegate(HandleAltActivateItem))
|
||||
.Bind(ContentKeyFunctions.ThrowItemInHand, new PointerInputCmdHandler(HandleThrowItem))
|
||||
.Bind(ContentKeyFunctions.SmartEquipBackpack, InputCmdHandler.FromDelegate(HandleSmartEquipBackpack))
|
||||
.Bind(ContentKeyFunctions.SmartEquipBelt, InputCmdHandler.FromDelegate(HandleSmartEquipBelt))
|
||||
@@ -220,6 +221,14 @@ namespace Content.Server.Hands
|
||||
hands.UseActiveHeldEntity();
|
||||
}
|
||||
|
||||
private void HandleAltActivateItem(ICommonSession? session)
|
||||
{
|
||||
if (!TryGetHandsComp(session, out var hands))
|
||||
return;
|
||||
|
||||
hands.UseActiveHeldEntity(altInteract: true);
|
||||
}
|
||||
|
||||
private bool HandleThrowItem(ICommonSession? session, EntityCoordinates coords, EntityUid uid)
|
||||
{
|
||||
if (session is not IPlayerSession playerSession)
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Content.Server.Interaction
|
||||
|
||||
data.Visibility = VerbVisibility.Visible;
|
||||
data.Text = Loc.GetString("in-range-unoccluded-verb-get-data-text");
|
||||
data.IconTexture = "/Textures/Interface/VerbIcons/information.svg.192dpi.png";
|
||||
data.CategoryData = VerbCategories.Debug;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ using Content.Shared.Inventory;
|
||||
using Content.Shared.Notification.Managers;
|
||||
using Content.Shared.Rotatable;
|
||||
using Content.Shared.Throwing;
|
||||
using Content.Shared.Verbs;
|
||||
using Content.Shared.Weapons.Melee;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects;
|
||||
@@ -52,10 +53,13 @@ namespace Content.Server.Interaction
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeNetworkEvent<DragDropRequestEvent>(HandleDragDropRequestEvent);
|
||||
SubscribeNetworkEvent<InteractInventorySlotEvent>(HandleInteractInventorySlotEvent);
|
||||
|
||||
CommandBinds.Builder
|
||||
.Bind(EngineKeyFunctions.Use,
|
||||
new PointerInputCmdHandler(HandleUseInteraction))
|
||||
.Bind(ContentKeyFunctions.AltActivateItemInWorld,
|
||||
new PointerInputCmdHandler(HandleAltUseInteraction))
|
||||
.Bind(ContentKeyFunctions.WideAttack,
|
||||
new PointerInputCmdHandler(HandleWideAttack))
|
||||
.Bind(ContentKeyFunctions.ActivateItemInWorld,
|
||||
@@ -102,6 +106,34 @@ namespace Content.Server.Interaction
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Handles the event were a client uses an item in their inventory or in their hands, either by
|
||||
/// alt-clicking it or pressing 'E' while hovering over it.
|
||||
/// </summary>
|
||||
private void HandleInteractInventorySlotEvent(InteractInventorySlotEvent msg, EntitySessionEventArgs args)
|
||||
{
|
||||
if (!EntityManager.TryGetEntity(msg.ItemUid, out var item))
|
||||
{
|
||||
Logger.WarningS("system.interaction",
|
||||
$"Client sent inventory interaction with an invalid target item. Session={args.SenderSession}");
|
||||
return;
|
||||
}
|
||||
|
||||
// client sanitization
|
||||
if (!ValidateClientInput(args.SenderSession, item.Transform.Coordinates, msg.ItemUid, out var userEntity))
|
||||
{
|
||||
Logger.InfoS("system.interaction", $"Inventory interaction validation failed. Session={args.SenderSession}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.AltInteract)
|
||||
// Use 'UserInteraction' function - behaves as if the user alt-clicked the item in the world.
|
||||
UserInteraction(userEntity, item.Transform.Coordinates, msg.ItemUid, msg.AltInteract);
|
||||
else
|
||||
// User used 'E'. We want to activate it, not simulate clicking on the item
|
||||
InteractionActivate(userEntity, item);
|
||||
}
|
||||
|
||||
#region Drag drop
|
||||
private void HandleDragDropRequestEvent(DragDropRequestEvent msg, EntitySessionEventArgs args)
|
||||
{
|
||||
@@ -241,6 +273,20 @@ namespace Content.Server.Interaction
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool HandleAltUseInteraction(ICommonSession? session, EntityCoordinates coords, EntityUid uid)
|
||||
{
|
||||
// client sanitization
|
||||
if (!ValidateClientInput(session, coords, uid, out var userEntity))
|
||||
{
|
||||
Logger.InfoS("system.interaction", $"Alt-use input validation failed");
|
||||
return true;
|
||||
}
|
||||
|
||||
UserInteraction(userEntity, coords, uid, altInteract : true );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool HandleTryPullObject(ICommonSession? session, EntityCoordinates coords, EntityUid uid)
|
||||
{
|
||||
if (!ValidateClientInput(session, coords, uid, out var userEntity))
|
||||
@@ -264,12 +310,24 @@ namespace Content.Server.Interaction
|
||||
return pull.TogglePull(userEntity);
|
||||
}
|
||||
|
||||
public async void UserInteraction(IEntity user, EntityCoordinates coordinates, EntityUid clickedUid)
|
||||
/// <summary>
|
||||
/// Resolves user interactions with objects.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Checks Whether combat mode is enabled and whether the user can actually interact with the given entity.
|
||||
/// </remarks>
|
||||
/// <param name="altInteract">Whether to use default or alternative interactions (usually as a result of
|
||||
/// alt+clicking). If combat mode is enabled, the alternative action is to perform the default non-combat
|
||||
/// interaction. Having an item in the active hand also disables alternative interactions.</param>
|
||||
public async void UserInteraction(IEntity user, EntityCoordinates coordinates, EntityUid clickedUid, bool altInteract = false )
|
||||
{
|
||||
if (user.TryGetComponent(out CombatModeComponent? combatMode) && combatMode.IsInCombatMode)
|
||||
// TODO COMBAT Consider using alt-interact for advanced combat? maybe alt-interact disarms?
|
||||
if (!altInteract && user.TryGetComponent(out CombatModeComponent? combatMode) && combatMode.IsInCombatMode)
|
||||
{
|
||||
|
||||
DoAttack(user, coordinates, false, clickedUid);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (!ValidateInteractAndFace(user, coordinates))
|
||||
@@ -313,12 +371,22 @@ namespace Content.Server.Interaction
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are close to the nearby object and the object isn't contained in our active hand
|
||||
// InteractUsing/AfterInteract: We will either use the item on the nearby object
|
||||
if (item != null)
|
||||
// We are close to the nearby object.
|
||||
if (altInteract)
|
||||
// We are trying to use alternative interactions. Perform alternative interactions, using context
|
||||
// menu verbs.
|
||||
|
||||
// Verbs can be triggered with an item in the hand, but currently there are no verbs that depend on
|
||||
// the currently held item. Maybe this if statement should be changed to
|
||||
// (altInteract && (item == null || item == target)).
|
||||
// Note that item == target will happen when alt-clicking the item currently in your hands.
|
||||
AltInteract(user, target);
|
||||
else if (item != null && item != target)
|
||||
// We are performing a standard interaction with an item, and the target isn't the same as the item
|
||||
// currently in our hand. We will use the item in our hand on the nearby object via InteractUsing
|
||||
await InteractUsing(user, item, target, coordinates);
|
||||
// InteractHand/Activate: Since our hand is empty we will use InteractHand/Activate
|
||||
else
|
||||
else if (item == null)
|
||||
// Since our hand is empty we will use InteractHand/Activate
|
||||
InteractHand(user, target);
|
||||
}
|
||||
}
|
||||
@@ -432,6 +500,44 @@ namespace Content.Server.Interaction
|
||||
await InteractDoAfter(user, used, target, clickLocation, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Alternative interactions on an entity.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Uses the context menu verb list, and acts out the first verb marked as an alternative interaction. Note
|
||||
/// that this does not have any checks to see whether this interaction is valid, as these are all done in <see
|
||||
/// cref="UserInteraction(IEntity, EntityCoordinates, EntityUid, bool)"/>
|
||||
/// </remarks>
|
||||
public void AltInteract(IEntity user, IEntity target)
|
||||
{
|
||||
// TODO VERB SYSTEM when ECS-ing verbs and re-writing VerbUtility.GetVerbs, maybe sort verbs by some
|
||||
// priority property, such that which verbs appear first is more predictable?.
|
||||
|
||||
// Iterate through list of verbs that apply to target. We do not include global verbs here. If in the future
|
||||
// alt click should also support global verbs, this needs to be changed.
|
||||
foreach (var (component, verb) in VerbUtility.GetVerbs(target))
|
||||
{
|
||||
// Check that the verb marked as an alternative interaction?
|
||||
if (!verb.AlternativeInteraction)
|
||||
continue;
|
||||
|
||||
// Can the verb be acted out?
|
||||
if (!VerbUtility.VerbAccessChecks(user, target, verb))
|
||||
continue;
|
||||
|
||||
// Is the verb currently enabled?
|
||||
var verbData = verb.GetData(user, component);
|
||||
if (verbData.IsInvisible || verbData.IsDisabled)
|
||||
continue;
|
||||
|
||||
// Act out the verb. Note that, if there is more than one AlternativeInteraction verb, only the first
|
||||
// one is activated. The priority is effectively determined by the order in which VerbUtility.GetVerbs()
|
||||
// returns the verbs.
|
||||
verb.Activate(user, component);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Uses an empty hand on an entity
|
||||
/// Finds components with the InteractHand interface and calls their function
|
||||
@@ -470,11 +576,14 @@ namespace Content.Server.Interaction
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="used"></param>
|
||||
public void TryUseInteraction(IEntity user, IEntity used)
|
||||
public void TryUseInteraction(IEntity user, IEntity used, bool altInteract = false)
|
||||
{
|
||||
if (user != null && used != null && _actionBlockerSystem.CanUse(user))
|
||||
{
|
||||
UseInteraction(user, used);
|
||||
if (altInteract)
|
||||
AltInteract(user, used);
|
||||
else
|
||||
UseInteraction(user, used);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ namespace Content.Server.Items
|
||||
}
|
||||
|
||||
data.Text = Loc.GetString("pick-up-verb-get-data-text");
|
||||
data.IconTexture = "/Textures/Interface/VerbIcons/pickup.svg.192dpi.png";
|
||||
}
|
||||
|
||||
protected override void Activate(IEntity user, ItemComponent component)
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace Content.Server.Storage.Components
|
||||
[Verb]
|
||||
private sealed class ToggleLockVerb : Verb<LockComponent>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, LockComponent component, VerbData data)
|
||||
{
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user) ||
|
||||
|
||||
@@ -228,6 +228,8 @@ namespace Content.Server.Medical.Components
|
||||
[Verb]
|
||||
public sealed class EjectVerb : Verb<MedicalScannerComponent>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, MedicalScannerComponent component, VerbData data)
|
||||
{
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user))
|
||||
@@ -238,6 +240,7 @@ namespace Content.Server.Medical.Components
|
||||
|
||||
data.Text = Loc.GetString("medical-scanner-eject-verb-get-data-text");
|
||||
data.Visibility = component.IsOccupied ? VerbVisibility.Visible : VerbVisibility.Invisible;
|
||||
data.IconTexture = "/Textures/Interface/VerbIcons/eject.svg.192dpi.png";
|
||||
}
|
||||
|
||||
protected override void Activate(IEntity user, MedicalScannerComponent component)
|
||||
|
||||
@@ -375,6 +375,8 @@ namespace Content.Server.PDA
|
||||
[Verb]
|
||||
public sealed class EjectIDVerb : Verb<PDAComponent>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, PDAComponent component, VerbData data)
|
||||
{
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user))
|
||||
|
||||
@@ -162,6 +162,8 @@ namespace Content.Server.Power.Components
|
||||
[Verb]
|
||||
private sealed class EjectVerb : Verb<BaseCharger>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, BaseCharger component, VerbData data)
|
||||
{
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user))
|
||||
|
||||
@@ -179,6 +179,8 @@ namespace Content.Server.PowerCell.Components
|
||||
[Verb]
|
||||
public sealed class EjectCellVerb : Verb<PowerCellSlotComponent>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, PowerCellSlotComponent component, VerbData data)
|
||||
{
|
||||
if (!component.ShowVerb || !EntitySystem.Get<ActionBlockerSystem>().CanInteract(user))
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
||||
using Content.Server.DoAfter;
|
||||
using Content.Server.Hands.Components;
|
||||
using Content.Server.Items;
|
||||
using Content.Shared.ActionBlocker;
|
||||
using Content.Shared.Acts;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Interaction.Helpers;
|
||||
@@ -14,6 +15,7 @@ using Content.Shared.Notification.Managers;
|
||||
using Content.Shared.Placeable;
|
||||
using Content.Shared.Sound;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Verbs;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.Player;
|
||||
@@ -22,6 +24,7 @@ using Robust.Shared.Containers;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Network;
|
||||
@@ -629,5 +632,46 @@ namespace Content.Server.Storage.Components
|
||||
{
|
||||
SoundSystem.Play(Filter.Pvs(Owner), StorageSoundCollection.GetSound(), Owner, AudioParams.Default);
|
||||
}
|
||||
|
||||
[Verb]
|
||||
private sealed class ToggleOpenVerb : Verb<ServerStorageComponent>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, ServerStorageComponent component, VerbData data)
|
||||
{
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user))
|
||||
{
|
||||
data.Visibility = VerbVisibility.Invisible;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the session for the user
|
||||
var session = user.GetComponentOrNull<ActorComponent>()?.PlayerSession;
|
||||
if (session == null)
|
||||
{
|
||||
data.Visibility = VerbVisibility.Invisible;
|
||||
return;
|
||||
}
|
||||
|
||||
// Does this player currently have the storage UI open?
|
||||
if (component.SubscribedSessions.Contains(session))
|
||||
{
|
||||
data.Text = Loc.GetString("toggle-open-verb-close");
|
||||
data.IconTexture = "/Textures/Interface/VerbIcons/close.svg.192dpi.png";
|
||||
} else
|
||||
{
|
||||
data.Text = Loc.GetString("toggle-open-verb-open");
|
||||
data.IconTexture = "/Textures/Interface/VerbIcons/open.svg.192dpi.png";
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Activate(IEntity user, ServerStorageComponent component)
|
||||
{
|
||||
// "Open" actually closes the UI if it is already open.
|
||||
component.OpenStorageUI(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,6 +290,8 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
|
||||
[Verb]
|
||||
public sealed class EjectCellVerb : Verb<ServerBatteryBarrelComponent>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, ServerBatteryBarrelComponent component, VerbData data)
|
||||
{
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user) || !component._powerCellRemovable)
|
||||
|
||||
@@ -429,6 +429,8 @@ namespace Content.Server.Weapon.Ranged.Barrels.Components
|
||||
[Verb]
|
||||
private sealed class EjectMagazineVerb : Verb<ServerMagazineBarrelComponent>
|
||||
{
|
||||
public override bool AlternativeInteraction => true;
|
||||
|
||||
protected override void GetData(IEntity user, ServerMagazineBarrelComponent component, VerbData data)
|
||||
{
|
||||
if (!EntitySystem.Get<ActionBlockerSystem>().CanInteract(user))
|
||||
|
||||
@@ -674,12 +674,12 @@ namespace Content.Shared.Hands.Components
|
||||
DoInteraction(activeHeldEntity, heldEntity);
|
||||
}
|
||||
|
||||
public void UseActiveHeldEntity()
|
||||
public void UseActiveHeldEntity(bool altInteract = false)
|
||||
{
|
||||
if (!TryGetActiveHeldEntity(out var heldEntity))
|
||||
return;
|
||||
|
||||
DoUse(heldEntity);
|
||||
DoUse(heldEntity, altInteract);
|
||||
}
|
||||
|
||||
public void ActivateHeldEntity(string handName)
|
||||
@@ -783,7 +783,7 @@ namespace Content.Shared.Hands.Components
|
||||
|
||||
protected virtual void DoInteraction(IEntity activeHeldEntity, IEntity heldEntity) { }
|
||||
|
||||
protected virtual void DoUse(IEntity heldEntity) { }
|
||||
protected virtual void DoUse(IEntity heldEntity, bool altInteract = false) { }
|
||||
|
||||
protected virtual void DoActivate(IEntity heldEntity) { }
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@ namespace Content.Shared.Input
|
||||
{
|
||||
public static readonly BoundKeyFunction WideAttack = "WideAttack";
|
||||
public static readonly BoundKeyFunction ActivateItemInHand = "ActivateItemInHand";
|
||||
public static readonly BoundKeyFunction ActivateItemInWorld = "ActivateItemInWorld"; // default action on world entity
|
||||
public static readonly BoundKeyFunction AltActivateItemInHand = "AltActivateItemInHand";
|
||||
public static readonly BoundKeyFunction ActivateItemInWorld = "ActivateItemInWorld";
|
||||
public static readonly BoundKeyFunction AltActivateItemInWorld = "AltActivateItemInWorld";
|
||||
public static readonly BoundKeyFunction Drop = "Drop";
|
||||
public static readonly BoundKeyFunction ExamineEntity = "ExamineEntity";
|
||||
public static readonly BoundKeyFunction FocusChat = "FocusChatInputWindow";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Content.Shared.Notification;
|
||||
using Content.Shared.Notification.Managers;
|
||||
@@ -9,6 +10,7 @@ using Robust.Shared.Localization;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Broadphase;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Interaction
|
||||
{
|
||||
@@ -338,4 +340,27 @@ namespace Content.Shared.Interaction
|
||||
return inRange;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when a player attempts to activate an item in an inventory slot or hand slot
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public class InteractInventorySlotEvent : EntityEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Entity that was interacted with.
|
||||
/// </summary>
|
||||
public EntityUid ItemUid { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the interaction used the alt-modifier to trigger alternative interactions.
|
||||
/// </summary>
|
||||
public bool AltInteract { get; }
|
||||
|
||||
public InteractInventorySlotEvent(EntityUid itemUid, bool altInteract = false)
|
||||
{
|
||||
ItemUid = itemUid;
|
||||
AltInteract = altInteract;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
namespace Content.Shared.Verbs
|
||||
{
|
||||
public abstract class VerbBase
|
||||
@@ -15,5 +15,10 @@ namespace Content.Shared.Verbs
|
||||
/// OR the user can be the entity's container
|
||||
/// </summary>
|
||||
public virtual bool BlockedByContainers => true;
|
||||
|
||||
/// <summary>
|
||||
/// If true, this verb can be activated by alt-clicking on the entity.
|
||||
/// </summary>
|
||||
public virtual bool AlternativeInteraction => false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ namespace Content.Shared.Verbs
|
||||
("Debug", "/Textures/Interface/VerbIcons/debug.svg.192dpi.png");
|
||||
|
||||
public static readonly VerbCategoryData Rotate = ("Rotate", null);
|
||||
public static readonly VerbCategoryData Construction = ("Construction", null);
|
||||
public static readonly VerbCategoryData Construction =
|
||||
("Construction", "/Textures/Interface/hammer_scaled.svg.192dpi.png");
|
||||
public static readonly VerbCategoryData SetTransferAmount =
|
||||
("Set Transfer Amount", "/Textures/Interface/VerbIcons/spill.svg.192dpi.png");
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@ namespace Content.Shared.Verbs
|
||||
/// <summary>
|
||||
/// The text that the user sees on the verb button.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This string is automatically passed through Loc.GetString().
|
||||
/// </remarks>
|
||||
public string Text { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -16,8 +16,12 @@ disposal-mailing-unit-is-valid-interaction-no-hands = You have no hands.
|
||||
|
||||
## SelfInsertVerb
|
||||
|
||||
self-insert-verb-get-data-text = Jump inside
|
||||
disposal-self-insert-verb-get-data-text = Jump inside
|
||||
|
||||
## FlushVerb
|
||||
|
||||
flush-verb-get-data-text = Flush
|
||||
disposal-flush-verb-get-data-text = Flush
|
||||
|
||||
## EjectVerb
|
||||
|
||||
disposal-eject-verb-get-data-text = Eject
|
||||
|
||||
@@ -72,7 +72,9 @@ ui-options-function-walk = Walk
|
||||
ui-options-function-use = Use
|
||||
ui-options-function-wide-attack = Wide attack
|
||||
ui-options-function-activate-item-in-hand = Activate item in hand
|
||||
ui-options-function-alt-activate-item-in-hand = Alternative activate item in hand
|
||||
ui-options-function-activate-item-in-world = Activate item in world
|
||||
ui-options-function-alt-activate-item-in-world = Alternative activate item in world
|
||||
ui-options-function-drop = Drop item
|
||||
ui-options-function-examine-entity = Examine
|
||||
ui-options-function-swap-hands = Swap hands
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
## ToggleOpenVerb
|
||||
|
||||
toggle-open-verb-open = Open
|
||||
toggle-open-verb-close = Close
|
||||
74
Resources/Textures/Interface/VerbIcons/climb.svg
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1"
|
||||
viewBox="0 0 32 32"
|
||||
id="svg4"
|
||||
sodipodi:docname="climb.svg"
|
||||
width="32"
|
||||
height="32"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
inkscape:export-filename="C:\Users\ElectroSR\Documents\GitHub\space-station-14\Resources\Textures\Interface\VerbIcons\pickup.svg.192dpi.png"
|
||||
inkscape:export-xdpi="192"
|
||||
inkscape:export-ydpi="192"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs8">
|
||||
<symbol
|
||||
id="UpArrow">
|
||||
<title
|
||||
id="title4024">Up Arrow</title>
|
||||
<path
|
||||
d="M 36,9 58,31 58,46 42,30 42,62 30,62 30,30 14,46 14,31 z"
|
||||
style="stroke:none"
|
||||
id="path4026" />
|
||||
</symbol>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1284"
|
||||
inkscape:window-height="1081"
|
||||
id="namedview6"
|
||||
showgrid="false"
|
||||
inkscape:pagecheckerboard="true"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="8.4631843"
|
||||
inkscape:cy="18.760427"
|
||||
inkscape:window-x="578"
|
||||
inkscape:window-y="502"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg4" />
|
||||
<use
|
||||
xlink:href="#UpArrow"
|
||||
style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:0, 11.00000008;stroke-dashoffset:0;fill-opacity:1"
|
||||
id="use12482"
|
||||
x="0"
|
||||
y="0"
|
||||
width="100%"
|
||||
height="100%"
|
||||
transform="matrix(0.52591705,0,0,0.52591705,-3.0032019,-3.4294343)" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
version="1.1"
|
||||
id="svg6"
|
||||
sodipodi:docname="delete_white.svg"
|
||||
width="32"
|
||||
height="32"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
inkscape:export-filename="C:\Users\ElectroSR\Documents\GitHub\space-station-14\Resources\Textures\Interface\VerbIcons\delete_transparent.svg.192dpi.png"
|
||||
inkscape:export-xdpi="192"
|
||||
inkscape:export-ydpi="192"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs10">
|
||||
<color-profile
|
||||
name="Agfa-:-Swop-Standard"
|
||||
xlink:href="../../../../../../../../../WINDOWS/system32/spool/drivers/color/RSWOP.icm"
|
||||
id="color-profile1466" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1271"
|
||||
inkscape:window-height="1272"
|
||||
id="namedview8"
|
||||
showgrid="true"
|
||||
inkscape:pagecheckerboard="true"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:zoom="16"
|
||||
inkscape:cx="11.21875"
|
||||
inkscape:cy="13.0625"
|
||||
inkscape:window-x="341"
|
||||
inkscape:window-y="107"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg6">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid837"
|
||||
empspacing="4" />
|
||||
<sodipodi:guide
|
||||
position="24.91123,3.1839064"
|
||||
orientation="-0.99756278,0.069774599"
|
||||
id="guide848" />
|
||||
<sodipodi:guide
|
||||
position="6.8635256,3.1839064"
|
||||
orientation="-0.99830447,-0.058208125"
|
||||
id="guide850" />
|
||||
</sodipodi:namedview>
|
||||
<g
|
||||
id="g846"
|
||||
transform="translate(0.99999985,0.4620656)"
|
||||
style="fill:#ffffff;fill-opacity:1">
|
||||
<path
|
||||
id="path2"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.225696"
|
||||
d="M 11.875975,2.7218408 11.26413,4.2466048 H 3.8056135 L 3.3542233,7.7523717 H 26.645777 L 26.194387,4.2466048 H 18.73587 l -0.611845,-1.524764 z" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.225696"
|
||||
d="M 20.609312,9 V 25.675027 H 18.976634 V 9 H 15.704055 V 25.675027 H 14.071152 V 9 H 10.573781 V 25.675027 H 8.9413298 V 9 H 4.7350507 L 5.8742488,28.537934 H 23.898367 L 25.264949,9 Z"
|
||||
id="path841"
|
||||
sodipodi:nodetypes="ccccccccccccccccc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 650 B |
@@ -0,0 +1,3 @@
|
||||
#variant of delete.svg, with transparent background
|
||||
sample:
|
||||
filter: true
|
||||
90
Resources/Textures/Interface/VerbIcons/information.svg
Normal file
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1"
|
||||
viewBox="0 0 32 32"
|
||||
id="svg4"
|
||||
sodipodi:docname="information.svg"
|
||||
width="32"
|
||||
height="32"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
inkscape:export-filename="C:\Users\ElectroSR\Documents\GitHub\space-station-14\Resources\Textures\Interface\VerbIcons\information.svg.192dpi.png"
|
||||
inkscape:export-xdpi="192"
|
||||
inkscape:export-ydpi="192"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs8">
|
||||
<symbol
|
||||
id="Information">
|
||||
<title
|
||||
id="title622">Information</title>
|
||||
<circle
|
||||
cx="36"
|
||||
cy="36"
|
||||
r="24"
|
||||
style="fill:none;stroke-width:6"
|
||||
id="circle624" />
|
||||
<path
|
||||
d="m 27,32 c 0,-5 1,-11 9,-11 4,0 8,3 8,7 0,4 -2,6 -4,7 -2,1 -4,2 -4,5 0,3 0,6 0,6"
|
||||
style="fill:none;stroke-width:6"
|
||||
id="path626" />
|
||||
<rect
|
||||
x="33"
|
||||
y="48"
|
||||
width="6"
|
||||
height="6"
|
||||
style="stroke:none"
|
||||
id="rect628" />
|
||||
</symbol>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1271"
|
||||
inkscape:window-height="1081"
|
||||
id="namedview6"
|
||||
showgrid="false"
|
||||
inkscape:pagecheckerboard="true"
|
||||
inkscape:zoom="35.2"
|
||||
inkscape:cx="13.508523"
|
||||
inkscape:cy="14.701705"
|
||||
inkscape:window-x="1119"
|
||||
inkscape:window-y="319"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg4" />
|
||||
<use
|
||||
xlink:href="#Information"
|
||||
style="fill:#ffffff;stroke:#ffffff;stroke-opacity:1"
|
||||
id="use4000"
|
||||
x="0"
|
||||
y="0"
|
||||
width="100%"
|
||||
height="100%"
|
||||
transform="matrix(0.48863637,0,0,0.48863637,-1.5909093,-1.5909093)"
|
||||
inkscape:export-filename="C:\Users\ElectroSR\Documents\GitHub\space-station-14\Resources\Textures\Interface\VerbIcons\information.svg.192dpi.png"
|
||||
inkscape:export-xdpi="192"
|
||||
inkscape:export-ydpi="192" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,2 @@
|
||||
sample:
|
||||
filter: true
|
||||
77
Resources/Textures/Interface/VerbIcons/pickup.svg
Normal file
@@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1"
|
||||
viewBox="0 0 32 32"
|
||||
id="svg4"
|
||||
sodipodi:docname="pickup.svg"
|
||||
width="32"
|
||||
height="32"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
inkscape:export-filename="C:\Users\Pieter-Jan Briers\Projects\space-station-14\Resources\Textures\Interface\VerbIcons\anchor.svg.96dpi.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs8">
|
||||
<symbol
|
||||
id="UpArrow">
|
||||
<title
|
||||
id="title4024">Up Arrow</title>
|
||||
<path
|
||||
d="M 36,9 58,31 58,46 42,30 42,62 30,62 30,30 14,46 14,31 z"
|
||||
style="stroke:none"
|
||||
id="path4026" />
|
||||
</symbol>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1417"
|
||||
id="namedview6"
|
||||
showgrid="false"
|
||||
inkscape:pagecheckerboard="true"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="8.4852814"
|
||||
inkscape:cy="18.760427"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4" />
|
||||
<use
|
||||
xlink:href="#UpArrow"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:0, 11;stroke-dashoffset:0"
|
||||
id="use12482"
|
||||
x="0"
|
||||
y="0"
|
||||
width="100%"
|
||||
height="100%"
|
||||
transform="matrix(0.46866551,0,0,0.46866551,-0.87195836,-0.6376256)"
|
||||
inkscape:export-filename="C:\Users\ElectroSR\Documents\GitHub\space-station-14\Resources\Textures\Interface\VerbIcons\pickup.svg.192dpi.png"
|
||||
inkscape:export-xdpi="192"
|
||||
inkscape:export-ydpi="192" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
BIN
Resources/Textures/Interface/VerbIcons/pickup.svg.192dpi.png
Normal file
|
After Width: | Height: | Size: 513 B |
@@ -0,0 +1,2 @@
|
||||
sample:
|
||||
filter: true
|
||||
@@ -0,0 +1,3 @@
|
||||
#this is just a copy of hammer.svg, but scaled and adjusted slightly so that it can be used as a right-click context menu icon.
|
||||
sample:
|
||||
filter: true
|
||||
76
Resources/Textures/Interface/hammer_scaled.svg
Normal file
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1"
|
||||
viewBox="0 0 32 32"
|
||||
id="svg4"
|
||||
sodipodi:docname="hammer_scaled.svg"
|
||||
width="32"
|
||||
height="32"
|
||||
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
|
||||
inkscape:export-filename="C:\Users\ElectroSR\Documents\GitHub\space-station-14\Resources\Textures\Interface\hammer_scaled.svg.192dpi.png"
|
||||
inkscape:export-xdpi="192"
|
||||
inkscape:export-ydpi="192"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs8">
|
||||
<symbol
|
||||
id="UpArrow">
|
||||
<title
|
||||
id="title4024">Up Arrow</title>
|
||||
<path
|
||||
d="M 36,9 58,31 58,46 42,30 42,62 30,62 30,30 14,46 14,31 z"
|
||||
style="stroke:none"
|
||||
id="path4026" />
|
||||
</symbol>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1417"
|
||||
id="namedview6"
|
||||
showgrid="false"
|
||||
inkscape:pagecheckerboard="true"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="5.8778251"
|
||||
inkscape:cy="12.926796"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4" />
|
||||
<g
|
||||
transform="matrix(3.1774603,0,0,3.1774603,246.59289,376.58527)"
|
||||
id="layer1">
|
||||
<path
|
||||
id="path34"
|
||||
d="m -70.236934,-117.55773 -0.861483,0.0297 c -0.04048,0.001 -0.07832,0.0195 -0.105569,0.0503 l -0.102658,0.11563 -0.112713,-0.10822 c -0.03016,-0.0288 -0.06958,-0.044 -0.109802,-0.0429 l -1.723231,0.0593 c -0.345546,0.0119 -0.924454,0.0318 -1.479814,0.65811 -0.555096,0.62585 -0.529432,1.18144 -0.51144,1.58708 0.0029,0.064 0.0426,0.12052 0.100806,0.14295 0.05821,0.0227 0.123296,0.007 0.164571,-0.04 0.827352,-0.93271 1.309423,-0.67016 1.599935,-0.39139 0.241565,0.23159 0.245269,0.55176 0.259557,0.73109 h 1.480872 c 0.0463,-0.33388 0.127,-0.82923 0.259028,-0.9535 l 0.154516,0.14827 c 0.03016,0.0288 0.06959,0.044 0.109802,0.0428 l 1.077119,-0.0371 c 0.04022,-0.002 0.07832,-0.0195 0.105569,-0.0503 l 0.0034,-0.004 c 0.02752,-0.033 0.04022,-0.0765 0.03519,-0.11983 l -0.184679,-1.67522 c -0.0093,-0.0833 -0.07858,-0.14548 -0.159015,-0.14294 z"
|
||||
style="clip-rule:evenodd;fill:#ffffff;fill-opacity:0.941176;fill-rule:evenodd;stroke-width:0.264583" />
|
||||
<path
|
||||
id="path36"
|
||||
d="m -73.125919,-110.25648 c -0.004,0.22704 0.07726,0.43934 0.242094,0.61087 0.313531,0.32631 0.832379,0.31758 1.157287,-0.0195 0.165365,-0.17174 0.256381,-0.40722 0.249767,-0.64571 l -0.163777,-4.08366 h -1.485371 z"
|
||||
style="clip-rule:evenodd;fill:#ffffff;fill-opacity:0.941176;fill-rule:evenodd;stroke-width:0.264583" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
BIN
Resources/Textures/Interface/hammer_scaled.svg.192dpi.png
Normal file
|
After Width: | Height: | Size: 812 B |
@@ -109,6 +109,10 @@ binds:
|
||||
- function: ActivateItemInHand
|
||||
type: State
|
||||
key: Z
|
||||
- function: AltActivateItemInHand
|
||||
type: State
|
||||
key: Z
|
||||
mod1: Alt
|
||||
- function: OpenCharacterMenu
|
||||
type: State
|
||||
key: C
|
||||
@@ -128,6 +132,15 @@ binds:
|
||||
- function: ActivateItemInWorld
|
||||
type: State
|
||||
key: E
|
||||
- function: AltActivateItemInWorld
|
||||
type: State
|
||||
key: MouseLeft
|
||||
canFocus: true
|
||||
mod1: Alt
|
||||
- function: AltActivateItemInWorld # secondary binding
|
||||
type: State
|
||||
key: E
|
||||
mod1: Alt
|
||||
- function: ThrowItemInHand
|
||||
type: State
|
||||
key: Q
|
||||
|
||||