Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mirror: Door Remote Now Shows Mode in UI #293

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Content.Client/Remotes/EntitySystems/DoorRemoteSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Content.Client.Remote.UI;
using Content.Client.Items;
using Content.Shared.Remotes.EntitySystems;
using Content.Shared.Remotes.Components;

namespace Content.Client.Remotes.EntitySystems;

public sealed class DoorRemoteSystem : SharedDoorRemoteSystem
{
public override void Initialize()
{
base.Initialize();

Subs.ItemStatus<DoorRemoteComponent>(ent => new DoorRemoteStatusControl(ent));
}
}
46 changes: 46 additions & 0 deletions Content.Client/Remotes/UI/DoorRemoteStatusControl.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
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)));
}
}
16 changes: 0 additions & 16 deletions Content.Server/Remotes/DoorRemoteComponent.cs

This file was deleted.

64 changes: 15 additions & 49 deletions Content.Server/Remotes/DoorRemoteSystem.cs
Original file line number Diff line number Diff line change
@@ -1,74 +1,43 @@
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;
}
Expand All @@ -77,19 +46,19 @@ private void OnBeforeInteract(EntityUid uid, DoorRemoteComponent component, Befo

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;
}

if (TryComp<AccessReaderComponent>(args.Target, out var accessComponent)
&& !_doorSystem.HasAccess(args.Target.Value, args.Used, 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:
if (_doorSystem.TryToggleDoor(args.Target.Value, doorComp, args.Used))
Expand All @@ -115,11 +84,8 @@ private void OnBeforeInteract(EntityUid uid, DoorRemoteComponent component, Befo
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);
}
}
19 changes: 19 additions & 0 deletions Content.Shared/Remotes/Components/DoorRemoteComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Robust.Shared.GameStates;

namespace Content.Shared.Remotes.Components;

[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class DoorRemoteComponent : Component
{
[AutoNetworkedField]
[DataField]
public OperatingMode Mode = OperatingMode.OpenClose;
}

public enum OperatingMode : byte
{
OpenClose,
ToggleBolts,
ToggleEmergencyAccess,
placeholderForUiUpdates
}
47 changes: 47 additions & 0 deletions Content.Shared/Remotes/EntitySystems/SharedDoorRemoteSystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
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);
}
}
9 changes: 9 additions & 0 deletions Resources/Locale/en-US/door-remote/door-remote.ftl
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## UI
door-remote-open-close-text = Opens and Closes Doors
door-remote-toggle-bolt-text = Toggles Bolts
door-remote-emergency-access-text = Toggles Emergency Access
door-remote-invalid-text = Invalid
door-remote-mode-label = Mode: [color=white]{$modeString}[/color]

## Entity

door-remote-switch-state-open-close = You switch the remote to open and close doors
door-remote-switch-state-toggle-bolts = You switch the remote to toggle bolts
door-remote-switch-state-toggle-emergency-access = You switch the remote to toggle emergency access
Expand Down
Loading