diff --git a/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUi.cs b/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUi.cs new file mode 100644 index 00000000000..f1688c8dab4 --- /dev/null +++ b/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUi.cs @@ -0,0 +1,28 @@ +using Robust.Client.UserInterface; +using Content.Client.UserInterface.Fragments; +using Content.Shared.CartridgeLoader.Cartridges; + +namespace Content.Client.DeltaV.CartridgeLoader.Cartridges; + +public sealed partial class MailMetricUi : UIFragment +{ + private MailMetricUiFragment? _fragment; + + public override Control GetUIFragmentRoot() + { + return _fragment!; + } + + public override void Setup(BoundUserInterface userInterface, EntityUid? fragmentOwner) + { + _fragment = new MailMetricUiFragment(); + } + + public override void UpdateState(BoundUserInterfaceState state) + { + if (state is MailMetricUiState cast) + { + _fragment?.UpdateState(cast); + } + } +} diff --git a/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml b/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml new file mode 100644 index 00000000000..c31a1c6063d --- /dev/null +++ b/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml.cs b/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml.cs new file mode 100644 index 00000000000..d1560b53668 --- /dev/null +++ b/Content.Client/DeltaV/CartridgeLoader/Cartridges/MailMetricUiFragment.xaml.cs @@ -0,0 +1,105 @@ +using System.Runtime.CompilerServices; +using Content.Shared.CartridgeLoader.Cartridges; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; + +namespace Content.Client.DeltaV.CartridgeLoader.Cartridges; + +[GenerateTypedNameReferences] +public sealed partial class MailMetricUiFragment : BoxContainer +{ + + private OpenedMailPercentGrade? _successGrade; + + public MailMetricUiFragment() + { + RobustXamlLoader.Load(this); + + // This my way of adding multiple classes to a XAML control. + // Haha Batman I'm going to blow up Gotham City + OpenedMailCount.StyleClasses.Add("Good"); + OpenedMailSpesos.StyleClasses.Add("Good"); + TamperedMailCount.StyleClasses.Add("Danger"); + TamperedMailSpesos.StyleClasses.Add("Danger"); + ExpiredMailCount.StyleClasses.Add("Danger"); + ExpiredMailSpesos.StyleClasses.Add("Danger"); + DamagedMailCount.StyleClasses.Add("Danger"); + DamagedMailSpesos.StyleClasses.Add("Danger"); + UnopenedMailCount.StyleClasses.Add("Caution"); + } + + public void UpdateState(MailMetricUiState state) + { + UpdateTextLabels(state); + UpdateSuccessGrade(state); + } + + public void UpdateTextLabels(MailMetricUiState state) + { + var stats = state.Metrics; + + OpenedMailCount.Text = stats.OpenedCount.ToString(); + OpenedMailSpesos.Text = stats.Earnings.ToString(); + TamperedMailCount.Text = stats.TamperedCount.ToString(); + TamperedMailSpesos.Text = stats.TamperedLosses.ToString(); + ExpiredMailCount.Text = stats.ExpiredCount.ToString(); + ExpiredMailSpesos.Text = stats.ExpiredLosses.ToString(); + DamagedMailCount.Text = stats.DamagedCount.ToString(); + DamagedMailSpesos.Text = stats.DamagedLosses.ToString(); + UnopenedMailCount.Text = state.UnopenedMailCount.ToString(); + TotalMailCount.Text = state.TotalMail.ToString(); + TotalMailSpesos.Text = stats.TotalIncome.ToString(); + SuccessRateCounts.Text = Loc.GetString("mail-metrics-progress", + ("opened", stats.OpenedCount), + ("total", state.TotalMail)); + SuccessRatePercent.Text = Loc.GetString("mail-metrics-progress-percent", + ("successRate", state.SuccessRate)); + } + + public void UpdateSuccessGrade(MailMetricUiState state) + { + var previousGrade = _successGrade; + _successGrade = GetSuccessRateGrade(state.SuccessRate); + + // No need to update if they're the same + if (previousGrade == _successGrade) + return; + + var previousGradeClass = GetClassForGrade(previousGrade); + if (previousGradeClass != string.Empty) + { + SuccessRatePercent.StyleClasses.Remove(previousGradeClass); + } + + SuccessRatePercent.StyleClasses.Add(GetClassForGrade(_successGrade)); + } + + private static OpenedMailPercentGrade GetSuccessRateGrade(double successRate) + { + return successRate switch + { + > 75 => OpenedMailPercentGrade.Good, + > 50 => OpenedMailPercentGrade.Average, + _ => OpenedMailPercentGrade.Bad, + }; + } + + private string GetClassForGrade(OpenedMailPercentGrade? grade) + { + return grade switch + { + OpenedMailPercentGrade.Good => "Good", + OpenedMailPercentGrade.Average => "Caution", + OpenedMailPercentGrade.Bad => "Danger", + _ => string.Empty, + }; + } +} + +enum OpenedMailPercentGrade +{ + Good, + Average, + Bad +} diff --git a/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs b/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs index ea250953422..a5b71cfa7bf 100644 --- a/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs +++ b/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs @@ -113,7 +113,31 @@ public bool IsAllowed(JobPrototype job, [NotNullWhen(false)] out FormattedMessag public bool CheckRoleTime(JobPrototype job, [NotNullWhen(false)] out FormattedMessage? reason) { var reqs = _entManager.System().GetJobRequirement(job); - return CheckRoleTime(reqs, out reason); + + //return CheckRoleTime(reqs, out reason); // Frontier: old implementation + + // Frontier: alternate role time checks + if (CheckRoleTime(reqs, out reason)) + return true; + + var altReqs = _entManager.System().GetAlternateJobRequirements(job); + if (altReqs != null) + { + foreach (var alternateSet in altReqs.Values) + { + // Suppress reasons on alternate requirement sets + if (CheckRoleTime(alternateSet, out var altReason)) + { + return true; + } + reason.PushNewline(); + reason.AddMarkupPermissive(Loc.GetString("role-requirement-alternative")); + reason.PushNewline(); + reason.AddMarkupPermissive(altReason.ToMarkup()); + } + } + return false; + // End Frontier: alternate role time checks } public bool CheckRoleTime(HashSet? requirements, [NotNullWhen(false)] out FormattedMessage? reason) diff --git a/Content.Client/_NC/Radio/UI/HandheldRadioBoundUserInterface.cs b/Content.Client/_NC/Radio/UI/HandheldRadioBoundUserInterface.cs new file mode 100644 index 00000000000..2b671443af8 --- /dev/null +++ b/Content.Client/_NC/Radio/UI/HandheldRadioBoundUserInterface.cs @@ -0,0 +1,62 @@ +using Content.Shared._NC.Radio; +using JetBrains.Annotations; +using Robust.Client.GameObjects; + +namespace Content.Client._NC.Radio.UI; + + +[UsedImplicitly] +public sealed class HandheldRadioBoundUserInterface : BoundUserInterface +{ + [ViewVariables] + private HandheldRadioMenu? _menu; + + public HandheldRadioBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) + { + + } + + protected override void Open() + { + base.Open(); + + _menu = new(); + + _menu.OnMicPressed += enabled => + { + SendMessage(new ToggleHandheldRadioMicMessage(enabled)); + }; + _menu.OnSpeakerPressed += enabled => + { + SendMessage(new ToggleHandheldRadioSpeakerMessage(enabled)); + }; + _menu.OnFrequencyChanged += frequency => + { + if (int.TryParse(frequency.Trim(), out var intFreq) && intFreq > 0) + SendMessage(new SelectHandheldRadioFrequencyMessage(intFreq)); + else + SendMessage(new SelectHandheldRadioFrequencyMessage(-1)); // Query the current frequency + }; + + _menu.OnClose += Close; + _menu.OpenCentered(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + _menu?.Close(); + } + + protected override void UpdateState(BoundUserInterfaceState state) + { + base.UpdateState(state); + + if (state is not HandheldRadioBoundUIState msg) + return; + + _menu?.Update(msg); + } +} diff --git a/Content.Client/_NC/Radio/UI/HandheldRadioMenu.xaml b/Content.Client/_NC/Radio/UI/HandheldRadioMenu.xaml new file mode 100644 index 00000000000..e228d97f1a5 --- /dev/null +++ b/Content.Client/_NC/Radio/UI/HandheldRadioMenu.xaml @@ -0,0 +1,29 @@ + + + + + + +