/// <summary>
/// Choose a random sensor mode when item is spawned.
/// </summary>
- [DataField("randomMode")]
+ [DataField]
public bool RandomMode = true;
/// <summary>
/// If true user can't change suit sensor mode
/// </summary>
- [DataField("controlsLocked")]
+ [DataField]
public bool ControlsLocked = false;
+ /// <summary>
+ /// How much time it takes to change another player's sensors
+ /// </summary>
+ [DataField]
+ public float SensorsTime = 1.75f;
+
/// <summary>
/// Current sensor mode. Can be switched by user verbs.
/// </summary>
- [DataField("mode")]
+ [DataField]
public SuitSensorMode Mode = SuitSensorMode.SensorOff;
/// <summary>
/// Activate sensor if user wear it in this slot.
/// </summary>
- [DataField("activationSlot")]
+ [DataField]
public string ActivationSlot = "jumpsuit";
/// <summary>
/// Activate sensor if user has this in a sensor-compatible container.
/// </summary>
- [DataField("activationContainer")]
+ [DataField]
public string? ActivationContainer;
/// <summary>
/// How often does sensor update its owners status (in seconds). Limited by the system update rate.
/// </summary>
- [DataField("updateRate")]
+ [DataField]
public TimeSpan UpdateRate = TimeSpan.FromSeconds(2f);
/// <summary>
/// <summary>
/// Next time when sensor updated owners status
/// </summary>
- [DataField("nextUpdate", customTypeSerializer:typeof(TimeOffsetSerializer))]
+ [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
[AutoPausedField]
public TimeSpan NextUpdate = TimeSpan.Zero;
using Content.Server.Medical.CrewMonitoring;
using Content.Server.Popups;
using Content.Server.Station.Systems;
+using Content.Shared.ActionBlocker;
using Content.Shared.Clothing;
using Content.Shared.Damage;
using Content.Shared.DeviceNetwork;
+using Content.Shared.DoAfter;
using Content.Shared.Examine;
+using Content.Shared.Interaction;
using Content.Shared.Medical.SuitSensor;
using Content.Shared.Mobs.Components;
using Content.Shared.Mobs.Systems;
[Dependency] private readonly StationSystem _stationSystem = default!;
[Dependency] private readonly SingletonDeviceNetServerSystem _singletonServerSystem = 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()
{
SubscribeLocalEvent<SuitSensorComponent, EntGotRemovedFromContainerMessage>(OnRemove);
SubscribeLocalEvent<SuitSensorComponent, EmpPulseEvent>(OnEmpPulse);
SubscribeLocalEvent<SuitSensorComponent, EmpDisabledRemoved>(OnEmpFinished);
+ SubscribeLocalEvent<SuitSensorComponent, SuitSensorChangeDoAfterEvent>(OnSuitSensorDoAfter);
}
public override void Update(float frameTime)
return;
// 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;
args.Verbs.UnionWith(new[]
args.Disabled = true;
component.PreviousMode = component.Mode;
- SetSensor(uid, SuitSensorMode.SensorOff, null, component);
+ SetSensor((uid, component), SuitSensorMode.SensorOff, null);
component.PreviousControlsLocked = component.ControlsLocked;
component.ControlsLocked = true;
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;
}
Disabled = component.Mode == mode,
Priority = -(int) mode, // sort them in descending order
Category = VerbCategory.SetSensor,
- Act = () => SetSensor(uid, mode, userUid, component)
+ Act = () => TrySetSensor((uid, component), mode, userUid)
};
}
return Loc.GetString(name);
}
- public void SetSensor(EntityUid uid, SuitSensorMode mode, EntityUid? userUid = null,
- SuitSensorComponent? component = null)
+ public void TrySetSensor(Entity<SuitSensorComponent> sensors, SuitSensorMode mode, EntityUid userUid)
{
- if (!Resolve(uid, ref component))
+ var comp = sensors.Comp;
+
+ if (!Resolve(sensors, ref comp))
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)
{
var msg = Loc.GetString("suit-sensor-mode-state", ("mode", GetModeName(mode)));
- _popupSystem.PopupEntity(msg, uid, userUid.Value);
+ _popupSystem.PopupEntity(msg, sensors, userUid.Value);
}
}