Skip to content

Commit cae037d

Browse files
authored
Zooming for everyone with keyboard keys (space-wizards#16605)
1 parent 9bdaca5 commit cae037d

File tree

5 files changed

+74
-135
lines changed

5 files changed

+74
-135
lines changed

‎Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs‎

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public sealed partial class AdminVerbSystem
7575
[Dependency] private readonly TabletopSystem _tabletopSystem = default!;
7676
[Dependency] private readonly VomitSystem _vomitSystem = default!;
7777
[Dependency] private readonly WeldableSystem _weldableSystem = default!;
78+
[Dependency] private readonly SharedContentEyeSystem _eyeSystem = default!;
7879

7980
// All smite verbs have names so invokeverb works.
8081
private void AddSmiteVerbs(GetVerbsEvent<Verb> args)
@@ -704,11 +705,8 @@ private void AddSmiteVerbs(GetVerbsEvent<Verb> args)
704705
Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/AdminActions/zoom.png")),
705706
Act = () =>
706707
{
707-
var eye = EnsureComp<EyeComponent>(args.Target);
708-
709-
eye.Zoom *= Vector2.One * 0.2f;
710-
711-
Dirty(eye);
708+
var eye = EnsureComp<ContentEyeComponent>(args.Target);
709+
_eyeSystem.SetZoom(args.Target, eye.TargetZoom * 0.2f, ignoreLimits: true);
712710
},
713711
Impact = LogImpact.Extreme,
714712
Message = Loc.GetString("admin-smite-zoom-in-description"),
@@ -722,11 +720,8 @@ private void AddSmiteVerbs(GetVerbsEvent<Verb> args)
722720
Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/AdminActions/flip.png")),
723721
Act = () =>
724722
{
725-
var eye = EnsureComp<EyeComponent>(args.Target);
726-
727-
eye.Zoom *= -1;
728-
729-
Dirty(eye);
723+
var eye = EnsureComp<ContentEyeComponent>(args.Target);
724+
_eyeSystem.SetZoom(args.Target, eye.TargetZoom * -1, ignoreLimits: true);
730725
},
731726
Impact = LogImpact.Extreme,
732727
Message = Loc.GetString("admin-smite-flip-eye-description"),

‎Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs‎

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using Content.Shared.Shuttles.Events;
1414
using Content.Shared.Shuttles.Systems;
1515
using Content.Shared.Tag;
16+
using Content.Shared.Movement.Systems;
1617
using Robust.Server.GameObjects;
1718
using Robust.Shared.Collections;
1819
using Robust.Shared.GameStates;
@@ -33,6 +34,7 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
3334
[Dependency] private readonly StationSystem _station = default!;
3435
[Dependency] private readonly TagSystem _tags = default!;
3536
[Dependency] private readonly UserInterfaceSystem _ui = default!;
37+
[Dependency] private readonly SharedContentEyeSystem _eyeSystem = default!;
3638

3739
public override void Initialize()
3840
{
@@ -69,7 +71,8 @@ private void OnFtlDestShutdown(EntityUid uid, FTLDestinationComponent component,
6971
RefreshShuttleConsoles();
7072
}
7173

72-
private void OnDestinationMessage(EntityUid uid, ShuttleConsoleComponent component, ShuttleConsoleFTLRequestMessage args)
74+
private void OnDestinationMessage(EntityUid uid, ShuttleConsoleComponent component,
75+
ShuttleConsoleFTLRequestMessage args)
7376
{
7477
if (!TryComp<FTLDestinationComponent>(args.Destination, out var dest))
7578
{
@@ -157,7 +160,7 @@ public void RefreshShuttleConsoles()
157160
/// </summary>
158161
private void OnConsoleUIClose(EntityUid uid, ShuttleConsoleComponent component, BoundUIClosedEvent args)
159162
{
160-
if ((ShuttleConsoleUiKey) args.UiKey != ShuttleConsoleUiKey.Key ||
163+
if ((ShuttleConsoleUiKey)args.UiKey != ShuttleConsoleUiKey.Key ||
161164
args.Session.AttachedEntity is not { } user)
162165
{
163166
return;
@@ -172,13 +175,15 @@ private void OnConsoleUIClose(EntityUid uid, ShuttleConsoleComponent component,
172175
RemovePilot(user);
173176
}
174177

175-
private void OnConsoleUIOpenAttempt(EntityUid uid, ShuttleConsoleComponent component, ActivatableUIOpenAttemptEvent args)
178+
private void OnConsoleUIOpenAttempt(EntityUid uid, ShuttleConsoleComponent component,
179+
ActivatableUIOpenAttemptEvent args)
176180
{
177181
if (!TryPilot(args.User, uid))
178182
args.Cancel();
179183
}
180184

181-
private void OnConsoleAnchorChange(EntityUid uid, ShuttleConsoleComponent component, ref AnchorStateChangedEvent args)
185+
private void OnConsoleAnchorChange(EntityUid uid, ShuttleConsoleComponent component,
186+
ref AnchorStateChangedEvent args)
182187
{
183188
UpdateState(uid);
184189
}
@@ -398,10 +403,7 @@ public void AddPilot(EntityUid entity, ShuttleConsoleComponent component)
398403
return;
399404
}
400405

401-
if (TryComp<SharedEyeComponent>(entity, out var eye))
402-
{
403-
eye.Zoom = component.Zoom;
404-
}
406+
_eyeSystem.SetZoom(entity, component.Zoom, ignoreLimits:true);
405407

406408
component.SubscribedPilots.Add(pilotComponent);
407409

@@ -422,11 +424,7 @@ public void RemovePilot(EntityUid pilotUid, PilotComponent pilotComponent)
422424

423425
pilotComponent.Console = null;
424426
pilotComponent.Position = null;
425-
426-
if (TryComp<SharedEyeComponent>(pilotUid, out var eye))
427-
{
428-
eye.Zoom = new(1.0f, 1.0f);
429-
}
427+
_eyeSystem.ResetZoom(pilotUid);
430428

431429
if (!helmsman.SubscribedPilots.Remove(pilotComponent))
432430
return;

‎Content.Shared/Movement/Systems/SharedContentEyeSystem.cs‎

Lines changed: 55 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Robust.Shared.Input.Binding;
77
using Robust.Shared.Players;
88
using Robust.Shared.Serialization;
9+
using Robust.Shared.Serialization.TypeSerializers.Implementations.Generic;
910

1011
namespace Content.Shared.Movement.Systems;
1112

@@ -16,12 +17,9 @@ public abstract class SharedContentEyeSystem : EntitySystem
1617
{
1718
[Dependency] private readonly ISharedAdminManager _admin = default!;
1819

19-
private const float ZoomMod = 1.2f;
20-
private const byte ZoomMultiple = 10;
21-
22-
protected static readonly Vector2 MinZoom = new(MathF.Pow(ZoomMod, -ZoomMultiple), MathF.Pow(ZoomMod, -ZoomMultiple));
23-
24-
protected ISawmill Sawmill = Logger.GetSawmill("ceye");
20+
public const float ZoomMod = 1.5f;
21+
public static readonly Vector2 DefaultZoom = Vector2.One;
22+
public static readonly Vector2 MinZoom = DefaultZoom * (float)Math.Pow(ZoomMod, -3);
2523

2624
public override void Initialize()
2725
{
@@ -31,22 +29,60 @@ public override void Initialize()
3129
SubscribeAllEvent<RequestFovEvent>(OnRequestFov);
3230

3331
CommandBinds.Builder
34-
.Bind(ContentKeyFunctions.ZoomIn, new ScrollInputCmdHandler(true, this))
35-
.Bind(ContentKeyFunctions.ZoomOut, new ScrollInputCmdHandler(false, this))
36-
.Bind(ContentKeyFunctions.ResetZoom, new ResetZoomInputCmdHandler(this))
32+
.Bind(ContentKeyFunctions.ZoomIn, InputCmdHandler.FromDelegate(ZoomIn, handle:false))
33+
.Bind(ContentKeyFunctions.ZoomOut, InputCmdHandler.FromDelegate(ZoomOut, handle:false))
34+
.Bind(ContentKeyFunctions.ResetZoom, InputCmdHandler.FromDelegate(ResetZoom, handle:false))
3735
.Register<SharedContentEyeSystem>();
3836

39-
Sawmill.Level = LogLevel.Info;
37+
Log.Level = LogLevel.Info;
4038
UpdatesOutsidePrediction = true;
4139
}
4240

43-
private void OnContentZoomRequest(RequestTargetZoomEvent msg, EntitySessionEventArgs args)
41+
public override void Shutdown()
42+
{
43+
base.Shutdown();
44+
CommandBinds.Unregister<SharedContentEyeSystem>();
45+
}
46+
47+
private void ResetZoom(ICommonSession? session)
48+
{
49+
if (TryComp(session?.AttachedEntity, out ContentEyeComponent? eye))
50+
ResetZoom(session.AttachedEntity.Value, eye);
51+
}
52+
53+
private void ZoomOut(ICommonSession? session)
54+
{
55+
if (TryComp(session?.AttachedEntity, out ContentEyeComponent? eye))
56+
SetZoom(session.AttachedEntity.Value, eye.TargetZoom * ZoomMod, eye: eye);
57+
}
58+
59+
private void ZoomIn(ICommonSession? session)
4460
{
45-
if (!TryComp<ContentEyeComponent>(args.SenderSession.AttachedEntity, out var content))
61+
if (TryComp(session?.AttachedEntity, out ContentEyeComponent? eye))
62+
SetZoom(session.AttachedEntity.Value, eye.TargetZoom / ZoomMod, eye: eye);
63+
}
64+
65+
private Vector2 Clamp(Vector2 zoom, ContentEyeComponent component)
66+
{
67+
return Vector2.Clamp(zoom, MinZoom, component.MaxZoom);
68+
}
69+
70+
/// <summary>
71+
/// Sets the target zoom, optionally ignoring normal zoom limits.
72+
/// </summary>
73+
public void SetZoom(EntityUid uid, Vector2 zoom, bool ignoreLimits = false, ContentEyeComponent? eye = null)
74+
{
75+
if (!Resolve(uid, ref eye, false))
4676
return;
4777

48-
content.TargetZoom = msg.TargetZoom;
49-
Dirty(content);
78+
eye.TargetZoom = ignoreLimits ? zoom : Clamp(zoom, eye);
79+
Dirty(eye);
80+
}
81+
82+
private void OnContentZoomRequest(RequestTargetZoomEvent msg, EntitySessionEventArgs args)
83+
{
84+
if (TryComp<ContentEyeComponent>(args.SenderSession.AttachedEntity, out var content))
85+
SetZoom(args.SenderSession.AttachedEntity.Value, msg.TargetZoom, eye: content);
5086
}
5187

5288
private void OnRequestFov(RequestFovEvent msg, EntitySessionEventArgs args)
@@ -64,12 +100,6 @@ private void OnRequestFov(RequestFovEvent msg, EntitySessionEventArgs args)
64100
}
65101
}
66102

67-
public override void Shutdown()
68-
{
69-
base.Shutdown();
70-
CommandBinds.Unregister<SharedContentEyeSystem>();
71-
}
72-
73103
private void OnContentEyeStartup(EntityUid uid, ContentEyeComponent component, ComponentStartup args)
74104
{
75105
if (!TryComp<SharedEyeComponent>(uid, out var eyeComp))
@@ -83,7 +113,7 @@ protected void UpdateEye(EntityUid uid, ContentEyeComponent content, SharedEyeCo
83113
{
84114
var diff = content.TargetZoom - eye.Zoom;
85115

86-
if (diff.LengthSquared < 0.0000001f)
116+
if (diff.LengthSquared < 0.00001f)
87117
{
88118
eye.Zoom = content.TargetZoom;
89119
Dirty(eye);
@@ -96,106 +126,19 @@ protected void UpdateEye(EntityUid uid, ContentEyeComponent content, SharedEyeCo
96126
Dirty(eye);
97127
}
98128

99-
private bool CanZoom(EntityUid uid, ContentEyeComponent? component = null)
129+
public void ResetZoom(EntityUid uid, ContentEyeComponent? component = null)
100130
{
101-
return Resolve(uid, ref component, false);
102-
}
103-
104-
private void ResetZoom(EntityUid uid, ContentEyeComponent? component = null)
105-
{
106-
if (!Resolve(uid, ref component))
107-
return;
108-
109-
if (component.TargetZoom.Equals(Vector2.One))
110-
return;
111-
112-
component.TargetZoom = Vector2.One;
113-
Dirty(component);
131+
SetZoom(uid, DefaultZoom, eye: component);
114132
}
115133

116134
public void SetMaxZoom(EntityUid uid, Vector2 value, ContentEyeComponent? component = null)
117-
{
118-
if (Resolve(uid, ref component))
119-
component.MaxZoom = value;
120-
}
121-
122-
private void Zoom(EntityUid uid, bool zoomIn, ContentEyeComponent? component = null)
123135
{
124136
if (!Resolve(uid, ref component))
125137
return;
126138

127-
var actual = component.TargetZoom;
128-
129-
if (zoomIn)
130-
{
131-
actual /= ZoomMod;
132-
}
133-
else
134-
{
135-
actual *= ZoomMod;
136-
}
137-
138-
actual = Vector2.ComponentMax(MinZoom, actual);
139-
actual = Vector2.ComponentMin(component.MaxZoom, actual);
140-
141-
if (actual.Equals(component.TargetZoom))
142-
return;
143-
144-
component.TargetZoom = actual;
139+
component.MaxZoom = value;
140+
component.TargetZoom = Clamp(component.TargetZoom, component);
145141
Dirty(component);
146-
Sawmill.Debug($"Set target zoom to {actual}");
147-
}
148-
149-
private sealed class ResetZoomInputCmdHandler : InputCmdHandler
150-
{
151-
private readonly SharedContentEyeSystem _system;
152-
153-
public ResetZoomInputCmdHandler(SharedContentEyeSystem system)
154-
{
155-
_system = system;
156-
}
157-
158-
public override bool HandleCmdMessage(ICommonSession? session, InputCmdMessage message)
159-
{
160-
ContentEyeComponent? component = null;
161-
162-
if (message is not FullInputCmdMessage full || session?.AttachedEntity == null ||
163-
full.State != BoundKeyState.Down ||
164-
!_system.CanZoom(session.AttachedEntity.Value, component))
165-
{
166-
return false;
167-
}
168-
169-
_system.ResetZoom(session.AttachedEntity.Value, component);
170-
return false;
171-
}
172-
}
173-
174-
private sealed class ScrollInputCmdHandler : InputCmdHandler
175-
{
176-
private readonly bool _zoomIn;
177-
private readonly SharedContentEyeSystem _system;
178-
179-
public ScrollInputCmdHandler(bool zoomIn, SharedContentEyeSystem system)
180-
{
181-
_zoomIn = zoomIn;
182-
_system = system;
183-
}
184-
185-
public override bool HandleCmdMessage(ICommonSession? session, InputCmdMessage message)
186-
{
187-
ContentEyeComponent? component = null;
188-
189-
if (message is not FullInputCmdMessage full || session?.AttachedEntity == null ||
190-
full.State != BoundKeyState.Down ||
191-
!_system.CanZoom(session.AttachedEntity.Value, component))
192-
{
193-
return false;
194-
}
195-
196-
_system.Zoom(session.AttachedEntity.Value, _zoomIn, component);
197-
return false;
198-
}
199142
}
200143

201144
/// <summary>

‎Resources/Prototypes/Entities/Mobs/NPCs/revenant.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
- type: Actions
4545
- type: Eye
4646
drawFov: false
47+
- type: ContentEye
48+
maxZoom: 1.2, 1.2
4749
- type: DoAfter
4850
- type: Alerts
4951
- type: NameIdentifier

‎Resources/Prototypes/Entities/Mobs/Species/base.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@
300300
- type: MobPrice
301301
price: 1500 # Kidnapping a living person and selling them for cred is a good move.
302302
deathPenalty: 0.01 # However they really ought to be living and intact, otherwise they're worth 100x less.
303+
- type: ContentEye
303304

304305
- type: entity
305306
save: false

0 commit comments

Comments
 (0)