Skip to content

Commit 8926496

Browse files
Mirror: Door Remote Now Shows Mode in UI (#293)
## Mirror of PR #26162: [Door Remote now shows Mode in UI](space-wizards/space-station-14#26162) from <img src="https://avatars.githubusercontent.com/u/10567778?v=4" alt="space-wizards" width="22"/> [space-wizards](https://github.com/space-wizards)/[space-station-14](https://github.com/space-wizards/space-station-14) ###### `e627a0d24bc8ae89665feb0b0d519b5fbb77ce32` PR opened by <img src="https://avatars.githubusercontent.com/u/58439124?v=4" width="16"/><a href="https://github.com/Plykiya"> Plykiya</a> at 2024-03-15 23:14:52 UTC --- PR changed 7 files with 151 additions and 67 deletions. The PR had the following labels: - Status: Awaiting Changes --- <details open="true"><summary><h1>Original Body</h1></summary> > <!-- Please read these guidelines before opening your PR: https://docs.spacestation14.io/en/getting-started/pr-guideline --> > <!-- The text between the arrows are comments - they will not be visible on your PR. --> > > ## About the PR > <!-- What did you change in this PR? --> > Changed the door remote to show what mode it's in on the UI so you don't have to toggle it to figure out if you're bolting a door or setting it to emergency access... > > ## Why / Balance > <!-- Why was it changed? Link any discussions or issues here. Please discuss how this would affect game balance. --> > There is no indicator and it's awkward to set a door to emergency access instead of bolting it against nukies. > > ## Technical details > <!-- If this is a code change, summarize at high level how your new code works. This makes it easier to review. --> > - Split DoorRemoteSystem into Shared/Server/Client from just Server > - Added door remote status control that updates itself on first pickup and then whenever the mode is toggled > - Got rid of the custom "ShowPopupToUser" function that the DoorRemote used to have in favor of PopupClient/PopupEntity > - Created new Door Remote locale messages. > > The only problem I have with my code change is that I created a shitty fourth placeholder enum so that I could check for a difference on initial pickup with PrevOperatingMode. Without it, the mode string only appears on pickup for 2/3 options instead of 3/3 options because the default PrevOperatingMode would end up matching the current Mode the door remote is set to, thus not updating the UI. Would love a better implementation suggestion for that... > > ## Media > <!-- > PRs which make ingame changes (adding clothing, items, new features, etc) are required to have media attached that showcase the changes. > Small fixes/refactors are exempt. > Any media may be used in SS14 progress reports, with clear credit given. > > If you're unsure whether your PR will require media, ask a maintainer. > > Check the box below to confirm that you have in fact seen this (put an X in the brackets, like [X]): > --> > > - [ X ] I have added screenshots/videos to this PR showcasing its changes ingame, **or** this PR does not require an ingame showcase > > https://github.com/space-wizards/space-station-14/assets/58439124/733eb78a-d1a6-4678-a325-9fda8dc1a4c8 > > > > ## Breaking changes > <!-- > List any breaking changes, including namespace, public class/method/field changes, prototype renames; and provide instructions for fixing them. This will be pasted in #codebase-changes. > --> > DoorRemoteComponent moved from Content.Server.Remotes to Content.Shared.Remotes.Components, DoorRemoteSystem OnInHandActivation changed from Public to Private, DoorRemoteSystem moved from Content.Server to Content.Shared, DoorRemoteSystem is now SharedDoorRemoteSystem > > **Changelog** > <!-- > Make players aware of new features and changes that could affect how they play the game by adding a Changelog entry. Please read the Changelog guidelines located at: https://docs.spacestation14.io/en/getting-started/pr-guideline#changelog > --> > > <!-- > Make sure to take this Changelog template out of the comment block in order for it to show up. > 🆑 > - add: Added fun! > - remove: Removed fun! > - tweak: Changed fun! > - fix: Fixed fun! > --> > 🆑 > - add: Door remote UI now shows the mode it is in. > </details> Signed-off-by: VMSolidus <evilexecutive@gmail.com> Co-authored-by: SimpleStation14 <Unknown> Co-authored-by: VMSolidus <evilexecutive@gmail.com>
1 parent 399bd96 commit 8926496

7 files changed

Lines changed: 152 additions & 65 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Content.Client.Remote.UI;
2+
using Content.Client.Items;
3+
using Content.Shared.Remotes.EntitySystems;
4+
using Content.Shared.Remotes.Components;
5+
6+
namespace Content.Client.Remotes.EntitySystems;
7+
8+
public sealed class DoorRemoteSystem : SharedDoorRemoteSystem
9+
{
10+
public override void Initialize()
11+
{
12+
base.Initialize();
13+
14+
Subs.ItemStatus<DoorRemoteComponent>(ent => new DoorRemoteStatusControl(ent));
15+
}
16+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using Content.Client.Message;
2+
using Content.Client.Stylesheets;
3+
using Content.Shared.Remotes.Components;
4+
using Robust.Client.UserInterface;
5+
using Robust.Client.UserInterface.Controls;
6+
using Robust.Shared.Timing;
7+
8+
namespace Content.Client.Remote.UI;
9+
10+
public sealed class DoorRemoteStatusControl : Control
11+
{
12+
private readonly Entity<DoorRemoteComponent> _entity;
13+
private readonly RichTextLabel _label;
14+
15+
// set to toggle bolts initially just so that it updates on first pickup of remote
16+
private OperatingMode PrevOperatingMode = OperatingMode.placeholderForUiUpdates;
17+
18+
public DoorRemoteStatusControl(Entity<DoorRemoteComponent> entity)
19+
{
20+
_entity = entity;
21+
_label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
22+
AddChild(_label);
23+
}
24+
25+
protected override void FrameUpdate(FrameEventArgs args)
26+
{
27+
base.FrameUpdate(args);
28+
29+
// only updates the UI if any of the details are different than they previously were
30+
if (PrevOperatingMode == _entity.Comp.Mode)
31+
return;
32+
33+
PrevOperatingMode = _entity.Comp.Mode;
34+
35+
// Update current volume and injector state
36+
var modeStringLocalized = Loc.GetString(_entity.Comp.Mode switch
37+
{
38+
OperatingMode.OpenClose => "door-remote-open-close-text",
39+
OperatingMode.ToggleBolts => "door-remote-toggle-bolt-text",
40+
OperatingMode.ToggleEmergencyAccess => "door-remote-emergency-access-text",
41+
_ => "door-remote-invalid-text"
42+
});
43+
44+
_label.SetMarkup(Loc.GetString("door-remote-mode-label", ("modeString", modeStringLocalized)));
45+
}
46+
}

‎Content.Server/Remotes/DoorRemoteComponent.cs‎

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 15 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,43 @@
11
using Content.Server.Administration.Logs;
2-
using Robust.Shared.Player;
32
using Content.Shared.Interaction;
4-
using Content.Shared.Popups;
53
using Content.Shared.Doors.Components;
6-
using Content.Shared.Doors.Systems;
7-
using Content.Shared.Physics;
84
using Content.Shared.Access.Components;
95
using Content.Server.Doors.Systems;
106
using Content.Server.Power.EntitySystems;
117
using Content.Shared.Database;
12-
using Content.Shared.Interaction.Events;
138
using Content.Shared.Examine;
14-
using static Content.Server.Remotes.DoorRemoteComponent;
9+
using Content.Shared.Remotes.EntitySystems;
10+
using Content.Shared.Remotes.Components;
1511

16-
namespace Content.Server.Remotes
12+
namespace Content.Shared.Remotes
1713
{
18-
public sealed class DoorRemoteSystem : EntitySystem
14+
public sealed class DoorRemoteSystem : SharedDoorRemoteSystem
1915
{
2016
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
2117
[Dependency] private readonly AirlockSystem _airlock = default!;
22-
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
2318
[Dependency] private readonly DoorSystem _doorSystem = default!;
2419
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
2520
[Dependency] private readonly ExamineSystemShared _examine = default!;
2621
// I'm so sorry [Dependency] private readonly SharedAirlockSystem _sharedAirlockSystem = default!;
27-
22+
2823
public override void Initialize()
2924
{
30-
SubscribeLocalEvent<DoorRemoteComponent, UseInHandEvent>(OnInHandActivation);
31-
SubscribeLocalEvent<DoorRemoteComponent, BeforeRangedInteractEvent>(OnBeforeInteract);
32-
}
33-
34-
public void OnInHandActivation(EntityUid user, DoorRemoteComponent component, UseInHandEvent args)
35-
{
36-
string switchMessageId;
37-
switch (component.Mode)
38-
{
39-
case OperatingMode.OpenClose:
40-
component.Mode = OperatingMode.ToggleBolts;
41-
switchMessageId = "door-remote-switch-state-toggle-bolts";
42-
break;
25+
base.Initialize();
4326

44-
// Skip toggle bolts mode and move on from there (to emergency access)
45-
case OperatingMode.ToggleBolts:
46-
component.Mode = OperatingMode.ToggleEmergencyAccess;
47-
switchMessageId = "door-remote-switch-state-toggle-emergency-access";
48-
break;
49-
50-
// Skip ToggleEmergencyAccess mode and move on from there (to door toggle)
51-
case OperatingMode.ToggleEmergencyAccess:
52-
component.Mode = OperatingMode.OpenClose;
53-
switchMessageId = "door-remote-switch-state-open-close";
54-
break;
55-
default:
56-
throw new InvalidOperationException(
57-
$"{nameof(DoorRemoteComponent)} had invalid mode {component.Mode}");
58-
}
59-
ShowPopupToUser(switchMessageId, args.User);
27+
SubscribeLocalEvent<DoorRemoteComponent, BeforeRangedInteractEvent>(OnBeforeInteract);
6028
}
6129

62-
private void OnBeforeInteract(EntityUid uid, DoorRemoteComponent component, BeforeRangedInteractEvent args)
30+
private void OnBeforeInteract(Entity<DoorRemoteComponent> entity, ref BeforeRangedInteractEvent args)
6331
{
6432
bool isAirlock = TryComp<AirlockComponent>(args.Target, out var airlockComp);
6533

6634
if (args.Handled
6735
|| args.Target == null
6836
|| !TryComp<DoorComponent>(args.Target, out var doorComp) // If it isn't a door we don't use it
69-
// Only able to control doors if they are within your vision and within your max range.
70-
// Not affected by mobs or machines anymore.
37+
// Only able to control doors if they are within your vision and within your max range.
38+
// Not affected by mobs or machines anymore.
7139
|| !_examine.InRangeUnOccluded(args.User, args.Target.Value, SharedInteractionSystem.MaxRaycastRange, null))
40+
7241
{
7342
return;
7443
}
@@ -77,19 +46,19 @@ private void OnBeforeInteract(EntityUid uid, DoorRemoteComponent component, Befo
7746

7847
if (!this.IsPowered(args.Target.Value, EntityManager))
7948
{
80-
ShowPopupToUser("door-remote-no-power", args.User);
49+
Popup.PopupEntity(Loc.GetString("door-remote-no-power"), args.User, args.User);
8150
return;
8251
}
8352

8453
if (TryComp<AccessReaderComponent>(args.Target, out var accessComponent)
8554
&& !_doorSystem.HasAccess(args.Target.Value, args.Used, doorComp, accessComponent))
8655
{
8756
_doorSystem.Deny(args.Target.Value, doorComp, args.User);
88-
ShowPopupToUser("door-remote-denied", args.User);
57+
Popup.PopupEntity(Loc.GetString("door-remote-denied"), args.User, args.User);
8958
return;
9059
}
9160

92-
switch (component.Mode)
61+
switch (entity.Comp.Mode)
9362
{
9463
case OperatingMode.OpenClose:
9564
if (_doorSystem.TryToggleDoor(args.Target.Value, doorComp, args.Used))
@@ -115,11 +84,8 @@ private void OnBeforeInteract(EntityUid uid, DoorRemoteComponent component, Befo
11584
break;
11685
default:
11786
throw new InvalidOperationException(
118-
$"{nameof(DoorRemoteComponent)} had invalid mode {component.Mode}");
87+
$"{nameof(DoorRemoteComponent)} had invalid mode {entity.Comp.Mode}");
11988
}
12089
}
121-
122-
private void ShowPopupToUser(string messageId, EntityUid user) =>
123-
_popupSystem.PopupEntity(Loc.GetString(messageId), user, user);
12490
}
12591
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Robust.Shared.GameStates;
2+
3+
namespace Content.Shared.Remotes.Components;
4+
5+
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
6+
public sealed partial class DoorRemoteComponent : Component
7+
{
8+
[AutoNetworkedField]
9+
[DataField]
10+
public OperatingMode Mode = OperatingMode.OpenClose;
11+
}
12+
13+
public enum OperatingMode : byte
14+
{
15+
OpenClose,
16+
ToggleBolts,
17+
ToggleEmergencyAccess,
18+
placeholderForUiUpdates
19+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using Content.Shared.Interaction;
2+
using Content.Shared.Popups;
3+
using Content.Shared.Interaction.Events;
4+
using Content.Shared.Remotes.Components;
5+
6+
namespace Content.Shared.Remotes.EntitySystems;
7+
8+
public abstract class SharedDoorRemoteSystem : EntitySystem
9+
{
10+
[Dependency] protected readonly SharedPopupSystem Popup = default!;
11+
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
12+
// I'm so sorry [Dependency] private readonly SharedAirlockSystem _sharedAirlockSystem = default!;
13+
14+
public override void Initialize()
15+
{
16+
SubscribeLocalEvent<DoorRemoteComponent, UseInHandEvent>(OnInHandActivation);
17+
}
18+
19+
private void OnInHandActivation(Entity<DoorRemoteComponent> entity, ref UseInHandEvent args)
20+
{
21+
string switchMessageId;
22+
switch (entity.Comp.Mode)
23+
{
24+
case OperatingMode.OpenClose:
25+
entity.Comp.Mode = OperatingMode.ToggleBolts;
26+
switchMessageId = "door-remote-switch-state-toggle-bolts";
27+
break;
28+
29+
// Skip toggle bolts mode and move on from there (to emergency access)
30+
case OperatingMode.ToggleBolts:
31+
entity.Comp.Mode = OperatingMode.ToggleEmergencyAccess;
32+
switchMessageId = "door-remote-switch-state-toggle-emergency-access";
33+
break;
34+
35+
// Skip ToggleEmergencyAccess mode and move on from there (to door toggle)
36+
case OperatingMode.ToggleEmergencyAccess:
37+
entity.Comp.Mode = OperatingMode.OpenClose;
38+
switchMessageId = "door-remote-switch-state-open-close";
39+
break;
40+
default:
41+
throw new InvalidOperationException(
42+
$"{nameof(DoorRemoteComponent)} had invalid mode {entity.Comp.Mode}");
43+
}
44+
Dirty(entity);
45+
Popup.PopupClient(Loc.GetString(switchMessageId), entity, args.User);
46+
}
47+
}

‎Resources/Locale/en-US/door-remote/door-remote.ftl‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
## UI
2+
door-remote-open-close-text = Opens and Closes Doors
3+
door-remote-toggle-bolt-text = Toggles Bolts
4+
door-remote-emergency-access-text = Toggles Emergency Access
5+
door-remote-invalid-text = Invalid
6+
door-remote-mode-label = Mode: [color=white]{$modeString}[/color]
7+
8+
## Entity
9+
110
door-remote-switch-state-open-close = You switch the remote to open and close doors
211
door-remote-switch-state-toggle-bolts = You switch the remote to toggle bolts
312
door-remote-switch-state-toggle-emergency-access = You switch the remote to toggle emergency access

0 commit comments

Comments
 (0)