Zooming for everyone with keyboard keys (#16605)
This commit is contained in:
@@ -75,6 +75,7 @@ public sealed partial class AdminVerbSystem
|
|||||||
[Dependency] private readonly TabletopSystem _tabletopSystem = default!;
|
[Dependency] private readonly TabletopSystem _tabletopSystem = default!;
|
||||||
[Dependency] private readonly VomitSystem _vomitSystem = default!;
|
[Dependency] private readonly VomitSystem _vomitSystem = default!;
|
||||||
[Dependency] private readonly WeldableSystem _weldableSystem = default!;
|
[Dependency] private readonly WeldableSystem _weldableSystem = default!;
|
||||||
|
[Dependency] private readonly SharedContentEyeSystem _eyeSystem = default!;
|
||||||
|
|
||||||
// All smite verbs have names so invokeverb works.
|
// All smite verbs have names so invokeverb works.
|
||||||
private void AddSmiteVerbs(GetVerbsEvent<Verb> args)
|
private void AddSmiteVerbs(GetVerbsEvent<Verb> args)
|
||||||
@@ -704,11 +705,8 @@ public sealed partial class AdminVerbSystem
|
|||||||
Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/AdminActions/zoom.png")),
|
Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/AdminActions/zoom.png")),
|
||||||
Act = () =>
|
Act = () =>
|
||||||
{
|
{
|
||||||
var eye = EnsureComp<EyeComponent>(args.Target);
|
var eye = EnsureComp<ContentEyeComponent>(args.Target);
|
||||||
|
_eyeSystem.SetZoom(args.Target, eye.TargetZoom * 0.2f, ignoreLimits: true);
|
||||||
eye.Zoom *= Vector2.One * 0.2f;
|
|
||||||
|
|
||||||
Dirty(eye);
|
|
||||||
},
|
},
|
||||||
Impact = LogImpact.Extreme,
|
Impact = LogImpact.Extreme,
|
||||||
Message = Loc.GetString("admin-smite-zoom-in-description"),
|
Message = Loc.GetString("admin-smite-zoom-in-description"),
|
||||||
@@ -722,11 +720,8 @@ public sealed partial class AdminVerbSystem
|
|||||||
Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/AdminActions/flip.png")),
|
Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/AdminActions/flip.png")),
|
||||||
Act = () =>
|
Act = () =>
|
||||||
{
|
{
|
||||||
var eye = EnsureComp<EyeComponent>(args.Target);
|
var eye = EnsureComp<ContentEyeComponent>(args.Target);
|
||||||
|
_eyeSystem.SetZoom(args.Target, eye.TargetZoom * -1, ignoreLimits: true);
|
||||||
eye.Zoom *= -1;
|
|
||||||
|
|
||||||
Dirty(eye);
|
|
||||||
},
|
},
|
||||||
Impact = LogImpact.Extreme,
|
Impact = LogImpact.Extreme,
|
||||||
Message = Loc.GetString("admin-smite-flip-eye-description"),
|
Message = Loc.GetString("admin-smite-flip-eye-description"),
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ using Content.Shared.Shuttles.Components;
|
|||||||
using Content.Shared.Shuttles.Events;
|
using Content.Shared.Shuttles.Events;
|
||||||
using Content.Shared.Shuttles.Systems;
|
using Content.Shared.Shuttles.Systems;
|
||||||
using Content.Shared.Tag;
|
using Content.Shared.Tag;
|
||||||
|
using Content.Shared.Movement.Systems;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Collections;
|
using Robust.Shared.Collections;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
@@ -33,6 +34,7 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
|
|||||||
[Dependency] private readonly StationSystem _station = default!;
|
[Dependency] private readonly StationSystem _station = default!;
|
||||||
[Dependency] private readonly TagSystem _tags = default!;
|
[Dependency] private readonly TagSystem _tags = default!;
|
||||||
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
||||||
|
[Dependency] private readonly SharedContentEyeSystem _eyeSystem = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -69,7 +71,8 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
|
|||||||
RefreshShuttleConsoles();
|
RefreshShuttleConsoles();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDestinationMessage(EntityUid uid, ShuttleConsoleComponent component, ShuttleConsoleFTLRequestMessage args)
|
private void OnDestinationMessage(EntityUid uid, ShuttleConsoleComponent component,
|
||||||
|
ShuttleConsoleFTLRequestMessage args)
|
||||||
{
|
{
|
||||||
if (!TryComp<FTLDestinationComponent>(args.Destination, out var dest))
|
if (!TryComp<FTLDestinationComponent>(args.Destination, out var dest))
|
||||||
{
|
{
|
||||||
@@ -157,7 +160,7 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnConsoleUIClose(EntityUid uid, ShuttleConsoleComponent component, BoundUIClosedEvent args)
|
private void OnConsoleUIClose(EntityUid uid, ShuttleConsoleComponent component, BoundUIClosedEvent args)
|
||||||
{
|
{
|
||||||
if ((ShuttleConsoleUiKey) args.UiKey != ShuttleConsoleUiKey.Key ||
|
if ((ShuttleConsoleUiKey)args.UiKey != ShuttleConsoleUiKey.Key ||
|
||||||
args.Session.AttachedEntity is not { } user)
|
args.Session.AttachedEntity is not { } user)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -172,13 +175,15 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
|
|||||||
RemovePilot(user);
|
RemovePilot(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnConsoleUIOpenAttempt(EntityUid uid, ShuttleConsoleComponent component, ActivatableUIOpenAttemptEvent args)
|
private void OnConsoleUIOpenAttempt(EntityUid uid, ShuttleConsoleComponent component,
|
||||||
|
ActivatableUIOpenAttemptEvent args)
|
||||||
{
|
{
|
||||||
if (!TryPilot(args.User, uid))
|
if (!TryPilot(args.User, uid))
|
||||||
args.Cancel();
|
args.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnConsoleAnchorChange(EntityUid uid, ShuttleConsoleComponent component, ref AnchorStateChangedEvent args)
|
private void OnConsoleAnchorChange(EntityUid uid, ShuttleConsoleComponent component,
|
||||||
|
ref AnchorStateChangedEvent args)
|
||||||
{
|
{
|
||||||
UpdateState(uid);
|
UpdateState(uid);
|
||||||
}
|
}
|
||||||
@@ -398,10 +403,7 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TryComp<SharedEyeComponent>(entity, out var eye))
|
_eyeSystem.SetZoom(entity, component.Zoom, ignoreLimits:true);
|
||||||
{
|
|
||||||
eye.Zoom = component.Zoom;
|
|
||||||
}
|
|
||||||
|
|
||||||
component.SubscribedPilots.Add(pilotComponent);
|
component.SubscribedPilots.Add(pilotComponent);
|
||||||
|
|
||||||
@@ -422,11 +424,7 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
|
|||||||
|
|
||||||
pilotComponent.Console = null;
|
pilotComponent.Console = null;
|
||||||
pilotComponent.Position = null;
|
pilotComponent.Position = null;
|
||||||
|
_eyeSystem.ResetZoom(pilotUid);
|
||||||
if (TryComp<SharedEyeComponent>(pilotUid, out var eye))
|
|
||||||
{
|
|
||||||
eye.Zoom = new(1.0f, 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!helmsman.SubscribedPilots.Remove(pilotComponent))
|
if (!helmsman.SubscribedPilots.Remove(pilotComponent))
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Robust.Shared.Input;
|
|||||||
using Robust.Shared.Input.Binding;
|
using Robust.Shared.Input.Binding;
|
||||||
using Robust.Shared.Players;
|
using Robust.Shared.Players;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Generic;
|
||||||
|
|
||||||
namespace Content.Shared.Movement.Systems;
|
namespace Content.Shared.Movement.Systems;
|
||||||
|
|
||||||
@@ -16,12 +17,9 @@ public abstract class SharedContentEyeSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly ISharedAdminManager _admin = default!;
|
[Dependency] private readonly ISharedAdminManager _admin = default!;
|
||||||
|
|
||||||
private const float ZoomMod = 1.2f;
|
public const float ZoomMod = 1.5f;
|
||||||
private const byte ZoomMultiple = 10;
|
public static readonly Vector2 DefaultZoom = Vector2.One;
|
||||||
|
public static readonly Vector2 MinZoom = DefaultZoom * (float)Math.Pow(ZoomMod, -3);
|
||||||
protected static readonly Vector2 MinZoom = new(MathF.Pow(ZoomMod, -ZoomMultiple), MathF.Pow(ZoomMod, -ZoomMultiple));
|
|
||||||
|
|
||||||
protected ISawmill Sawmill = Logger.GetSawmill("ceye");
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -31,22 +29,60 @@ public abstract class SharedContentEyeSystem : EntitySystem
|
|||||||
SubscribeAllEvent<RequestFovEvent>(OnRequestFov);
|
SubscribeAllEvent<RequestFovEvent>(OnRequestFov);
|
||||||
|
|
||||||
CommandBinds.Builder
|
CommandBinds.Builder
|
||||||
.Bind(ContentKeyFunctions.ZoomIn, new ScrollInputCmdHandler(true, this))
|
.Bind(ContentKeyFunctions.ZoomIn, InputCmdHandler.FromDelegate(ZoomIn, handle:false))
|
||||||
.Bind(ContentKeyFunctions.ZoomOut, new ScrollInputCmdHandler(false, this))
|
.Bind(ContentKeyFunctions.ZoomOut, InputCmdHandler.FromDelegate(ZoomOut, handle:false))
|
||||||
.Bind(ContentKeyFunctions.ResetZoom, new ResetZoomInputCmdHandler(this))
|
.Bind(ContentKeyFunctions.ResetZoom, InputCmdHandler.FromDelegate(ResetZoom, handle:false))
|
||||||
.Register<SharedContentEyeSystem>();
|
.Register<SharedContentEyeSystem>();
|
||||||
|
|
||||||
Sawmill.Level = LogLevel.Info;
|
Log.Level = LogLevel.Info;
|
||||||
UpdatesOutsidePrediction = true;
|
UpdatesOutsidePrediction = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Shutdown()
|
||||||
|
{
|
||||||
|
base.Shutdown();
|
||||||
|
CommandBinds.Unregister<SharedContentEyeSystem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetZoom(ICommonSession? session)
|
||||||
|
{
|
||||||
|
if (TryComp(session?.AttachedEntity, out ContentEyeComponent? eye))
|
||||||
|
ResetZoom(session.AttachedEntity.Value, eye);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ZoomOut(ICommonSession? session)
|
||||||
|
{
|
||||||
|
if (TryComp(session?.AttachedEntity, out ContentEyeComponent? eye))
|
||||||
|
SetZoom(session.AttachedEntity.Value, eye.TargetZoom * ZoomMod, eye: eye);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ZoomIn(ICommonSession? session)
|
||||||
|
{
|
||||||
|
if (TryComp(session?.AttachedEntity, out ContentEyeComponent? eye))
|
||||||
|
SetZoom(session.AttachedEntity.Value, eye.TargetZoom / ZoomMod, eye: eye);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector2 Clamp(Vector2 zoom, ContentEyeComponent component)
|
||||||
|
{
|
||||||
|
return Vector2.Clamp(zoom, MinZoom, component.MaxZoom);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the target zoom, optionally ignoring normal zoom limits.
|
||||||
|
/// </summary>
|
||||||
|
public void SetZoom(EntityUid uid, Vector2 zoom, bool ignoreLimits = false, ContentEyeComponent? eye = null)
|
||||||
|
{
|
||||||
|
if (!Resolve(uid, ref eye, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
eye.TargetZoom = ignoreLimits ? zoom : Clamp(zoom, eye);
|
||||||
|
Dirty(eye);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnContentZoomRequest(RequestTargetZoomEvent msg, EntitySessionEventArgs args)
|
private void OnContentZoomRequest(RequestTargetZoomEvent msg, EntitySessionEventArgs args)
|
||||||
{
|
{
|
||||||
if (!TryComp<ContentEyeComponent>(args.SenderSession.AttachedEntity, out var content))
|
if (TryComp<ContentEyeComponent>(args.SenderSession.AttachedEntity, out var content))
|
||||||
return;
|
SetZoom(args.SenderSession.AttachedEntity.Value, msg.TargetZoom, eye: content);
|
||||||
|
|
||||||
content.TargetZoom = msg.TargetZoom;
|
|
||||||
Dirty(content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRequestFov(RequestFovEvent msg, EntitySessionEventArgs args)
|
private void OnRequestFov(RequestFovEvent msg, EntitySessionEventArgs args)
|
||||||
@@ -64,12 +100,6 @@ public abstract class SharedContentEyeSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Shutdown()
|
|
||||||
{
|
|
||||||
base.Shutdown();
|
|
||||||
CommandBinds.Unregister<SharedContentEyeSystem>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnContentEyeStartup(EntityUid uid, ContentEyeComponent component, ComponentStartup args)
|
private void OnContentEyeStartup(EntityUid uid, ContentEyeComponent component, ComponentStartup args)
|
||||||
{
|
{
|
||||||
if (!TryComp<SharedEyeComponent>(uid, out var eyeComp))
|
if (!TryComp<SharedEyeComponent>(uid, out var eyeComp))
|
||||||
@@ -83,7 +113,7 @@ public abstract class SharedContentEyeSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
var diff = content.TargetZoom - eye.Zoom;
|
var diff = content.TargetZoom - eye.Zoom;
|
||||||
|
|
||||||
if (diff.LengthSquared < 0.0000001f)
|
if (diff.LengthSquared < 0.00001f)
|
||||||
{
|
{
|
||||||
eye.Zoom = content.TargetZoom;
|
eye.Zoom = content.TargetZoom;
|
||||||
Dirty(eye);
|
Dirty(eye);
|
||||||
@@ -96,106 +126,19 @@ public abstract class SharedContentEyeSystem : EntitySystem
|
|||||||
Dirty(eye);
|
Dirty(eye);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CanZoom(EntityUid uid, ContentEyeComponent? component = null)
|
public void ResetZoom(EntityUid uid, ContentEyeComponent? component = null)
|
||||||
{
|
{
|
||||||
return Resolve(uid, ref component, false);
|
SetZoom(uid, DefaultZoom, eye: component);
|
||||||
}
|
|
||||||
|
|
||||||
private void ResetZoom(EntityUid uid, ContentEyeComponent? component = null)
|
|
||||||
{
|
|
||||||
if (!Resolve(uid, ref component))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (component.TargetZoom.Equals(Vector2.One))
|
|
||||||
return;
|
|
||||||
|
|
||||||
component.TargetZoom = Vector2.One;
|
|
||||||
Dirty(component);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetMaxZoom(EntityUid uid, Vector2 value, ContentEyeComponent? component = null)
|
public void SetMaxZoom(EntityUid uid, Vector2 value, ContentEyeComponent? component = null)
|
||||||
{
|
|
||||||
if (Resolve(uid, ref component))
|
|
||||||
component.MaxZoom = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Zoom(EntityUid uid, bool zoomIn, ContentEyeComponent? component = null)
|
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref component))
|
if (!Resolve(uid, ref component))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var actual = component.TargetZoom;
|
component.MaxZoom = value;
|
||||||
|
component.TargetZoom = Clamp(component.TargetZoom, component);
|
||||||
if (zoomIn)
|
|
||||||
{
|
|
||||||
actual /= ZoomMod;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
actual *= ZoomMod;
|
|
||||||
}
|
|
||||||
|
|
||||||
actual = Vector2.ComponentMax(MinZoom, actual);
|
|
||||||
actual = Vector2.ComponentMin(component.MaxZoom, actual);
|
|
||||||
|
|
||||||
if (actual.Equals(component.TargetZoom))
|
|
||||||
return;
|
|
||||||
|
|
||||||
component.TargetZoom = actual;
|
|
||||||
Dirty(component);
|
Dirty(component);
|
||||||
Sawmill.Debug($"Set target zoom to {actual}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class ResetZoomInputCmdHandler : InputCmdHandler
|
|
||||||
{
|
|
||||||
private readonly SharedContentEyeSystem _system;
|
|
||||||
|
|
||||||
public ResetZoomInputCmdHandler(SharedContentEyeSystem system)
|
|
||||||
{
|
|
||||||
_system = system;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool HandleCmdMessage(ICommonSession? session, InputCmdMessage message)
|
|
||||||
{
|
|
||||||
ContentEyeComponent? component = null;
|
|
||||||
|
|
||||||
if (message is not FullInputCmdMessage full || session?.AttachedEntity == null ||
|
|
||||||
full.State != BoundKeyState.Down ||
|
|
||||||
!_system.CanZoom(session.AttachedEntity.Value, component))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_system.ResetZoom(session.AttachedEntity.Value, component);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class ScrollInputCmdHandler : InputCmdHandler
|
|
||||||
{
|
|
||||||
private readonly bool _zoomIn;
|
|
||||||
private readonly SharedContentEyeSystem _system;
|
|
||||||
|
|
||||||
public ScrollInputCmdHandler(bool zoomIn, SharedContentEyeSystem system)
|
|
||||||
{
|
|
||||||
_zoomIn = zoomIn;
|
|
||||||
_system = system;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool HandleCmdMessage(ICommonSession? session, InputCmdMessage message)
|
|
||||||
{
|
|
||||||
ContentEyeComponent? component = null;
|
|
||||||
|
|
||||||
if (message is not FullInputCmdMessage full || session?.AttachedEntity == null ||
|
|
||||||
full.State != BoundKeyState.Down ||
|
|
||||||
!_system.CanZoom(session.AttachedEntity.Value, component))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_system.Zoom(session.AttachedEntity.Value, _zoomIn, component);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -44,6 +44,8 @@
|
|||||||
- type: Actions
|
- type: Actions
|
||||||
- type: Eye
|
- type: Eye
|
||||||
drawFov: false
|
drawFov: false
|
||||||
|
- type: ContentEye
|
||||||
|
maxZoom: 1.2, 1.2
|
||||||
- type: DoAfter
|
- type: DoAfter
|
||||||
- type: Alerts
|
- type: Alerts
|
||||||
- type: NameIdentifier
|
- type: NameIdentifier
|
||||||
|
|||||||
@@ -300,6 +300,7 @@
|
|||||||
- type: MobPrice
|
- type: MobPrice
|
||||||
price: 1500 # Kidnapping a living person and selling them for cred is a good move.
|
price: 1500 # Kidnapping a living person and selling them for cred is a good move.
|
||||||
deathPenalty: 0.01 # However they really ought to be living and intact, otherwise they're worth 100x less.
|
deathPenalty: 0.01 # However they really ought to be living and intact, otherwise they're worth 100x less.
|
||||||
|
- type: ContentEye
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
save: false
|
save: false
|
||||||
|
|||||||
Reference in New Issue
Block a user