diff --git a/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs b/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs
index 6eae796856..73f18aec8d 100644
--- a/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs
+++ b/Content.Client/Access/UI/AgentIDCardBoundUserInterface.cs
@@ -18,7 +18,8 @@ namespace Content.Client.Access.UI
{
base.Open();
- _window = new AgentIDCardWindow();
+ _window?.Dispose();
+ _window = new AgentIDCardWindow(this);
if (State != null)
UpdateState(State);
@@ -39,6 +40,11 @@ namespace Content.Client.Access.UI
SendMessage(new AgentIDCardJobChangedMessage(newJob));
}
+ public void OnJobIconChanged(string newJobIcon)
+ {
+ SendMessage(new AgentIDCardJobIconChangedMessage(newJobIcon));
+ }
+
///
/// Update the UI state based on server-sent info
///
@@ -51,6 +57,7 @@ namespace Content.Client.Access.UI
_window.SetCurrentName(cast.CurrentName);
_window.SetCurrentJob(cast.CurrentJob);
+ _window.SetAllowedIcons(cast.Icons);
}
protected override void Dispose(bool disposing)
diff --git a/Content.Client/Access/UI/AgentIDCardWindow.xaml b/Content.Client/Access/UI/AgentIDCardWindow.xaml
index 22bb3cb275..4947cd7f10 100644
--- a/Content.Client/Access/UI/AgentIDCardWindow.xaml
+++ b/Content.Client/Access/UI/AgentIDCardWindow.xaml
@@ -6,5 +6,12 @@
+
+
+
+
+
+
+
diff --git a/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs b/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs
index 1be816f027..beca0c41ba 100644
--- a/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs
+++ b/Content.Client/Access/UI/AgentIDCardWindow.xaml.cs
@@ -1,18 +1,35 @@
-using Robust.Client.UserInterface.CustomControls;
+using Content.Client.Stylesheets;
+using Content.Shared.StatusIcon;
using Robust.Client.AutoGenerated;
+using Robust.Client.GameObjects;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
+using Robust.Shared.Prototypes;
+using System.Numerics;
namespace Content.Client.Access.UI
{
[GenerateTypedNameReferences]
public sealed partial class AgentIDCardWindow : DefaultWindow
{
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+ [Dependency] private readonly IEntitySystemManager _entitySystem = default!;
+ private readonly SpriteSystem _spriteSystem;
+ private readonly AgentIDCardBoundUserInterface _bui;
+
+ private const int JobIconColumnCount = 10;
+
public event Action? OnNameChanged;
public event Action? OnJobChanged;
- public AgentIDCardWindow()
+ public AgentIDCardWindow(AgentIDCardBoundUserInterface bui)
{
RobustXamlLoader.Load(this);
+ IoCManager.InjectDependencies(this);
+ _spriteSystem = _entitySystem.GetEntitySystem();
+ _bui = bui;
NameLineEdit.OnTextEntered += e => OnNameChanged?.Invoke(e.Text);
NameLineEdit.OnFocusExit += e => OnNameChanged?.Invoke(e.Text);
@@ -21,6 +38,51 @@ namespace Content.Client.Access.UI
JobLineEdit.OnFocusExit += e => OnJobChanged?.Invoke(e.Text);
}
+ public void SetAllowedIcons(HashSet icons)
+ {
+ IconGrid.DisposeAllChildren();
+
+ var jobIconGroup = new ButtonGroup();
+ var i = 0;
+ foreach (var jobIconId in icons)
+ {
+ if (!_prototypeManager.TryIndex(jobIconId, out var jobIcon))
+ {
+ continue;
+ }
+
+ String styleBase = StyleBase.ButtonOpenBoth;
+ var modulo = i % JobIconColumnCount;
+ if (modulo == 0)
+ styleBase = StyleBase.ButtonOpenRight;
+ else if (modulo == JobIconColumnCount - 1)
+ styleBase = StyleBase.ButtonOpenLeft;
+
+ // Generate buttons
+ var jobIconButton = new Button
+ {
+ Access = AccessLevel.Public,
+ StyleClasses = { styleBase },
+ MaxSize = new Vector2(42, 28),
+ Group = jobIconGroup,
+ Pressed = i == 0,
+ };
+
+ // Generate buttons textures
+ TextureRect jobIconTexture = new TextureRect
+ {
+ Texture = _spriteSystem.Frame0(jobIcon.Icon),
+ TextureScale = new Vector2(2.5f, 2.5f),
+ Stretch = TextureRect.StretchMode.KeepCentered,
+ };
+
+ jobIconButton.AddChild(jobIconTexture);
+ jobIconButton.OnPressed += _ => _bui.OnJobIconChanged(jobIcon.ID);
+ IconGrid.AddChild(jobIconButton);
+ i++;
+ }
+ }
+
public void SetCurrentName(string name)
{
NameLineEdit.Text = name;
diff --git a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs
index bcfc6fdc01..bf68a55d00 100644
--- a/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs
+++ b/Content.Client/Chemistry/UI/ChemMasterWindow.xaml.cs
@@ -1,5 +1,3 @@
-using System.Linq;
-using System.Numerics;
using Content.Client.Stylesheets;
using Content.Client.UserInterface.Controls;
using Content.Shared.Chemistry;
@@ -7,11 +5,12 @@ using Content.Shared.Chemistry.Reagent;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
-using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Client.Utility;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
+using System.Linq;
+using System.Numerics;
using static Robust.Client.UserInterface.Controls.BoxContainer;
namespace Content.Client.Chemistry.UI
diff --git a/Content.Client/CrewManifest/CrewManifestUi.xaml.cs b/Content.Client/CrewManifest/CrewManifestUi.xaml.cs
index 151d21312a..5cfead0d8b 100644
--- a/Content.Client/CrewManifest/CrewManifestUi.xaml.cs
+++ b/Content.Client/CrewManifest/CrewManifestUi.xaml.cs
@@ -3,7 +3,9 @@ using System.Numerics;
using Content.Shared.CCVar;
using Content.Shared.CrewManifest;
using Content.Shared.Roles;
+using Content.Shared.StatusIcon;
using Robust.Client.AutoGenerated;
+using Robust.Client.GameObjects;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
@@ -100,8 +102,15 @@ public sealed partial class CrewManifestUi : DefaultWindow
private sealed class CrewManifestSection : BoxContainer
{
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+ [Dependency] private readonly IEntitySystemManager _entitySystem = default!;
+ private readonly SpriteSystem _spriteSystem = default!;
+
public CrewManifestSection(string sectionTitle, List entries, IResourceCache cache, CrewManifestSystem crewManifestSystem)
{
+ IoCManager.InjectDependencies(this);
+ _spriteSystem = _entitySystem.GetEntitySystem();
+
Orientation = LayoutOrientation.Vertical;
HorizontalExpand = true;
@@ -122,9 +131,6 @@ public sealed partial class CrewManifestUi : DefaultWindow
AddChild(gridContainer);
- var path = new ResPath("/Textures/Interface/Misc/job_icons.rsi");
- cache.TryGetResource(path, out RSIResource? rsi);
-
foreach (var entry in entries)
{
var name = new RichTextLabel()
@@ -143,25 +149,15 @@ public sealed partial class CrewManifestUi : DefaultWindow
title.SetMessage(entry.JobTitle);
- if (rsi != null)
+ if (_prototypeManager.TryIndex(entry.JobIcon, out var jobIcon))
{
var icon = new TextureRect()
{
TextureScale = new Vector2(2, 2),
- Stretch = TextureRect.StretchMode.KeepCentered
+ Stretch = TextureRect.StretchMode.KeepCentered,
+ Texture = _spriteSystem.Frame0(jobIcon.Icon),
};
- if (rsi.RSI.TryGetState(entry.JobIcon, out _))
- {
- var specifier = new SpriteSpecifier.Rsi(path, entry.JobIcon);
- icon.Texture = specifier.Frame0();
- }
- else if (rsi.RSI.TryGetState("Unknown", out _))
- {
- var specifier = new SpriteSpecifier.Rsi(path, "Unknown");
- icon.Texture = specifier.Frame0();
- }
-
titleContainer.AddChild(icon);
titleContainer.AddChild(title);
}
diff --git a/Content.Client/LateJoin/LateJoinGui.cs b/Content.Client/LateJoin/LateJoinGui.cs
index f569edaddf..d2b4103140 100644
--- a/Content.Client/LateJoin/LateJoinGui.cs
+++ b/Content.Client/LateJoin/LateJoinGui.cs
@@ -5,6 +5,7 @@ using Content.Client.UserInterface.Controls;
using Content.Client.Players.PlayTimeTracking;
using Content.Shared.CCVar;
using Content.Shared.Roles;
+using Content.Shared.StatusIcon;
using Robust.Client.Console;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface;
@@ -233,8 +234,8 @@ namespace Content.Client.LateJoin
Stretch = TextureRect.StretchMode.KeepCentered
};
- var specifier = new SpriteSpecifier.Rsi(new ("/Textures/Interface/Misc/job_icons.rsi"), prototype.Icon);
- icon.Texture = _sprites.Frame0(specifier);
+ var jobIcon = _prototypeManager.Index(prototype.Icon);
+ icon.Texture = _sprites.Frame0(jobIcon.Icon);
jobSelector.AddChild(icon);
var jobLabel = new Label
diff --git a/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs b/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs
index fea1d2397b..eaae35aa8a 100644
--- a/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs
+++ b/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs
@@ -13,6 +13,7 @@ using Content.Shared.Humanoid.Markings;
using Content.Shared.Humanoid.Prototypes;
using Content.Shared.Preferences;
using Content.Shared.Roles;
+using Content.Shared.StatusIcon;
using Content.Shared.Traits;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
@@ -574,7 +575,7 @@ namespace Content.Client.Preferences.UI
foreach (var job in jobs)
{
- var selector = new JobPrioritySelector(job);
+ var selector = new JobPrioritySelector(job, _prototypeManager);
if (!_requirements.IsAllowed(job, out var reason))
{
@@ -1192,7 +1193,7 @@ namespace Content.Client.Preferences.UI
private Label _requirementsLabel;
private Label _jobTitle;
- public JobPrioritySelector(JobPrototype job)
+ public JobPrioritySelector(JobPrototype job, IPrototypeManager prototypeManager)
{
Job = job;
@@ -1222,12 +1223,8 @@ namespace Content.Client.Preferences.UI
Stretch = TextureRect.StretchMode.KeepCentered
};
- if (job.Icon != null)
- {
- var specifier = new SpriteSpecifier.Rsi(new ("/Textures/Interface/Misc/job_icons.rsi"),
- job.Icon);
- icon.Texture = specifier.Frame0();
- }
+ var jobIcon = prototypeManager.Index(job.Icon);
+ icon.Texture = jobIcon.Icon.Frame0();
_requirementsLabel = new Label()
{
diff --git a/Content.Server/Access/Components/AgentIDCardComponent.cs b/Content.Server/Access/Components/AgentIDCardComponent.cs
index cc267034b8..37b6b25229 100644
--- a/Content.Server/Access/Components/AgentIDCardComponent.cs
+++ b/Content.Server/Access/Components/AgentIDCardComponent.cs
@@ -1,7 +1,15 @@
+using Content.Shared.StatusIcon;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set;
+
namespace Content.Server.Access.Components
{
[RegisterComponent]
public sealed class AgentIDCardComponent : Component
{
+ ///
+ /// Set of job icons that the agent ID card can show.
+ ///
+ [DataField("icons", customTypeSerializer: typeof(PrototypeIdHashSetSerializer))]
+ public readonly HashSet Icons = new();
}
}
diff --git a/Content.Server/Access/Systems/AgentIDCardSystem.cs b/Content.Server/Access/Systems/AgentIDCardSystem.cs
index b749dc9769..1b5037e8d5 100644
--- a/Content.Server/Access/Systems/AgentIDCardSystem.cs
+++ b/Content.Server/Access/Systems/AgentIDCardSystem.cs
@@ -4,7 +4,9 @@ using Content.Server.UserInterface;
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Interaction;
+using Content.Shared.StatusIcon;
using Robust.Server.GameObjects;
+using Robust.Shared.Prototypes;
namespace Content.Server.Access.Systems
{
@@ -13,6 +15,7 @@ namespace Content.Server.Access.Systems
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly IdCardSystem _cardSystem = default!;
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
public override void Initialize()
{
@@ -22,6 +25,7 @@ namespace Content.Server.Access.Systems
SubscribeLocalEvent(AfterUIOpen);
SubscribeLocalEvent(OnNameChanged);
SubscribeLocalEvent(OnJobChanged);
+ SubscribeLocalEvent(OnJobIconChanged);
}
private void OnAfterInteract(EntityUid uid, AgentIDCardComponent component, AfterInteractEvent args)
@@ -61,7 +65,7 @@ namespace Content.Server.Access.Systems
if (!TryComp(uid, out var idCard))
return;
- var state = new AgentIDCardBoundUserInterfaceState(idCard.FullName ?? "", idCard.JobTitle ?? "");
+ var state = new AgentIDCardBoundUserInterfaceState(idCard.FullName ?? "", idCard.JobTitle ?? "", component.Icons);
UserInterfaceSystem.SetUiState(ui, state, args.Session);
}
@@ -80,5 +84,20 @@ namespace Content.Server.Access.Systems
_cardSystem.TryChangeFullName(uid, args.Name, idCard);
}
+
+ private void OnJobIconChanged(EntityUid uid, AgentIDCardComponent comp, AgentIDCardJobIconChangedMessage args)
+ {
+ if (!TryComp(uid, out var idCard))
+ {
+ return;
+ }
+
+ if (!_prototypeManager.TryIndex(args.JobIcon, out var jobIcon))
+ {
+ return;
+ }
+
+ _cardSystem.TryChangeJobIcon(uid, jobIcon, idCard);
+ }
}
}
diff --git a/Content.Server/Access/Systems/IdCardConsoleSystem.cs b/Content.Server/Access/Systems/IdCardConsoleSystem.cs
index e33bb946bf..6730a07137 100644
--- a/Content.Server/Access/Systems/IdCardConsoleSystem.cs
+++ b/Content.Server/Access/Systems/IdCardConsoleSystem.cs
@@ -1,4 +1,3 @@
-using System.Linq;
using Content.Server.Station.Systems;
using Content.Server.StationRecords.Systems;
using Content.Shared.Access.Components;
@@ -7,10 +6,12 @@ using Content.Shared.Administration.Logs;
using Content.Shared.Database;
using Content.Shared.Roles;
using Content.Shared.StationRecords;
+using Content.Shared.StatusIcon;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Shared.Containers;
using Robust.Shared.Prototypes;
+using System.Linq;
using static Content.Shared.Access.Components.IdCardConsoleComponent;
namespace Content.Server.Access.Systems;
@@ -129,6 +130,12 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
_idCard.TryChangeFullName(targetId, newFullName, player: player);
_idCard.TryChangeJobTitle(targetId, newJobTitle, player: player);
+ if (_prototype.TryIndex(newJobProto, out var job)
+ && _prototype.TryIndex(job.Icon, out var jobIcon))
+ {
+ _idCard.TryChangeJobIcon(targetId, jobIcon, player: player);
+ }
+
if (!newAccessList.TrueForAll(x => component.AccessLevels.Contains(x)))
{
_sawmill.Warning($"User {ToPrettyString(uid)} tried to write unknown access tag.");
@@ -145,7 +152,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
// I hate that C# doesn't have an option for this and don't desire to write this out the hard way.
// var difference = newAccessList.Difference(oldTags);
- var difference = (newAccessList.Union(oldTags)).Except(newAccessList.Intersect(oldTags)).ToHashSet();
+ var difference = newAccessList.Union(oldTags).Except(newAccessList.Intersect(oldTags)).ToHashSet();
// NULL SAFETY: PrivilegedIdIsAuthorized checked this earlier.
var privilegedPerms = _accessReader.FindAccessTags(privilegedId!.Value).ToHashSet();
if (!difference.IsSubsetOf(privilegedPerms))
@@ -163,7 +170,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
_adminLogger.Add(LogType.Action, LogImpact.Medium,
$"{ToPrettyString(player):player} has modified {ToPrettyString(targetId):entity} with the following accesses: [{string.Join(", ", addedTags.Union(removedTags))}] [{string.Join(", ", newAccessList)}]");
- UpdateStationRecord(uid, targetId, newFullName, newJobTitle, newJobProto);
+ UpdateStationRecord(uid, targetId, newFullName, newJobTitle, job);
}
///
@@ -184,7 +191,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
return privilegedId != null && _accessReader.IsAllowed(privilegedId.Value, reader);
}
- private void UpdateStationRecord(EntityUid uid, EntityUid targetId, string newFullName, string newJobTitle, string newJobProto)
+ private void UpdateStationRecord(EntityUid uid, EntityUid targetId, string newFullName, string newJobTitle, JobPrototype? newJobProto)
{
if (_station.GetOwningStation(uid) is not { } station
|| !EntityManager.TryGetComponent(targetId, out var keyStorage)
@@ -197,10 +204,10 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
record.Name = newFullName;
record.JobTitle = newJobTitle;
- if (_prototype.TryIndex(newJobProto, out var job))
+ if (newJobProto != null)
{
- record.JobPrototype = newJobProto;
- record.JobIcon = job.Icon;
+ record.JobPrototype = newJobProto.ID;
+ record.JobIcon = newJobProto.Icon;
}
_record.Synchronize(station);
diff --git a/Content.Server/Access/Systems/IdCardSystem.cs b/Content.Server/Access/Systems/IdCardSystem.cs
index 4fcc2ada53..82a6c45555 100644
--- a/Content.Server/Access/Systems/IdCardSystem.cs
+++ b/Content.Server/Access/Systems/IdCardSystem.cs
@@ -1,4 +1,3 @@
-using System.Linq;
using Content.Server.Administration.Logs;
using Content.Server.Kitchen.Components;
using Content.Server.Popups;
@@ -7,8 +6,10 @@ using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Database;
using Content.Shared.Popups;
+using Content.Shared.StatusIcon;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
+using System.Linq;
namespace Content.Server.Access.Systems
{
@@ -118,6 +119,30 @@ namespace Content.Server.Access.Systems
return true;
}
+ public bool TryChangeJobIcon(EntityUid uid, StatusIconPrototype jobIcon, IdCardComponent? id = null, EntityUid? player = null)
+ {
+ if (!Resolve(uid, ref id))
+ {
+ return false;
+ }
+
+ if (id.JobIcon == jobIcon.ID)
+ {
+ return true;
+ }
+
+ id.JobIcon = jobIcon.ID;
+ Dirty(id);
+
+ if (player != null)
+ {
+ _adminLogger.Add(LogType.Identity, LogImpact.Low,
+ $"{ToPrettyString(player.Value):player} has changed the job icon of {ToPrettyString(id.Owner):entity} to {jobIcon} ");
+ }
+
+ return true;
+ }
+
///
/// Attempts to change the full name of a card.
/// Returns true/false.
diff --git a/Content.Server/Access/Systems/PresetIdCardSystem.cs b/Content.Server/Access/Systems/PresetIdCardSystem.cs
index 3192e45d65..271e16cbf9 100644
--- a/Content.Server/Access/Systems/PresetIdCardSystem.cs
+++ b/Content.Server/Access/Systems/PresetIdCardSystem.cs
@@ -4,6 +4,7 @@ using Content.Server.Station.Components;
using Content.Server.Station.Systems;
using Content.Shared.Access.Systems;
using Content.Shared.Roles;
+using Content.Shared.StatusIcon;
using Robust.Shared.Prototypes;
namespace Content.Server.Access.Systems
@@ -67,8 +68,12 @@ namespace Content.Server.Access.Systems
_accessSystem.SetAccessToJob(uid, job, extended);
- // and also change job title on a card id
_cardSystem.TryChangeJobTitle(uid, job.LocalizedName);
+
+ if (_prototypeManager.TryIndex(job.Icon, out var jobIcon))
+ {
+ _cardSystem.TryChangeJobIcon(uid, jobIcon);
+ }
}
}
}
diff --git a/Content.Server/Station/Systems/StationSpawningSystem.cs b/Content.Server/Station/Systems/StationSpawningSystem.cs
index 02cdcc7e95..7908ffb6b1 100644
--- a/Content.Server/Station/Systems/StationSpawningSystem.cs
+++ b/Content.Server/Station/Systems/StationSpawningSystem.cs
@@ -19,6 +19,7 @@ using Content.Shared.Preferences;
using Content.Shared.Random;
using Content.Shared.Random.Helpers;
using Content.Shared.Roles;
+using Content.Shared.StatusIcon;
using JetBrains.Annotations;
using Robust.Shared.Configuration;
using Robust.Shared.Map;
@@ -220,6 +221,11 @@ public sealed class StationSpawningSystem : EntitySystem
_cardSystem.TryChangeFullName(cardId, characterName, card);
_cardSystem.TryChangeJobTitle(cardId, jobPrototype.LocalizedName, card);
+ if (_prototypeManager.TryIndex(jobPrototype.Icon, out var jobIcon))
+ {
+ _cardSystem.TryChangeJobIcon(cardId, jobIcon, card);
+ }
+
var extendedAccess = false;
if (station != null)
{
diff --git a/Content.Shared/Access/Components/IdCardComponent.cs b/Content.Shared/Access/Components/IdCardComponent.cs
index 578d614f12..31ded30ebd 100644
--- a/Content.Shared/Access/Components/IdCardComponent.cs
+++ b/Content.Shared/Access/Components/IdCardComponent.cs
@@ -1,6 +1,8 @@
using Content.Shared.Access.Systems;
using Content.Shared.PDA;
+using Content.Shared.StatusIcon;
using Robust.Shared.GameStates;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.Access.Components
{
@@ -18,5 +20,13 @@ namespace Content.Shared.Access.Components
[AutoNetworkedField]
[Access(typeof(SharedIdCardSystem), typeof(SharedPdaSystem), typeof(SharedAgentIdCardSystem), Other = AccessPermissions.ReadWrite)]
public string? JobTitle;
+
+ ///
+ /// The state of the job icon rsi.
+ ///
+ [DataField("jobIcon", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ [AutoNetworkedField]
+ public string JobIcon = "JobIconUnknown";
+
}
}
diff --git a/Content.Shared/Access/SharedAgentIDCardSystem.cs b/Content.Shared/Access/SharedAgentIDCardSystem.cs
index 2105f39011..d127b326cc 100644
--- a/Content.Shared/Access/SharedAgentIDCardSystem.cs
+++ b/Content.Shared/Access/SharedAgentIDCardSystem.cs
@@ -23,11 +23,13 @@ namespace Content.Shared.Access.Systems
[Serializable, NetSerializable]
public sealed class AgentIDCardBoundUserInterfaceState : BoundUserInterfaceState
{
+ public readonly HashSet Icons;
public string CurrentName { get; }
public string CurrentJob { get; }
- public AgentIDCardBoundUserInterfaceState(string currentName, string currentJob)
+ public AgentIDCardBoundUserInterfaceState(string currentName, string currentJob, HashSet icons)
{
+ Icons = icons;
CurrentName = currentName;
CurrentJob = currentJob;
}
@@ -54,4 +56,15 @@ namespace Content.Shared.Access.Systems
Job = job;
}
}
+
+ [Serializable, NetSerializable]
+ public sealed class AgentIDCardJobIconChangedMessage : BoundUserInterfaceMessage
+ {
+ public string JobIcon { get; }
+
+ public AgentIDCardJobIconChangedMessage(string jobIcon)
+ {
+ JobIcon = jobIcon;
+ }
+ }
}
diff --git a/Content.Shared/Roles/JobPrototype.cs b/Content.Shared/Roles/JobPrototype.cs
index 25595b3026..cc8a7a6ae9 100644
--- a/Content.Shared/Roles/JobPrototype.cs
+++ b/Content.Shared/Roles/JobPrototype.cs
@@ -1,5 +1,6 @@
using Content.Shared.Access;
using Content.Shared.Players.PlayTimeTracking;
+using Content.Shared.StatusIcon;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
@@ -80,9 +81,10 @@ namespace Content.Shared.Roles
[DataField("jobEntity", customTypeSerializer: typeof(PrototypeIdSerializer))]
public string? JobEntity = null;
- [DataField("icon")] public string Icon { get; } = string.Empty;
+ [DataField("icon", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string Icon { get; } = "JobIconUnknown";
- [DataField("special", serverOnly:true)]
+ [DataField("special", serverOnly: true)]
public JobSpecial[] Special { get; private set; } = Array.Empty();
[DataField("access", customTypeSerializer: typeof(PrototypeIdListSerializer))]
diff --git a/Content.Shared/StatusIcon/Components/StatusIconComponent.cs b/Content.Shared/StatusIcon/Components/StatusIconComponent.cs
index 8d3583c39c..9efe9731c8 100644
--- a/Content.Shared/StatusIcon/Components/StatusIconComponent.cs
+++ b/Content.Shared/StatusIcon/Components/StatusIconComponent.cs
@@ -1,4 +1,4 @@
-using Robust.Shared.GameStates;
+using Robust.Shared.GameStates;
namespace Content.Shared.StatusIcon.Components;
diff --git a/Content.Shared/StatusIcon/StatusIconPrototype.cs b/Content.Shared/StatusIcon/StatusIconPrototype.cs
index 582c6cacf4..2b675f3d60 100644
--- a/Content.Shared/StatusIcon/StatusIconPrototype.cs
+++ b/Content.Shared/StatusIcon/StatusIconPrototype.cs
@@ -1,4 +1,6 @@
-using Robust.Shared.Prototypes;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array;
using Robust.Shared.Utility;
namespace Content.Shared.StatusIcon;
@@ -32,8 +34,17 @@ public class StatusIconData : IComparable
/// but in new convenient prototype form!
///
[Prototype("statusIcon")]
-public sealed class StatusIconPrototype : StatusIconData, IPrototype
+public sealed class StatusIconPrototype : StatusIconData, IPrototype, IInheritingPrototype
{
+ ///
+ [ParentDataField(typeof(AbstractPrototypeIdArraySerializer))]
+ public string[]? Parents { get; }
+
+ ///
+ [NeverPushInheritance]
+ [AbstractDataField]
+ public bool Abstract { get; }
+
///
[IdDataField]
public string ID { get; } = default!;
diff --git a/Resources/Locale/en-US/access/components/agent-id-card-component.ftl b/Resources/Locale/en-US/access/components/agent-id-card-component.ftl
index 2628813db5..17a92f6012 100644
--- a/Resources/Locale/en-US/access/components/agent-id-card-component.ftl
+++ b/Resources/Locale/en-US/access/components/agent-id-card-component.ftl
@@ -3,4 +3,5 @@ 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-card-job-icon-label = Job icon:
agent-id-menu-title = Agent ID Card
diff --git a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
index a4be8db5ad..f9db5d4b51 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
@@ -499,6 +499,58 @@
suffix: Agent
components:
- type: AgentIDCard
+ icons:
+ # TODO figure out a better way of doing this.
+ # Probably by adding a bool or icon-category data-field to the icon prototype?
+ - JobIconDetective
+ - JobIconQuarterMaster
+ - JobIconBotanist
+ - JobIconBoxer
+ - JobIconAtmosphericTechnician
+ - JobIconNanotrasen
+ - JobIconPrisoner
+ - JobIconJanitor
+ - JobIconChemist
+ - JobIconStationEngineer
+ - JobIconSecurityOfficer
+ - JobIconChiefMedicalOfficer
+ - JobIconRoboticist
+ - JobIconChaplain
+ - JobIconLawyer
+ - JobIconUnknown
+ - JobIconLibrarian
+ - JobIconCargoTechnician
+ - JobIconScientist
+ - JobIconResearchAssistant
+ - JobIconGeneticist
+ - JobIconClown
+ - JobIconCaptain
+ - JobIconHeadOfPersonnel
+ - JobIconVirologist
+ - JobIconShaftMiner
+ - JobIconPassenger
+ - JobIconChiefEngineer
+ - JobIconBartender
+ - JobIconHeadOfSecurity
+ - JobIconBrigmedic
+ - JobIconMedicalDoctor
+ - JobIconParamedic
+ - JobIconChef
+ - JobIconWarden
+ - JobIconResearchDirector
+ - JobIconMime
+ - JobIconMusician
+ - JobIconReporter
+ - JobIconPsychologist
+ - JobIconMedicalIntern
+ - JobIconTechnicalAssistant
+ - JobIconServiceWorker
+ - JobIconSecurityCadet
+ - JobIconZookeeper
+ - JobIconSeniorPhysician
+ - JobIconSeniorOfficer
+ - JobIconSeniorEngineer
+ - JobIconSeniorResearcher
- type: ActivatableUI
key: enum.AgentIDCardUiKey.Key
inHandsOnly: true
diff --git a/Resources/Prototypes/Roles/Jobs/Cargo/cargo_technician.yml b/Resources/Prototypes/Roles/Jobs/Cargo/cargo_technician.yml
index 1ae36f0bdd..e199f168a2 100644
--- a/Resources/Prototypes/Roles/Jobs/Cargo/cargo_technician.yml
+++ b/Resources/Prototypes/Roles/Jobs/Cargo/cargo_technician.yml
@@ -4,7 +4,7 @@
description: job-description-cargotech
playTimeTracker: JobCargoTechnician
startingGear: CargoTechGear
- icon: "CargoTechnician"
+ icon: "JobIconCargoTechnician"
supervisors: job-supervisors-qm
access:
- Cargo
diff --git a/Resources/Prototypes/Roles/Jobs/Cargo/quartermaster.yml b/Resources/Prototypes/Roles/Jobs/Cargo/quartermaster.yml
index f4010c4de6..c5d3ed554c 100644
--- a/Resources/Prototypes/Roles/Jobs/Cargo/quartermaster.yml
+++ b/Resources/Prototypes/Roles/Jobs/Cargo/quartermaster.yml
@@ -17,7 +17,7 @@
time: 144000 #40 hrs
weight: 10
startingGear: QuartermasterGear
- icon: "QuarterMaster"
+ icon: "JobIconQuarterMaster"
supervisors: job-supervisors-captain
canBeAntag: false
access:
diff --git a/Resources/Prototypes/Roles/Jobs/Cargo/salvage_specialist.yml b/Resources/Prototypes/Roles/Jobs/Cargo/salvage_specialist.yml
index 46bd2c7201..924357bf53 100644
--- a/Resources/Prototypes/Roles/Jobs/Cargo/salvage_specialist.yml
+++ b/Resources/Prototypes/Roles/Jobs/Cargo/salvage_specialist.yml
@@ -9,7 +9,7 @@
time: 10800 # 3 hrs
- !type:OverallPlaytimeRequirement
time: 36000 #10 hrs
- icon: "ShaftMiner"
+ icon: "JobIconShaftMiner"
startingGear: SalvageSpecialistGear
supervisors: job-supervisors-qm
access:
diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/assistant.yml b/Resources/Prototypes/Roles/Jobs/Civilian/assistant.yml
index 965adcd82c..0f7866f1a6 100644
--- a/Resources/Prototypes/Roles/Jobs/Civilian/assistant.yml
+++ b/Resources/Prototypes/Roles/Jobs/Civilian/assistant.yml
@@ -4,7 +4,7 @@
description: job-description-passenger
playTimeTracker: JobPassenger
startingGear: PassengerGear
- icon: "Passenger"
+ icon: "JobIconPassenger"
supervisors: job-supervisors-everyone
access:
- Maintenance
diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/bartender.yml b/Resources/Prototypes/Roles/Jobs/Civilian/bartender.yml
index b64d2c8230..33d988749a 100644
--- a/Resources/Prototypes/Roles/Jobs/Civilian/bartender.yml
+++ b/Resources/Prototypes/Roles/Jobs/Civilian/bartender.yml
@@ -8,7 +8,7 @@
department: Civilian
time: 1800
startingGear: BartenderGear
- icon: "Bartender"
+ icon: "JobIconBartender"
supervisors: job-supervisors-hop
access:
- Service
diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/botanist.yml b/Resources/Prototypes/Roles/Jobs/Civilian/botanist.yml
index fe4e93cc0b..2647a93eec 100644
--- a/Resources/Prototypes/Roles/Jobs/Civilian/botanist.yml
+++ b/Resources/Prototypes/Roles/Jobs/Civilian/botanist.yml
@@ -4,7 +4,7 @@
description: job-description-botanist
playTimeTracker: JobBotanist
startingGear: BotanistGear
- icon: "Botanist"
+ icon: "JobIconBotanist"
supervisors: job-supervisors-hop
access:
- Service
diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/chaplain.yml b/Resources/Prototypes/Roles/Jobs/Civilian/chaplain.yml
index 3840b9ca00..300af57cd4 100644
--- a/Resources/Prototypes/Roles/Jobs/Civilian/chaplain.yml
+++ b/Resources/Prototypes/Roles/Jobs/Civilian/chaplain.yml
@@ -4,7 +4,7 @@
description: job-description-chaplain
playTimeTracker: JobChaplain
startingGear: ChaplainGear
- icon: "Chaplain"
+ icon: "JobIconChaplain"
supervisors: job-supervisors-hop
access:
- Chapel
diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/chef.yml b/Resources/Prototypes/Roles/Jobs/Civilian/chef.yml
index fe0c7e791d..ff9a0ab477 100644
--- a/Resources/Prototypes/Roles/Jobs/Civilian/chef.yml
+++ b/Resources/Prototypes/Roles/Jobs/Civilian/chef.yml
@@ -8,7 +8,7 @@
department: Civilian
time: 1800
startingGear: ChefGear
- icon: "Chef"
+ icon: "JobIconChef"
supervisors: job-supervisors-hop
access:
- Service
diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/clown.yml b/Resources/Prototypes/Roles/Jobs/Civilian/clown.yml
index 8958163ee0..23c70d79cc 100644
--- a/Resources/Prototypes/Roles/Jobs/Civilian/clown.yml
+++ b/Resources/Prototypes/Roles/Jobs/Civilian/clown.yml
@@ -4,7 +4,7 @@
description: job-description-clown
playTimeTracker: JobClown
startingGear: ClownGear
- icon: "Clown"
+ icon: "JobIconClown"
supervisors: job-supervisors-hop
access:
- Theatre
diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/janitor.yml b/Resources/Prototypes/Roles/Jobs/Civilian/janitor.yml
index 4f668d3dd8..c701ed67ee 100644
--- a/Resources/Prototypes/Roles/Jobs/Civilian/janitor.yml
+++ b/Resources/Prototypes/Roles/Jobs/Civilian/janitor.yml
@@ -4,7 +4,7 @@
description: job-description-janitor
playTimeTracker: JobJanitor
startingGear: JanitorGear
- icon: "Janitor"
+ icon: "JobIconJanitor"
supervisors: job-supervisors-hop
access:
- Janitor
diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/lawyer.yml b/Resources/Prototypes/Roles/Jobs/Civilian/lawyer.yml
index 947877f822..34a3ac74ac 100644
--- a/Resources/Prototypes/Roles/Jobs/Civilian/lawyer.yml
+++ b/Resources/Prototypes/Roles/Jobs/Civilian/lawyer.yml
@@ -7,7 +7,7 @@
- !type:OverallPlaytimeRequirement
time: 36000 # 10 hrs
startingGear: LawyerGear
- icon: "Lawyer"
+ icon: "JobIconLawyer"
supervisors: job-supervisors-hop
access:
- Service
diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/librarian.yml b/Resources/Prototypes/Roles/Jobs/Civilian/librarian.yml
index b80827dfa9..8a3e2adaa3 100644
--- a/Resources/Prototypes/Roles/Jobs/Civilian/librarian.yml
+++ b/Resources/Prototypes/Roles/Jobs/Civilian/librarian.yml
@@ -4,7 +4,7 @@
description: job-description-librarian
playTimeTracker: JobLibrarian
startingGear: LibrarianGear
- icon: "Librarian"
+ icon: "JobIconLibrarian"
supervisors: job-supervisors-hop
access:
- Service
diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/mime.yml b/Resources/Prototypes/Roles/Jobs/Civilian/mime.yml
index e2fc390b46..43e0e7dc97 100644
--- a/Resources/Prototypes/Roles/Jobs/Civilian/mime.yml
+++ b/Resources/Prototypes/Roles/Jobs/Civilian/mime.yml
@@ -7,7 +7,7 @@
- !type:OverallPlaytimeRequirement
time: 14400 #4 hrs
startingGear: MimeGear
- icon: "Mime"
+ icon: "JobIconMime"
supervisors: job-supervisors-hop
access:
- Theatre
diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/musician.yml b/Resources/Prototypes/Roles/Jobs/Civilian/musician.yml
index 655b8972eb..f50825945a 100644
--- a/Resources/Prototypes/Roles/Jobs/Civilian/musician.yml
+++ b/Resources/Prototypes/Roles/Jobs/Civilian/musician.yml
@@ -4,7 +4,7 @@
description: job-description-musician
playTimeTracker: JobMusician
startingGear: MusicianGear
- icon: "Musician"
+ icon: "JobIconMusician"
supervisors: job-supervisors-hire
access:
- Maintenance # TODO Remove maint access for all gimmick jobs once access work is completed
diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/service_worker.yml b/Resources/Prototypes/Roles/Jobs/Civilian/service_worker.yml
index 16bb5737d8..c4e1dd1dfb 100644
--- a/Resources/Prototypes/Roles/Jobs/Civilian/service_worker.yml
+++ b/Resources/Prototypes/Roles/Jobs/Civilian/service_worker.yml
@@ -4,7 +4,7 @@
description: job-description-serviceworker
playTimeTracker: JobServiceWorker
startingGear: ServiceWorkerGear
- icon: "ServiceWorker"
+ icon: "JobIconServiceWorker"
supervisors: job-supervisors-service
canBeAntag: false
access:
diff --git a/Resources/Prototypes/Roles/Jobs/Command/captain.yml b/Resources/Prototypes/Roles/Jobs/Command/captain.yml
index 7147adca11..a8cfc426fa 100644
--- a/Resources/Prototypes/Roles/Jobs/Command/captain.yml
+++ b/Resources/Prototypes/Roles/Jobs/Command/captain.yml
@@ -18,7 +18,7 @@
time: 54000 # 15 hours
weight: 20
startingGear: CaptainGear
- icon: "Captain"
+ icon: "JobIconCaptain"
requireAdminNotify: true
joinNotifyCrew: true
supervisors: job-supervisors-centcom
diff --git a/Resources/Prototypes/Roles/Jobs/Command/centcom_official.yml b/Resources/Prototypes/Roles/Jobs/Command/centcom_official.yml
index 396b7a487b..c6088122dc 100644
--- a/Resources/Prototypes/Roles/Jobs/Command/centcom_official.yml
+++ b/Resources/Prototypes/Roles/Jobs/Command/centcom_official.yml
@@ -5,7 +5,7 @@
playTimeTracker: JobCentralCommandOfficial
setPreference: false
startingGear: CentcomGear
- icon: "Nanotrasen"
+ icon: "JobIconNanotrasen"
supervisors: job-supervisors-hos
canBeAntag: false
accessGroups:
diff --git a/Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml b/Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml
index 23b0c315ad..2aa0f313f2 100644
--- a/Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml
+++ b/Resources/Prototypes/Roles/Jobs/Command/head_of_personnel.yml
@@ -18,7 +18,7 @@
time: 36000 # 10 hours
weight: 20
startingGear: HoPGear
- icon: "HeadOfPersonnel"
+ icon: "JobIconHeadOfPersonnel"
requireAdminNotify: true
supervisors: job-supervisors-captain
canBeAntag: false
diff --git a/Resources/Prototypes/Roles/Jobs/Engineering/atmospheric_technician.yml b/Resources/Prototypes/Roles/Jobs/Engineering/atmospheric_technician.yml
index 9e7bd7ec74..5c3f42693a 100644
--- a/Resources/Prototypes/Roles/Jobs/Engineering/atmospheric_technician.yml
+++ b/Resources/Prototypes/Roles/Jobs/Engineering/atmospheric_technician.yml
@@ -8,7 +8,7 @@
department: Engineering
time: 54000 # 15 hrs
startingGear: AtmosphericTechnicianGear
- icon: "AtmosphericTechnician"
+ icon: "JobIconAtmosphericTechnician"
supervisors: job-supervisors-ce
access:
- Maintenance
diff --git a/Resources/Prototypes/Roles/Jobs/Engineering/chief_engineer.yml b/Resources/Prototypes/Roles/Jobs/Engineering/chief_engineer.yml
index 231f87f967..713117b10b 100644
--- a/Resources/Prototypes/Roles/Jobs/Engineering/chief_engineer.yml
+++ b/Resources/Prototypes/Roles/Jobs/Engineering/chief_engineer.yml
@@ -17,7 +17,7 @@
time: 144000 #40 hrs
weight: 10
startingGear: ChiefEngineerGear
- icon: "ChiefEngineer"
+ icon: "JobIconChiefEngineer"
requireAdminNotify: true
supervisors: job-supervisors-captain
canBeAntag: false
diff --git a/Resources/Prototypes/Roles/Jobs/Engineering/senior_engineer.yml b/Resources/Prototypes/Roles/Jobs/Engineering/senior_engineer.yml
index 4e3e795a08..ba7eb3a9e8 100644
--- a/Resources/Prototypes/Roles/Jobs/Engineering/senior_engineer.yml
+++ b/Resources/Prototypes/Roles/Jobs/Engineering/senior_engineer.yml
@@ -14,7 +14,7 @@
department: Engineering
time: 216000 # 60 hrs
startingGear: SeniorEngineerGear
- icon: "SeniorEngineer"
+ icon: "JobIconSeniorEngineer"
supervisors: job-supervisors-ce
access:
- Maintenance
diff --git a/Resources/Prototypes/Roles/Jobs/Engineering/station_engineer.yml b/Resources/Prototypes/Roles/Jobs/Engineering/station_engineer.yml
index 4123ece913..c77f79ccfc 100644
--- a/Resources/Prototypes/Roles/Jobs/Engineering/station_engineer.yml
+++ b/Resources/Prototypes/Roles/Jobs/Engineering/station_engineer.yml
@@ -8,7 +8,7 @@
department: Engineering
time: 14400 #4 hrs
startingGear: StationEngineerGear
- icon: "StationEngineer"
+ icon: "JobIconStationEngineer"
supervisors: job-supervisors-ce
access:
- Maintenance
diff --git a/Resources/Prototypes/Roles/Jobs/Engineering/technical_assistant.yml b/Resources/Prototypes/Roles/Jobs/Engineering/technical_assistant.yml
index 06d3c74ce2..0127be9cca 100644
--- a/Resources/Prototypes/Roles/Jobs/Engineering/technical_assistant.yml
+++ b/Resources/Prototypes/Roles/Jobs/Engineering/technical_assistant.yml
@@ -9,7 +9,7 @@
time: 54000 #15 hrs
inverted: true # stop playing intern if you're good at engineering!
startingGear: TechnicalAssistantGear
- icon: "TechnicalAssistant"
+ icon: "JobIconTechnicalAssistant"
supervisors: job-supervisors-engineering
canBeAntag: false
access:
diff --git a/Resources/Prototypes/Roles/Jobs/Fun/emergencyresponseteam.yml b/Resources/Prototypes/Roles/Jobs/Fun/emergencyresponseteam.yml
index 4e235a9c80..d71b3423d2 100644
--- a/Resources/Prototypes/Roles/Jobs/Fun/emergencyresponseteam.yml
+++ b/Resources/Prototypes/Roles/Jobs/Fun/emergencyresponseteam.yml
@@ -6,7 +6,7 @@
playTimeTracker: JobERTLeader
setPreference: false
startingGear: ERTLeaderGearEVA
- icon: "Nanotrasen"
+ icon: "JobIconNanotrasen"
supervisors: job-supervisors-centcom
canBeAntag: false
accessGroups:
@@ -51,7 +51,7 @@
playTimeTracker: JobERTEngineer
setPreference: false
startingGear: ERTEngineerGearEVA
- icon: "Nanotrasen"
+ icon: "JobIconNanotrasen"
supervisors: job-supervisors-centcom
canBeAntag: false
accessGroups:
@@ -96,7 +96,7 @@
playTimeTracker: JobERTSecurity
setPreference: false
startingGear: ERTEngineerGearEVA
- icon: "Nanotrasen"
+ icon: "JobIconNanotrasen"
supervisors: job-supervisors-centcom
canBeAntag: false
accessGroups:
@@ -143,7 +143,7 @@
playTimeTracker: JobERTMedical
setPreference: false
startingGear: ERTMedicalGearEVA
- icon: "Nanotrasen"
+ icon: "JobIconNanotrasen"
supervisors: job-supervisors-centcom
canBeAntag: false
accessGroups:
@@ -190,7 +190,7 @@
playTimeTracker: JobERTJanitor
setPreference: false
startingGear: ERTJanitorGearEVA
- icon: "Nanotrasen"
+ icon: "JobIconNanotrasen"
supervisors: job-supervisors-centcom
canBeAntag: false
accessGroups:
diff --git a/Resources/Prototypes/Roles/Jobs/Medical/chemist.yml b/Resources/Prototypes/Roles/Jobs/Medical/chemist.yml
index b98ddbce16..a8bd80cf6e 100644
--- a/Resources/Prototypes/Roles/Jobs/Medical/chemist.yml
+++ b/Resources/Prototypes/Roles/Jobs/Medical/chemist.yml
@@ -8,7 +8,7 @@
department: Medical
time: 14400 #4 hrs
startingGear: ChemistGear
- icon: "Chemist"
+ icon: "JobIconChemist"
supervisors: job-supervisors-cmo
access:
- Medical
diff --git a/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml b/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml
index 2e71cc39aa..d9083d2c8a 100644
--- a/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml
+++ b/Resources/Prototypes/Roles/Jobs/Medical/chief_medical_officer.yml
@@ -19,7 +19,7 @@
time: 144000 #40 hrs
weight: 10
startingGear: CMOGear
- icon: "ChiefMedicalOfficer"
+ icon: "JobIconChiefMedicalOfficer"
requireAdminNotify: true
supervisors: job-supervisors-captain
canBeAntag: false
diff --git a/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml b/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml
index dfae17710d..b10c4a182d 100644
--- a/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml
+++ b/Resources/Prototypes/Roles/Jobs/Medical/medical_doctor.yml
@@ -8,7 +8,7 @@
department: Medical
time: 14400 #4 hrs
startingGear: DoctorGear
- icon: "MedicalDoctor"
+ icon: "JobIconMedicalDoctor"
supervisors: job-supervisors-cmo
access:
- Medical
diff --git a/Resources/Prototypes/Roles/Jobs/Medical/medical_intern.yml b/Resources/Prototypes/Roles/Jobs/Medical/medical_intern.yml
index dba6adeba6..1b4ef7523c 100644
--- a/Resources/Prototypes/Roles/Jobs/Medical/medical_intern.yml
+++ b/Resources/Prototypes/Roles/Jobs/Medical/medical_intern.yml
@@ -9,7 +9,7 @@
time: 54000 # 15 hrs
inverted: true # stop playing intern if you're good at med!
startingGear: MedicalInternGear
- icon: "MedicalIntern"
+ icon: "JobIconMedicalIntern"
supervisors: job-supervisors-medicine
canBeAntag: false
access:
diff --git a/Resources/Prototypes/Roles/Jobs/Medical/paramedic.yml b/Resources/Prototypes/Roles/Jobs/Medical/paramedic.yml
index 392ccd1cd1..d453d4ff2e 100644
--- a/Resources/Prototypes/Roles/Jobs/Medical/paramedic.yml
+++ b/Resources/Prototypes/Roles/Jobs/Medical/paramedic.yml
@@ -10,7 +10,7 @@
- !type:OverallPlaytimeRequirement
time: 54000 # 15 hrs
startingGear: ParamedicGear
- icon: "Paramedic"
+ icon: "JobIconParamedic"
supervisors: job-supervisors-cmo
access:
- Medical
diff --git a/Resources/Prototypes/Roles/Jobs/Medical/senior_physician.yml b/Resources/Prototypes/Roles/Jobs/Medical/senior_physician.yml
index 5fb4e813d9..ac49923eaf 100644
--- a/Resources/Prototypes/Roles/Jobs/Medical/senior_physician.yml
+++ b/Resources/Prototypes/Roles/Jobs/Medical/senior_physician.yml
@@ -14,7 +14,7 @@
department: Medical
time: 216000 # 60 hrs
startingGear: SeniorPhysicianGear
- icon: "SeniorPhysician"
+ icon: "JobIconSeniorPhysician"
supervisors: job-supervisors-cmo
access:
- Medical
diff --git a/Resources/Prototypes/Roles/Jobs/Science/research_assistant.yml b/Resources/Prototypes/Roles/Jobs/Science/research_assistant.yml
index c66ce497eb..03ef192be0 100644
--- a/Resources/Prototypes/Roles/Jobs/Science/research_assistant.yml
+++ b/Resources/Prototypes/Roles/Jobs/Science/research_assistant.yml
@@ -9,7 +9,7 @@
time: 54000 #15 hrs
inverted: true # stop playing intern if you're good at science!
startingGear: ResearchAssistantGear
- icon: "ResearchAssistant"
+ icon: "JobIconResearchAssistant"
supervisors: job-supervisors-science
canBeAntag: false
access:
diff --git a/Resources/Prototypes/Roles/Jobs/Science/research_director.yml b/Resources/Prototypes/Roles/Jobs/Science/research_director.yml
index bddf10f856..b5ad3292e9 100644
--- a/Resources/Prototypes/Roles/Jobs/Science/research_director.yml
+++ b/Resources/Prototypes/Roles/Jobs/Science/research_director.yml
@@ -11,7 +11,7 @@
time: 144000 #40 hrs
weight: 10
startingGear: ResearchDirectorGear
- icon: "ResearchDirector"
+ icon: "JobIconResearchDirector"
requireAdminNotify: true
supervisors: job-supervisors-captain
canBeAntag: false
diff --git a/Resources/Prototypes/Roles/Jobs/Science/scientist.yml b/Resources/Prototypes/Roles/Jobs/Science/scientist.yml
index 87c0872f06..676514b121 100644
--- a/Resources/Prototypes/Roles/Jobs/Science/scientist.yml
+++ b/Resources/Prototypes/Roles/Jobs/Science/scientist.yml
@@ -8,7 +8,7 @@
department: Science
time: 14400 #4 hrs
startingGear: ScientistGear
- icon: "Scientist"
+ icon: "JobIconScientist"
supervisors: job-supervisors-rd
access:
- Research
diff --git a/Resources/Prototypes/Roles/Jobs/Science/senior_researcher.yml b/Resources/Prototypes/Roles/Jobs/Science/senior_researcher.yml
index 62f867b825..13375e271b 100644
--- a/Resources/Prototypes/Roles/Jobs/Science/senior_researcher.yml
+++ b/Resources/Prototypes/Roles/Jobs/Science/senior_researcher.yml
@@ -8,7 +8,7 @@
department: Science
time: 216000 #60 hrs
startingGear: SeniorResearcherGear
- icon: "SeniorResearcher"
+ icon: "JobIconSeniorResearcher"
supervisors: job-supervisors-rd
access:
- Research
diff --git a/Resources/Prototypes/Roles/Jobs/Security/detective.yml b/Resources/Prototypes/Roles/Jobs/Security/detective.yml
index 94bafbaf67..a1da692dde 100644
--- a/Resources/Prototypes/Roles/Jobs/Security/detective.yml
+++ b/Resources/Prototypes/Roles/Jobs/Security/detective.yml
@@ -8,7 +8,7 @@
department: Security
time: 54000 # 15 hours
startingGear: DetectiveGear
- icon: "Detective"
+ icon: "JobIconDetective"
supervisors: job-supervisors-hos
canBeAntag: false
access:
diff --git a/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml b/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml
index 2135cf3168..7b70149d96 100644
--- a/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml
+++ b/Resources/Prototypes/Roles/Jobs/Security/head_of_security.yml
@@ -17,7 +17,7 @@
time: 144000 #40 hrs
weight: 10
startingGear: HoSGear
- icon: "HeadOfSecurity"
+ icon: "JobIconHeadOfSecurity"
requireAdminNotify: true
supervisors: job-supervisors-captain
canBeAntag: false
diff --git a/Resources/Prototypes/Roles/Jobs/Security/security_cadet.yml b/Resources/Prototypes/Roles/Jobs/Security/security_cadet.yml
index 26548bddc6..b58009ae86 100644
--- a/Resources/Prototypes/Roles/Jobs/Security/security_cadet.yml
+++ b/Resources/Prototypes/Roles/Jobs/Security/security_cadet.yml
@@ -11,7 +11,7 @@
time: 54000 #15 hrs
inverted: true # stop playing intern if you're good at security!
startingGear: SecurityCadetGear
- icon: "SecurityCadet"
+ icon: "JobIconSecurityCadet"
supervisors: job-supervisors-security
canBeAntag: false
access:
diff --git a/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml b/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml
index 7ed268afbd..e38256b8a1 100644
--- a/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml
+++ b/Resources/Prototypes/Roles/Jobs/Security/security_officer.yml
@@ -8,7 +8,7 @@
department: Security
time: 36000 #10 hrs
startingGear: SecurityOfficerGear
- icon: "SecurityOfficer"
+ icon: "JobIconSecurityOfficer"
supervisors: job-supervisors-hos
canBeAntag: false
access:
diff --git a/Resources/Prototypes/Roles/Jobs/Security/senior_officer.yml b/Resources/Prototypes/Roles/Jobs/Security/senior_officer.yml
index fbc5e161c8..5da1347e14 100644
--- a/Resources/Prototypes/Roles/Jobs/Security/senior_officer.yml
+++ b/Resources/Prototypes/Roles/Jobs/Security/senior_officer.yml
@@ -17,7 +17,7 @@
department: Security
time: 216000 # 60 hrs
startingGear: SeniorOfficerGear
- icon: "SeniorOfficer"
+ icon: "JobIconSeniorOfficer"
supervisors: job-supervisors-hos
canBeAntag: false
access:
diff --git a/Resources/Prototypes/Roles/Jobs/Security/warden.yml b/Resources/Prototypes/Roles/Jobs/Security/warden.yml
index ea45490632..53ba868dcf 100644
--- a/Resources/Prototypes/Roles/Jobs/Security/warden.yml
+++ b/Resources/Prototypes/Roles/Jobs/Security/warden.yml
@@ -8,7 +8,7 @@
role: JobSecurityOfficer
time: 36000 #10 hrs
startingGear: WardenGear
- icon: "Warden"
+ icon: "JobIconWarden"
supervisors: job-supervisors-hos
canBeAntag: false
access:
diff --git a/Resources/Prototypes/Roles/Jobs/Wildcards/boxer.yml b/Resources/Prototypes/Roles/Jobs/Wildcards/boxer.yml
index a2b7ff1d95..1be182f1f7 100644
--- a/Resources/Prototypes/Roles/Jobs/Wildcards/boxer.yml
+++ b/Resources/Prototypes/Roles/Jobs/Wildcards/boxer.yml
@@ -4,7 +4,7 @@
description: job-description-boxer
playTimeTracker: JobBoxer
startingGear: BoxerGear
- icon: "Boxer"
+ icon: "JobIconBoxer"
supervisors: job-supervisors-hop
access:
- Service
diff --git a/Resources/Prototypes/Roles/Jobs/Wildcards/psychologist.yml b/Resources/Prototypes/Roles/Jobs/Wildcards/psychologist.yml
index b28c805d22..f405d2ca9d 100644
--- a/Resources/Prototypes/Roles/Jobs/Wildcards/psychologist.yml
+++ b/Resources/Prototypes/Roles/Jobs/Wildcards/psychologist.yml
@@ -4,7 +4,7 @@
description: job-description-psychologist
playTimeTracker: JobPsychologist
startingGear: PsychologistGear
- icon: "Psychologist"
+ icon: "JobIconPsychologist"
supervisors: job-supervisors-cmo
access:
- Medical
diff --git a/Resources/Prototypes/Roles/Jobs/Wildcards/reporter.yml b/Resources/Prototypes/Roles/Jobs/Wildcards/reporter.yml
index 42a7dcbed3..22d9cb91af 100644
--- a/Resources/Prototypes/Roles/Jobs/Wildcards/reporter.yml
+++ b/Resources/Prototypes/Roles/Jobs/Wildcards/reporter.yml
@@ -4,7 +4,7 @@
description: job-description-reporter
playTimeTracker: JobReporter
startingGear: ReporterGear
- icon: "Reporter"
+ icon: "JobIconReporter"
supervisors: job-supervisors-hop
access:
- Service
diff --git a/Resources/Prototypes/Roles/Jobs/Wildcards/zookeeper.yml b/Resources/Prototypes/Roles/Jobs/Wildcards/zookeeper.yml
index 0790fad2a6..73b804db7a 100644
--- a/Resources/Prototypes/Roles/Jobs/Wildcards/zookeeper.yml
+++ b/Resources/Prototypes/Roles/Jobs/Wildcards/zookeeper.yml
@@ -4,7 +4,7 @@
description: job-description-zookeeper
playTimeTracker: JobZookeeper
startingGear: ZookeeperGear
- icon: "Zookeeper"
+ icon: "JobIconZookeeper"
supervisors: job-supervisors-hop
access:
- Service
diff --git a/Resources/Prototypes/StatusEffects/job.yml b/Resources/Prototypes/StatusEffects/job.yml
new file mode 100644
index 0000000000..e8418a6716
--- /dev/null
+++ b/Resources/Prototypes/StatusEffects/job.yml
@@ -0,0 +1,361 @@
+- type: statusIcon
+ id: JobIcon
+ abstract: true
+ priority: 1
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconDetective
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Detective
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconQuarterMaster
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: QuarterMaster
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconBotanist
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Botanist
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconBoxer
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Boxer
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconAtmosphericTechnician
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: AtmosphericTechnician
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconNanotrasen
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Nanotrasen
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconPrisoner
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Prisoner
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconJanitor
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Janitor
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconChemist
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Chemist
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconStationEngineer
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: StationEngineer
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconSecurityOfficer
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: SecurityOfficer
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconNoId
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: NoId
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconChiefMedicalOfficer
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: ChiefMedicalOfficer
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconRoboticist
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Roboticist
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconChaplain
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Chaplain
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconLawyer
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Lawyer
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconUnknown
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Unknown
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconLibrarian
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Librarian
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconCargoTechnician
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: CargoTechnician
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconScientist
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Scientist
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconResearchAssistant
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: ResearchAssistant
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconGeneticist
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Geneticist
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconClown
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Clown
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconCaptain
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Captain
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconHeadOfPersonnel
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: HeadOfPersonnel
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconVirologist
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Virologist
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconShaftMiner
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: ShaftMiner
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconPassenger
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Passenger
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconChiefEngineer
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: ChiefEngineer
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconBartender
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Bartender
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconHeadOfSecurity
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: HeadOfSecurity
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconBrigmedic
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Brigmedic
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconMedicalDoctor
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: MedicalDoctor
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconParamedic
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Paramedic
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconChef
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Chef
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconWarden
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Warden
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconResearchDirector
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: ResearchDirector
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconMime
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Mime
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconMusician
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Musician
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconReporter
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Reporter
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconPsychologist
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Psychologist
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconMedicalIntern
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: MedicalIntern
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconTechnicalAssistant
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: TechnicalAssistant
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconServiceWorker
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: ServiceWorker
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconSecurityCadet
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: SecurityCadet
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconZombie # This is a perfectly legitimate profession to pursue
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Zombie
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconZookeeper
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: Zookeeper
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconSeniorPhysician
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: SeniorPhysician
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconSeniorOfficer
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: SeniorOfficer
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconSeniorEngineer
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: SeniorEngineer
+
+- type: statusIcon
+ parent: JobIcon
+ id: JobIconSeniorResearcher
+ icon:
+ sprite: Interface/Misc/job_icons.rsi
+ state: SeniorResearcher