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",
|
||||
"FloorTile",
|
||||
"RandomInsulation",
|
||||
"AgentIDCard",
|
||||
"Electrified",
|
||||
"Electrocution",
|
||||
"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.Inventory;
|
||||
using Content.Shared.MobState.Components;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Server.Cooldown;
|
||||
using Content.Server.Inventory;
|
||||
using Content.Server.Mind.Components;
|
||||
using Content.Server.Bible.Components;
|
||||
using Content.Server.Popups;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
|
||||
@@ -70,7 +63,7 @@ namespace Content.Server.Bible
|
||||
if (_random.Prob(component.FailChance))
|
||||
{
|
||||
var othersFailMessage = Loc.GetString("bible-heal-fail-others", ("user", args.User),("target", args.Target),("bible", uid));
|
||||
_popupSystem.PopupEntity(othersFailMessage, args.User, Filter.Pvs(args.User).RemoveWhereAttachedEntity(puid => puid == args.User));
|
||||
_popupSystem.PopupEntity(othersFailMessage, args.User, Filter.Pvs(args.User).RemoveWhereAttachedEntity(puid => puid == args.User));
|
||||
|
||||
var selfFailMessage = Loc.GetString("bible-heal-fail-self", ("target", args.Target),("bible", uid));
|
||||
_popupSystem.PopupEntity(selfFailMessage, args.User, Filter.Entities(args.User));
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.PDA;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
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
|
||||
// networked.
|
||||
[RegisterComponent]
|
||||
[Friend(typeof(SharedIdCardSystem), typeof(SharedPDASystem))]
|
||||
[Friend(typeof(SharedIdCardSystem), typeof(SharedPDASystem), typeof(SharedAgentIdCardSystem))]
|
||||
public sealed class IdCardComponent : Component
|
||||
{
|
||||
[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
|
||||
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
|
||||
id: UplinkHypopen
|
||||
category: Utility
|
||||
|
||||
@@ -377,3 +377,16 @@
|
||||
- state: idmusician
|
||||
- type: PresetIdCard
|
||||
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