From 375b1c0739cbe92ea818364821df8efe715499be Mon Sep 17 00:00:00 2001 From: SimpleStation14 <130339894+SimpleStation14@users.noreply.github.com> Date: Sat, 4 May 2024 16:38:47 -0700 Subject: [PATCH] Mirror: Criminal record hud icons (#144) ## Mirror of PR #25192: [Criminal record hud icons](https://github.com/space-wizards/space-station-14/pull/25192) from space-wizards [space-wizards](https://github.com/space-wizards)/[space-station-14](https://github.com/space-wizards/space-station-14) ###### `60b9d89e4dbdd8aaad4992a105628297d9480617` PR opened by Arendian at 2024-02-13 19:39:59 UTC PR merged by web-flow at 2024-03-11 03:12:52 UTC --- PR changed 19 files with 230 additions and 40 deletions. The PR had the following labels: - Changes: UI - Changes: Sprites - Status: Needs Review ---

Original Body

> > > > ## About the PR > > Added three more statuses to the criminal record console: Paroled, Suspect, Discharged. > Entities now have a hud icon based on the criminal record linked to the name they are currently showing. > If "Urist McHands" is wanted, anyone that currently shows as being "Urist McHands", even when their real name is not Urist McHands, will show the relevant hud icon to entities wearing a security hud. If Urist McHands is disguised as someone without a criminal record or has no name(middle-aged captain man etc.), they won't show an icon. > > ## Why / Balance > > Icons showing on sechuds will make sechuds more usefull, it will (hopefully) improve security coordination by allowing officers to more easily see who they need to keep track of. > It also gives warden something extra to do. > > ## Technical details > > > When a criminal record is changed, every entity with an IdentityComponent will have their name checked to see if it equals the name of the changed criminal record, if it's equal the person will get the CriminalRecordComponent which holds the icon that needs to be shown on the entity. > If a criminal record is removed, the CriminalRecordComponent will be removed from all entities that currently have the visible name associated with the criminal record. > > If an entity changes identity, all criminal records will be searched to see if the name has a criminal record attached to it. If the name has a record attached to it, the entity will get the CriminalRecordComponent and the corresponding criminal record hud icon until they change their identity again or the criminal record gets removed. > > ## Media > > > https://github.com/space-wizards/space-station-14/assets/137322659/3c9422e6-897f-456f-b54b-8fdc053cb4e1 > > > - [X] I have added screenshots/videos to this PR showcasing its changes ingame, **or** this PR does not require an ingame showcase > > **Changelog** > > > :cl: Dygon > - add: The following criminal record statuses have been added: Suspect, Discharged, Paroled. > - add: Security huds now show an icon on entities that have a visible name linked to a criminal record. >
Co-authored-by: Arendian <137322659+Arendian@users.noreply.github.com> --- ...riminalRecordsConsoleBoundUserInterface.cs | 4 +- .../CriminalRecordsConsoleWindow.xaml.cs | 10 +-- .../Overlays/ShowSecurityIconsSystem.cs | 7 +- .../Administration/Systems/AdminSystem.cs | 2 +- .../Systems/CriminalRecordsConsoleSystem.cs | 64 ++++++++++++++---- .../IdentityManagement/IdentitySystem.cs | 28 ++++---- .../SharedCriminalRecordsConsoleSystem.cs | 50 +++++++++++++- .../Components/IdentityComponent.cs | 3 +- .../SharedIdentitySystem.cs | 5 ++ .../Components/CriminalRecordComponent.cs | 15 ++++ Content.Shared/Security/SecurityStatus.cs | 8 ++- .../criminal-records/criminal-records.ftl | 8 +++ .../Prototypes/StatusEffects/security.yml | 40 +++++++++++ .../security_icons.rsi/hud_discharged.png | Bin 0 -> 152 bytes .../security_icons.rsi/hud_incarcerated.png | Bin 0 -> 139 bytes .../Misc/security_icons.rsi/hud_paroled.png | Bin 0 -> 157 bytes .../Misc/security_icons.rsi/hud_suspected.png | Bin 0 -> 139 bytes .../Misc/security_icons.rsi/hud_wanted.png | Bin 0 -> 158 bytes .../Misc/security_icons.rsi/meta.json | 26 +++++++ 19 files changed, 230 insertions(+), 40 deletions(-) create mode 100644 Content.Shared/Security/Components/CriminalRecordComponent.cs create mode 100644 Resources/Prototypes/StatusEffects/security.yml create mode 100644 Resources/Textures/Interface/Misc/security_icons.rsi/hud_discharged.png create mode 100644 Resources/Textures/Interface/Misc/security_icons.rsi/hud_incarcerated.png create mode 100644 Resources/Textures/Interface/Misc/security_icons.rsi/hud_paroled.png create mode 100644 Resources/Textures/Interface/Misc/security_icons.rsi/hud_suspected.png create mode 100644 Resources/Textures/Interface/Misc/security_icons.rsi/hud_wanted.png create mode 100644 Resources/Textures/Interface/Misc/security_icons.rsi/meta.json diff --git a/Content.Client/CriminalRecords/CriminalRecordsConsoleBoundUserInterface.cs b/Content.Client/CriminalRecords/CriminalRecordsConsoleBoundUserInterface.cs index 88b9c90c2ff..9047624f49b 100644 --- a/Content.Client/CriminalRecords/CriminalRecordsConsoleBoundUserInterface.cs +++ b/Content.Client/CriminalRecords/CriminalRecordsConsoleBoundUserInterface.cs @@ -37,8 +37,8 @@ protected override void Open() SendMessage(new SetStationRecordFilter(type, filterValue)); _window.OnStatusSelected += status => SendMessage(new CriminalRecordChangeStatus(status, null)); - _window.OnDialogConfirmed += (_, reason) => - SendMessage(new CriminalRecordChangeStatus(SecurityStatus.Wanted, reason)); + _window.OnDialogConfirmed += (status, reason) => + SendMessage(new CriminalRecordChangeStatus(status, reason)); _window.OnHistoryUpdated += UpdateHistory; _window.OnHistoryClosed += () => _historyWindow?.Close(); _window.OnClose += Close; diff --git a/Content.Client/CriminalRecords/CriminalRecordsConsoleWindow.xaml.cs b/Content.Client/CriminalRecords/CriminalRecordsConsoleWindow.xaml.cs index 61b5c383315..b259e08e723 100644 --- a/Content.Client/CriminalRecords/CriminalRecordsConsoleWindow.xaml.cs +++ b/Content.Client/CriminalRecords/CriminalRecordsConsoleWindow.xaml.cs @@ -219,16 +219,16 @@ private void FilterListingOfRecords(string text = "") private void SetStatus(SecurityStatus status) { - if (status == SecurityStatus.Wanted) + if (status == SecurityStatus.Wanted || status == SecurityStatus.Suspected) { - GetWantedReason(); + GetReason(status); return; } OnStatusSelected?.Invoke(status); } - private void GetWantedReason() + private void GetReason(SecurityStatus status) { if (_reasonDialog != null) { @@ -237,7 +237,7 @@ private void GetWantedReason() } var field = "reason"; - var title = Loc.GetString("criminal-records-status-wanted"); + var title = Loc.GetString("criminal-records-status-" + status.ToString().ToLower()); var placeholders = _proto.Index(ReasonPlaceholders); var placeholder = Loc.GetString("criminal-records-console-reason-placeholder", ("placeholder", _random.Pick(placeholders.Values))); // just funny it doesn't actually get used var prompt = Loc.GetString("criminal-records-console-reason"); @@ -251,7 +251,7 @@ private void GetWantedReason() if (reason.Length < 1 || reason.Length > _maxLength) return; - OnDialogConfirmed?.Invoke(SecurityStatus.Wanted, reason); + OnDialogConfirmed?.Invoke(status, reason); }; _reasonDialog.OnClose += () => { _reasonDialog = null; }; diff --git a/Content.Client/Overlays/ShowSecurityIconsSystem.cs b/Content.Client/Overlays/ShowSecurityIconsSystem.cs index 77c14c5ef0f..7a4abd05e00 100644 --- a/Content.Client/Overlays/ShowSecurityIconsSystem.cs +++ b/Content.Client/Overlays/ShowSecurityIconsSystem.cs @@ -3,6 +3,7 @@ using Content.Shared.Mindshield.Components; using Content.Shared.Overlays; using Content.Shared.PDA; +using Content.Shared.Security.Components; using Content.Shared.StatusIcon; using Content.Shared.StatusIcon.Components; using Robust.Shared.Prototypes; @@ -74,7 +75,11 @@ private IReadOnlyList DecideSecurityIcon(EntityUid uid) result.Add(icon); } - // Add arrest icons here, WYCI. + if (TryComp(uid, out var record)) + { + if(_prototypeMan.TryIndex(record.StatusIcon.Id, out var criminalIcon)) + result.Add(criminalIcon); + } return result; } diff --git a/Content.Server/Administration/Systems/AdminSystem.cs b/Content.Server/Administration/Systems/AdminSystem.cs index 5760f830016..53eabb1a481 100644 --- a/Content.Server/Administration/Systems/AdminSystem.cs +++ b/Content.Server/Administration/Systems/AdminSystem.cs @@ -134,7 +134,7 @@ public void UpdatePlayerList(ICommonSession player) return value ?? null; } - private void OnIdentityChanged(IdentityChangedEvent ev) + private void OnIdentityChanged(ref IdentityChangedEvent ev) { if (!TryComp(ev.CharacterEntity, out var actor)) return; diff --git a/Content.Server/CriminalRecords/Systems/CriminalRecordsConsoleSystem.cs b/Content.Server/CriminalRecords/Systems/CriminalRecordsConsoleSystem.cs index 84f8ffc2e50..4290726cc40 100644 --- a/Content.Server/CriminalRecords/Systems/CriminalRecordsConsoleSystem.cs +++ b/Content.Server/CriminalRecords/Systems/CriminalRecordsConsoleSystem.cs @@ -12,6 +12,8 @@ using Robust.Server.GameObjects; using Robust.Shared.Player; using System.Diagnostics.CodeAnalysis; +using Content.Shared.IdentityManagement; +using Content.Shared.Security.Components; namespace Content.Server.CriminalRecords.Systems; @@ -71,7 +73,8 @@ private void OnFiltersChanged(Entity ent, ref S private void OnChangeStatus(Entity ent, ref CriminalRecordChangeStatus msg) { // prevent malf client violating wanted/reason nullability - if ((msg.Status == SecurityStatus.Wanted) != (msg.Reason != null)) + if (msg.Status == SecurityStatus.Wanted != (msg.Reason != null) && + msg.Status == SecurityStatus.Suspected != (msg.Reason != null)) return; if (!CheckSelected(ent, msg.Session, out var mob, out var key)) @@ -105,7 +108,7 @@ private void OnChangeStatus(Entity ent, ref Cri var name = RecordName(key.Value); var officer = Loc.GetString("criminal-records-console-unknown-officer"); - if (_idCard.TryFindIdCard(mob.Value, out var id) && id.Comp.FullName is {} fullName) + if (_idCard.TryFindIdCard(mob.Value, out var id) && id.Comp.FullName is { } fullName) officer = fullName; (string, object)[] args; @@ -117,20 +120,32 @@ private void OnChangeStatus(Entity ent, ref Cri // figure out which radio message to send depending on transition var statusString = (oldStatus, msg.Status) switch { - // going from wanted or detained on the spot + // person has been detained (_, SecurityStatus.Detained) => "detained", + // person did something sus + (_, SecurityStatus.Suspected) => "suspected", + // released on parole + (_, SecurityStatus.Paroled) => "paroled", // prisoner did their time - (SecurityStatus.Detained, SecurityStatus.None) => "released", - // going from wanted to none, must have been a mistake - (_, SecurityStatus.None) => "not-wanted", - // going from none or detained, AOS or prisonbreak / lazy secoff never set them to released and they reoffended + (_, SecurityStatus.Discharged) => "released", + // going from any other state to wanted, AOS or prisonbreak / lazy secoff never set them to released and they reoffended (_, SecurityStatus.Wanted) => "wanted", + // person is no longer sus + (SecurityStatus.Suspected, SecurityStatus.None) => "not-suspected", + // going from wanted to none, must have been a mistake + (SecurityStatus.Wanted, SecurityStatus.None) => "not-wanted", + // criminal status removed + (SecurityStatus.Detained, SecurityStatus.None) => "released", + // criminal is no longer on parole + (SecurityStatus.Paroled, SecurityStatus.None) => "not-parole", // this is impossible _ => "not-wanted" }; - _radio.SendRadioMessage(ent, Loc.GetString($"criminal-records-console-{statusString}", args), ent.Comp.SecurityChannel, ent); + _radio.SendRadioMessage(ent, Loc.GetString($"criminal-records-console-{statusString}", args), + ent.Comp.SecurityChannel, ent); UpdateUserInterface(ent); + UpdateCriminalIdentity(name, msg.Status); } private void OnAddHistory(Entity ent, ref CriminalRecordAddHistory msg) @@ -177,7 +192,7 @@ private void UpdateUserInterface(Entity ent) var listing = _stationRecords.BuildListing((owningStation.Value, stationRecords), console.Filter); var state = new CriminalRecordsConsoleState(listing, console.Filter); - if (console.ActiveKey is {} id) + if (console.ActiveKey is { } id) { // get records to display when a crewmember is selected var key = new StationRecordKey(id, owningStation.Value); @@ -198,7 +213,7 @@ private bool CheckSelected(Entity ent, ICommonS { key = null; mob = null; - if (session.AttachedEntity is not {} user) + if (session.AttachedEntity is not { } user) return false; if (!_access.IsAllowed(user, ent)) @@ -207,11 +222,11 @@ private bool CheckSelected(Entity ent, ICommonS return false; } - if (ent.Comp.ActiveKey is not {} id) + if (ent.Comp.ActiveKey is not { } id) return false; // checking the console's station since the user might be off-grid using on-grid console - if (_station.GetOwningStation(ent) is not {} station) + if (_station.GetOwningStation(ent) is not { } station) return false; key = new StationRecordKey(id, station); @@ -229,4 +244,29 @@ private string RecordName(StationRecordKey key) return record.Name; } + + /// + /// Checks if the new identity's name has a criminal record attached to it, and gives the entity the icon that + /// belongs to the status if it does. + /// + public void CheckNewIdentity(EntityUid uid) + { + var name = Identity.Name(uid, EntityManager); + var xform = Transform(uid); + var station = _station.GetStationInMap(xform.MapID); + + if (station != null && _stationRecords.GetRecordByName(station.Value, name) is { } id) + { + if (_stationRecords.TryGetRecord(new StationRecordKey(id, station.Value), + out var record)) + { + if (record.Status != SecurityStatus.None) + { + SetCriminalIcon(name, record.Status, uid); + return; + } + } + } + RemComp(uid); + } } diff --git a/Content.Server/IdentityManagement/IdentitySystem.cs b/Content.Server/IdentityManagement/IdentitySystem.cs index dbd34d74843..ec8412ed1ab 100644 --- a/Content.Server/IdentityManagement/IdentitySystem.cs +++ b/Content.Server/IdentityManagement/IdentitySystem.cs @@ -1,5 +1,6 @@ using Content.Server.Access.Systems; using Content.Server.Administration.Logs; +using Content.Server.CriminalRecords.Systems; using Content.Server.Humanoid; using Content.Shared.Clothing; using Content.Shared.Database; @@ -25,6 +26,7 @@ public class IdentitySystem : SharedIdentitySystem [Dependency] private readonly MetaDataSystem _metaData = default!; [Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly HumanoidAppearanceSystem _humanoid = default!; + [Dependency] private readonly CriminalRecordsConsoleSystem _criminalRecordsConsole = default!; private HashSet _queuedIdentityUpdates = new(); @@ -107,7 +109,9 @@ private void UpdateIdentityInfo(EntityUid uid, IdentityComponent identity) _metaData.SetEntityName(ident, name); _adminLog.Add(LogType.Identity, LogImpact.Medium, $"{ToPrettyString(uid)} changed identity to {name}"); - RaiseLocalEvent(new IdentityChangedEvent(uid, ident)); + var identityChangedEvent = new IdentityChangedEvent(uid, ident); + RaiseLocalEvent(uid, ref identityChangedEvent); + SetIdentityCriminalIcon(uid); } private string GetIdentityName(EntityUid target, IdentityRepresentation representation) @@ -118,6 +122,16 @@ private string GetIdentityName(EntityUid target, IdentityRepresentation represen return representation.ToStringKnown(!ev.Cancelled); } + /// + /// When the identity of a person is changed, searches the criminal records to see if the name of the new identity + /// has a record. If the new name has a criminal status attached to it, the person will get the criminal status + /// until they change identity again. + /// + private void SetIdentityCriminalIcon(EntityUid uid) + { + _criminalRecordsConsole.CheckNewIdentity(uid); + } + /// /// Gets an 'identity representation' of an entity, with their true name being the entity name /// and their 'presumed name' and 'presumed job' being the name/job on their ID card, if they have one. @@ -159,15 +173,3 @@ private IdentityRepresentation GetIdentityRepresentation(EntityUid target, #endregion } - -public sealed class IdentityChangedEvent : EntityEventArgs -{ - public EntityUid CharacterEntity; - public EntityUid IdentityEntity; - - public IdentityChangedEvent(EntityUid characterEntity, EntityUid identityEntity) - { - CharacterEntity = characterEntity; - IdentityEntity = identityEntity; - } -} diff --git a/Content.Shared/CriminalRecords/Systems/SharedCriminalRecordsConsoleSystem.cs b/Content.Shared/CriminalRecords/Systems/SharedCriminalRecordsConsoleSystem.cs index f9fc67c8964..6c51cb77acc 100644 --- a/Content.Shared/CriminalRecords/Systems/SharedCriminalRecordsConsoleSystem.cs +++ b/Content.Shared/CriminalRecords/Systems/SharedCriminalRecordsConsoleSystem.cs @@ -1,8 +1,52 @@ +using Content.Shared.IdentityManagement; +using Content.Shared.IdentityManagement.Components; +using Content.Shared.Security; +using Content.Shared.Security.Components; + namespace Content.Shared.CriminalRecords.Systems; -/// -/// Nothing is predicted just exists for access. -/// public abstract class SharedCriminalRecordsConsoleSystem : EntitySystem { + /// + /// Any entity that has a the name of the record that was just changed as their visible name will get their icon + /// updated with the new status, if the record got removed their icon will be removed too. + /// + public void UpdateCriminalIdentity(string name, SecurityStatus status) + { + var query = EntityQueryEnumerator(); + + while (query.MoveNext(out var uid, out var identity)) + { + if (!Identity.Name(uid, EntityManager).Equals(name)) + continue; + + if (status == SecurityStatus.None) + RemComp(uid); + else + SetCriminalIcon(name, status, uid); + } + } + + /// + /// Decides the icon that should be displayed on the entity based on the security status + /// + public void SetCriminalIcon(string name, SecurityStatus status, EntityUid characterUid) + { + EnsureComp(characterUid, out var record); + + var previousIcon = record.StatusIcon; + + record.StatusIcon = status switch + { + SecurityStatus.Paroled => "SecurityIconParoled", + SecurityStatus.Wanted => "SecurityIconWanted", + SecurityStatus.Detained => "SecurityIconIncarcerated", + SecurityStatus.Discharged => "SecurityIconDischarged", + SecurityStatus.Suspected => "SecurityIconSuspected", + _ => record.StatusIcon + }; + + if(previousIcon != record.StatusIcon) + Dirty(characterUid, record); + } } diff --git a/Content.Shared/IdentityManagement/Components/IdentityComponent.cs b/Content.Shared/IdentityManagement/Components/IdentityComponent.cs index 7bbdeffe907..5e4c4531c17 100644 --- a/Content.Shared/IdentityManagement/Components/IdentityComponent.cs +++ b/Content.Shared/IdentityManagement/Components/IdentityComponent.cs @@ -1,5 +1,4 @@ -using Content.Shared.Humanoid.Prototypes; -using Robust.Shared.Containers; +using Robust.Shared.Containers; using Robust.Shared.Enums; namespace Content.Shared.IdentityManagement.Components; diff --git a/Content.Shared/IdentityManagement/SharedIdentitySystem.cs b/Content.Shared/IdentityManagement/SharedIdentitySystem.cs index a02e00f0b19..ef1c50f63ce 100644 --- a/Content.Shared/IdentityManagement/SharedIdentitySystem.cs +++ b/Content.Shared/IdentityManagement/SharedIdentitySystem.cs @@ -40,3 +40,8 @@ private void OnMaskToggled(Entity ent, ref ItemMaskTog ent.Comp.Enabled = !args.IsToggled; } } +/// +/// Gets called whenever an entity changes their identity. +/// +[ByRefEvent] +public record struct IdentityChangedEvent(EntityUid CharacterEntity, EntityUid IdentityEntity); diff --git a/Content.Shared/Security/Components/CriminalRecordComponent.cs b/Content.Shared/Security/Components/CriminalRecordComponent.cs new file mode 100644 index 00000000000..25fab3f1350 --- /dev/null +++ b/Content.Shared/Security/Components/CriminalRecordComponent.cs @@ -0,0 +1,15 @@ +using Content.Shared.StatusIcon; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Security.Components; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class CriminalRecordComponent : Component +{ + /// + /// The icon that should be displayed based on the criminal status of the entity. + /// + [DataField, AutoNetworkedField] + public ProtoId StatusIcon = "SecurityIconWanted"; +} diff --git a/Content.Shared/Security/SecurityStatus.cs b/Content.Shared/Security/SecurityStatus.cs index 95250a86459..c7fe3766f1f 100644 --- a/Content.Shared/Security/SecurityStatus.cs +++ b/Content.Shared/Security/SecurityStatus.cs @@ -4,12 +4,18 @@ /// Status used in Criminal Records. /// /// None - the default value +/// Suspected - the person is suspected of doing something illegal /// Wanted - the person is being wanted by security /// Detained - the person is detained by security +/// Paroled - the person is on parole +/// Discharged - the person has been released from prison /// public enum SecurityStatus : byte { None, + Suspected, Wanted, - Detained + Detained, + Paroled, + Discharged } diff --git a/Resources/Locale/en-US/criminal-records/criminal-records.ftl b/Resources/Locale/en-US/criminal-records/criminal-records.ftl index 8e8124edcbd..cd73883f06f 100644 --- a/Resources/Locale/en-US/criminal-records/criminal-records.ftl +++ b/Resources/Locale/en-US/criminal-records/criminal-records.ftl @@ -10,8 +10,12 @@ criminal-records-console-status = Status criminal-records-status-none = None criminal-records-status-wanted = Wanted criminal-records-status-detained = Detained +criminal-records-status-suspected = Suspect +criminal-records-status-discharged = Discharged +criminal-records-status-paroled = Paroled criminal-records-console-wanted-reason = [color=gray]Wanted Reason[/color] +criminal-records-console-suspected-reason = [color=gray]Suspected Reason[/color] criminal-records-console-reason = Reason criminal-records-console-reason-placeholder = For example: {$placeholder} @@ -28,9 +32,13 @@ criminal-records-permission-denied = Permission denied ## Security channel notifications criminal-records-console-wanted = {$name} is wanted by {$officer} for: {$reason}. +criminal-records-console-suspected = {$officer} marked {$name} as suspicious because of: {$reason} +criminal-records-console-not-suspected = {$name} is no longer a suspect. criminal-records-console-detained = {$name} has been detained by {$officer}. criminal-records-console-released = {$name} has been released by {$officer}. criminal-records-console-not-wanted = {$name} is no longer wanted. +criminal-records-console-paroled = {$name} has been released on parole by {$officer}. +criminal-records-console-not-parole = {$name} is no longer on parole. criminal-records-console-unknown-officer = ## Filters diff --git a/Resources/Prototypes/StatusEffects/security.yml b/Resources/Prototypes/StatusEffects/security.yml new file mode 100644 index 00000000000..aeb2c1e9d52 --- /dev/null +++ b/Resources/Prototypes/StatusEffects/security.yml @@ -0,0 +1,40 @@ +- type: statusIcon + id: SecurityIcon + abstract: true + priority: 1 + locationPreference: Left + +- type: statusIcon + parent: SecurityIcon + id: SecurityIconDischarged + icon: + sprite: Interface/Misc/security_icons.rsi + state: hud_discharged + +- type: statusIcon + parent: SecurityIcon + id: SecurityIconIncarcerated + icon: + sprite: Interface/Misc/security_icons.rsi + state: hud_incarcerated + +- type: statusIcon + parent: SecurityIcon + id: SecurityIconParoled + icon: + sprite: Interface/Misc/security_icons.rsi + state: hud_paroled + +- type: statusIcon + parent: SecurityIcon + id: SecurityIconSuspected + icon: + sprite: Interface/Misc/security_icons.rsi + state: hud_suspected + +- type: statusIcon + parent: SecurityIcon + id: SecurityIconWanted + icon: + sprite: Interface/Misc/security_icons.rsi + state: hud_wanted diff --git a/Resources/Textures/Interface/Misc/security_icons.rsi/hud_discharged.png b/Resources/Textures/Interface/Misc/security_icons.rsi/hud_discharged.png new file mode 100644 index 0000000000000000000000000000000000000000..2e012349e06af8ca7aa6f8dd857c0e2ec3bf6bdf GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|f;?RuLnNjq zC-nUJKA({tOtm&PHaaeTZy)Ar?*BhMAu%B#VMknt=E|G=3nMph9x^d>H8e1IxJjOk vL(5?!(@kB2*AkKv3il2!`~AO2&5a>dT%`Qh-LT_8(-}Nn{an^LB{Ts5a0@eQ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Misc/security_icons.rsi/hud_incarcerated.png b/Resources/Textures/Interface/Misc/security_icons.rsi/hud_incarcerated.png new file mode 100644 index 0000000000000000000000000000000000000000..1dc03f7b86b387476fea64e2f5e1a667e0c1e5a7 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|Ts>VJLnNjq zujsn?|9k^;$k7-7(~}Ys5^mgh_US(eT+Czx0=1Z3fjtLVAB5#(m8TwX6HaAyWbH91 hPnet&T{KaUVS%~zgZnc-y8#Vk@O1TaS?83{1OUuqF_!=U literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Misc/security_icons.rsi/hud_paroled.png b/Resources/Textures/Interface/Misc/security_icons.rsi/hud_paroled.png new file mode 100644 index 0000000000000000000000000000000000000000..042fb147b1f3f7f13c87e1e80370ff32954c6aa6 GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|!aZFaLnNjq zbG#M!bH0JOrHtcWdSXIC!ixKPeW4e(cJG&nkN^THo45oIvo{lfGC<%Y-r{+{Wa9!2 z2P4j90-=l{0+JgZOln|sn^C^ObKSa%^BfGjT_n$MIw;5qw1UCY)z4*}Q$iB}jPxVJLnNlQ z_8;VBP!wP~-Yr|m8Z;&K&9x`BrjfRF6F3<+sH@-H%&f7frHE&qDM#l7vkYdfzf85J l`Oo$)ymf)0FZ}H{MxJv*OaGtw@fc_zgQu&X%Q~loCIAn^Enfft literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Misc/security_icons.rsi/hud_wanted.png b/Resources/Textures/Interface/Misc/security_icons.rsi/hud_wanted.png new file mode 100644 index 0000000000000000000000000000000000000000..2df379d112042b9e741caf354210cd87f3c72031 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|B0OCjLnNlA z_8sIsV8Fw~zuNi9ZP86h;V*4s7v9ftl=oFS>gcphP~kOGctGmW&zBhk4yu&(GH93` zjgvYiyRy