From 6e2799f048d740a0f34934d9d1d1fe42d19f79e4 Mon Sep 17 00:00:00 2001 From: DamianX Date: Fri, 6 Sep 2019 08:12:44 +0200 Subject: [PATCH] ID card console (#324) * ID card console * Container -> ContainerSlot --- Content.Client/EntryPoint.cs | 1 + .../Access/IdCardConsoleBoundUserInterface.cs | 52 +++++ .../Components/Access/IdCardConsoleWindow.cs | 143 +++++++++++++ .../Components/Access/AccessComponent.cs | 5 +- .../Access/AccessReaderComponent.cs | 8 + .../Components/Access/IdCardComponent.cs | 54 ++++- .../Access/IdCardConsoleComponent.cs | 192 ++++++++++++++++++ Content.Shared/Access/SharedAccess.cs | 16 ++ .../Access/SharedIdCardConsoleComponent.cs | 77 +++++++ .../Entities/buildings/computers.yml | 7 + .../Entities/items/clothing/IDs.yml | 114 ++++++++++- .../Textures/Clothing/id_cards.rsi/CE.png | Bin 0 -> 750 bytes .../Textures/Clothing/id_cards.rsi/CMO.png | Bin 0 -> 743 bytes .../Clothing/id_cards.rsi/ERT_empty.png | Bin 0 -> 836 bytes .../Clothing/id_cards.rsi/ERT_engineering.png | Bin 0 -> 890 bytes .../Clothing/id_cards.rsi/ERT_leader.png | Bin 0 -> 892 bytes .../Clothing/id_cards.rsi/ERT_medical.png | Bin 0 -> 913 bytes .../Clothing/id_cards.rsi/ERT_security.png | Bin 0 -> 900 bytes .../Textures/Clothing/id_cards.rsi/HoS.png | Bin 0 -> 731 bytes .../Textures/Clothing/id_cards.rsi/RD.png | Bin 0 -> 752 bytes .../Clothing/id_cards.rsi/TDgreen.png | Bin 0 -> 822 bytes .../Textures/Clothing/id_cards.rsi/TDred.png | Bin 0 -> 780 bytes .../Textures/Clothing/id_cards.rsi/admin.png | Bin 0 -> 914 bytes .../Clothing/id_cards.rsi/assistant.png | Bin 389 -> 0 bytes .../Textures/Clothing/id_cards.rsi/cargo.png | Bin 0 -> 972 bytes .../Clothing/id_cards.rsi/centcom.png | Bin 0 -> 763 bytes .../Clothing/id_cards.rsi/centcom_old.png | Bin 0 -> 966 bytes .../id_cards.rsi/civilian-inhand-left.png | Bin 0 -> 177 bytes .../id_cards.rsi/civilian-inhand-right.png | Bin 0 -> 179 bytes .../Clothing/id_cards.rsi/civilian.png | Bin 0 -> 1001 bytes .../Textures/Clothing/id_cards.rsi/clown.png | Bin 0 -> 977 bytes .../Textures/Clothing/id_cards.rsi/creed.png | Bin 0 -> 696 bytes .../Clothing/id_cards.rsi/deathsquad.png | Bin 0 -> 678 bytes .../Clothing/id_cards.rsi/debit-elite.png | Bin 0 -> 434 bytes .../Clothing/id_cards.rsi/debit-preferred.png | Bin 0 -> 525 bytes .../Textures/Clothing/id_cards.rsi/debit.png | Bin 0 -> 517 bytes .../Textures/Clothing/id_cards.rsi/emag.png | Bin 0 -> 1070 bytes .../Clothing/id_cards.rsi/engineering.png | Bin 0 -> 980 bytes .../Clothing/id_cards.rsi/fingerprint0.png | Bin 0 -> 281 bytes .../Clothing/id_cards.rsi/fingerprint1.png | Bin 0 -> 383 bytes .../id_cards.rsi/gold-inhand-left.png | Bin 0 -> 177 bytes .../id_cards.rsi/gold-inhand-right.png | Bin 0 -> 180 bytes .../Textures/Clothing/id_cards.rsi/gold.png | Bin 0 -> 491 bytes .../Clothing/id_cards.rsi/medical.png | Bin 0 -> 958 bytes .../Textures/Clothing/id_cards.rsi/meta.json | 2 +- .../Textures/Clothing/id_cards.rsi/mime.png | Bin 0 -> 753 bytes .../Textures/Clothing/id_cards.rsi/old.png | Bin 0 -> 905 bytes .../Clothing/id_cards.rsi/research.png | Bin 0 -> 981 bytes .../Textures/Clothing/id_cards.rsi/robot.png | Bin 0 -> 1139 bytes .../Clothing/id_cards.rsi/security.png | Bin 0 -> 953 bytes .../Textures/Clothing/id_cards.rsi/silver.png | Bin 0 -> 667 bytes .../Textures/Clothing/id_cards.rsi/syndie.png | Bin 0 -> 683 bytes .../Textures/Clothing/id_cards.rsi/trader.png | Bin 0 -> 1034 bytes .../Textures/Clothing/idcard_standard.png | Bin 650 -> 0 bytes 54 files changed, 661 insertions(+), 10 deletions(-) create mode 100644 Content.Client/GameObjects/Components/Access/IdCardConsoleBoundUserInterface.cs create mode 100644 Content.Client/GameObjects/Components/Access/IdCardConsoleWindow.cs create mode 100644 Content.Server/GameObjects/Components/Access/IdCardConsoleComponent.cs create mode 100644 Content.Shared/Access/SharedAccess.cs create mode 100644 Content.Shared/GameObjects/Components/Access/SharedIdCardConsoleComponent.cs create mode 100644 Resources/Textures/Clothing/id_cards.rsi/CE.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/CMO.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/ERT_empty.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/ERT_engineering.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/ERT_leader.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/ERT_medical.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/ERT_security.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/HoS.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/RD.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/TDgreen.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/TDred.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/admin.png delete mode 100644 Resources/Textures/Clothing/id_cards.rsi/assistant.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/cargo.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/centcom.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/centcom_old.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/civilian-inhand-left.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/civilian-inhand-right.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/civilian.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/clown.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/creed.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/deathsquad.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/debit-elite.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/debit-preferred.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/debit.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/emag.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/engineering.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/fingerprint0.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/fingerprint1.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/gold-inhand-left.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/gold-inhand-right.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/gold.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/medical.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/mime.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/old.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/research.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/robot.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/security.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/silver.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/syndie.png create mode 100644 Resources/Textures/Clothing/id_cards.rsi/trader.png delete mode 100644 Resources/Textures/Clothing/idcard_standard.png diff --git a/Content.Client/EntryPoint.cs b/Content.Client/EntryPoint.cs index 33597d77ac..c82ac92871 100644 --- a/Content.Client/EntryPoint.cs +++ b/Content.Client/EntryPoint.cs @@ -106,6 +106,7 @@ namespace Content.Client "IdCard", "Access", "AccessReader", + "IdCardConsole", }; foreach (var ignoreName in registerIgnore) diff --git a/Content.Client/GameObjects/Components/Access/IdCardConsoleBoundUserInterface.cs b/Content.Client/GameObjects/Components/Access/IdCardConsoleBoundUserInterface.cs new file mode 100644 index 0000000000..ebd658d479 --- /dev/null +++ b/Content.Client/GameObjects/Components/Access/IdCardConsoleBoundUserInterface.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; +using Robust.Client.GameObjects.Components.UserInterface; +using Robust.Shared.GameObjects.Components.UserInterface; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using static Content.Shared.GameObjects.Components.Access.SharedIdCardConsoleComponent; + +namespace Content.Client.GameObjects.Components.Access +{ + public class IdCardConsoleBoundUserInterface : BoundUserInterface + { +#pragma warning disable 649 + [Dependency] private readonly ILocalizationManager _localizationManager; +#pragma warning restore 649 + public IdCardConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey) + { + } + + private IdCardConsoleWindow _window; + + protected override void Open() + { + IoCManager.InjectDependencies(this); + base.Open(); + + _window = new IdCardConsoleWindow(this, _localizationManager); + _window.Title = Owner.Owner.Name; + _window.OnClose += Close; + _window.OpenCentered(); + } + + protected override void UpdateState(BoundUserInterfaceState state) + { + base.UpdateState(state); + var castState = (IdCardConsoleBoundUserInterfaceState) state; + _window.UpdateState(castState); + } + + public void ButtonPressed(UiButton button) + { + SendMessage(new IdButtonPressedMessage(button)); + } + + public void SubmitData(string newFullName, string newJobTitle, List newAccessList) + { + SendMessage(new WriteToTargetIdMessage( + newFullName, + newJobTitle, + newAccessList)); + } + } +} diff --git a/Content.Client/GameObjects/Components/Access/IdCardConsoleWindow.cs b/Content.Client/GameObjects/Components/Access/IdCardConsoleWindow.cs new file mode 100644 index 0000000000..abedc157d0 --- /dev/null +++ b/Content.Client/GameObjects/Components/Access/IdCardConsoleWindow.cs @@ -0,0 +1,143 @@ +using System.Collections.Generic; +using System.Linq; +using Content.Shared.Access; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.CustomControls; +using Robust.Shared.Localization; +using Robust.Shared.Maths; +using Robust.Shared.Utility; +using static Content.Shared.GameObjects.Components.Access.SharedIdCardConsoleComponent; + +namespace Content.Client.GameObjects.Components.Access +{ + public class IdCardConsoleWindow : SS14Window + { + private readonly Label _fullNameLabel; + private readonly LineEdit _fullNameLineEdit; + private readonly Label _jobTitleLabel; + private readonly LineEdit _jobTitleLineEdit; + private readonly IdCardConsoleBoundUserInterface _owner; + private readonly Button _privilegedIdButton; + private readonly Button _targetIdButton; + private readonly Button _submitButton; + private readonly ILocalizationManager _localizationManager; + + private Dictionary _accessButtons = new Dictionary(); + + public IdCardConsoleWindow(IdCardConsoleBoundUserInterface owner, ILocalizationManager localizationManager) + { + _localizationManager = localizationManager; + _owner = owner; + var vBox = new VBoxContainer(); + + { + var hBox = new HBoxContainer(); + vBox.AddChild(hBox); + + _privilegedIdButton = new Button(); + _privilegedIdButton.OnPressed += _ => _owner.ButtonPressed(UiButton.PrivilegedId); + hBox.AddChild(_privilegedIdButton); + + _targetIdButton = new Button(); + _targetIdButton.OnPressed += _ => _owner.ButtonPressed(UiButton.TargetId); + hBox.AddChild(_targetIdButton); + } + + { + var hBox = new HBoxContainer(); + vBox.AddChild(hBox); + hBox.AddChild(_fullNameLabel = new Label() + { + Text = localizationManager.GetString("Full name:") + }); + + _fullNameLineEdit = new LineEdit() + { + SizeFlagsHorizontal = SizeFlags.FillExpand, + }; + hBox.AddChild(_fullNameLineEdit); + } + + { + var hBox = new HBoxContainer(); + vBox.AddChild(hBox); + hBox.AddChild(_jobTitleLabel = new Label() + { + Text = localizationManager.GetString("Job title:") + }); + + _jobTitleLineEdit = new LineEdit() + { + SizeFlagsHorizontal = SizeFlags.FillExpand + }; + hBox.AddChild(_jobTitleLineEdit); + } + + { + var hBox = new HBoxContainer(); + vBox.AddChild(hBox); + + foreach (var accessName in SharedAccess.AllAccess) + { + var newButton = new Button() + { + Text = accessName, + ToggleMode = true, + }; + hBox.AddChild(newButton); + _accessButtons.Add(accessName, newButton); + } + } + + { + var hBox = new HBoxContainer(); + vBox.AddChild(hBox); + + _submitButton = new Button() + { + Text = localizationManager.GetString("Submit") + }; + _submitButton.OnPressed += _ => owner.SubmitData( + _fullNameLineEdit.Text, + _jobTitleLineEdit.Text, + // Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair + _accessButtons.Where(x => x.Value.Pressed).Select(x => x.Key).ToList()); + hBox.AddChild(_submitButton); + } + + Contents.AddChild(vBox); + } + + public void UpdateState(IdCardConsoleBoundUserInterfaceState state) + { + _privilegedIdButton.Text = state.IsPrivilegedIdPresent + ? _localizationManager.GetString("Remove privileged ID card") + : _localizationManager.GetString("Insert privileged ID card"); + + _targetIdButton.Text = state.IsTargetIdPresent + ? _localizationManager.GetString("Remove target ID card") + : _localizationManager.GetString("Insert target ID card"); + + var interfaceEnabled = state.IsPrivilegedIdPresent && state.IsPrivilegedIdAuthorized && state.IsTargetIdPresent; + + _fullNameLabel.Modulate = interfaceEnabled ? Color.White : Color.Gray; + _fullNameLineEdit.Editable = interfaceEnabled; + _fullNameLineEdit.Text = state.TargetIdFullName; + + _jobTitleLabel.Modulate = interfaceEnabled ? Color.White : Color.Gray; + _jobTitleLineEdit.Editable = interfaceEnabled; + _jobTitleLineEdit.Text = state.TargetIdJobTitle; + + foreach (var (accessName, button) in _accessButtons) + { + button.Disabled = !interfaceEnabled; + if (interfaceEnabled) + { + button.Pressed = state.TargetIdAccessList.Contains(accessName); + } + } + + _submitButton.Disabled = !interfaceEnabled; + } + } +} diff --git a/Content.Server/GameObjects/Components/Access/AccessComponent.cs b/Content.Server/GameObjects/Components/Access/AccessComponent.cs index 4de9021f28..fa122346b7 100644 --- a/Content.Server/GameObjects/Components/Access/AccessComponent.cs +++ b/Content.Server/GameObjects/Components/Access/AccessComponent.cs @@ -9,14 +9,13 @@ namespace Content.Server.GameObjects.Components.Access public class AccessComponent : Component { public override string Name => "Access"; - private List _tags; [ViewVariables] - public List Tags => _tags; + public List Tags; public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); - serializer.DataField(ref _tags, "tags", new List()); + serializer.DataField(ref Tags, "tags", new List()); } } } diff --git a/Content.Server/GameObjects/Components/Access/AccessReaderComponent.cs b/Content.Server/GameObjects/Components/Access/AccessReaderComponent.cs index ffa555006e..6eba78317f 100644 --- a/Content.Server/GameObjects/Components/Access/AccessReaderComponent.cs +++ b/Content.Server/GameObjects/Components/Access/AccessReaderComponent.cs @@ -13,9 +13,17 @@ namespace Content.Server.GameObjects.Components.Access public class AccessReader : Component { public override string Name => "AccessReader"; + [ViewVariables] private List _necessaryTags; + [ViewVariables] private List _sufficientTags; + /// + /// Searches an in the entity itself, in its active hand or in its ID slot. + /// Returns true if an is found and its tags list contains + /// at least one of or all of . + /// + /// The entity to be searched for access. public bool IsAllowed(IEntity entity) { var accessProvider = FindAccessProvider(entity); diff --git a/Content.Server/GameObjects/Components/Access/IdCardComponent.cs b/Content.Server/GameObjects/Components/Access/IdCardComponent.cs index 0449164baf..a870dc9438 100644 --- a/Content.Server/GameObjects/Components/Access/IdCardComponent.cs +++ b/Content.Server/GameObjects/Components/Access/IdCardComponent.cs @@ -1,4 +1,3 @@ -using System.Security.Cryptography; using Robust.Shared.GameObjects; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -9,10 +8,61 @@ namespace Content.Server.GameObjects.Components.Access public class IdCardComponent : Component { public override string Name => "IdCard"; - [ViewVariables(VVAccess.ReadWrite)] + + /// See . + private string _ownerOriginalName; + private string _fullName; [ViewVariables(VVAccess.ReadWrite)] + public string FullName + { + get => _fullName; + set + { + _fullName = value; + UpdateEntityName(); + } + } + private string _jobTitle; + [ViewVariables(VVAccess.ReadWrite)] + public string JobTitle + { + get => _jobTitle; + set + { + _jobTitle = value; + UpdateEntityName(); + } + } + + /// + /// Changes the of . + /// + /// + /// If either or is empty, it's replaced by placeholders. + /// If both are empty, the original entity's name is restored. + /// + private void UpdateEntityName() + { + if (string.IsNullOrWhiteSpace(FullName) && string.IsNullOrWhiteSpace(JobTitle)) + { + Owner.Name = _ownerOriginalName; + return; + } + + var tempFullName = string.IsNullOrWhiteSpace(FullName) ? "Unknown" : FullName; + var tempJobTitle = string.IsNullOrWhiteSpace(JobTitle) ? "N/A" : JobTitle; + + Owner.Name = $"{_ownerOriginalName} ({tempFullName}, {tempJobTitle})"; + } + + public override void Initialize() + { + base.Initialize(); + _ownerOriginalName = Owner.Name; + UpdateEntityName(); + } public override void ExposeData(ObjectSerializer serializer) { diff --git a/Content.Server/GameObjects/Components/Access/IdCardConsoleComponent.cs b/Content.Server/GameObjects/Components/Access/IdCardConsoleComponent.cs new file mode 100644 index 0000000000..4726bc95ce --- /dev/null +++ b/Content.Server/GameObjects/Components/Access/IdCardConsoleComponent.cs @@ -0,0 +1,192 @@ +using System.Collections.Generic; +using System.Linq; +using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces; +using Content.Server.Interfaces.GameObjects; +using Content.Shared.Access; +using Content.Shared.GameObjects.Components.Access; +using Robust.Server.GameObjects.Components.Container; +using Robust.Server.GameObjects.Components.UserInterface; +using Robust.Server.Interfaces.GameObjects; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.Log; + +namespace Content.Server.GameObjects.Components.Access +{ + [RegisterComponent] + [ComponentReference(typeof(IActivate))] + public class IdCardConsoleComponent : SharedIdCardConsoleComponent, IActivate + { +#pragma warning disable 649 + [Dependency] private readonly IServerNotifyManager _notifyManager; + [Dependency] private readonly ILocalizationManager _localizationManager; +#pragma warning restore 649 + + private BoundUserInterface _userInterface; + private ContainerSlot _privilegedIdContainer; + private ContainerSlot _targetIdContainer; + private AccessReader _accessReader; + + public override void Initialize() + { + base.Initialize(); + + _privilegedIdContainer = ContainerManagerComponent.Ensure($"{Name}-privilegedId", Owner); + _targetIdContainer = ContainerManagerComponent.Ensure($"{Name}-targetId", Owner); + + _accessReader = Owner.GetComponent(); + + _userInterface = Owner.GetComponent() + .GetBoundUserInterface(IdCardConsoleUiKey.Key); + _userInterface.OnReceiveMessage += OnUiReceiveMessage; + UpdateUserInterface(); + } + + private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj) + { + switch (obj.Message) + { + case IdButtonPressedMessage msg: + switch (msg.Button) + { + case UiButton.PrivilegedId: + HandleId(obj.Session.AttachedEntity, _privilegedIdContainer); + break; + case UiButton.TargetId: + HandleId(obj.Session.AttachedEntity, _targetIdContainer); + break; + } + break; + case WriteToTargetIdMessage msg: + TryWriteToTargetId(msg.FullName, msg.JobTitle, msg.AccessList); + break; + } + } + + /// + /// Returns true if there is an ID in and said ID satisfies the requirements of . + /// + private bool PrivilegedIdIsAuthorized() + { + var privilegedIdEntity = _privilegedIdContainer.ContainedEntity; + return privilegedIdEntity != null && _accessReader.IsAllowed(privilegedIdEntity); + } + /// + /// Called when the "Submit" button in the UI gets pressed. + /// Writes data passed from the UI into the ID stored in , if present. + /// + private void TryWriteToTargetId(string newFullName, string newJobTitle, List newAccessList) + { + if (!PrivilegedIdIsAuthorized() || _targetIdContainer.ContainedEntity == null) + { + return; + } + + var targetIdEntity = _targetIdContainer.ContainedEntity; + + var targetIdComponent = targetIdEntity.GetComponent(); + targetIdComponent.FullName = newFullName; + targetIdComponent.JobTitle = newJobTitle; + + if (!newAccessList.TrueForAll(x => SharedAccess.AllAccess.Contains(x))) + { + Logger.Warning($"Tried to write unknown access tag."); + return; + } + var targetIdAccess = targetIdEntity.GetComponent(); + targetIdAccess.Tags = newAccessList; + } + + /// + /// Called when one of the insert/remove ID buttons gets pressed. + /// + private void HandleId(IEntity user, ContainerSlot container) + { + if (!user.TryGetComponent(out IHandsComponent hands)) + { + _notifyManager.PopupMessage(Owner.Transform.GridPosition, user, _localizationManager.GetString("You have no hands.")); + return; + } + + if (container.ContainedEntity == null) + { + InsertIdFromHand(user, container, hands); + } + else + { + PutIdInHand(container, hands); + } + } + + private void InsertIdFromHand(IEntity user, ContainerSlot container, IHandsComponent hands) + { + var isId = hands.GetActiveHand?.Owner.HasComponent(); + if (isId != true) + { + return; + } + if(!hands.Drop(hands.ActiveIndex, container)) + { + _notifyManager.PopupMessage(Owner.Transform.GridPosition, user, _localizationManager.GetString("You can't let go of the ID card!")); + return; + } + UpdateUserInterface(); + } + + private void PutIdInHand(ContainerSlot container, IHandsComponent hands) + { + var idEntity = container.ContainedEntity; + if (idEntity == null || !container.Remove(idEntity)) + { + return; + } + UpdateUserInterface(); + + hands.PutInHand(idEntity.GetComponent()); + } + + private void UpdateUserInterface() + { + var isPrivilegedIdPresent = _privilegedIdContainer.ContainedEntity != null; + var targetIdEntity = _targetIdContainer.ContainedEntity; + IdCardConsoleBoundUserInterfaceState newState; + // this could be prettier + if (targetIdEntity == null) + { + newState = new IdCardConsoleBoundUserInterfaceState( + isPrivilegedIdPresent, + PrivilegedIdIsAuthorized(), + false, + null, + null, + null); + } + else + { + var targetIdComponent = targetIdEntity.GetComponent(); + var targetAccessComponent = targetIdEntity.GetComponent(); + newState = new IdCardConsoleBoundUserInterfaceState( + isPrivilegedIdPresent, + PrivilegedIdIsAuthorized(), + true, + targetIdComponent.FullName, + targetIdComponent.JobTitle, + targetAccessComponent.Tags); + } + _userInterface.SetState(newState); + } + + public void Activate(ActivateEventArgs eventArgs) + { + if(!eventArgs.User.TryGetComponent(out IActorComponent actor)) + { + return; + } + + _userInterface.Open(actor.playerSession); + } + } +} diff --git a/Content.Shared/Access/SharedAccess.cs b/Content.Shared/Access/SharedAccess.cs new file mode 100644 index 0000000000..b705c26b19 --- /dev/null +++ b/Content.Shared/Access/SharedAccess.cs @@ -0,0 +1,16 @@ +namespace Content.Shared.Access +{ + public static class SharedAccess + { + public static readonly string[] AllAccess = { + "command", + "security", + "engineering", + "medical", + "cargo", + "research", + "service", + "maintenance", + }; + } +} diff --git a/Content.Shared/GameObjects/Components/Access/SharedIdCardConsoleComponent.cs b/Content.Shared/GameObjects/Components/Access/SharedIdCardConsoleComponent.cs new file mode 100644 index 0000000000..0d4627cf39 --- /dev/null +++ b/Content.Shared/GameObjects/Components/Access/SharedIdCardConsoleComponent.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Components.UserInterface; +using Robust.Shared.Serialization; + +namespace Content.Shared.GameObjects.Components.Access +{ + public class SharedIdCardConsoleComponent : Component + { + public override string Name => "IdCardConsole"; + + public enum UiButton + { + PrivilegedId, + TargetId, + } + + [Serializable, NetSerializable] + public class IdButtonPressedMessage : BoundUserInterfaceMessage + { + public readonly UiButton Button; + + public IdButtonPressedMessage(UiButton button) + { + Button = button; + } + } + + [Serializable, NetSerializable] + public class WriteToTargetIdMessage : BoundUserInterfaceMessage + { + public readonly string FullName; + public readonly string JobTitle; + public readonly List AccessList; + + public WriteToTargetIdMessage(string fullName, string jobTitle, List accessList) + { + FullName = fullName; + JobTitle = jobTitle; + AccessList = accessList; + } + } + + [Serializable, NetSerializable] + public class IdCardConsoleBoundUserInterfaceState : BoundUserInterfaceState + { + public readonly bool IsPrivilegedIdPresent; + public readonly bool IsPrivilegedIdAuthorized; + public readonly bool IsTargetIdPresent; + public readonly string TargetIdFullName; + public readonly string TargetIdJobTitle; + public readonly List TargetIdAccessList; + + public IdCardConsoleBoundUserInterfaceState(bool isPrivilegedIdPresent, + bool isPrivilegedIdAuthorized, + bool isTargetIdPresent, + string targetIdFullName, + string targetIdJobTitle, + List targetIdAccessList) + { + IsPrivilegedIdPresent = isPrivilegedIdPresent; + IsPrivilegedIdAuthorized = isPrivilegedIdAuthorized; + IsTargetIdPresent = isTargetIdPresent; + TargetIdFullName = targetIdFullName; + TargetIdJobTitle = targetIdJobTitle; + TargetIdAccessList = targetIdAccessList; + } + } + + [Serializable, NetSerializable] + public enum IdCardConsoleUiKey + { + Key, + } + } +} diff --git a/Resources/Prototypes/Entities/buildings/computers.yml b/Resources/Prototypes/Entities/buildings/computers.yml index 9b7e604a1f..e61008a012 100644 --- a/Resources/Prototypes/Entities/buildings/computers.yml +++ b/Resources/Prototypes/Entities/buildings/computers.yml @@ -109,6 +109,13 @@ parent: computerBase name: ID Card Computer components: + - type: AccessReader + necessary: ["command"] + - type: IdCardConsole + - type: UserInterface + interfaces: + - key: enum.IdCardConsoleUiKey.Key + type: IdCardConsoleBoundUserInterface - type: Appearance visuals: - type: ComputerVisualizer2D diff --git a/Resources/Prototypes/Entities/items/clothing/IDs.yml b/Resources/Prototypes/Entities/items/clothing/IDs.yml index 85b2ba7dea..f8a930fd50 100644 --- a/Resources/Prototypes/Entities/items/clothing/IDs.yml +++ b/Resources/Prototypes/Entities/items/clothing/IDs.yml @@ -6,15 +6,121 @@ components: - type: Sprite sprite: Clothing/id_cards.rsi - state: assistant + state: civilian - type: Icon sprite: Clothing/id_cards.rsi - state: assistant + state: civilian - type: Clothing Slots: - idcard + sprite: Clothing/id_cards.rsi + HeldPrefix: civilian + - type: IdCard + - type: Access + +- type: entity + parent: IDCardStandard + id: CommandIDCard + name: Command Identification Card + components: + - type: Clothing + HeldPrefix: gold + - type: Sprite + state: gold + - type: Icon + state: gold + - type: IdCard + jobTitle: Captain + - type: Access + tags: ["command"] + +- type: entity + parent: IDCardStandard + id: SecurityIDCard + name: Security Identification Card + components: + - type: Sprite + state: security + - type: Icon + state: security + - type: IdCard + jobTitle: Security Officer + - type: Access + tags: ["security"] + +- type: entity + parent: IDCardStandard + id: EngineeringIDCard + name: Engineering Identification Card + components: + - type: Sprite + state: engineering + - type: Icon + state: engineering + - type: IdCard + jobTitle: Engineer + - type: Access + tags: ["engineering"] + +- type: entity + parent: IDCardStandard + id: MedicalIDCard + name: Medical Identification Card + components: + - type: Sprite + state: medical + - type: Icon + state: medical + - type: IdCard + jobTitle: Doctor + - type: Access + tags: ["medical"] + +- type: entity + parent: IDCardStandard + id: CargoIDCard + name: Cargo Identification Card + components: + - type: Sprite + state: cargo + - type: Icon + state: cargo + - type: IdCard + jobTitle: Cargo Technician + - type: Access + tags: ["cargo"] + +- type: entity + parent: IDCardStandard + id: ResearchIDCard + name: Research Identification Card + components: + - type: Sprite + state: research + - type: Icon + state: research + - type: IdCard + jobTitle: Scientist + - type: Access + tags: ["research"] + +- type: entity + parent: IDCardStandard + id: ServiceIDCard + name: Service Identification Card + components: + - type: IdCard + jobTitle: Bartender + - type: Access + tags: ["service"] + +- type: entity + parent: IDCardStandard + id: AssistantIDCard + name: Assistant Identification Card + components: - type: IdCard - fullName: John Doe jobTitle: Assistant - type: Access - tags: ["civilian", "maintenance", "engineering"] + tags: ["maintenance"] + diff --git a/Resources/Textures/Clothing/id_cards.rsi/CE.png b/Resources/Textures/Clothing/id_cards.rsi/CE.png new file mode 100644 index 0000000000000000000000000000000000000000..c9d389c3dad31977cb1b0b4e945b6cdae31a3f96 GIT binary patch literal 750 zcmVX;v0zLKgKSJ>W^r9tPESwOjSYC< zFW+AIW6Mje`5?GZC`87BS-6&gR4Nq#cLK$M9mfe};r#quUCBT)nG~fIyL%Inx$&`` z2q^BllT^3KWHKoL!^6XVk5^XfA@JAlul@U%mj+_j+1%U&V0L!a52$IHluD)e7I@&e zUBrPqRiRKQAR;KGa9tN@g%Ln06|O*V$A)3xI1T`F3m*aa@czw}s<6Gi?FUUnn4X>v z8M7>l{r&xhiFN}X93VHd2Egd(697u3O2kA^=8qx(@7~@6U~+OY0zNo60O0KGEP4!; zYWc~{toh(LEiVoDCjQjR{Q6yGFwsxVzF>E6B9w!jGpR4OI&^Yi|-7sjovtwwU2pIj~%$-;|gpAZpFPENXlyBbI&5|Yhk z{V=YtuQzUPW~BYNt*q90`TR2g?Z5YzDYgZ+Z7XS>qhKD|!IoulbaX_qcztkJ0}wtD z`F!4Qg9oluD)jaB-57kSfw(GImPNT-Mk#gW9^cpiw5nj5CYEKPlp^?V=FSZ?VFFOA g)ovBsQ%|1$0v9JjGH&A!-~a#s07*qoM6N<$g7xHGr2qf` literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/CMO.png b/Resources/Textures/Clothing/id_cards.rsi/CMO.png new file mode 100644 index 0000000000000000000000000000000000000000..a7aab02e96c08904a65c9a1c9705ae3a54d562ff GIT binary patch literal 743 zcmV?P)y*|(7o-xxRUN`xBUr9Y6WY|e~_tIP@JF; zO(eQ2vv4)1i}}c%593GUs(B$Wb7zLzCBIW|lS+&#axb1SswP zK6N#a$z%jza&pp}@!e0_gYyxv`R*$KZD2$jgRZ^3JpdLK7QAo#E{KSv8VJB?Rm8#i zTKxTLwTg(Kl)`mgpc6&_r4*4`2y=6D z5o5M(b8>RxnTQ(*-~g4%5CFrU)&aQvypb@W>uC445B&zf?Cfj;e0qB7ecx^;x1mxU zKb6W*2u{<8mWS4xWjKW4@-ny84Q7@$BY8*z2Z|WDyu4I^=tpQ!Idn##S3F!^heO~k zj2?eybn&$Z8l30P@g`?yXDFo-;IQcULN=R~iHQkJ(+o!t2iIyflv0Si2VmNV>aup$ z5E1lq|4{}46Dun#;e8Os{r!C}x&E(IDkZY;>&FK~gsZEouHdc)#>U2^SS*HN+}hgm zUiLE*-)`-}d5(5J0ucYde@Ln4K(pCY;_o9p4{@+<+gw~+0JSHByBdJ#j#yn?4aX3G z&(F^p7#Mgq_(20{U9fGNdcBTP>d`ZPwgKpL!LlrD+eRt%V5)m+z=sJytJUf$xUaqf Z{RQE8L-H)9Y)k+E002ovPDHLkV1j}>SF`{C literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/ERT_empty.png b/Resources/Textures/Clothing/id_cards.rsi/ERT_empty.png new file mode 100644 index 0000000000000000000000000000000000000000..2050b3362ce02cceee8d02f11bbf06c446ec90ef GIT binary patch literal 836 zcmV-K1H1f*P)Fy-sp`?EDrq|*0UhjOW?8M1bf46(@ai8z~e&6>yxYo7)4+_Ij zg<+@`?S1mG!2piq=p}V@bR>#rY99lKQoV+vkjd$@*Ev|L*Me3aGASjNWf>DUUi`{$TU!8pw)Z!#>tb0JQc7d?JXot_ zU^pBK;NPaTdeCd}sFgp?9^S_DAWc)Gl#Is@c)R&2Y;E!RUY)BpV1tq0Ma!5px|p=OY0x;2W7YahDfRa O0000ZKbfm&+m|-2I|UrwdPB{Rr1}5t&ay?!3X} za#?g;r%)(h8}Q!SQLI+0VHgIMWu;u4i-BqI>gp<$N(IMplK5yeN=(e^OeKhGtm`_O zrjgI*F-?=NYeQhjuL0P`#Kh9l5|(8#9*-pm0`#5)zkKI!06LsxVK2%;tyaTzUB=_F92^{|XEI>hwkV}A z3}Y_#LIbvK3xH{wXqpDV@$qpA z{NcC5WPQA5TFt#l88(Q(aTY{GG7ZGwN~MyT55q7MJe`Fw4Do#*(=^%I+CoIQ?nGH= zG#aV@DW%dGnBKADI2;`v0g!w6Cjk8qbZ$I2JT(iuySud8?X0~4;JPlIPA4)kYaoUL zjPC6K@Ldb2wzx%=zpgF=lTu7;Ft`SQ$U^|u*46;H`qt09QG&aVudu(r55RCZoIi$2 zP5g}R?L^>MttwO@pU)G9A)2NoCSHH^8-J{?18`~U9}L4l(=@^`1mK6A7`&f=W2FrA zdOZb94r#Rottz*w(Qth8GNuW>?-Pb0gTXZp>#xE3I#+Jr=E*1T!pRAZ&GmXclu~ox zWYe<~#bQwm!@zNzqy*!ems4xDx3^JBA@VT*g~CsBKlXhe5yA7kOmJofX0x#L+4}$- z5jErH<|az1q*N;_zs&VQ5Cn(_{eFKTI9BE&%d*6>tfU#^3nT{D>-D4z5T$!C7yvN) z-k+w-d%*KNB_h&nHdC)!y|VOn;;0t<#I0!PB@E#rfG_8 z+sUQWZnyC~52e&I*Z52Z;$8sg_xmWNPVMUF)xyW<1SSB!@1HC9LKlklAF97;wm(^b literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/ERT_leader.png b/Resources/Textures/Clothing/id_cards.rsi/ERT_leader.png new file mode 100644 index 0000000000000000000000000000000000000000..1a58bb35945db8561e99a6f233a8a5b6877ca654 GIT binary patch literal 892 zcmV-?1B3jDP)Q*52r5WQlEFjf{DDH2bPaUq*r8brfh3(X zct|LrHs;zPX+>KQ0c{y#BujTEIZH`>G7XJh2kD-4J|R1CGS%Ph-up@4@B99~@Au#c zNBBRWSS-q7u_&kQ&Ao48fP6k5FUhT~EiqY>c^|}%@sbFNUa=_ z7(mx`0A7Fk2LNAud=miA^YDEi-}e>oJ8{5q9O*cY)ODT3#YIY`60Ym2{eHg>pq!Y* zp)wHnSl4wlO(U1fVVWl2R(e2>=f6H6cy&>U$Y!%xmc?K&kYN~#w-zuZTnT*R>CDg1 zvoQCV;MGN*|N9vWbC1>jWES2i1BF6C0vLvo+I#r5uE>Fr3-IMHKLT(jdjo)MHjC$Z zG@DJfx3|TC9I$O$3L$0^U%LGgfL!i1rfKrs?+XB!ACB9wy1EL0Wm)R?GX>bTEdfl^ zMAI|?c6WCZ#23ErsrtBP5|eF!p@2%Ig6DZiDdp4_#KfgiDX|_!5%<43o+3`WFbw1R z`Z`id@@G51^fn{}OrF?vU3PYM0La{Z3P9(qP83D^y0E#qse(35K&@7z*=z!&1;pe4 z{aa4}xKjtpb*@q7+2`}XxD}J=cF&DS?*g#2v;@FUz4H`b^vLHQ(Q35-==FN(YbeB6 zPyg1FA#sd)8OlR@qbNetG$rDrd%yAL$_fC-*Z;;a3^Yw6iXs3`eeeUVe_FI!W8xSI z0qu5M0OLzqu0y@dwes+DaP=gn2|*ALMG@WZIbK$e!O9A!u3zV`E2m*J8e(znb{io? zidY?b??RzakcMI4x~^)$;Ofal&Bn$CLI|Y13_w2rDD}rd5Fn*Y%>8LdUBgKivNz5E zu){EnYinx=AylhQocKAFg)j_}Qqt*k4m9MZ7Fm`hEz442j0Z?eT&-4B8(?U6x7!6^ z?|Z)=rVb+C_l1;F)@rrHt5&U66Lp6no+$v5H)45tSX4#DRN!C;@R606LuxLWq4+{ic}t7>&pzKoA7)l=uioi18mWv~_j^ Sj1mC=0000GOTR-}k)- zH@eaPLHT@M<@0$pZtR`64F)g_BYLEckB`M$H&7@Plv0Y-)m3y|XLolO*L6{9vh|s5;+aMYf&iryp65*jM;iN* zWm(FytT>F(1`>f678c?*z_8ryb{l|;=lx|GyAQNlEuoZBwOTDU5rLDs3V5OcNUw-W zr4sK60F6e2APC50GH(oyIgpb;-9c0O;JN2Bz&J=$)z2DROeBbZ)d+))8 zF7!6Ywr#O(Tk>M>ylF5%sZ>gaq}^_-@i~Pz0j^f7V%xTO?Ka-~ZCuxl=`x*!b2U({ zR;604imvOFN+ni-)n*)XT^GYJuq-R%;#>@jgBKSUaU6$wy`IL0!(nP-QfKOcq{h0g zqiGt&ViD6c`N16k1D=2S8TR9i)WqD}9F}D<8jYma>#5f^kkeclec#ZTpPvT@Za&`N zn*S$HoP{(#-V3i}pi-&)FZh?QFCW9>@9#eR3xE*fEI11cheKS~rO{|G8jWOse_y?n zfpWPlN+}G(n2J68RtMn5y#oM>#eXqPlOLad0Km1eGOVw!17KNJ`u|J=<#Jg7Ow&Zu zGysl{jxyjcej23nlR4vh;w+?PSU(<1vLGUoYajtTj*}UWq9_+Uo`ooi2*VK5G}+qP zLPWSpT!xi9cQWfKrLq|q-*LTO=kV|lfWrOX0qB0NbK~B@sae?F-NpC)yuAU?Xf)W{ z+lx(18c5&(!@Exb__+zxnygaek5A@-lTwVU-@guk$bA5omX_jm2OH3Y7t71ES}gzu zgTeGMRO-af@b1$XoTyoY8Wf8~q9{VswA93V51#Sc+8O|txBkH}3^Yw6iXs4BTw123 zx1iNZ!HF^kI-QOJP7Z0U3C$X-wfJ*%>nf%RVHgrc5&iyk4!n0^ZH?vIxB2_4kKp)( zCgwVw4oayhaJuQqfl8$!hG9^z*V7V=Ze7jH+1}npDTT-SeBJGV{(BcV9)c? zGC-W}e!maEXba_@m42$YD(&dyHeRr5SAGw&?mnFb(xB34#b(mMgb_kDW39)&{T zwZSQ8R?sv}DVNLXrR4iQK@gyndg&UU$w1Nz0NrjErPQfi{i>Sz7#+g|APmEE1z+ew aiT(prc5Jst=6VnS0000gr0p zxPfxHEFwasQo*t;0D8S1BH2Zlsey92EC5SOO8^l(ejfyZ3p%^>lyH4pggee`-v>v-`}fe87LNuqLgCKT*=Js_P=L9dC!k&qJd(u zC;-dL%b2D~3uw4r0{rFm+u_TuN2|J!`<6tCE_EPUSwps>FWK(Mm|lU4y}RTnruK8}JWB5Z7IB#ha% z&Dq)6&_vom2nTp*HUaoFn*W?*B2n?_uov384nVC|%Ye_%&jGl*yUVtrQe!_4&1MA7 zQ>(fVnRs{F;sjU)z5;vZN+J(=;7|zz*VoqykoXY_!^&Y?eZ1mT-~@ONd|PV}rl#R~ z?EU^lzu!kGl>tXZrw4Rhmuj_&Wm(Y{q`}>87o`-n%S!<2YmLl@cl+NF5#s0mvkZhL zwzjsS=P-=zc6*rI(Y3z5p2@-o`v)Sz&CSh3@I(WPi;H3yMij<_gM;DAql~26v*CJt zbbbPm{=a`px#z%OFie+idwE-BfLa*1uwr!MBPo{dN21YOe@H}s(;JM}s^#>F;KUtSR5&r-H N002ovPDHLkV1ilJR9*l8 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/RD.png b/Resources/Textures/Clothing/id_cards.rsi/RD.png new file mode 100644 index 0000000000000000000000000000000000000000..a3be1be285a5623d1120f8fa450737fca80ce474 GIT binary patch literal 752 zcmVC+A+r&+BvEa}7Q9^gk$(NJt`)kf^;!4-E!LrBd#a zoSvSl2RD#RCPhR@rBWD%0f1?mh=hx9uLhFIqyUVJi~x9W|Fz>dQmt0KD%^_!KX`O> z6iw3rSYKZUU~+O2P17(8gHov!`0t$zxIK2kuKZwEwr!(n8rf_X$8n@yud7=daKYc+ zeDT(n&X>JwKRBPyht~XAxRHT)JRSmf14V&t+YV%*(P*e^8PIiIlu~TWuZH$!R^~#W zsNdbBF5A>~T>vtfjMwAEp@jhW``fSH{r)!iwYj+o!1VOA7f{nQIXF0oZh;GqdW$G< zw<_fGc|-)I6prHn?Jxo;rGgdkzp-H$*tQKodS3^iJXX0@6$*ud7c>!JYHBKA%(5&F z4-cCrIt{pRfWe&s0G?-`0kB)z3z_h1yRZ$whx3mBOiWCKz(+?%09;&LgvU^+wx7YB z0S_FdrSoOa#GjwPsn#p#{lirL*4UU|4dfvT>@hnZ9FNB(m&*kV?3VU`b_-mk_jUCC zVE|%JbslG)1oq$kc+c_iF-j?FwOVB0BMqd}X$-^gTF?nD7Kac^x&D5 zIYb2ixgVv_6r7!%DL@Rvpz-2YbFrC4wzjsK$!)c&JXQ&1;pL}ShzONRT{f#I!}!RaJcLM z3T`Oi4YCkjBr+FM+&wX12De{tVRa=9KxN%A0Ae9cy*oMVvl!S_35*&$Ty}0e=msDj z(iGVLCIC|6xmd6M<8qgg&1PlnrzUo6z`VH(aC$vz1qM79PHnl?Kb4@ip-Kl=IP$;- zw6nL3cu2!p;Q*}ZHx%#&iTzBFm`{prWuT_sErk$Uf{k%!g#-WiENg!@$V0aO-_ukZ4y7d~ai ztf8kb6)>BTTip@|q16W9I%BY#2t2~Av^5G6niZkn>9 zfi8y4EQuPTMZTtGLc6HxTo>)V&a|bVz)IdtGc%oe-t(Sw?+je)TK|LM(Ws0^qq5yK zan)deo~|wcN|g#<_V#?tn^yr&M5EGefTxp50J4^al&v9LY66Ky#i2&U3a*s3EDjxq zoueboy%Ymp@S~9tD%C0gw|jd5DA>0C??Nu;GjO36#692_Gcy{dz@N9akWz9#7Ss3i zheFh(ls{}+{Idb?a4E2=T7d!X4Gf(5tiNi(U?d^|ZgqFJfE9FZY>a|!(-RB={`i%$ zmPNs~`FVUS&Xqtc9F{_eGr{V7PcX=;Y4WR912|wKtNZv zYMKB%86VeXx&i?{Zf+u_WMX(&pMSr;4#2a?$(9t_CeRF4s#L4wn!uH6l~vP32*KRg zm`(!V_0kfq>mr0`y9cx+a2hykSpYf(HRT^RHnbV9-YhR`pzFFkotW@lSJk&Q;Dsyj zq2mDcCDd%f3k4WWB*<@X12CUTQLt^@imYX^TPy;wTPn3KLm~e7QM*zxEZWucn`kr?~7u&+yd$kg>>~$pM`>L^J;b$K>sf0^E`;h^?m6~hIeag z>^ly-rIKid!zmk4*0PvRCVjp4YB8V30A4o0fUoLwCWC!)g6q1d9q%-?y*L<&NbfW& zE#z_-hJg?QAq3B-rhK!I&SWT-%Sb8tc5ra6O|ESMwOUQ5puhlzQSVr@xpXE&sZs&z zZ9EUSqk)~HBjJMdnt;~j_Q^CgxcNilLI%J;o$c0fv0Ubc5dRET>Ui^=zCIc8Out&1 zhGCq$#}_hix35q3he81CI}Qf;J|-?h9p8oxm<0HK$>3{UOX)W(E@r;)oA3Jo0000< KMNUMnLSTYxRB0su literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/admin.png b/Resources/Textures/Clothing/id_cards.rsi/admin.png new file mode 100644 index 0000000000000000000000000000000000000000..1cbc2004a0e35f22641e5aac47ba3f938c5975e4 GIT binary patch literal 914 zcmV;D18w|?P)u3#d++yq^Zow*yx$vm!3+KmNF)+6 zkx0mKw#nxv21uvV{+2vDI}^_?Ael@`DJAK2ntVQwrfHa_iIk&Bcv1n$WKsg8QYirP z`Mk0jh5^8EIF#LPS7qTz1O$n5xg3#5gfDNaKvVgA`t||CFlaWLp|k%9Z=k#9;1_LxrBb&`K91i8><)wJEfM9dY&(8zkx-Ocgh5Wv}ttt^g z1bab@Sbu2Wx=_kX^^Fbvg@hlhvs`+f1C48&qFDTE-C z$*8XO$$tC(3jn{q{yjvz(Ov++G))Y{z;SlQe*1?4VzHP6&~=?$E~oZCzxm3iZy&}I z|Iz!2!C(*|cG%h3!M1I6-oFu2N;y`*eZ&Bs=W%*GIg;w#tK}Py>t1jiM>S-rRAOyy z4L~&`fDnR-yTq|rOzOJM($bP5FBA$C3I*l2(O%&6c#_lONp`Q6*}Yn(TCD=GzrU~i zB9VxSd~tD6?fX3dV@jawx*8xpX|Y%&nM?vuuh;QBkB#;Mnx+wr-kx1wUk4x>jVj`D zxeP!ek)Y9NaCCG8K)>G~y@o>EUW%ES8H&ZCT6a2~kWkY!0f@)r%+1Z=I1Yd!UR_;P zzCq$%uNS&`p%U1(En2OXTKiGgYBg%L8ufZTB*HKZwP)KlD=RC?7L7(RO_S~IZ7j>8 z*XxP9*6YoBZHOAv{ zSt^y(+Vea`UaQq87K?0cZ2{NKH9b8IT$iQQY9XcM{QUeuLvCyahQlF^MkDl^IgW$l zI3vv!i9|3>lXko9XXIZ^*RcY+-L8-~1KSs2+cxELSw#+DS(YNc`=jwt+C#yQ zhYk)7anKwI+Bs|8Xd*}QcC9YIdL50x-L-^A%q~Bg+#Lu zK#%#_aU1~NK6ZI(H`#x$#dIvIk(W$OYzhHO{qvu-=x4+IpI9Vb<5CnSLUDu`4=>X6dS9O`SJRjo6 z0RUb%U+A`bT-@~mP)gOxGZYO#p=i)*Eg2xsVzHoAwbGK52Kc@((&^xx-t`&N0UQU9 jzY>{lLW{*>`Ex!2wSkEyx!Mw<00000NkvXXu0mjfaCEF` diff --git a/Resources/Textures/Clothing/id_cards.rsi/cargo.png b/Resources/Textures/Clothing/id_cards.rsi/cargo.png new file mode 100644 index 0000000000000000000000000000000000000000..3a45ef68e51166711747c9dcaf9e71f65ee8bad1 GIT binary patch literal 972 zcmV;-12g=IP)79^MC?Txk|iFLN?#~-YCCu6cBr(;VxxuH!$5uC-{avm?~*0cuIs$mF9brKB%km5eV*sX z4|cSp|AWHeu!h57ZB>)I4F-tE;{X(kMV6PB8<_Xp4R9n9QB@@#j}wc<0I)0z)#ebk zHGxPZq5%E<{Qw@kCd;zO=kt`yWskcp3Dkpo9_yj2qYD64#TbJz2HUoY#bV_1`G()# zQ3CZn?mp1nQ1f^CnV6VBRT&rmPIC$p<1oVrV&sN}*<2gix!!I4?(9uHxl&U4poIZo9A|hV@MTCuw4exzJ0`=f%G)i^7 z3c#&H z=D+>~fCG=Xdp*BcX);l-+=U_lpMSXoz`(G(e*R8B#u(=2=9rqA0$_D@wRsI|QHuya zeD$#hZl#OYcJYM&4*<$bmng0NM#rArtgTh9#6Y&|DKWKZyd+x z^C2R9S83z%uHQNK)<=Nb#?65L(LlLemRv5U0MTgF`+V@VK@Y5|T>0?|#iBd;H(xaF z$N)5M#Msyvl{I$|Rh6rkuTm%!@cDdO2LG#p`V?vxi>1XS^7%X>vgsag*#O)~!LlrJ uIrq4&zs>w73IqZg2n1T*Xm_-u?a*J&Z?#1Yy`g6S0000DZ}t(5;J5oZ6vXI*4>O32rKs zg51^wFI5OeiDMfMy4>3#xyxPdO#C}F4+M^TFZX-C_j}&&V4{is2kE*lx~@x9?ZJJ6 z0aB@ydrMlamb!NX$z)PQgj6bpVHjwd#=*e>BH2$ik$NRKc41k~Smb~Y6-!}NQwY3Gn z^71k;mU0mgQrTCI9P6A{Yga$pgrX;QD(dnSerxNv|yd!tv#LN*JBAHyd6YSdbNXwPt= zPyp~I!Zb}9jRpXnPA5EuN)7z%*&C1@)D91WFx{62UO(f<<|Y&$@~HBMg~ECu4^d!` zIlPKQA|a(xi9LIR?5jSw4|iAZs#eqaU3>_@la&?t@HJ5XYklVE=m@10XJ=<2)};n! zXJ;`C!`p%|xQ0>+krx2W=k?Hwe^%ZiBKXh!D;aQ2luCnOxnbPd+36*>|I6p|p)Ay^ z?+_7APftgJM;e%(o|a4|Fi=zm=b2l}~3A1W@I`@lR*rc?|ph?R9fKgCT@j?WrL&jJyqO@!xo9j^N zRVlfVT{m5lCNLb6o{@{*)L(1sEToCC8G}(6f}HcdUW6QTnmA*vSL^rc@ILQ3pXdF) z&-0!awzaMQgABvahGFPtG4ZCs0Fg)pfLty|p-}KJcf1L3Fc{QYYa)>d;cyrL%d*hA z(S$8^AQ%j4fWg5*02f}9Wm#l08A_#+%iR(O>cKr9_Rz7b0|2cxN-305*tShL943>= zc;0<22kOD*2c{>s`|aHfuMY!|XiK1!0;(>gQYp&ivVcuGu+i%7_q*Nw6+&?H_AmVW zaheJNScpQL{kr5onp}oBw%d(iBo^D

8LI}|Sb{D;IAP@-X zXf#S+Umw38KMp|fyKh`~q?BB{at(k_OC2w+)#7nDs o%jNU=w9n^jdZXRewzfjg0By&c)uks`(f|Me07*qoM6N<$f)L!yNB{r; literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/civilian-inhand-left.png b/Resources/Textures/Clothing/id_cards.rsi/civilian-inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..f7848f63f6a3f7bd57aa4fd8430f34fe515f8f04 GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=6`n4RAr*7p-ZJDpV8Fw2z(}(} z$nbp5(;%OhA}nvcJB!#4{Q5pY)s7FSmf^wbRj-WCcYC$QCUJ&dy?s~7@%G(cSG*;j zu7CcfzRmY+uSBA7{(&z~+t=O)DF=cRw|?Eu`Tc2Sb<0cLQu7I$uH1Dvb?qtRgW2MO Wy`l3x=dP{=sq%F7b6Mw<&;$UHibqTU literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/civilian-inhand-right.png b/Resources/Textures/Clothing/id_cards.rsi/civilian-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..82b5598806de72b5cd2ed0cb65cee99adbb58df8 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Rh}-6Ar*7p-rC69V8Fw2AmW3y++4=+d%hUb*TI&yrtXKQRQ{ YXFb^-I$!GNix(h8p00i_>zopr0QOu&O#lD@ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/civilian.png b/Resources/Textures/Clothing/id_cards.rsi/civilian.png new file mode 100644 index 0000000000000000000000000000000000000000..050139ae1ffe9a57d4867d69a5abf3b59f900edf GIT binary patch literal 1001 zcmV3=ogU0Vo!WY;0^aalZ00h{NHqsw(k#oLDRdfNk5T9yZ}r z9SDcR3NSo84B(O1VcRzOe4c8x>hYe61C7KzeLZxvcL1QO7-KNTP^;C5#bV_1`KEtg z$brU;BfXKPZ@zOrGMNmj%IN4Q#u&hLA(zXswY4R1LI>)^?|kqU2wdpC;N>eK-1+Vf zs>=BIIJH_0$8kJ2fTmh_E(e0aU=wj89UxjA-rcH~$N1OfpS5#D~k&)oqEDu6Z-H|{Q*&Ehx?V`F1p9Xxjz1OfpCNF)-R z?>P^^{q+(6yQ_NuyxQCDtuoMkiP@Q1RFz~hNv&4H7(*(R0w9%2;W!Sht*zL$&Ft*# z(KXOW+!^Ua2w-nj8_wDYirES%^i*)5C~`@ zkzjCe5P;;&Cm;~{x(k4ZlfRQ5ng+lwFM9teiXhyr7652lc@2Qk3Ag=x=X@ArSYBRc zetsT+?d|QuZCJNjMEG>(V!LH;Hx) zxV8%{EiD})uA@o7=H{jp3I!b;90W&jP%uh)@=p**4Sm%(ox7C+v>CVokuSRNWjetJ zMh$j(k=KonTrP)*93u8M{qGmSU{FU!Mi>|vVB-5R04Cr4(sReMEV8$RwM2K}?#4a!L(+?|v8{=_^|5HG< zT9t)`1qFykqu%@EXGxD(RVn{crdTWj9J*+{kN{}zi0SERw)Wh-Rh9K$*C`YVSeA8S z;%5qIbfJE+c=X#N^7%X>a_o#xEC8OmVB0ne3k!(IGpqX4;rIL1@An^hqdmhJP6Ph{ XmG958iIq)q00000NkvXXu0mjfVL#GF literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/clown.png b/Resources/Textures/Clothing/id_cards.rsi/clown.png new file mode 100644 index 0000000000000000000000000000000000000000..749b1a54718dc50f2aaa52c1d21b00234e2ad55d GIT binary patch literal 977 zcmV;?11|iDP)1v75vnxkVrIZJe~S(b?M4NWCef~@X)4;zLIoF&=r}1Yg%QV}O~|Ge!BRUi znV_PGD-jo^DM?J2tyek~g`$g@j?`(BmZk_}ozcy`=W~(CZ8EvqA3H1iuI|k__dM@? z&-a~NIMkv34+;i@5)1~#ZA{&3FhDF81E5qYv9hw##JulbfJ32>hzPM*j7TH`fN7eD zw1#k?34}r+0qE=N190GVnWjmhP@qz&INSqCpb^~tXgA&?UI0V{tuT{< z=BpV*gwfGaEX%^SZ6^(&sTTH>Kp+qhfR*7=%h*%joCV<23#Skfyhps)wvE;r5y7@? zEX$&;tqs#O$!4=ut5vnD1pI!#D5YG%PZnNtz>RO0$z-r?o8jSMrw;bq1%AI@0OIjD z$GeXM@Xnt@07Ua=0QmOl&z$*_o;hZ}o<&3$85zN{EVR}nlSu%Q$t1RIrP$iqa;}>aXatAD zVX8N)06c#FF93d+ZU^A)+k^jT=Kc08=?~IQ+#*6Ml|pOn)WqWABH3)VX5wxG@pzox z-d+H_r>_HW^4JpqT;9CWVxm!(lV1YxYT$DK5@WUY>p0qh)|!Qd1?J}F0NB{rXl=uK z)JiEHerd@8yJ^xh$6L3at=)Y13%56aC(H@H<0>n|CEmM#rWU(``T6-4u*1B2;XoiD z6B847PhW3(bAa!s9>6dR$K+$L-y+Nj0NRf|1m`-N);jy^6uDdur4(yxYpw)^4pb@?mCxq|ARG=mzmJ?7alj(NwV$q0DwVj% z#XW=n)c`bi#Q69)>%Xl7wZ2~Zd5L1Nh+!D}2JdK~F@^ev#q!l<3WWknsa@~!z74>3 z3Z`k2&*xD}?O4?ZE}zdQKA+F^i}p~5Itcv@V7aJgV9lJB00000NkvXXu0mjf^BUDN literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/creed.png b/Resources/Textures/Clothing/id_cards.rsi/creed.png new file mode 100644 index 0000000000000000000000000000000000000000..995b5ec12dbb59e933d48bffff7ac2e0c5a0c43c GIT binary patch literal 696 zcmV;p0!RIcP)-BACG9V&J01WTU*RV{DOS7^o34JoSn3`h}R zY$cHJ01&|P>5yEyB5#izu@DCYA$|!dk6>dExu;&M7dc{%fiLQ1!rexGLr$vaa2TR0#DPO3^KZyYNU9SVsY&Hwv!C(MDzuy;_Xhhl8xfh0PkKoylXJ=}(kwiR6BA$)@ zZ*?UHH{iiwK)>G?121F%hFi_DEcU{XUCU)ZiTE-aGqX2(+G?fHSHQ027EHF=ZA65V zlatbdztMonLK!#+0z`z@qw%!~Fu=E3f~w~F{!9iYO~AMqO+}lZ@B4*X_--qzN~hDA zsmGK)WZSkbEsam=IF5%8k7^{_7hqVBJEL7VdEU=u0H9W@X|-C-8OUxYqaX<80#7xN z%|hAbB1sY~%OVWJd!4AazHG9PH4w)!A~N$DPt&beG6NM6uCK2Vk*QVv;IeI7ZQGuD e)mmtwdG!yn%_+rYh^RyW0000HRo`Vd_@K_8={OkH>f5bDyksB`A35#S_B2;l)B zfaTM{xz6<;NC+@BKPggt&$Yjw&pr3}!d!Fx5AuCqec#uzn7lL?KqSGaDxFRz!(4m` zaIIETRZYQ0s>LKcYX)kyT4|bXMNver*Gsw2k^uu=US0;E)oKCob*Bx$_ro{oSYA)c zfLY@p2r}cJKOU!GTgJrg?JfO&UuHI7z}wyN*wJQCI@dO14BXt@aB*?*cmvgHRRMN- z#oOGyP72C{Z5b2S*VkNLUdmJkJkL`RnF>5fk22tSo&v0{uBKxjeuo)wZ`)5}_bo%S z*#uyHeLZ91>guX|7Z~uu!a^Zd1~y|HW(}O4o?`kz9LI%ciAc5v@?f*AHgnSQlF5yIpbqtV(S)r(aboCawF%1Qw|91Z~( z3I!vG62a|a~vlz z&`7}bPf5(Yz0t<;aSDA0{BZnC{Ae?v*=!;roS&bU7W};iV7vr*a2SS&2wUx>)xOSw z0d^}fs+#HhQyIvcfN?RNoSY<;JNgAdP^g7(uA-`RyWOdJOz9-ob#-xZyhEcXN+yqL z#O@1_6y%yXEFd#sZ?}nX(?mC-cCkg7|sNqXu!@w+2JCNV;sk!-EKeWi~8Wr zCJVNKD2fn~sn>Xt9z2j3sEBZPcZY~ftm$>W??!=?kTyxE;f4yfTeghk@WB>pF M07*qoM6N<$g0G4`%K!iX literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/debit-elite.png b/Resources/Textures/Clothing/id_cards.rsi/debit-elite.png new file mode 100644 index 0000000000000000000000000000000000000000..9d7c21fb1642348682eafb1834ebe49d27c5fb74 GIT binary patch literal 434 zcmV;j0ZsmiP)77I6H^n+jM~ZtgTUMj2?zuMBojDDW_p%nStc9Y=mZ8;!4l-s z$%*|@vkb9oX;`j1hq*6l`g-r$_j|v-99S$Ci{+o$%1R2v($nM`>h7iDzer@}_cH|u z#Img7tAo#E{cKoT+gn~+SrHnD$mtRuko$Vz^?ZlPpwCIQ!er3rMTsc`H-SU|P9Sjt z2`WD7%B-4Z0vf>g;XMHD(SlB^Nqe+NiUag&ftf* zI*=wV8mi|IsJjte)qPCejTrhxLM1$8Guj!5N%vS*mq60>iwGn_?WnsEyM8YbXF7&P z4mf|TjsOQq6z7r5f%)Ys=GieUpCO>ZZ^yHg)ggLoAC(IYipBzrPD0&Dx9MMp1}CA# cVzF3$01AF~X393p=Kufz07*qoM6N<$f()gr*36JKGhE9XWX()u1HSXQQ=Uwc<5y^L!Pc8+GJf~oGFn^!u+#kP+c;}x=$!6{ zzJZHTTzaDJXb6Bi8nS+{!a`x`x4QL%6&|LRWu34bjzfC;j=-aHx-ZvST%g4TtwxE3 zD@(K*C0dP=6i+larMX}C1ra)eZftA#JjE56Mhib^+Nt164F(yM>@YK+5^&em`v}8%}l1!x;>p%!aVCZDx;3dV| z5jR7Z;w%Ay22XOKjmLIJMp&dTL70P8R7>HYAm{g1Ej`*U-IVYpPp{VanJg5iV5 z>>YmO+PmP{<_6c^MJmSkeOj#+zVD-yLMa7+QVQ2~7uC!sAdX|!fBgjDWPHQv@c}2} zo3uDUwOU0fMGypO@gN8&7K^zBJj^mAvmbo<%GNHtdb7vr@d5qK4PyBe;eAd;09clF zD}Fki-c3Nlrw?y=vGp8)NAd~7vo`ws6<8MCZZ|WoR;v+);oSwmpNFTl#B`&)i%`#W5|-o ziYOEcb7NMv>#X+A`8FQs7Mp7mW^KAeOxCQIb#E{j3go5r#z zV>%0VZdwy52xOWrjAf<;Qd=6Dri0plOdAGhj4PwOdtBU^=|Hiih&xVl7x&$F-}k$} zbMCzlwqh$bF;b_|XPx706z0~VZtdE@)k4b3%CxMk?3u-_TgY1Q)M>N;cCqc$vpcjQ z5#{CO7JMoPCfD4@1#H_)A?4-e3UH_O4gj~e1NBgm7di=X7j@&b0mNZgHVfSP!X4su zwtu@GD%t_JsQ))`8QeI;L9oO7He7`8sJL2MT8P)#6}po-=m3PThiRB;u>I{hxC=g? zPvJi}kgw>s_PqfD;p#>JI%hiVYA;#%w+E9{T(WcAN$5Ia$8rt{D#Ef0YO%X$wx!=UQT{}vXBZ@rMtTuV+@|>VT|G0wQCFw4Ou~} z1w`dl#TY~Bi=`N2 zn3|emcz76q`T2Q)RW*>eT15EhOglASRe`E)w&n^Eex;FQ`T_v=KmL^)$7i7gc<503 z&g+D#!q#?yiHV8F!1-7q;NHD^l1L=9si_G(!9&3)>8{^E;Ary~#jkUIE&(M5jzdjn z6{RODp%jc7Qt5GCHl>V=j36S9feVXX{U8_&YHMpN;c%Fa?+yXb_4ellcO1td))zxW zSlsgffR;c6MQz^I=KadZG^$D_lX>D-Me=;bg%sDNm#ridV70$ zuw?VCs?1)WC6P$rIL?N_PZdz?LPLYSQg7Y7#n{*wBC_rrZ&(04av_yUF*-Vmh&;8b oH$D7*zxw_D|L13NE4Bjo2mUj{_yC=oO8@`>07*qoM6N<$f(bnKL;wH) literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/engineering.png b/Resources/Textures/Clothing/id_cards.rsi/engineering.png new file mode 100644 index 0000000000000000000000000000000000000000..0fed7dcf8034354cd90f54444b313950c9d0c637 GIT binary patch literal 980 zcmV;_11tQAP)_+{S$Pn8??j+SdO;!C+8=!JyPzQ}-GS5RFCw$mjDcE-qFvcianbC=?PAAsUSmi9`S} zO%svY5VkadP$(n-y}i8v9^92_nq;$Cip8SG-I4?bYmZlbL+eT}R zh+x|`mSxe<(12;0q*5u$<+55=0)aq4lu~uUhoAe!16ST%GMU7-Z3YJiy*}9R6a)eR z0f@z7v~{!r@aoY50EhY)0QmZwHgEsg^PP-;HI9fdG&F=|S!k_^$KwFR<8f@;rm?XR z(=-_$AFtm7mEhg&yHV=4&wAiP{R=3ic=kvq2M-?vV7a`^=~Jf>5tLG1{gqOzuC98Y zs}iULhr?mYx5@zQee`1hX6N4o;MmLacQkY6+#`&AIOfGIA|w(CwANlv%*@P?N~IhV ze>V_|#pvnj0igMzw*ctqco={};d+gUN?raj55VB-_W>|4;*6ia*^kzm>FH@ECMEz_ zSy`zaLpN%r6ivHMdf<9Gd%lxbUYY~ok3Sc<_4^`zV+S{j78fra;PW$koY)miO-kVHnca*GE@Z7fLA- ziG;Ix4LovU1fS36eLwo*EKfiAJwVO-{%)#Uf?~0#GMS73gu`L)_o3rM9#}-UI(L

literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/fingerprint0.png b/Resources/Textures/Clothing/id_cards.rsi/fingerprint0.png new file mode 100644 index 0000000000000000000000000000000000000000..f00072064bad889d273e92ebf01dcd4ff7a77bfe GIT binary patch literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ2c9mDAr*7pPV?qEtRUdv`!ec- z(!KvO^A1RJ#3k&?IJRo;k^5(~>^KgFRG!h+4b0kH$xsld(!OEG%WBTf$#<&P&ncch z`~I0n_nG#c7I50Te8qvl1v4ZVCfPh+b;ygc=#f-1PpMw$49yFshOS|XvJxN$YoOxA z;DoBAu3d*>8((&6ZfLr;tHMt-VXnl%`N=&SR|JS_9FckQ=uchIpIX*SN!huRw2%Jw zw@^_NS2qYw4C&DkpCP*4E+;HPRQWLLjw80SySeTpEs1pSx>GH&=erV^X>;gp^xL$} ar`W~c9O99Aw*D2+uMD29elF{r5}E*LNOTwg literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/fingerprint1.png b/Resources/Textures/Clothing/id_cards.rsi/fingerprint1.png new file mode 100644 index 0000000000000000000000000000000000000000..6755d11237764f0be4cb359d27fc53a831874288 GIT binary patch literal 383 zcmV-_0f7FAP)eAp$vB?nG1Az34d_woc}#rb_* z*JNJ((Cgh=N-0)KrFDLnYv&w0=a`6?h}c@o*4o(Cs+W=gA|mG$B!M24s}&D@346w| z$0No^s#+k|qo{l8WmmKT;4|ghwgJF6>d^$MB(C=ONQW~p%lPceOhi+RqYeqoG9J;; dRNuNasz0?7lKpxouKxf4002ovPDHLkV1m{jrz-#e literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/gold-inhand-left.png b/Resources/Textures/Clothing/id_cards.rsi/gold-inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..65957acdfbb523756cec56aa66ec24a8b978a6d8 GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=6`n4RAr*7p-ZJDpV8Fw2z(BJ> z$neM{t@(K`MOfZ?cNVc9`1O5)Y9238EyIshtA3sNyeKGfdW2Kx*XLOi7o5NP>x#F; z)APSy)VKMb?UhIr&Oh+wY5UsyAmu=C;?}R*Iln)xtZsR!TWUUG)0Mjpr>;F^d@x&F Wl_OAIA@SEkkSb4CKbLh*2~7YahDeM6 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/gold-inhand-right.png b/Resources/Textures/Clothing/id_cards.rsi/gold-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..96cdf6d4251b28a129cdf4d9e55b4154a4c92b0b GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=)t)YnAr*7p-rC69;=se=Q0~NN z@<=H2)o(@XMcyYS+|26BwG0Ph)B3g>+XPP9?#-EMd0zS0E7g=|7X3f+ zk6D)d&rN9Q=ojwWAh%6B2QO8mvv4FO#ovCLIwZ; literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/gold.png b/Resources/Textures/Clothing/id_cards.rsi/gold.png new file mode 100644 index 0000000000000000000000000000000000000000..428c081ddb2f847860db6b138b4e7ef1b26de9ce GIT binary patch literal 491 zcmVz$zcAHq+)G6V;IbG7Y|J6_-opqn^iUux4ZtieOGk)3 zc!X*3k(1a%0U3}K0@y5u0U1ezrN{uA1CT?3s1P8=;wR6^3kAF(fGs7+DNvF)t6oVtfE41aMglD@2G5g^jyW`N%$p znfLMy4hLW>y(ZT~=-ft3M<9cRYaz4%A7P6LX2TN~Ar{|z1i?yjsPZ@OARJ+$!@#g+ z8>B2ac$$I1-xVT{&te!raln~t42O#27$7PHXkjtY h0AGuC6pR9D0091U#lP5`U5@|&002ovPDHLkV1j~=ylMad literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/medical.png b/Resources/Textures/Clothing/id_cards.rsi/medical.png new file mode 100644 index 0000000000000000000000000000000000000000..0c3f1ac41b9fcca17e3af7d2bad9e5c08fdbcecc GIT binary patch literal 958 zcmV;v13~AqTAHf6I7GtRGy#dYi~fSD z3u+_V*vqy|g;2g|Dz$-x2<#$^Xe(BgI&)7KgC}G(r8V+YA`?~5&@u4D6qY~UBi6+Re*!Rpoj>ONQ7`W41j5xh}4I0q6q|p zK>-*V8Uk?P6`7_?vJ_Ugy5617r_D_6E$a3fvl z+T{C9r!Rhc=Mvn8_UI+{mlO1j&J%j;7bkWFtE;PZ;EHMt?Ck8Qd_FIg1S;BJP5=;_ zexq*3?a`}n8+Z>qKP}=Jc^iNqpPc8-zp`X98I)3WV0Y8c-thbVGCVxYz`y|4uI&IY z{_$&WI)-78oJ*pVLgXU=dXJ#hy8G=Xh)B(MzbOM16SK3k7>42e$$kkGByT$4%5Unk zDYpz2-Ahd)A{2|orap2F$53m{%E}7;{rxDVNX{i4w?`>VUY^7-43ts~o_)l38=c%w ze+oEdYzF+F21=!p%4V|y5DJCd`?2Ym3lPynbqXuOmGsGW#JBEjy#F5t}d z#?Kq%^LY%zI5zmX2C7r294xke-6EIEp_FR6#>X}QPg5{WlWaDNQtG)~ed6+Zz2fzH g8=h!Sb*hulKW=WWw*pCktN;K207*qoM6N<$f{diMIRF3v literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/meta.json b/Resources/Textures/Clothing/id_cards.rsi/meta.json index 3480e885c2..ecbc01066f 100644 --- a/Resources/Textures/Clothing/id_cards.rsi/meta.json +++ b/Resources/Textures/Clothing/id_cards.rsi/meta.json @@ -1 +1 @@ -{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "assistant", "directions": 1, "delays": [[1.0]]}]} \ No newline at end of file +{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "CE", "directions": 1, "delays": [[1.0]]}, {"name": "CMO", "directions": 1, "delays": [[1.0]]}, {"name": "ERT_empty", "directions": 1, "delays": [[1.0]]}, {"name": "ERT_engineering", "directions": 1, "delays": [[1.0]]}, {"name": "ERT_leader", "directions": 1, "delays": [[1.0]]}, {"name": "ERT_medical", "directions": 1, "delays": [[1.0]]}, {"name": "ERT_security", "directions": 1, "delays": [[1.0]]}, {"name": "HoS", "directions": 1, "delays": [[1.0]]}, {"name": "RD", "directions": 1, "delays": [[1.0]]}, {"name": "TDgreen", "directions": 1, "delays": [[1.0]]}, {"name": "TDred", "directions": 1, "delays": [[1.0]]}, {"name": "admin", "directions": 1, "delays": [[1.0]]}, {"name": "cargo", "directions": 1, "delays": [[1.0]]}, {"name": "centcom", "directions": 1, "delays": [[1.0]]}, {"name": "centcom_old", "directions": 1, "delays": [[1.0]]}, {"name": "civilian", "directions": 1, "delays": [[1.0]]}, {"name": "civilian-inhand-left", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "civilian-inhand-right", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "clown", "directions": 1, "delays": [[1.0]]}, {"name": "creed", "directions": 1, "delays": [[1.0]]}, {"name": "deathsquad", "directions": 1, "delays": [[1.0]]}, {"name": "debit", "directions": 1, "delays": [[1.0]]}, {"name": "debit-elite", "directions": 1, "delays": [[1.0]]}, {"name": "debit-preferred", "directions": 1, "delays": [[1.0]]}, {"name": "emag", "directions": 1, "delays": [[1.0]]}, {"name": "engineering", "directions": 1, "delays": [[1.0]]}, {"name": "fingerprint0", "directions": 1, "delays": [[1.0]]}, {"name": "fingerprint1", "directions": 1, "delays": [[1.0]]}, {"name": "gold", "directions": 1, "delays": [[1.0]]}, {"name": "gold-inhand-left", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "gold-inhand-right", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "medical", "directions": 1, "delays": [[1.0]]}, {"name": "mime", "directions": 1, "delays": [[1.0]]}, {"name": "old", "directions": 1, "delays": [[1.0]]}, {"name": "research", "directions": 1, "delays": [[1.0]]}, {"name": "robot", "directions": 1, "delays": [[0.5, 0.5]]}, {"name": "security", "directions": 1, "delays": [[1.0]]}, {"name": "silver", "directions": 1, "delays": [[1.0]]}, {"name": "syndie", "directions": 1, "delays": [[1.0]]}, {"name": "trader", "directions": 1, "delays": [[1.0]]}]} \ No newline at end of file diff --git a/Resources/Textures/Clothing/id_cards.rsi/mime.png b/Resources/Textures/Clothing/id_cards.rsi/mime.png new file mode 100644 index 0000000000000000000000000000000000000000..cd5d879db53c3e7bf0cc596b26986370a6f609aa GIT binary patch literal 753 zcmVqiwTLhJfd=d;$EEWMYI8hjeTwh=F@bK`ZTpY&{$8jVG0%V;)l0?=-^Gi#MfB?Za@19+ZC7>0B@9bR5u z)I=39O;eOo6M++rKfk9BD`1+Y0L;zJ=^p#Op8}tspX>djZ5Y+s+8O}+`}=sF2Mlk- z#l=Ow2NH1JDe}PYRiRd^AtETH7z_r$n;8L=Qt1keo;Zpky4@}S^?Ds(;wo%xY-pp2 z2zz^bsl@8_I-O2un8bJj2^@xH0$5pD0ie-nWRe(FwOR$B-|qvkv$K-{UtV4U@cjIo zy@pD?Ay`AyG{QNv3!u|dIL_;ojlVKQAE|;|# zmzI`>n_oRLe%*ZEXJKIhfbsYJR0#kS3I%apmne#K0(sZz=H_N9aH4ld@#u{>IXTg7 zNWlGmpP8ANslgMeP$)g*P j1mN-U@%u{ss~@eu>ibMH;Q^_}00000NkvXXu0mjfZf91O literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/old.png b/Resources/Textures/Clothing/id_cards.rsi/old.png new file mode 100644 index 0000000000000000000000000000000000000000..64e7fe8abe3de02c2279a236235db895f231ac42 GIT binary patch literal 905 zcmV;419tq0P)%7{a}>d$yXiVL|yymhSGA_4z*E_j%qsxYCvW z?@A;Rnn)yc(7ODWV1P^}13Ev@H~%nI!(P^5B>k86X@RK zv3JIL)*^33C>D#TD)aO67-N956t=duI5;@4+zTfVfR{g624HAt$nLL*@Zg6Bs47cK zOL(4#@B20lAk+)zP9PqSD?n}~7h2o=X%m23AKXG!8ND`&@B0{IP*r^2$MZZ!Mn-U5 zmuj_2r_+&hB@m0nR7CoMt3OsPxVyS?xs31oEG#V8J{U9w0}aGtF$KtGv)mZJ(X&?B zr~oi`dkz3&3?f2hqk^ikxVVVtc^G5J=koxpuC8)&a$={WQmN?C(UF7j=KD7R*zfF9x>rI~5fQupBEs?UvAu?_9_R+AQYku5I{>`?*>?c^ zeRnyOQe~skV+Nr3P0_}!suT(Zj4`$+c6WEFR?iCQbUM;wAe+rHH8lmm?;ouK@Sb@C zfQQbrz9s^d?v*SQU_Lib^zEnx@9gZbxp~&ChlhvZF|?70@Y{!>I)7TXti3>Xf!lPAkahS832EMy@=DN;y}T<5NLRKn9^4zM5Hg+7Snwb zkH>XpW`@bhNuGZE1pse;|0PfUcmjaqIF!FF_ayK<7~uZh`>1N@+<&2gz{J|x8jj=i zoM8EU9ucv>+)6Gq+d%{F@9&@cfD4VGF^28!Z6+or5D^N6!kN>5dnC7#vnHPJgI23` z;de{OK)c1v3tORXPp|OzpMbb^O(Pd_$K`R+&)z-gS6)bKNk``hY)y!Jsx9llu(@h(@CT&H7haWRS!6O93Wb8p-H`-p!Cg;v(Y~)809C~pgE0o%wuwX{WHOn$ zZ|^CA+8TF0*;zN{ZSyiQF@dVm-`|fh2B@TvN~I{3N&?$VpbGx(t*-&NwEqXUz9Pbf zZ!Vy!3=Iuo+cu8lxM=`&y>M3v1OfpCIDdSyVeHh!_W(F@^a!d-`@VJ@$H5qbs^T~f zwr$hW(t>4KB$G+X<+5xk0l(j`BGMH6&fL2$xOR1kL;}Zg7#J9E`{1s3f#2^}fLJWX zfvy7pJpbD>01VHb2H?Yk@4N5MwJk99?G&oY;NT#(ZDWif9*+YMkH>Kwht}3sEX!hQ zYN~k;)Pg%YI}q9Q*$g~9dm0hp@T-S8^vWRs^5s0|&YVM45fQikBEtImx_e!hKrJ{N z4paWUT#0q^F905R;~@YJ-g^3uW@h(&&%_54ZrrNM$jAuB7`G>umzPNBCqsaN=lgvDJsS>-u;^JZh*k#^6aUc-T zv9U4o}*k)CoKu4*qobpgZk2$_zP|F)6|&hZ9*<|+;D0qxn?m(qasB7(WHK2< literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/robot.png b/Resources/Textures/Clothing/id_cards.rsi/robot.png new file mode 100644 index 0000000000000000000000000000000000000000..9e87091adc9693607f1325c48ac7652145010edb GIT binary patch literal 1139 zcmV-(1dRKMP)UQ$PClP#nkJg2 z$!+FOTxUYT6aa;-27v*b8ON)miQ_nZ$J}~;0Pik$gEdVP<`CwPeZ1eB@Pc9ZmSqj( zXSy5m`Fu}j!IZ~l0n;poUm&VP0Cr{^&+4X5}o(nQ}O0zXXqqz#A~?21iFn>D+KgJ}-e% zXBx}3D1Tk<%TH7&gcM51Vsgv{eOj#-I5SRY@lUl+o)OGQXB()cH^MM{Ug9xr-v}xB zJ)2-YpO@WT&$@~Pxc_x*N=U&5Ae+@FQ^vx#xE%pUL}YLj49jL=_2qHo(2AM-BAQU5yU$6h}m#?uQj*8#22?p>ax08a62%;29sZRJzOib|L-v?gB zrpNNrZ__M!Jp4oh#AMM{6ipF9RLLX?HVi`y!;r&Aha5gS1fc$XWUSd$e&S_>si~>- zzWAB>i3g!?@?XGir!EB>RWdzgd@#V#^pV$Lw$pd|qhAQVg6SzW{jt+FC>BS_PnDJe zx6^f90FJ*r?tslc1G^;;*n>!W zplIzH3Xg!__X}jRSpjI|8X>rzi?|uYT`lRI2~)pL0nq%a$*XT)F*!L&wOVC$b(Qn; z^DA{21wYXPdcar3m`Tj?-S4uSS!6>HCAhB3>+fFUx-J(N7XT=gy!KJ@V;Uq`Jmx;Z zy7&4`}2X9=ID2wRjX5wA)~8 z8y*xvDMewafa|(sGG4Z|ZJYJ=^`3=~lOHoc%q49$;#|Z*MOIpPrsx8S~@d_b8+5y0_c*OEJC@fyDz^`e`XFx7%&%|J2#o*gz@8$;nBo zls9Vr)oHNH^`hy<*fvl~5gf;(V1U}Y8r$33hzQMQbGVzB5%GJ^+kzN|?j1Iwn~)9K zhUV>@{*wf*R4RxFjYearg^!va^MK&QrD<;Ltg5}xfKH4)`|%l>OeUA?T|5|+b>jRZag-j-MV+$V_e*(N)7^QY&69r#kVPPR`t5&OQZEc~H8al?4WSsng z_v`cX^8jpaZlaXpChqss%DDNV61V-|ojbXcJGql#<$pY_mr+*zb|C-&002ovPDHLk FV1m&q9gP40 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/security.png b/Resources/Textures/Clothing/id_cards.rsi/security.png new file mode 100644 index 0000000000000000000000000000000000000000..ade9673563b404955df0c12ee0189a9cce42fe07 GIT binary patch literal 953 zcmV;q14jIbP)Y0i=*+OBq2_6s4&dEcDR_x(Qa z^X9;jj`V*}Fc{QeFsQA@D})zdK6dAyTUDut>tHa3Pa2B@Zx%jMYI+!Q!q0yXfB?w0`g?Uj>WeMN*@ zpWQ-LnV6WsaU5LN_0j+u_QDe-5C{Ym;L{T?H;rBYYX^XH@0>$b={VMb>$(_YP*q&l z#c>?k+S;&fn`|~qrBac7CE)k_RYY2XuRZ+J1J|!EolfJrF5~0l-adHZF7W&P3J{CM z=ov~Z2&%a_Bn6<%IFy~pJz~2;_*0+<6w*-kw^fLNF;Dwm-hB{Y}+Q2 z$+X@B_290aE<_&rYz4mhU>gzPEnxKRQ2;h78{C||iK-$ZUj0Rcot+);b3+34;BYuh zWxE2v>iZu8&^0>)z=^qU{?W|xo3E3)p7P>WRg%dh#u#r;EG{mR&1S169ybt+#TXbE z0O0P03jkc%9iM4oqF!I#$pcUb1OOPDthQh0@lK2}EG#TAH#Y~s*49>Y8`h#05xzTr z-UGMN%IF!ovtI*n>Q0{9z-izIs$KHS$ZOTu1?K1Ho4_?S7+7ClmtwJ~wFGLK*?oWh z+Q&^RJ`LOk-T;0)J3?%C>}38f`4>9L<#LEf6WCky;}-&ffDR1}(cjR*W;Js9#~aby0=8BR5}p&UkyNGM@&yov-!s+Q0?pGpO+~X zi&&O*VDO#>>QksaSgiiKN}*6dMD|_d0~>%xDcH76KA%TK_T1HnE}ze*KA*4U6YY_X bbQt;@6W^cpNfK=T00000NkvXXu0mjf?)Aja literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/silver.png b/Resources/Textures/Clothing/id_cards.rsi/silver.png new file mode 100644 index 0000000000000000000000000000000000000000..6d99f41d13118a1783e9b9b0fdcf0296eaec0912 GIT binary patch literal 667 zcmV;M0%ZM(P)B-E``b=@7bPbZ|L1u#^^@N(&CsqZpwD2cgm_Q>jqs;*c>* zK{{nQ5OfeO1-l#>9RwfrAYJ-ilbG{Q>rM5Wbf4LUDNJb z3}Bij0Ius21VPN1xofdu7yx*lmwNAB8%RE}luJC%TWMi04MfGoVv&44zjBWd0>dzH zT{kxVPYoo+QS$jbwrvAYuh$Vm0IMzhRRdBi1-|dct`7zSB?go{jhz~h;(ouc#+J(^ z0G&<;fNHf0pr#=z7ebKDX7M}^$8ng?=h{{cq=_X-vBb7*gb=EQ+gRH`+8mckB>-Bj z769#bTeaZ(eyo1^^p<4-&}=pVVlAXLux@ch#gb?Xl}ZJGSun%y*{Kf}ot9Vw$qi(& zSOD;{_#S}Xx zTrQU?mc#-CL7=&=8_EVGCs(Hcyd6C!7x_kbc}C$l!wh(!-{Y(H5$!&(Tv8|$a2!YN zd`WR?0LgGTL>O;)#vgH%Znq1-rx)N~-=IDE!uP~)$k#7<`fUs#TQCfR&%wLjqceb& zRXsU+y|NZ+wc1wVTLVZu&r_#aQru`X)MvRCb``G;AX|X=ks1{POePaG$GeKx21sIA zmf92cCEgeyt%ZGxHwK6z&+vVUw`Scx+5-pn!7qnTPifB&2*m&Z002ovPDHLkV1mv- BA#VTx literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/syndie.png b/Resources/Textures/Clothing/id_cards.rsi/syndie.png new file mode 100644 index 0000000000000000000000000000000000000000..fad21260d2e365949c5e783198e63e3a28424853 GIT binary patch literal 683 zcmV;c0#yBpP)q@;Gl}eWHPD!ww90Q zsw2k$OsCTd>`H5mF@`vfxx2el@WKd`;Lr1-V{RCptW3DzE;DW|Jj;OZ`*pCRCa4Q+ zjH%Va{r$aK%Yf&3qLkt?YiI0g&$d8a?T7TJ0nhWqoopDwr=O+<{<7%hgBSHQxQgQ# zfTN=$U{y0BBAo`BU{@`$)7Kn5olX%Elu}rmk8#tWl&bFn7hF~>z`N^f0DhmI0*^!i z7@la7B&iBbL^wP=Y%S#G<|a4MG*H3;b_N3gj)8OFYln&2q&5ZMhwlRrhGA<=6h#0m zmrDiEb6+a8^0PA-a9qFvMvaNwe1EhlyEd)HUS_HVkD`buidZg}s)V-;%w{u{BuUji zFFt=2Pq}(`#k)3TRE+)83wYlPfK`OzIA%N^x4_k+n;pLIOBjY|t*aC?!NwSrQhd0* z1*o8|uJ$Y}p`*L=6Rs#Y|CX>8!i$`nSs)cWF1rcFBpRaYycWy&#ZEd@h z7f4wnZhnU+xry&y-kzniXWcKI2C^(uQtTu5qUkypjLG56KN|mJ0O~v9;^Lx8L#ZT5 z==FLp20v-wp(vDfux^fDYyehKFvc(*k5NiJS=AdgP{0IWu~=*rywz5v{sJ)QH0b={ RRo(yq002ovPDHLkV1jDgIt2g# literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/id_cards.rsi/trader.png b/Resources/Textures/Clothing/id_cards.rsi/trader.png new file mode 100644 index 0000000000000000000000000000000000000000..65a1e25c2b55e4015befb4b60b9d2f8288947a6f GIT binary patch literal 1034 zcmV+l1oiugP)f;+0IslhM|xwQ&=jvyUe`c^6KV{QPXl-Rb7ZQCp_FQaK1 zp-?C*hFu#-&$#5xl8k$vS3Pufbs?q1vMd@K8__h4SS-fa*ckKk^NRbgBXGc%KD(sG zoP3243|}2aN=a*LE2e1@iA0o<^tq09Tmg^ABLU7gpI2kr%NhVTez*ZZ-G_BZDRCcj zV_6oqZ7aBGn&ju_6N|+d85v=5aZ&8ZfZOesLWm5oqdPy{;p|6evsN{Hbr{RCXl`!C zwrwoS!m=!Wx%M+!aUlTx{rv*|Ap*DCEdheTASX&s0PuA6DFC-`-3Fk(p&o$M$Ey?^ zE#T&lH<41(($a!yn%K5YC=>$V-I8~Bw!Fa#kI{+?DJm+GOG`^4s{-lZiHQl~@i+ii zzPrN6wGjZ$ynhBrMR5K5>j)vJJy)wLVcRy{Uw0#=L`q4;>*YLK-r%KI4paU?1=G{h zDuzS3z-47+1cO03Iy$Ips3Z9x$=%=YB7|UlWnERFzM)>3S$nd^5$yv78bHUL-9Nfk(SEfw_kATbZP3LM-SC_!O;TNo~$XTqx4U6 zV`GE9?mpu2IKSTi4en=xvkWAYNuley^!xn^4$#winX1}K00xEzGFF?erVC8~to*r> zdf$U2o12^Hx}Fo9Wx&zom6er@kB>7qH@D~QJZCFTBoac`bqRkTEM{kB zReN>%_Cc;rlzE%q@tptjgyT#J3Bf$I-sDS85tQ-Yfn*Z zPmGd`JUl$5rKO>vp`D$bo12>$7#L7$PEc!3i;;_;pP!ePmlhTl92^`^X-!XRO;2i0 zH#aw&oSd1NnUnPgkcy+Dqm`AFl9G}Y6%~h#hfZlsiI0gI8XA+6laP>*3rz(J zP6d>dlr+>T3r+@uiGzWMffpASG}9?G)F}&11`A*WO=nAnjE01Ygn@{G3rhwu)G0C1 zC<{ymPH0R_XG%u190004WQchCU8YpB zoLsqqDrX3qDNHeA{G98$BV$~kR{Jt7PztWgm|-x^J>BRuY}4%a5L~UX@4BwU0W)+@ z2%nO$+P%J6RY+|6et#fDu&iKAU`k2*?6wEZl>nO79}I_)5RwKgiZH&rue4z_`raNo zgW-5Qc@V145Zdj~U29{?J0oXqF0qDE1T2a6fq zxH4{(3&{teSn-PW8pm|=!~|M4A(XnF;}my(N(fR&