diff --git a/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs b/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs index ee581186f35..e932d67bb9e 100644 --- a/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs +++ b/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs @@ -1,13 +1,17 @@ using System.Diagnostics.CodeAnalysis; +using System.Text; // Nuclear 14 using Content.Shared.CCVar; using Content.Shared.Players; using Content.Shared.Players.PlayTimeTracking; using Content.Shared.Roles; +using Content.Shared._NC.Roles; // Nuclear 14 using Robust.Client; using Robust.Client.Player; +using Content.Client.Preferences; // Nuclear 14 using Robust.Shared.Configuration; using Robust.Shared.Network; using Robust.Shared.Prototypes; +using Content.Shared.Preferences; // Nuclear 14 using Robust.Shared.Utility; namespace Content.Client.Players.PlayTimeTracking; @@ -20,6 +24,7 @@ public sealed partial class JobRequirementsManager [Dependency] private readonly IEntityManager _entManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IPrototypeManager _prototypes = default!; + [Dependency] private readonly IClientPreferencesManager _clientPreferences = default!; // Nuclear 14 public readonly Dictionary PlayTimes = new(); private readonly List _roleBans = new(); @@ -81,6 +86,7 @@ private void RxPlayTime(MsgPlayTime message) public bool IsAllowed(JobPrototype job, [NotNullWhen(false)] out FormattedMessage? reason) { + var reasonBuilder = new StringBuilder(); // Nuclear 14 reason = null; if (_roleBans.Contains($"Job:{job.ID}")) @@ -93,8 +99,44 @@ public bool IsAllowed(JobPrototype job, [NotNullWhen(false)] out FormattedMessag if (player == null) return true; - return CheckRoleTime(job.Requirements, out reason); + // Nuclear 14 start + if (job.JobBlockForSpecies != null) + { + if (_clientPreferences?.Preferences == null) + return true; + + var nameSpecie = ((HumanoidCharacterProfile)_clientPreferences.Preferences.SelectedCharacter!).Species; + var first = true; + + foreach (var jobBlockForSpecie in job.JobBlockForSpecies) + { + string? speciesReason; + if (JobBlockForSpecies.TryRequirementMet(jobBlockForSpecie, nameSpecie, out speciesReason)) + continue; + + if (!first) + reasonBuilder.Append('\n'); + first = false; + reasonBuilder.AppendLine(speciesReason); + } + } + + if (!CheckRoleTime(job.Requirements, out var timeReason)) + { + if (reasonBuilder.Length > 0) + reasonBuilder.Append('\n'); + reasonBuilder.Append(timeReason!.ToMarkup()); + } + + if (reasonBuilder.Length > 0) + { + reason = FormattedMessage.FromMarkup(reasonBuilder.ToString()); + return false; + } + + return true; } + // Nuclear 14 end public bool CheckRoleTime(HashSet? requirements, [NotNullWhen(false)] out FormattedMessage? reason, string? localePrefix = "role-timer-") { @@ -133,6 +175,4 @@ public IEnumerable> FetchPlaytimeByRoles() } } } - - } diff --git a/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs b/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs index 04810b07719..23b167a9f39 100644 --- a/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs +++ b/Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs @@ -21,6 +21,7 @@ using Content.Shared.Roles; using Content.Shared.StatusIcon; using Content.Shared.Traits; +using Content.Shared._NC; // Nuclear 14 using Robust.Client.AutoGenerated; using Robust.Client.Graphics; using Robust.Client.UserInterface; @@ -953,6 +954,7 @@ private void SetGender(Gender newGender) private void SetSpecies(string newSpecies) { Profile = Profile?.WithSpecies(newSpecies); + Save(); // Nuclear 14 OnSkinColorOnValueChanged(); // Species may have special color prefs, make sure to update it. CMarkings.SetSpecies(newSpecies); // Repopulate the markings tab as well. UpdateSexControls(); // update sex for new species @@ -961,6 +963,7 @@ private void SetSpecies(string newSpecies) UpdateWidthControls(); UpdateWeight(); RebuildSpriteView(); // they might have different inv so we need a new dummy + UpdateJobPriorities(); // Nuclear 14 UpdateSpeciesGuidebookIcon(); IsDirty = true; _needUpdatePreview = true; @@ -1433,8 +1436,20 @@ private void UpdateJobPriorities() { foreach (var prioritySelector in _jobPriorities) { + prioritySelector.UnlockRequirements(); // Nuclear 14 var jobId = prioritySelector.Proto.ID; + // Nuclear 14 start + if (!_requirements.IsAllowed(prioritySelector.Proto, out var reason)) + { + prioritySelector.LockRequirements(reason); + if (Profile != null) + { + Profile = Profile.WithJobPriority(jobId, JobPriority.Never); + } + } + // Nuclear 14 start + var priority = Profile?.JobPriorities.GetValueOrDefault(jobId, JobPriority.Never) ?? JobPriority.Never; prioritySelector.Priority = priority; diff --git a/Content.Client/UndecidedLoadout/UndecidedLoadoutBackpackMenu.xaml b/Content.Client/UndecidedLoadout/UndecidedLoadoutBackpackMenu.xaml new file mode 100644 index 00000000000..79f74b0e0db --- /dev/null +++ b/Content.Client/UndecidedLoadout/UndecidedLoadoutBackpackMenu.xaml @@ -0,0 +1,39 @@ + + + +