Add conditional camera offset based on cursor - Hristov Rework, Part 1 (#31626)
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Content.Client.Movement.Systems;
|
||||||
|
using Content.Shared.Movement.Components;
|
||||||
|
|
||||||
|
namespace Content.Client.Movement.Components;
|
||||||
|
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed partial class EyeCursorOffsetComponent : SharedEyeCursorOffsetComponent
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The location the offset will attempt to pan towards; based on the cursor's position in the game window.
|
||||||
|
/// </summary>
|
||||||
|
public Vector2 TargetPosition = Vector2.Zero;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current positional offset being applied. Used to enable gradual panning.
|
||||||
|
/// </summary>
|
||||||
|
public Vector2 CurrentPosition = Vector2.Zero;
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Content.Shared.Movement.Components;
|
using Content.Shared.Movement.Components;
|
||||||
using Content.Shared.Movement.Systems;
|
using Content.Shared.Movement.Systems;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Client.Player;
|
using Robust.Client.Player;
|
||||||
|
|
||||||
namespace Content.Client.Movement.Systems;
|
namespace Content.Client.Movement.Systems;
|
||||||
@@ -52,4 +53,14 @@ public sealed class ContentEyeSystem : SharedContentEyeSystem
|
|||||||
{
|
{
|
||||||
RaisePredictiveEvent(new RequestEyeEvent(drawFov, drawLight));
|
RaisePredictiveEvent(new RequestEyeEvent(drawFov, drawLight));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void FrameUpdate(float frameTime)
|
||||||
|
{
|
||||||
|
base.FrameUpdate(frameTime);
|
||||||
|
var eyeEntities = AllEntityQuery<ContentEyeComponent, EyeComponent>();
|
||||||
|
while (eyeEntities.MoveNext(out var entity, out ContentEyeComponent? contentComponent, out EyeComponent? eyeComponent))
|
||||||
|
{
|
||||||
|
UpdateEyeOffset((entity, eyeComponent));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
91
Content.Client/Movement/Systems/EyeCursorOffsetSystem.cs
Normal file
91
Content.Client/Movement/Systems/EyeCursorOffsetSystem.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Content.Client.Movement.Components;
|
||||||
|
using Content.Shared.Camera;
|
||||||
|
using Content.Shared.Inventory;
|
||||||
|
using Content.Shared.Movement.Systems;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Client.Input;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Client.Player;
|
||||||
|
|
||||||
|
namespace Content.Client.Movement.Systems;
|
||||||
|
|
||||||
|
public partial class EyeCursorOffsetSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IEyeManager _eyeManager = default!;
|
||||||
|
[Dependency] private readonly IInputManager _inputManager = default!;
|
||||||
|
[Dependency] private readonly IPlayerManager _player = default!;
|
||||||
|
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||||
|
[Dependency] private readonly SharedContentEyeSystem _contentEye = default!;
|
||||||
|
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||||
|
[Dependency] private readonly IClyde _clyde = default!;
|
||||||
|
|
||||||
|
// This value is here to make sure the user doesn't have to move their mouse
|
||||||
|
// all the way out to the edge of the screen to get the full offset.
|
||||||
|
static private float _edgeOffset = 0.9f;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<EyeCursorOffsetComponent, GetEyeOffsetEvent>(OnGetEyeOffsetEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGetEyeOffsetEvent(EntityUid uid, EyeCursorOffsetComponent component, ref GetEyeOffsetEvent args)
|
||||||
|
{
|
||||||
|
var offset = OffsetAfterMouse(uid, component);
|
||||||
|
if (offset == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
args.Offset += offset.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2? OffsetAfterMouse(EntityUid uid, EyeCursorOffsetComponent? component)
|
||||||
|
{
|
||||||
|
var localPlayer = _player.LocalPlayer?.ControlledEntity;
|
||||||
|
var mousePos = _inputManager.MouseScreenPosition;
|
||||||
|
var screenSize = _clyde.MainWindow.Size;
|
||||||
|
var minValue = MathF.Min(screenSize.X / 2, screenSize.Y / 2) * _edgeOffset;
|
||||||
|
|
||||||
|
var mouseNormalizedPos = new Vector2(-(mousePos.X - screenSize.X / 2) / minValue, (mousePos.Y - screenSize.Y / 2) / minValue); // X needs to be inverted here for some reason, otherwise it ends up flipped.
|
||||||
|
|
||||||
|
if (localPlayer == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var playerPos = _transform.GetWorldPosition(localPlayer.Value);
|
||||||
|
|
||||||
|
if (component == null)
|
||||||
|
{
|
||||||
|
component = EnsureComp<EyeCursorOffsetComponent>(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doesn't move the offset if the mouse has left the game window!
|
||||||
|
if (mousePos.Window != WindowId.Invalid)
|
||||||
|
{
|
||||||
|
// The offset must account for the in-world rotation.
|
||||||
|
var eyeRotation = _eyeManager.CurrentEye.Rotation;
|
||||||
|
var mouseActualRelativePos = Vector2.Transform(mouseNormalizedPos, System.Numerics.Quaternion.CreateFromAxisAngle(-System.Numerics.Vector3.UnitZ, (float)(eyeRotation.Opposite().Theta))); // I don't know, it just works.
|
||||||
|
|
||||||
|
// Caps the offset into a circle around the player.
|
||||||
|
mouseActualRelativePos *= component.MaxOffset;
|
||||||
|
if (mouseActualRelativePos.Length() > component.MaxOffset)
|
||||||
|
{
|
||||||
|
mouseActualRelativePos = mouseActualRelativePos.Normalized() * component.MaxOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
component.TargetPosition = mouseActualRelativePos;
|
||||||
|
|
||||||
|
//Makes the view not jump immediately when moving the cursor fast.
|
||||||
|
if (component.CurrentPosition != component.TargetPosition)
|
||||||
|
{
|
||||||
|
Vector2 vectorOffset = component.TargetPosition - component.CurrentPosition;
|
||||||
|
if (vectorOffset.Length() > component.OffsetSpeed)
|
||||||
|
{
|
||||||
|
vectorOffset = vectorOffset.Normalized() * component.OffsetSpeed;
|
||||||
|
}
|
||||||
|
component.CurrentPosition += vectorOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return component.CurrentPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
49
Content.Client/Wieldable/WieldableSystem.cs
Normal file
49
Content.Client/Wieldable/WieldableSystem.cs
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Content.Client.Movement.Components;
|
||||||
|
using Content.Client.Movement.Systems;
|
||||||
|
using Content.Shared.Camera;
|
||||||
|
using Content.Shared.Hands;
|
||||||
|
using Content.Shared.Movement.Components;
|
||||||
|
using Content.Shared.Wieldable;
|
||||||
|
using Content.Shared.Wieldable.Components;
|
||||||
|
using Robust.Client.Timing;
|
||||||
|
|
||||||
|
namespace Content.Client.Wieldable;
|
||||||
|
|
||||||
|
public sealed class WieldableSystem : SharedWieldableSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly EyeCursorOffsetSystem _eyeOffset = default!;
|
||||||
|
[Dependency] private readonly IClientGameTiming _gameTiming = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<CursorOffsetRequiresWieldComponent, ItemUnwieldedEvent>(OnEyeOffsetUnwielded);
|
||||||
|
SubscribeLocalEvent<CursorOffsetRequiresWieldComponent, HeldRelayedEvent<GetEyeOffsetRelayedEvent>>(OnGetEyeOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnEyeOffsetUnwielded(Entity<CursorOffsetRequiresWieldComponent> entity, ref ItemUnwieldedEvent args)
|
||||||
|
{
|
||||||
|
if (!TryComp(entity.Owner, out EyeCursorOffsetComponent? cursorOffsetComp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_gameTiming.IsFirstTimePredicted)
|
||||||
|
cursorOffsetComp.CurrentPosition = Vector2.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnGetEyeOffset(Entity<CursorOffsetRequiresWieldComponent> entity, ref HeldRelayedEvent<GetEyeOffsetRelayedEvent> args)
|
||||||
|
{
|
||||||
|
if (!TryComp(entity.Owner, out WieldableComponent? wieldableComp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!wieldableComp.Wielded)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var offset = _eyeOffset.OffsetAfterMouse(entity.Owner, null);
|
||||||
|
if (offset == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
args.Args.Offset += offset.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Content.Shared.Movement.Components;
|
||||||
|
using Content.Shared.Movement.Systems;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Server.Movement.Components;
|
||||||
|
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed partial class EyeCursorOffsetComponent : SharedEyeCursorOffsetComponent
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
45
Content.Server/Wieldable/WieldableSystem.cs
Normal file
45
Content.Server/Wieldable/WieldableSystem.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
using Content.Server.Movement.Components;
|
||||||
|
using Content.Server.Movement.Systems;
|
||||||
|
using Content.Shared.Camera;
|
||||||
|
using Content.Shared.Hands;
|
||||||
|
using Content.Shared.Movement.Components;
|
||||||
|
using Content.Shared.Wieldable;
|
||||||
|
using Content.Shared.Wieldable.Components;
|
||||||
|
|
||||||
|
namespace Content.Server.Wieldable;
|
||||||
|
|
||||||
|
public sealed class WieldableSystem : SharedWieldableSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly ContentEyeSystem _eye = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<CursorOffsetRequiresWieldComponent, ItemUnwieldedEvent>(OnEyeOffsetUnwielded);
|
||||||
|
SubscribeLocalEvent<CursorOffsetRequiresWieldComponent, ItemWieldedEvent>(OnEyeOffsetWielded);
|
||||||
|
SubscribeLocalEvent<CursorOffsetRequiresWieldComponent, HeldRelayedEvent<GetEyePvsScaleRelayedEvent>>(OnGetEyePvsScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEyeOffsetUnwielded(Entity<CursorOffsetRequiresWieldComponent> entity, ref ItemUnwieldedEvent args)
|
||||||
|
{
|
||||||
|
_eye.UpdatePvsScale(args.User);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEyeOffsetWielded(Entity<CursorOffsetRequiresWieldComponent> entity, ref ItemWieldedEvent args)
|
||||||
|
{
|
||||||
|
_eye.UpdatePvsScale(args.User);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGetEyePvsScale(Entity<CursorOffsetRequiresWieldComponent> entity,
|
||||||
|
ref HeldRelayedEvent<GetEyePvsScaleRelayedEvent> args)
|
||||||
|
{
|
||||||
|
if (!TryComp(entity, out EyeCursorOffsetComponent? eyeCursorOffset) || !TryComp(entity.Owner, out WieldableComponent? wieldableComp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!wieldableComp.Wielded)
|
||||||
|
return;
|
||||||
|
|
||||||
|
args.Args.Scale += eyeCursorOffset.PvsIncrease;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using Content.Shared.Inventory;
|
||||||
using Content.Shared.Movement.Systems;
|
using Content.Shared.Movement.Systems;
|
||||||
|
|
||||||
namespace Content.Shared.Camera;
|
namespace Content.Shared.Camera;
|
||||||
@@ -17,3 +18,15 @@ namespace Content.Shared.Camera;
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
[ByRefEvent]
|
[ByRefEvent]
|
||||||
public record struct GetEyeOffsetEvent(Vector2 Offset);
|
public record struct GetEyeOffsetEvent(Vector2 Offset);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised on any equipped and in-hand items that may modify the eye offset.
|
||||||
|
/// Pockets and suitstorage are excluded.
|
||||||
|
/// </summary>
|
||||||
|
[ByRefEvent]
|
||||||
|
public sealed class GetEyeOffsetRelayedEvent : EntityEventArgs, IInventoryRelayEvent
|
||||||
|
{
|
||||||
|
public SlotFlags TargetSlots { get; } = ~(SlotFlags.POCKET & SlotFlags.SUITSTORAGE);
|
||||||
|
|
||||||
|
public Vector2 Offset;
|
||||||
|
}
|
||||||
|
|||||||
33
Content.Shared/Camera/GetEyePvsScaleEvent.cs
Normal file
33
Content.Shared/Camera/GetEyePvsScaleEvent.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Content.Shared.Inventory;
|
||||||
|
using Content.Shared.Movement.Systems;
|
||||||
|
|
||||||
|
namespace Content.Shared.Camera;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised directed by-ref when <see cref="SharedContentEyeSystem.UpdatePvsScale"/> is called.
|
||||||
|
/// Should be subscribed to by any systems that want to modify an entity's eye PVS scale,
|
||||||
|
/// so that they do not override each other. Keep in mind that this should be done serverside;
|
||||||
|
/// the client may set a new PVS scale, but the server won't provide the data if it isn't done on the server.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Scale">
|
||||||
|
/// The total scale to apply.
|
||||||
|
/// </param>
|
||||||
|
/// <remarks>
|
||||||
|
/// Note that in most cases <see cref="Scale"/> should be incremented or decremented by subscribers, not set.
|
||||||
|
/// Otherwise, any offsets applied by previous subscribing systems will be overridden.
|
||||||
|
/// </remarks>
|
||||||
|
[ByRefEvent]
|
||||||
|
public record struct GetEyePvsScaleEvent(float Scale);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised on any equipped and in-hand items that may modify the eye offset.
|
||||||
|
/// Pockets and suitstorage are excluded.
|
||||||
|
/// </summary>
|
||||||
|
[ByRefEvent]
|
||||||
|
public sealed class GetEyePvsScaleRelayedEvent : EntityEventArgs, IInventoryRelayEvent
|
||||||
|
{
|
||||||
|
public SlotFlags TargetSlots { get; } = ~(SlotFlags.POCKET & SlotFlags.SUITSTORAGE);
|
||||||
|
|
||||||
|
public float Scale;
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using Content.Shared.Movement.Components;
|
||||||
|
using Content.Shared.Movement.Systems;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.Network;
|
using Robust.Shared.Network;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
@@ -28,7 +30,7 @@ public abstract class SharedCameraRecoilSystem : EntitySystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected const float KickMagnitudeMax = 1f;
|
protected const float KickMagnitudeMax = 1f;
|
||||||
|
|
||||||
[Dependency] private readonly SharedEyeSystem _eye = default!;
|
[Dependency] private readonly SharedContentEyeSystem _eye = default!;
|
||||||
[Dependency] private readonly INetManager _net = default!;
|
[Dependency] private readonly INetManager _net = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
@@ -81,9 +83,7 @@ public abstract class SharedCameraRecoilSystem : EntitySystem
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
recoil.LastKick = recoil.CurrentKick;
|
recoil.LastKick = recoil.CurrentKick;
|
||||||
var ev = new GetEyeOffsetEvent();
|
_eye.UpdateEyeOffset((uid, eye));
|
||||||
RaiseLocalEvent(uid, ref ev);
|
|
||||||
_eye.SetOffset(uid, ev.Offset, eye);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Shared.Camera;
|
||||||
using Content.Shared.Hands.Components;
|
using Content.Shared.Hands.Components;
|
||||||
using Content.Shared.Movement.Systems;
|
using Content.Shared.Movement.Systems;
|
||||||
|
|
||||||
@@ -7,6 +8,8 @@ public abstract partial class SharedHandsSystem
|
|||||||
{
|
{
|
||||||
private void InitializeRelay()
|
private void InitializeRelay()
|
||||||
{
|
{
|
||||||
|
SubscribeLocalEvent<HandsComponent, GetEyeOffsetRelayedEvent>(RelayEvent);
|
||||||
|
SubscribeLocalEvent<HandsComponent, GetEyePvsScaleRelayedEvent>(RelayEvent);
|
||||||
SubscribeLocalEvent<HandsComponent, RefreshMovementSpeedModifiersEvent>(RelayEvent);
|
SubscribeLocalEvent<HandsComponent, RefreshMovementSpeedModifiersEvent>(RelayEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using Content.Shared.Wieldable;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Movement.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that this item requires wielding for the cursor offset effect to be active.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent, Access(typeof(SharedWieldableSystem))]
|
||||||
|
public sealed partial class CursorOffsetRequiresWieldComponent : Component
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Content.Shared.Movement.Systems;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
|
namespace Content.Shared.Movement.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Displaces SS14 eye data when given to an entity.
|
||||||
|
/// </summary>
|
||||||
|
[ComponentProtoName("EyeCursorOffset"), NetworkedComponent]
|
||||||
|
public abstract partial class SharedEyeCursorOffsetComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The amount the view will be displaced when the cursor is positioned at/beyond the max offset distance.
|
||||||
|
/// Measured in tiles.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public float MaxOffset = 3f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The speed which the camera adjusts to new positions. 0.5f seems like a good value, but can be changed if you want very slow/instant adjustments.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public float OffsetSpeed = 0.5f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The amount the PVS should increase to account for the max offset.
|
||||||
|
/// Should be 1/10 of MaxOffset most of the time.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public float PvsIncrease = 0.3f;
|
||||||
|
}
|
||||||
@@ -140,11 +140,29 @@ public abstract class SharedContentEyeSystem : EntitySystem
|
|||||||
Dirty(uid, component);
|
Dirty(uid, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateEyeOffset(Entity<EyeComponent?> eye)
|
public void UpdateEyeOffset(Entity<EyeComponent> eye)
|
||||||
{
|
{
|
||||||
var ev = new GetEyeOffsetEvent();
|
var ev = new GetEyeOffsetEvent();
|
||||||
RaiseLocalEvent(eye, ref ev);
|
RaiseLocalEvent(eye, ref ev);
|
||||||
_eye.SetOffset(eye, ev.Offset, eye);
|
|
||||||
|
var evRelayed = new GetEyeOffsetRelayedEvent();
|
||||||
|
RaiseLocalEvent(eye, ref evRelayed);
|
||||||
|
|
||||||
|
_eye.SetOffset(eye, ev.Offset + evRelayed.Offset, eye);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdatePvsScale(EntityUid uid, ContentEyeComponent? contentEye = null, EyeComponent? eye = null)
|
||||||
|
{
|
||||||
|
if (!Resolve(uid, ref contentEye) || !Resolve(uid, ref eye))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var ev = new GetEyePvsScaleEvent();
|
||||||
|
RaiseLocalEvent(uid, ref ev);
|
||||||
|
|
||||||
|
var evRelayed = new GetEyePvsScaleRelayedEvent();
|
||||||
|
RaiseLocalEvent(uid, ref evRelayed);
|
||||||
|
|
||||||
|
_eye.SetPvsScale((uid, eye), 1 + ev.Scale + evRelayed.Scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Content.Shared.Weapons.Melee.Components;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates that this meleeweapon requires wielding to be useable.
|
/// Indicates that this meleeweapon requires wielding to be useable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent, NetworkedComponent, Access(typeof(WieldableSystem))]
|
[RegisterComponent, NetworkedComponent, Access(typeof(SharedWieldableSystem))]
|
||||||
public sealed partial class MeleeRequiresWieldComponent : Component
|
public sealed partial class MeleeRequiresWieldComponent : Component
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Content.Shared.Weapons.Ranged.Components;
|
|||||||
/// Indicates that this gun requires wielding to be useable.
|
/// Indicates that this gun requires wielding to be useable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
[Access(typeof(WieldableSystem))]
|
[Access(typeof(SharedWieldableSystem))]
|
||||||
public sealed partial class GunRequiresWieldComponent : Component
|
public sealed partial class GunRequiresWieldComponent : Component
|
||||||
{
|
{
|
||||||
[DataField, AutoNetworkedField]
|
[DataField, AutoNetworkedField]
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Content.Shared.Weapons.Ranged.Components;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Applies an accuracy bonus upon wielding.
|
/// Applies an accuracy bonus upon wielding.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(WieldableSystem))]
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedWieldableSystem))]
|
||||||
public sealed partial class GunWieldBonusComponent : Component
|
public sealed partial class GunWieldBonusComponent : Component
|
||||||
{
|
{
|
||||||
[ViewVariables(VVAccess.ReadWrite), DataField("minAngle"), AutoNetworkedField]
|
[ViewVariables(VVAccess.ReadWrite), DataField("minAngle"), AutoNetworkedField]
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using Content.Shared.Damage;
|
|||||||
|
|
||||||
namespace Content.Shared.Wieldable.Components;
|
namespace Content.Shared.Wieldable.Components;
|
||||||
|
|
||||||
[RegisterComponent, Access(typeof(WieldableSystem))]
|
[RegisterComponent, Access(typeof(SharedWieldableSystem))]
|
||||||
public sealed partial class IncreaseDamageOnWieldComponent : Component
|
public sealed partial class IncreaseDamageOnWieldComponent : Component
|
||||||
{
|
{
|
||||||
[DataField("damage", required: true)]
|
[DataField("damage", required: true)]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Content.Shared.Wieldable.Components;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used for objects that can be wielded in two or more hands,
|
/// Used for objects that can be wielded in two or more hands,
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent, NetworkedComponent, Access(typeof(WieldableSystem)), AutoGenerateComponentState]
|
[RegisterComponent, NetworkedComponent, Access(typeof(SharedWieldableSystem)), AutoGenerateComponentState]
|
||||||
public sealed partial class WieldableComponent : Component
|
public sealed partial class WieldableComponent : Component
|
||||||
{
|
{
|
||||||
[DataField("wieldSound")]
|
[DataField("wieldSound")]
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Shared.Camera;
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
using Content.Shared.Hands;
|
using Content.Shared.Hands;
|
||||||
using Content.Shared.Hands.Components;
|
using Content.Shared.Hands.Components;
|
||||||
@@ -7,6 +8,7 @@ using Content.Shared.IdentityManagement;
|
|||||||
using Content.Shared.Interaction.Events;
|
using Content.Shared.Interaction.Events;
|
||||||
using Content.Shared.Inventory.VirtualItem;
|
using Content.Shared.Inventory.VirtualItem;
|
||||||
using Content.Shared.Item;
|
using Content.Shared.Item;
|
||||||
|
using Content.Shared.Movement.Components;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Content.Shared.Timing;
|
using Content.Shared.Timing;
|
||||||
using Content.Shared.Verbs;
|
using Content.Shared.Verbs;
|
||||||
@@ -23,7 +25,7 @@ using Robust.Shared.Timing;
|
|||||||
|
|
||||||
namespace Content.Shared.Wieldable;
|
namespace Content.Shared.Wieldable;
|
||||||
|
|
||||||
public sealed class WieldableSystem : EntitySystem
|
public abstract class SharedWieldableSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IGameTiming _timing = default!;
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
[Dependency] private readonly INetManager _netManager = default!;
|
[Dependency] private readonly INetManager _netManager = default!;
|
||||||
@@ -63,6 +63,10 @@
|
|||||||
- CartridgeAntiMateriel
|
- CartridgeAntiMateriel
|
||||||
capacity: 5
|
capacity: 5
|
||||||
proto: CartridgeAntiMateriel
|
proto: CartridgeAntiMateriel
|
||||||
|
- type: CursorOffsetRequiresWield
|
||||||
|
- type: EyeCursorOffset
|
||||||
|
maxOffset: 3
|
||||||
|
pvsIncrease: 0.3
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: musket
|
name: musket
|
||||||
|
|||||||
Reference in New Issue
Block a user