Change suit sensors on other players (#29668)
* Suit sensors can be turned off on other players * less doafter time + interaction (nostate) check * code cleanup * code cleanup 2
This commit is contained in:
@@ -14,37 +14,43 @@ public sealed partial class SuitSensorComponent : Component
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Choose a random sensor mode when item is spawned.
|
/// Choose a random sensor mode when item is spawned.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("randomMode")]
|
[DataField]
|
||||||
public bool RandomMode = true;
|
public bool RandomMode = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If true user can't change suit sensor mode
|
/// If true user can't change suit sensor mode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("controlsLocked")]
|
[DataField]
|
||||||
public bool ControlsLocked = false;
|
public bool ControlsLocked = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How much time it takes to change another player's sensors
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public float SensorsTime = 1.75f;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current sensor mode. Can be switched by user verbs.
|
/// Current sensor mode. Can be switched by user verbs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("mode")]
|
[DataField]
|
||||||
public SuitSensorMode Mode = SuitSensorMode.SensorOff;
|
public SuitSensorMode Mode = SuitSensorMode.SensorOff;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Activate sensor if user wear it in this slot.
|
/// Activate sensor if user wear it in this slot.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("activationSlot")]
|
[DataField]
|
||||||
public string ActivationSlot = "jumpsuit";
|
public string ActivationSlot = "jumpsuit";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Activate sensor if user has this in a sensor-compatible container.
|
/// Activate sensor if user has this in a sensor-compatible container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("activationContainer")]
|
[DataField]
|
||||||
public string? ActivationContainer;
|
public string? ActivationContainer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// How often does sensor update its owners status (in seconds). Limited by the system update rate.
|
/// How often does sensor update its owners status (in seconds). Limited by the system update rate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("updateRate")]
|
[DataField]
|
||||||
public TimeSpan UpdateRate = TimeSpan.FromSeconds(2f);
|
public TimeSpan UpdateRate = TimeSpan.FromSeconds(2f);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -56,7 +62,7 @@ public sealed partial class SuitSensorComponent : Component
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Next time when sensor updated owners status
|
/// Next time when sensor updated owners status
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("nextUpdate", customTypeSerializer:typeof(TimeOffsetSerializer))]
|
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
|
||||||
[AutoPausedField]
|
[AutoPausedField]
|
||||||
public TimeSpan NextUpdate = TimeSpan.Zero;
|
public TimeSpan NextUpdate = TimeSpan.Zero;
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,13 @@ using Content.Server.GameTicking;
|
|||||||
using Content.Server.Medical.CrewMonitoring;
|
using Content.Server.Medical.CrewMonitoring;
|
||||||
using Content.Server.Popups;
|
using Content.Server.Popups;
|
||||||
using Content.Server.Station.Systems;
|
using Content.Server.Station.Systems;
|
||||||
|
using Content.Shared.ActionBlocker;
|
||||||
using Content.Shared.Clothing;
|
using Content.Shared.Clothing;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.DeviceNetwork;
|
using Content.Shared.DeviceNetwork;
|
||||||
|
using Content.Shared.DoAfter;
|
||||||
using Content.Shared.Examine;
|
using Content.Shared.Examine;
|
||||||
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Medical.SuitSensor;
|
using Content.Shared.Medical.SuitSensor;
|
||||||
using Content.Shared.Mobs.Components;
|
using Content.Shared.Mobs.Components;
|
||||||
using Content.Shared.Mobs.Systems;
|
using Content.Shared.Mobs.Systems;
|
||||||
@@ -35,6 +38,9 @@ public sealed class SuitSensorSystem : EntitySystem
|
|||||||
[Dependency] private readonly StationSystem _stationSystem = default!;
|
[Dependency] private readonly StationSystem _stationSystem = default!;
|
||||||
[Dependency] private readonly SingletonDeviceNetServerSystem _singletonServerSystem = default!;
|
[Dependency] private readonly SingletonDeviceNetServerSystem _singletonServerSystem = default!;
|
||||||
[Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!;
|
[Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!;
|
||||||
|
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
||||||
|
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
|
||||||
|
[Dependency] private readonly ActionBlockerSystem _actionBlocker = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -49,6 +55,7 @@ public sealed class SuitSensorSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<SuitSensorComponent, EntGotRemovedFromContainerMessage>(OnRemove);
|
SubscribeLocalEvent<SuitSensorComponent, EntGotRemovedFromContainerMessage>(OnRemove);
|
||||||
SubscribeLocalEvent<SuitSensorComponent, EmpPulseEvent>(OnEmpPulse);
|
SubscribeLocalEvent<SuitSensorComponent, EmpPulseEvent>(OnEmpPulse);
|
||||||
SubscribeLocalEvent<SuitSensorComponent, EmpDisabledRemoved>(OnEmpFinished);
|
SubscribeLocalEvent<SuitSensorComponent, EmpDisabledRemoved>(OnEmpFinished);
|
||||||
|
SubscribeLocalEvent<SuitSensorComponent, SuitSensorChangeDoAfterEvent>(OnSuitSensorDoAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
public override void Update(float frameTime)
|
||||||
@@ -205,7 +212,14 @@ public sealed class SuitSensorSystem : EntitySystem
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// standard interaction checks
|
// standard interaction checks
|
||||||
if (!args.CanAccess || !args.CanInteract || args.Hands == null)
|
if (!args.CanInteract || args.Hands == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!_interactionSystem.InRangeUnobstructed(args.User, args.Target))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// check if target is incapacitated (cuffed, dead, etc)
|
||||||
|
if (component.User != null && args.User != component.User && _actionBlocker.CanInteract(component.User.Value, null))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
args.Verbs.UnionWith(new[]
|
args.Verbs.UnionWith(new[]
|
||||||
@@ -239,7 +253,7 @@ public sealed class SuitSensorSystem : EntitySystem
|
|||||||
args.Disabled = true;
|
args.Disabled = true;
|
||||||
|
|
||||||
component.PreviousMode = component.Mode;
|
component.PreviousMode = component.Mode;
|
||||||
SetSensor(uid, SuitSensorMode.SensorOff, null, component);
|
SetSensor((uid, component), SuitSensorMode.SensorOff, null);
|
||||||
|
|
||||||
component.PreviousControlsLocked = component.ControlsLocked;
|
component.PreviousControlsLocked = component.ControlsLocked;
|
||||||
component.ControlsLocked = true;
|
component.ControlsLocked = true;
|
||||||
@@ -247,7 +261,7 @@ public sealed class SuitSensorSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnEmpFinished(EntityUid uid, SuitSensorComponent component, ref EmpDisabledRemoved args)
|
private void OnEmpFinished(EntityUid uid, SuitSensorComponent component, ref EmpDisabledRemoved args)
|
||||||
{
|
{
|
||||||
SetSensor(uid, component.PreviousMode, null, component);
|
SetSensor((uid, component), component.PreviousMode, null);
|
||||||
component.ControlsLocked = component.PreviousControlsLocked;
|
component.ControlsLocked = component.PreviousControlsLocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,7 +273,7 @@ public sealed class SuitSensorSystem : EntitySystem
|
|||||||
Disabled = component.Mode == mode,
|
Disabled = component.Mode == mode,
|
||||||
Priority = -(int) mode, // sort them in descending order
|
Priority = -(int) mode, // sort them in descending order
|
||||||
Category = VerbCategory.SetSensor,
|
Category = VerbCategory.SetSensor,
|
||||||
Act = () => SetSensor(uid, mode, userUid, component)
|
Act = () => TrySetSensor((uid, component), mode, userUid)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,18 +301,46 @@ public sealed class SuitSensorSystem : EntitySystem
|
|||||||
return Loc.GetString(name);
|
return Loc.GetString(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetSensor(EntityUid uid, SuitSensorMode mode, EntityUid? userUid = null,
|
public void TrySetSensor(Entity<SuitSensorComponent> sensors, SuitSensorMode mode, EntityUid userUid)
|
||||||
SuitSensorComponent? component = null)
|
|
||||||
{
|
{
|
||||||
if (!Resolve(uid, ref component))
|
var comp = sensors.Comp;
|
||||||
|
|
||||||
|
if (!Resolve(sensors, ref comp))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
component.Mode = mode;
|
if (comp.User == null || userUid == comp.User)
|
||||||
|
SetSensor(sensors, mode, userUid);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var doAfterEvent = new SuitSensorChangeDoAfterEvent(mode);
|
||||||
|
var doAfterArgs = new DoAfterArgs(EntityManager, userUid, comp.SensorsTime, doAfterEvent, sensors)
|
||||||
|
{
|
||||||
|
BreakOnMove = true,
|
||||||
|
BreakOnDamage = true
|
||||||
|
};
|
||||||
|
|
||||||
|
_doAfterSystem.TryStartDoAfter(doAfterArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSuitSensorDoAfter(Entity<SuitSensorComponent> sensors, ref SuitSensorChangeDoAfterEvent args)
|
||||||
|
{
|
||||||
|
if (args.Handled || args.Cancelled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SetSensor(sensors, args.Mode, args.User);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetSensor(Entity<SuitSensorComponent> sensors, SuitSensorMode mode, EntityUid? userUid = null)
|
||||||
|
{
|
||||||
|
var comp = sensors.Comp;
|
||||||
|
|
||||||
|
comp.Mode = mode;
|
||||||
|
|
||||||
if (userUid != null)
|
if (userUid != null)
|
||||||
{
|
{
|
||||||
var msg = Loc.GetString("suit-sensor-mode-state", ("mode", GetModeName(mode)));
|
var msg = Loc.GetString("suit-sensor-mode-state", ("mode", GetModeName(mode)));
|
||||||
_popupSystem.PopupEntity(msg, uid, userUid.Value);
|
_popupSystem.PopupEntity(msg, sensors, userUid.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Shared.DoAfter;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
@@ -67,3 +68,16 @@ public static class SuitSensorConstants
|
|||||||
///Used by the CrewMonitoringServerSystem to send the status of all connected suit sensors to each crew monitor
|
///Used by the CrewMonitoringServerSystem to send the status of all connected suit sensors to each crew monitor
|
||||||
public const string NET_STATUS_COLLECTION = "suit-status-collection";
|
public const string NET_STATUS_COLLECTION = "suit-status-collection";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed partial class SuitSensorChangeDoAfterEvent : DoAfterEvent
|
||||||
|
{
|
||||||
|
public SuitSensorMode Mode { get; private set; } = SuitSensorMode.SensorOff;
|
||||||
|
|
||||||
|
public SuitSensorChangeDoAfterEvent(SuitSensorMode mode)
|
||||||
|
{
|
||||||
|
Mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override DoAfterEvent Clone() => this;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user