--- /dev/null
+using Content.Client.Message;
+using Content.Client.Stylesheets;
+using Content.Shared.Remotes.Components;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using Robust.Shared.Timing;
+
+namespace Content.Client.Remote.UI;
+
+public sealed class DoorRemoteStatusControl : Control
+{
+ private readonly Entity<DoorRemoteComponent> _entity;
+ private readonly RichTextLabel _label;
+
+ // set to toggle bolts initially just so that it updates on first pickup of remote
+ private OperatingMode PrevOperatingMode = OperatingMode.placeholderForUiUpdates;
+
+ public DoorRemoteStatusControl(Entity<DoorRemoteComponent> entity)
+ {
+ _entity = entity;
+ _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
+ AddChild(_label);
+ }
+
+ protected override void FrameUpdate(FrameEventArgs args)
+ {
+ base.FrameUpdate(args);
+
+ // only updates the UI if any of the details are different than they previously were
+ if (PrevOperatingMode == _entity.Comp.Mode)
+ return;
+
+ PrevOperatingMode = _entity.Comp.Mode;
+
+ // Update current volume and injector state
+ var modeStringLocalized = Loc.GetString(_entity.Comp.Mode switch
+ {
+ OperatingMode.OpenClose => "door-remote-open-close-text",
+ OperatingMode.ToggleBolts => "door-remote-toggle-bolt-text",
+ OperatingMode.ToggleEmergencyAccess => "door-remote-emergency-access-text",
+ _ => "door-remote-invalid-text"
+ });
+
+ _label.SetMarkup(Loc.GetString("door-remote-mode-label", ("modeString", modeStringLocalized)));
+ }
+}
using Content.Server.Administration.Logs;
-using Robust.Shared.Player;
using Content.Shared.Interaction;
-using Content.Shared.Popups;
using Content.Shared.Doors.Components;
-using Content.Shared.Doors.Systems;
-using Content.Shared.Physics;
using Content.Shared.Access.Components;
using Content.Server.Doors.Systems;
using Content.Server.Power.EntitySystems;
using Content.Shared.Database;
-using Content.Shared.Interaction.Events;
using Content.Shared.Examine;
-using static Content.Server.Remotes.DoorRemoteComponent;
+using Content.Shared.Remotes.EntitySystems;
+using Content.Shared.Remotes.Components;
-namespace Content.Server.Remotes
+namespace Content.Shared.Remotes
{
- public sealed class DoorRemoteSystem : EntitySystem
+ public sealed class DoorRemoteSystem : SharedDoorRemoteSystem
{
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly AirlockSystem _airlock = default!;
- [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly DoorSystem _doorSystem = default!;
- [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
[Dependency] private readonly ExamineSystemShared _examine = default!;
- // I'm so sorry [Dependency] private readonly SharedAirlockSystem _sharedAirlockSystem = default!;
-
public override void Initialize()
{
- SubscribeLocalEvent<DoorRemoteComponent, UseInHandEvent>(OnInHandActivation);
- SubscribeLocalEvent<DoorRemoteComponent, BeforeRangedInteractEvent>(OnBeforeInteract);
- }
-
- public void OnInHandActivation(EntityUid user, DoorRemoteComponent component, UseInHandEvent args)
- {
- string switchMessageId;
- switch (component.Mode)
- {
- case OperatingMode.OpenClose:
- component.Mode = OperatingMode.ToggleBolts;
- switchMessageId = "door-remote-switch-state-toggle-bolts";
- break;
+ base.Initialize();
- // Skip toggle bolts mode and move on from there (to emergency access)
- case OperatingMode.ToggleBolts:
- component.Mode = OperatingMode.ToggleEmergencyAccess;
- switchMessageId = "door-remote-switch-state-toggle-emergency-access";
- break;
-
- // Skip ToggleEmergencyAccess mode and move on from there (to door toggle)
- case OperatingMode.ToggleEmergencyAccess:
- component.Mode = OperatingMode.OpenClose;
- switchMessageId = "door-remote-switch-state-open-close";
- break;
- default:
- throw new InvalidOperationException(
- $"{nameof(DoorRemoteComponent)} had invalid mode {component.Mode}");
- }
- ShowPopupToUser(switchMessageId, args.User);
+ SubscribeLocalEvent<DoorRemoteComponent, BeforeRangedInteractEvent>(OnBeforeInteract);
}
- private void OnBeforeInteract(EntityUid uid, DoorRemoteComponent component, BeforeRangedInteractEvent args)
+ private void OnBeforeInteract(Entity<DoorRemoteComponent> entity, ref BeforeRangedInteractEvent args)
{
bool isAirlock = TryComp<AirlockComponent>(args.Target, out var airlockComp);
if (args.Handled
|| args.Target == null
|| !TryComp<DoorComponent>(args.Target, out var doorComp) // If it isn't a door we don't use it
- // Only able to control doors if they are within your vision and within your max range.
- // Not affected by mobs or machines anymore.
+ // Only able to control doors if they are within your vision and within your max range.
+ // Not affected by mobs or machines anymore.
|| !_examine.InRangeUnOccluded(args.User, args.Target.Value, SharedInteractionSystem.MaxRaycastRange, null))
+
{
return;
}
if (!this.IsPowered(args.Target.Value, EntityManager))
{
- ShowPopupToUser("door-remote-no-power", args.User);
+ Popup.PopupEntity(Loc.GetString("door-remote-no-power"), args.User, args.User);
return;
}
&& !_doorSystem.HasAccess(args.Target.Value, args.User, doorComp, accessComponent))
{
_doorSystem.Deny(args.Target.Value, doorComp, args.User);
- ShowPopupToUser("door-remote-denied", args.User);
+ Popup.PopupEntity(Loc.GetString("door-remote-denied"), args.User, args.User);
return;
}
- switch (component.Mode)
+ switch (entity.Comp.Mode)
{
case OperatingMode.OpenClose:
// Note we provide args.User here to TryToggleDoor as the "user"
break;
default:
throw new InvalidOperationException(
- $"{nameof(DoorRemoteComponent)} had invalid mode {component.Mode}");
+ $"{nameof(DoorRemoteComponent)} had invalid mode {entity.Comp.Mode}");
}
}
-
- private void ShowPopupToUser(string messageId, EntityUid user) =>
- _popupSystem.PopupEntity(Loc.GetString(messageId), user, user);
}
}
--- /dev/null
+using Content.Shared.Interaction;
+using Content.Shared.Popups;
+using Content.Shared.Interaction.Events;
+using Content.Shared.Remotes.Components;
+
+namespace Content.Shared.Remotes.EntitySystems;
+
+public abstract class SharedDoorRemoteSystem : EntitySystem
+{
+ [Dependency] protected readonly SharedPopupSystem Popup = default!;
+ [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
+ // I'm so sorry [Dependency] private readonly SharedAirlockSystem _sharedAirlockSystem = default!;
+
+ public override void Initialize()
+ {
+ SubscribeLocalEvent<DoorRemoteComponent, UseInHandEvent>(OnInHandActivation);
+ }
+
+ private void OnInHandActivation(Entity<DoorRemoteComponent> entity, ref UseInHandEvent args)
+ {
+ string switchMessageId;
+ switch (entity.Comp.Mode)
+ {
+ case OperatingMode.OpenClose:
+ entity.Comp.Mode = OperatingMode.ToggleBolts;
+ switchMessageId = "door-remote-switch-state-toggle-bolts";
+ break;
+
+ // Skip toggle bolts mode and move on from there (to emergency access)
+ case OperatingMode.ToggleBolts:
+ entity.Comp.Mode = OperatingMode.ToggleEmergencyAccess;
+ switchMessageId = "door-remote-switch-state-toggle-emergency-access";
+ break;
+
+ // Skip ToggleEmergencyAccess mode and move on from there (to door toggle)
+ case OperatingMode.ToggleEmergencyAccess:
+ entity.Comp.Mode = OperatingMode.OpenClose;
+ switchMessageId = "door-remote-switch-state-open-close";
+ break;
+ default:
+ throw new InvalidOperationException(
+ $"{nameof(DoorRemoteComponent)} had invalid mode {entity.Comp.Mode}");
+ }
+ Dirty(entity);
+ Popup.PopupClient(Loc.GetString(switchMessageId), entity, args.User);
+ }
+}