using Content.Shared.Alert;
using JetBrains.Annotations;
using Robust.Client.Player;
+using Robust.Shared.GameStates;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
SubscribeLocalEvent<AlertsComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<AlertsComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);
-
- SubscribeLocalEvent<AlertsComponent, AfterAutoHandleStateEvent>(ClientAlertsHandleState);
+ SubscribeLocalEvent<AlertsComponent, ComponentHandleState>(OnHandleState);
}
protected override void LoadPrototypes()
{
}
}
- protected override void AfterShowAlert(Entity<AlertsComponent> alerts)
+ private void OnHandleState(Entity<AlertsComponent> alerts, ref ComponentHandleState args)
{
+ if (args.Current is not AlertComponentState cast)
+ return;
+
+ alerts.Comp.Alerts = cast.Alerts;
+
UpdateHud(alerts);
}
- protected override void AfterClearAlert(Entity<AlertsComponent> alerts)
+ protected override void AfterShowAlert(Entity<AlertsComponent> alerts)
{
UpdateHud(alerts);
}
- private void ClientAlertsHandleState(Entity<AlertsComponent> alerts, ref AfterAutoHandleStateEvent args)
+ protected override void AfterClearAlert(Entity<AlertsComponent> alerts)
{
UpdateHud(alerts);
}
+using Content.Shared.Alert;
+using Content.Shared.CCVar;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Pulling.Components;
using Content.Shared.Movement.Systems;
using Robust.Client.GameObjects;
using Robust.Client.Physics;
using Robust.Client.Player;
+using Robust.Shared.Configuration;
using Robust.Shared.Physics.Components;
using Robust.Shared.Player;
using Robust.Shared.Timing;
{
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
+ [Dependency] private readonly AlertsSystem _alerts = default!;
+ [Dependency] private readonly IConfigurationManager _cfg = default!;
public override void Initialize()
{
{
return _timing is { IsFirstTimePredicted: true, InSimulation: true };
}
+
+ public override void SetSprinting(Entity<InputMoverComponent> entity, ushort subTick, bool walking)
+ {
+ // Logger.Info($"[{_gameTiming.CurTick}/{subTick}] Sprint: {enabled}");
+ base.SetSprinting(entity, subTick, walking);
+
+ if (walking && _cfg.GetCVar(CCVars.ToggleWalk))
+ _alerts.ShowAlert(entity, WalkingAlert, showCooldown: false, autoRemove: false);
+ else
+ _alerts.ClearAlert(entity, WalkingAlert);
+ }
}
using Content.Shared.Alert;
+using Robust.Shared.GameStates;
namespace Content.Server.Alert;
internal sealed class ServerAlertsSystem : AlertsSystem
{
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent<AlertsComponent, ComponentGetState>(OnGetState);
+ }
+
+ private void OnGetState(Entity<AlertsComponent> alerts, ref ComponentGetState args)
+ {
+ args.State = new AlertComponentState(alerts.Comp.Alerts);
+ }
}
using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
namespace Content.Shared.Alert;
/// Handles the icons on the right side of the screen.
/// Should only be used for player-controlled entities.
/// </summary>
-[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
+// Component is not AutoNetworked due to supporting clientside-only alerts.
+// Component state is handled manually to avoid the server overwriting the client list.
+[RegisterComponent, NetworkedComponent]
public sealed partial class AlertsComponent : Component
{
[ViewVariables]
- [AutoNetworkedField]
public Dictionary<AlertKey, AlertState> Alerts = new();
public override bool SendOnlyToOwner => true;
}
+
+[Serializable, NetSerializable]
+public sealed class AlertComponentState : ComponentState
+{
+ public Dictionary<AlertKey, AlertState> Alerts { get; }
+ public AlertComponentState(Dictionary<AlertKey, AlertState> alerts)
+ {
+ Alerts = alerts;
+ }
+}
using System.Numerics;
+using Content.Shared.Alert;
using Content.Shared.CCVar;
using Content.Shared.Follower.Components;
using Content.Shared.Input;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Player;
+using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
{
public bool CameraRotationLocked { get; set; }
+ public static ProtoId<AlertPrototype> WalkingAlert = "Walking";
+
private void InitializeInput()
{
var moveUpCmdHandler = new MoverDirInputCmdHandler(this, Direction.North);
component.LastInputSubTick = 0;
}
- public void SetSprinting(Entity<InputMoverComponent> entity, ushort subTick, bool walking)
+ public virtual void SetSprinting(Entity<InputMoverComponent> entity, ushort subTick, bool walking)
{
// Logger.Info($"[{_gameTiming.CurTick}/{subTick}] Sprint: {enabled}");
Gravity has ceased affecting you, and you're floating around aimlessly. Find something sturdy to hold onto, or throw or shoot something in a direction opposite of you.
Mag-boots or jetpacks would help you move with more control.
+alerts-walking-name = Walking
+alerts-walking-desc = You are walking, moving at a slow pace.
+
alerts-stunned-name = [color=yellow]Stunned[/color]
alerts-stunned-desc = You're [color=yellow]stunned[/color]! Something is impairing your ability to move or interact with objects.
- alertType: Ensnared
- category: Buckled
- alertType: Pulling
+ - alertType: Walking
- category: Piloting
- alertType: Corporeal
- alertType: Stun
name: alerts-weightless-name
description: alerts-weightless-desc
+- type: alert
+ id: Walking
+ icons:
+ - sprite: /Textures/Interface/Alerts/walking.rsi
+ state: walking
+ name: alerts-walking-name
+ description: alerts-walking-desc
+
- type: alert
id: Stun
icons:
--- /dev/null
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Created by SlamBamActionman",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "walking"
+ }
+ ]
+}