diff --git a/Content.Client/_Impstation/Cosmiccult/CosmicCultSystem.cs b/Content.Client/_Impstation/Cosmiccult/CosmicCultSystem.cs new file mode 100644 index 00000000000000..5502421ec66bbc --- /dev/null +++ b/Content.Client/_Impstation/Cosmiccult/CosmicCultSystem.cs @@ -0,0 +1,37 @@ +using Content.Shared._Impstation.Cosmiccult.Components; +using Content.Shared._Impstation.Cosmiccult; +using Content.Shared.StatusIcon.Components; +using Robust.Shared.Prototypes; + +namespace Content.Client._Impstation.Cosmiccult; + +/// +/// Used for the client to get status icons from other revs. +/// +public sealed class CosmicCultSystem : SharedCosmicCultSystem +{ + [Dependency] private readonly IPrototypeManager _prototype = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(GetCosmicCultIcon); + SubscribeLocalEvent(GetCosmicCultLeadIcon); + } + + private void GetCosmicCultIcon(Entity ent, ref GetStatusIconsEvent args) + { + if (HasComp(ent)) + return; + + if (_prototype.TryIndex(ent.Comp.StatusIcon, out var iconPrototype)) + args.StatusIcons.Add(iconPrototype); + } + + private void GetCosmicCultLeadIcon(Entity ent, ref GetStatusIconsEvent args) + { + if (_prototype.TryIndex(ent.Comp.StatusIcon, out var iconPrototype)) + args.StatusIcons.Add(iconPrototype); + } +} diff --git a/Content.Client/_Impstation/Cosmiccult/UI/CosmicDeconvertedEui.cs b/Content.Client/_Impstation/Cosmiccult/UI/CosmicDeconvertedEui.cs new file mode 100644 index 00000000000000..4f058f3944d305 --- /dev/null +++ b/Content.Client/_Impstation/Cosmiccult/UI/CosmicDeconvertedEui.cs @@ -0,0 +1,25 @@ +using Content.Client.Eui; + +namespace Content.Client._Impstation.Cosmiccult.UI; + +public sealed class CosmicDeconvertedEui : BaseEui +{ + private readonly CosmicDeconvertedMenu _menu; + + public CosmicDeconvertedEui() + { + _menu = new CosmicDeconvertedMenu(); + } + + public override void Opened() + { + _menu.OpenCentered(); + } + + public override void Closed() + { + base.Closed(); + + _menu.Close(); + } +} diff --git a/Content.Client/_Impstation/Cosmiccult/UI/CosmicDeconvertedMenu.xaml b/Content.Client/_Impstation/Cosmiccult/UI/CosmicDeconvertedMenu.xaml new file mode 100644 index 00000000000000..14b31c1950df19 --- /dev/null +++ b/Content.Client/_Impstation/Cosmiccult/UI/CosmicDeconvertedMenu.xaml @@ -0,0 +1,10 @@ + + + + diff --git a/Content.Client/_Impstation/Cosmiccult/UI/CosmicMonumentWindow.xaml.cs b/Content.Client/_Impstation/Cosmiccult/UI/CosmicMonumentWindow.xaml.cs new file mode 100644 index 00000000000000..b4685d06015cfd --- /dev/null +++ b/Content.Client/_Impstation/Cosmiccult/UI/CosmicMonumentWindow.xaml.cs @@ -0,0 +1,79 @@ +using Content.Client.Message; +using Content.Shared._Impstation.Cosmiccult; +using Robust.Client.AutoGenerated; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Timing; +using FancyWindow = Content.Client.UserInterface.Controls.FancyWindow; + +namespace Content.Client._Impstation.Cosmiccult.UI; + +[GenerateTypedNameReferences] +public sealed partial class CosmicMonumentWindow : FancyWindow +{ + [Dependency] private readonly IGameTiming _timing = default!; + + private TimeSpan _cooldownEnd = TimeSpan.Zero; + private bool _hasEnoughFuel; + + public Action? OnGenerateButtonPressed; + + public CosmicMonumentWindow() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + + GenerateButton.OnPressed += _ => OnGenerateButtonPressed?.Invoke(); + } + + public void UpdateState(CosmicMonumentUserInterfaceState state) + { + _cooldownEnd = state.CooldownEndTime; + _hasEnoughFuel = state.FuelCost <= state.FuelAmount; + + var fuelCompletion = Math.Clamp((float) state.FuelAmount / state.FuelCost, 0f, 1f); + + FuelBar.Value = fuelCompletion; + + var charges = state.FuelAmount / state.FuelCost; + FuelText.Text = Loc.GetString("cosmic-monument-charges", ("charges", charges)); + + UpdateTimer(); + UpdateReady(); // yes this can trigger twice. no i don't care + } + + public void UpdateTimer() + { + if (_timing.CurTime > _cooldownEnd) + { + CooldownLabel.SetMarkup(Loc.GetString("cosmic-monument-no-cooldown")); + } + else + { + var timeLeft = _cooldownEnd - _timing.CurTime; + var timeString = $"{timeLeft.Minutes:0}:{timeLeft.Seconds:00}"; + CooldownLabel.SetMarkup(Loc.GetString("cosmic-monument-cooldown", ("time", timeString))); + UpdateReady(); + } + } + + public void UpdateReady() + { + var ready = _hasEnoughFuel && _timing.CurTime > _cooldownEnd; + + var msg = ready + ? Loc.GetString("cosmic-monument-yes-fire") + : Loc.GetString("cosmic-monument-no-fire"); + ReadyLabel.SetMarkup(msg); + + GenerateButton.Disabled = !ready; + } + + protected override void FrameUpdate(FrameEventArgs args) + { + base.FrameUpdate(args); + + UpdateTimer(); + } +} + diff --git a/Content.Client/_Impstation/CrewMedal/CrewMedalSystem.cs b/Content.Client/_Impstation/CrewMedal/CrewMedalSystem.cs new file mode 100644 index 00000000000000..693d04f5cfa85b --- /dev/null +++ b/Content.Client/_Impstation/CrewMedal/CrewMedalSystem.cs @@ -0,0 +1,21 @@ +using Content.Client._Impstation.CrewMedal.UI; +using Content.Shared._Impstation.CrewMedal; + +namespace Content.Client._Impstation.CrewMedal; + +public sealed class CrewMedalSystem : SharedCrewMedalSystem +{ + [Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!; + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnCrewMedalAfterState); + } + private void OnCrewMedalAfterState(Entity ent, ref AfterAutoHandleStateEvent args) + { + if (!_uiSystem.TryGetOpenUi(ent.Owner, CrewMedalUiKey.Key, out var bui)) + return; + + bui.Reload(); + } +} diff --git a/Content.Client/_Impstation/CrewMedal/UI/CrewMedalBoundUserInterface.cs b/Content.Client/_Impstation/CrewMedal/UI/CrewMedalBoundUserInterface.cs new file mode 100644 index 00000000000000..4cbe6f457eb137 --- /dev/null +++ b/Content.Client/_Impstation/CrewMedal/UI/CrewMedalBoundUserInterface.cs @@ -0,0 +1,49 @@ +using Content.Shared._Impstation.CrewMedal; +using Robust.Client.UserInterface; + +namespace Content.Client._Impstation.CrewMedal.UI; + +/// +/// Initializes a and updates it when new server messages are received. +/// +public sealed class CrewMedalBoundUserInterface : BoundUserInterface +{ + [Dependency] private readonly IEntityManager _entManager = default!; + + [ViewVariables] + private CrewMedalWindow? _window; + + public CrewMedalBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) + { + IoCManager.InjectDependencies(this); + } + + protected override void Open() + { + base.Open(); + + _window = this.CreateWindow(); + + _window.OnReasonChanged += OnReasonChanged; + Reload(); + } + + private void OnReasonChanged(string newReason) + { + if (_entManager.TryGetComponent(Owner, out var component) && + component.Reason.Equals(newReason)) + return; + + SendPredictedMessage(new CrewMedalReasonChangedMessage(newReason)); + } + + public void Reload() + { + if (_window == null || !_entManager.TryGetComponent(Owner, out var component)) + return; + + _window.SetCurrentReason(component.Reason); + _window.SetAwarded(component.Awarded); + _window.SetMaxCharacters(component.MaxCharacters); + } +} diff --git a/Content.Client/_Impstation/CrewMedal/UI/CrewMedalWindow.xaml b/Content.Client/_Impstation/CrewMedal/UI/CrewMedalWindow.xaml new file mode 100644 index 00000000000000..77e95f393303e6 --- /dev/null +++ b/Content.Client/_Impstation/CrewMedal/UI/CrewMedalWindow.xaml @@ -0,0 +1,13 @@ + + +