diff --git a/Content.Client/_LostParadise/Salvage/LPRestrictedRangeSystem.cs b/Content.Client/_LostParadise/Salvage/LPRestrictedRangeSystem.cs new file mode 100644 index 00000000000..f8a8449e0db --- /dev/null +++ b/Content.Client/_LostParadise/Salvage/LPRestrictedRangeSystem.cs @@ -0,0 +1,7 @@ +using Content.Shared._LostParadise.Salvage; + +namespace Content.Client._LostParadise.Salvage; + +public sealed class LPRestrictedRangeSystem : SharedLPRestrictedRangeSystem +{ +} diff --git a/Content.Client/_LostParadise/Salvage/LPSalvageExpeditionComponent.cs b/Content.Client/_LostParadise/Salvage/LPSalvageExpeditionComponent.cs new file mode 100644 index 00000000000..caf27fb4e46 --- /dev/null +++ b/Content.Client/_LostParadise/Salvage/LPSalvageExpeditionComponent.cs @@ -0,0 +1,9 @@ +using Content.Shared._LostParadise.Salvage.Expeditions; + +namespace Content.Client._LostParadise.Salvage; + +[RegisterComponent] +public sealed partial class LPSalvageExpeditionComponent : SharedLPSalvageExpeditionComponent +{ + +} diff --git a/Content.Client/_LostParadise/Salvage/LPSalvageSystem.cs b/Content.Client/_LostParadise/Salvage/LPSalvageSystem.cs new file mode 100644 index 00000000000..e33716490ad --- /dev/null +++ b/Content.Client/_LostParadise/Salvage/LPSalvageSystem.cs @@ -0,0 +1,50 @@ +using Content.Client.Audio; +using Content.Shared._LostParadise.Salvage; +using Content.Shared._LostParadise.Salvage.Expeditions; +using Robust.Client.Player; +using Robust.Shared.GameStates; + +namespace Content.Client._LostParadise.Salvage; + +public sealed class LPSalvageSystem : SharedLPSalvageSystem +{ + [Dependency] private readonly IPlayerManager _playerManager = default!; + [Dependency] private readonly ContentAudioSystem _audio = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnPlayAmbientMusic); + SubscribeLocalEvent(OnExpeditionHandleState); + } + + private void OnExpeditionHandleState(EntityUid uid, LPSalvageExpeditionComponent component, ref ComponentHandleState args) + { + if (args.Current is not LPSalvageExpeditionComponentState state) + return; + + component.Stage = state.Stage; + + if (component.Stage >= LPExpeditionStage.MusicCountdown) + { + _audio.DisableAmbientMusic(); + } + } + + private void OnPlayAmbientMusic(ref PlayAmbientMusicEvent ev) + { + if (ev.Cancelled) + return; + + var player = _playerManager.LocalEntity; + + if (!TryComp(player, out TransformComponent? xform) || + !TryComp(xform.MapUid, out var expedition) || + expedition.Stage < LPExpeditionStage.MusicCountdown) + { + return; + } + + ev.Cancelled = true; + } +} diff --git a/Content.Client/_LostParadise/Salvage/UI/LPOfferingWindow.xaml b/Content.Client/_LostParadise/Salvage/UI/LPOfferingWindow.xaml new file mode 100644 index 00000000000..63b41aa652a --- /dev/null +++ b/Content.Client/_LostParadise/Salvage/UI/LPOfferingWindow.xaml @@ -0,0 +1,36 @@ + + + + + + + + + + diff --git a/Content.Client/_LostParadise/Salvage/UI/LPOfferingWindow.xaml.cs b/Content.Client/_LostParadise/Salvage/UI/LPOfferingWindow.xaml.cs new file mode 100644 index 00000000000..3a45a09ea45 --- /dev/null +++ b/Content.Client/_LostParadise/Salvage/UI/LPOfferingWindow.xaml.cs @@ -0,0 +1,117 @@ +using Content.Client.Computer; +using Content.Client.UserInterface.Controls; +using Content.Shared.Shuttles.BUIStates; +using Robust.Client.AutoGenerated; +using Robust.Client.Graphics; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Timing; + +namespace Content.Client._LostParadise.Salvage.UI; + +/// +/// Generic window for offering multiple selections with a timer. +/// +[GenerateTypedNameReferences] +public sealed partial class LPOfferingWindow : FancyWindow, + IComputerWindow +{ + [Dependency] private readonly IGameTiming _timing = default!; + + public bool Claimed; + public TimeSpan NextOffer; + private TimeSpan? _progression; + + /// + /// Time between NextOffers + /// + public TimeSpan Cooldown; + + /// + /// Time between Progressions + /// + public TimeSpan ProgressionCooldown; + + /// + /// Secondary timer used for tracking active progress. + /// + public TimeSpan? Progression + { + get => _progression; + set + { + if (_progression == value) + return; + + _progression = value; + + if (value == null) + { + ProgressionBox.Visible = false; + } + else + { + ProgressionBox.Visible = true; + } + } + } + + public LPOfferingWindow() + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + + ProgressionBar.ForegroundStyleBoxOverride = new StyleBoxFlat(Color.FromHex("#C74EBD")); + } + + public void AddOption(LPOfferingWindowOption option) + { + Container.AddChild(option); + } + + public void ClearOptions() + { + Container.DisposeAllChildren(); + } + + protected override void FrameUpdate(FrameEventArgs args) + { + base.FrameUpdate(args); + + if (_progression != null) + { + var remaining = _progression.Value - _timing.CurTime; + + if (remaining < TimeSpan.Zero) + { + ProgressionBar.Value = 1f; + ProgressionText.Text = "00:00"; + } + else + { + ProgressionBar.Value = 1f - (float) (remaining / ProgressionCooldown); + ProgressionText.Text = $"{remaining.Minutes:00}:{remaining.Seconds:00}"; + } + } + + if (Claimed) + { + NextOfferBar.Value = 1f; + NextOfferText.Text = "00:00"; + } + else + { + var remaining = NextOffer - _timing.CurTime; + + if (remaining < TimeSpan.Zero) + { + NextOfferBar.Value = 1f; + NextOfferText.Text = "00:00"; + } + else + { + NextOfferBar.Value = 1f - (float) (remaining / Cooldown); + NextOfferText.Text = $"{remaining.Minutes:00}:{remaining.Seconds:00}"; + } + } + } +} diff --git a/Content.Client/_LostParadise/Salvage/UI/LPOfferingWindowOption.xaml b/Content.Client/_LostParadise/Salvage/UI/LPOfferingWindowOption.xaml new file mode 100644 index 00000000000..fc2bfaa94aa --- /dev/null +++ b/Content.Client/_LostParadise/Salvage/UI/LPOfferingWindowOption.xaml @@ -0,0 +1,24 @@ + + + + + + + + +