Agent ID Cards (#7041)
This commit is contained in:
64
Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs
Normal file
64
Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
using Content.Shared.Access.Systems;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
|
||||||
|
namespace Content.Client.Access.UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a <see cref="AgentIDCardWindow"/> and updates it when new server messages are received.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class AgentIDCardBoundUserInterface : BoundUserInterface
|
||||||
|
{
|
||||||
|
private AgentIDCardWindow? _window;
|
||||||
|
|
||||||
|
public AgentIDCardBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Open()
|
||||||
|
{
|
||||||
|
base.Open();
|
||||||
|
|
||||||
|
_window = new AgentIDCardWindow();
|
||||||
|
if (State != null)
|
||||||
|
UpdateState(State);
|
||||||
|
|
||||||
|
_window.OpenCentered();
|
||||||
|
|
||||||
|
_window.OnClose += Close;
|
||||||
|
_window.OnNameEntered += OnNameChanged;
|
||||||
|
_window.OnJobEntered += OnJobChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnNameChanged(string newName)
|
||||||
|
{
|
||||||
|
SendMessage(new AgentIDCardNameChangedMessage(newName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnJobChanged(string newJob)
|
||||||
|
{
|
||||||
|
SendMessage(new AgentIDCardJobChangedMessage(newJob));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update the UI state based on server-sent info
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="state"></param>
|
||||||
|
protected override void UpdateState(BoundUserInterfaceState state)
|
||||||
|
{
|
||||||
|
base.UpdateState(state);
|
||||||
|
if (_window == null || state is not AgentIDCardBoundUserInterfaceState cast)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_window.SetCurrentName(cast.CurrentName);
|
||||||
|
_window.SetCurrentJob(cast.CurrentJob);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
base.Dispose(disposing);
|
||||||
|
if (!disposing) return;
|
||||||
|
_window?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
10
Content.Client/Access/UI/AgentIDCardWindow.xaml
Normal file
10
Content.Client/Access/UI/AgentIDCardWindow.xaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<DefaultWindow xmlns="https://spacestation14.io"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="{Loc agent-id-menu-title}">
|
||||||
|
<BoxContainer Orientation="Vertical" SeparationOverride="4" MinWidth="150">
|
||||||
|
<Label Name="CurrentName" Text="{Loc 'agent-id-card-current-name'}" />
|
||||||
|
<LineEdit Name="NameLineEdit" />
|
||||||
|
<Label Name="CurrentJob" Text="{Loc 'agent-id-card-current-job'}" />
|
||||||
|
<LineEdit Name="JobLineEdit" />
|
||||||
|
</BoxContainer>
|
||||||
|
</DefaultWindow>
|
||||||
32
Content.Client/Access/UI/AgentIDCardWindow.xaml.cs
Normal file
32
Content.Client/Access/UI/AgentIDCardWindow.xaml.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
|
using Robust.Client.AutoGenerated;
|
||||||
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
|
||||||
|
namespace Content.Client.Access.UI
|
||||||
|
{
|
||||||
|
[GenerateTypedNameReferences]
|
||||||
|
public sealed partial class AgentIDCardWindow : DefaultWindow
|
||||||
|
{
|
||||||
|
public event Action<string>? OnNameEntered;
|
||||||
|
|
||||||
|
public event Action<string>? OnJobEntered;
|
||||||
|
|
||||||
|
public AgentIDCardWindow()
|
||||||
|
{
|
||||||
|
RobustXamlLoader.Load(this);
|
||||||
|
|
||||||
|
NameLineEdit.OnTextEntered += e => OnNameEntered?.Invoke(e.Text);
|
||||||
|
JobLineEdit.OnTextEntered += e => OnJobEntered?.Invoke(e.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCurrentName(string name)
|
||||||
|
{
|
||||||
|
NameLineEdit.Text = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCurrentJob(string job)
|
||||||
|
{
|
||||||
|
JobLineEdit.Text = job;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -64,6 +64,7 @@ namespace Content.Client.Entry
|
|||||||
"DiseaseSwab",
|
"DiseaseSwab",
|
||||||
"FloorTile",
|
"FloorTile",
|
||||||
"RandomInsulation",
|
"RandomInsulation",
|
||||||
|
"AgentIDCard",
|
||||||
"Electrified",
|
"Electrified",
|
||||||
"Electrocution",
|
"Electrocution",
|
||||||
"Paper",
|
"Paper",
|
||||||
|
|||||||
9
Content.Server/Access/Components/AgentIDCardComponent.cs
Normal file
9
Content.Server/Access/Components/AgentIDCardComponent.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using Content.Shared.Access.Systems;
|
||||||
|
using Content.Shared.PDA;
|
||||||
|
|
||||||
|
namespace Content.Server.Access.Components
|
||||||
|
{
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class AgentIDCardComponent : Component
|
||||||
|
{}
|
||||||
|
}
|
||||||
66
Content.Server/Access/Systems/AgentIDCardSystem.cs
Normal file
66
Content.Server/Access/Systems/AgentIDCardSystem.cs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
using Content.Shared.Access.Components;
|
||||||
|
using Content.Server.Access.Components;
|
||||||
|
using Content.Shared.Access.Systems;
|
||||||
|
using Content.Shared.Interaction;
|
||||||
|
using Content.Server.Popups;
|
||||||
|
using Robust.Shared.Player;
|
||||||
|
|
||||||
|
namespace Content.Server.Access.Systems
|
||||||
|
{
|
||||||
|
public sealed class AgentIDCardSystem : SharedAgentIdCardSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
||||||
|
[Dependency] private readonly IdCardSystem _cardSystem = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<AgentIDCardComponent, AfterInteractEvent>(OnAfterInteract);
|
||||||
|
// BUI
|
||||||
|
SubscribeLocalEvent<AgentIDCardComponent, AgentIDCardNameChangedMessage>(OnNameChanged);
|
||||||
|
SubscribeLocalEvent<AgentIDCardComponent, AgentIDCardJobChangedMessage> (OnJobChanged);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAfterInteract(EntityUid uid, AgentIDCardComponent component, AfterInteractEvent args)
|
||||||
|
{
|
||||||
|
if (!TryComp<AccessComponent>(args.Target, out var targetAccess) || !TryComp<IdCardComponent>(uid, out var targetIDCard) || args.Target == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!TryComp<AccessComponent>(uid, out var access) || !TryComp<IdCardComponent>(uid, out var idCard))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var beforeLength = access.Tags.Count;
|
||||||
|
access.Tags.UnionWith(targetAccess.Tags);
|
||||||
|
var addedLength = access.Tags.Count - beforeLength;
|
||||||
|
|
||||||
|
if (addedLength == 0)
|
||||||
|
{
|
||||||
|
_popupSystem.PopupEntity(Loc.GetString("agent-id-no-new", ("card", args.Target)), args.Target.Value, Filter.Pvs(args.User));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (addedLength == 1)
|
||||||
|
{
|
||||||
|
_popupSystem.PopupEntity(Loc.GetString("agent-id-new-1", ("card", args.Target)), args.Target.Value, Filter.Pvs(args.User));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_popupSystem.PopupEntity(Loc.GetString("agent-id-new", ("number", addedLength), ("card", args.Target)), args.Target.Value, Filter.Pvs(args.User));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnJobChanged(EntityUid uid, AgentIDCardComponent comp, AgentIDCardJobChangedMessage args)
|
||||||
|
{
|
||||||
|
if (!TryComp<IdCardComponent>(uid, out var idCard))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_cardSystem.TryChangeJobTitle(uid, args.Job, idCard);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnNameChanged(EntityUid uid, AgentIDCardComponent comp, AgentIDCardNameChangedMessage args)
|
||||||
|
{
|
||||||
|
if (!TryComp<IdCardComponent>(uid, out var idCard))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_cardSystem.TryChangeFullName(uid, args.Name, idCard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,13 @@
|
|||||||
using System;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Inventory;
|
using Content.Shared.Inventory;
|
||||||
using Content.Shared.MobState.Components;
|
using Content.Shared.MobState.Components;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Popups;
|
|
||||||
using Content.Server.Cooldown;
|
using Content.Server.Cooldown;
|
||||||
using Content.Server.Inventory;
|
|
||||||
using Content.Server.Mind.Components;
|
|
||||||
using Content.Server.Bible.Components;
|
using Content.Server.Bible.Components;
|
||||||
using Content.Server.Popups;
|
using Content.Server.Popups;
|
||||||
using Robust.Shared.IoC;
|
|
||||||
using Robust.Shared.Random;
|
using Robust.Shared.Random;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
using Content.Shared.Access.Systems;
|
using Content.Shared.Access.Systems;
|
||||||
using Content.Shared.PDA;
|
using Content.Shared.PDA;
|
||||||
using Robust.Shared.Analyzers;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
|
||||||
|
|
||||||
namespace Content.Shared.Access.Components
|
namespace Content.Shared.Access.Components
|
||||||
{
|
{
|
||||||
// TODO BUI NETWORKING if ever clients can open their own BUI's (id card console, pda), then this data should be
|
// TODO BUI NETWORKING if ever clients can open their own BUI's (id card console, pda), then this data should be
|
||||||
// networked.
|
// networked.
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
[Friend(typeof(SharedIdCardSystem), typeof(SharedPDASystem))]
|
[Friend(typeof(SharedIdCardSystem), typeof(SharedPDASystem), typeof(SharedAgentIdCardSystem))]
|
||||||
public sealed class IdCardComponent : Component
|
public sealed class IdCardComponent : Component
|
||||||
{
|
{
|
||||||
[DataField("originalOwnerName")]
|
[DataField("originalOwnerName")]
|
||||||
|
|||||||
55
Content.Shared/Access/SharedAgentIDCardSystem.cs
Normal file
55
Content.Shared/Access/SharedAgentIDCardSystem.cs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
|
namespace Content.Shared.Access.Systems
|
||||||
|
{
|
||||||
|
public class SharedAgentIdCardSystem : EntitySystem
|
||||||
|
{
|
||||||
|
/// Just for friending for now
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Key representing which <see cref="BoundUserInterface"/> is currently open.
|
||||||
|
/// Useful when there are multiple UI for an object. Here it's future-proofing only.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum AgentIDCardUiKey
|
||||||
|
{
|
||||||
|
Key,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents an <see cref="AgentIDCardComponent"/> state that can be sent to the client
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class AgentIDCardBoundUserInterfaceState : BoundUserInterfaceState
|
||||||
|
{
|
||||||
|
public string CurrentName { get; }
|
||||||
|
public string CurrentJob { get; }
|
||||||
|
|
||||||
|
public AgentIDCardBoundUserInterfaceState(string currentName, string currentJob)
|
||||||
|
{
|
||||||
|
CurrentName = currentName;
|
||||||
|
CurrentJob = currentJob;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class AgentIDCardNameChangedMessage : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
public AgentIDCardNameChangedMessage(string name)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public sealed class AgentIDCardJobChangedMessage : BoundUserInterfaceMessage
|
||||||
|
{
|
||||||
|
public string Job { get; }
|
||||||
|
public AgentIDCardJobChangedMessage(string job)
|
||||||
|
{
|
||||||
|
Job = job;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
agent-id-no-new = Didn't gain any new accesses from {THE($card)}.
|
||||||
|
agent-id-new-1 = Gained one new access from {THE($card)}.
|
||||||
|
agent-id-new = Gained {$number} new accesses from {THE($card)}.
|
||||||
|
agent-id-card-current-name = Name:
|
||||||
|
agent-id-card-current-job = Job:
|
||||||
|
agent-id-menu-title = Agent ID Card
|
||||||
@@ -157,6 +157,15 @@
|
|||||||
icon: /Textures/Objects/Tools/emag.rsi/icon.png
|
icon: /Textures/Objects/Tools/emag.rsi/icon.png
|
||||||
price: 8
|
price: 8
|
||||||
|
|
||||||
|
- type: uplinkListing
|
||||||
|
id: UplinkAgentIDCard
|
||||||
|
category: Utility
|
||||||
|
itemId: AgentIDCard
|
||||||
|
listingName: Agent ID Card
|
||||||
|
description: A modified ID card that can copy accesses from other cards and change its name and job title at-will.
|
||||||
|
icon: Objects/Misc/id_cards.rsi/default.png
|
||||||
|
price: 3
|
||||||
|
|
||||||
- type: uplinkListing
|
- type: uplinkListing
|
||||||
id: UplinkHypopen
|
id: UplinkHypopen
|
||||||
category: Utility
|
category: Utility
|
||||||
|
|||||||
@@ -377,3 +377,16 @@
|
|||||||
- state: idmusician
|
- state: idmusician
|
||||||
- type: PresetIdCard
|
- type: PresetIdCard
|
||||||
job: Musician
|
job: Musician
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: AssistantIDCard
|
||||||
|
id: AgentIDCard
|
||||||
|
suffix: Agent
|
||||||
|
components:
|
||||||
|
- type: AgentIDCard
|
||||||
|
- type: ActivatableUI
|
||||||
|
key: enum.AgentIDCardUiKey.Key
|
||||||
|
- type: UserInterface
|
||||||
|
interfaces:
|
||||||
|
- key: enum.AgentIDCardUiKey.Key
|
||||||
|
type: AgentIDCardBoundUserInterface
|
||||||
|
|||||||
Reference in New Issue
Block a user