using Content.Client._DV.Tips.UI;
using Content.Shared._DV.CCVars;
using Content.Shared._DV.Tips;
using JetBrains.Annotations;
using Robust.Client.UserInterface;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
namespace Content.Client._DV.Tips;
///
/// Client-side system that receives tip events from the server and displays the tip popup UI.
///
public sealed class TipSystem : SharedTipSystem
{
[Dependency] private readonly IUserInterfaceManager _ui = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
///
/// Queue of tips waiting to be shown. Only one tip is displayed at a time.
///
private readonly Queue _tipQueue = new();
///
/// Currently displayed tip popup, if any.
///
private TipPopup? _currentPopup;
///
/// The tip ID of the currently displayed popup, used for dismiss events.
///
private ProtoId? _currentTipId;
public override void Initialize()
{
base.Initialize();
SubscribeNetworkEvent(OnShowTip);
}
private void OnShowTip(ShowTipEvent ev)
{
// Return if tips are disabled globally
if (_cfg.GetCVar(DCCVars.DisableTipsGlobal))
return;
// Return if tips are disabled locally and IgnoreCvar is the default value
if (_cfg.GetCVar(DCCVars.DisableTips) && !ev.IgnoreCvar)
return;
_tipQueue.Enqueue(ev);
TryShowNextTip();
}
private void TryShowNextTip()
{
while (true)
{
if (_currentPopup != null)
return;
if (_tipQueue.Count == 0)
return;
var tipEvent = _tipQueue.Dequeue();
if (!Prototype.TryIndex(tipEvent.TipId, out var tipProto))
{
Log.Warning($"Received tip event for unknown prototype: {tipEvent.TipId}");
continue;
}
ShowTipPopup(tipProto, tipEvent);
break;
}
}
private void ShowTipPopup(TipPrototype tip, ShowTipEvent ev)
{
_currentPopup = new TipPopup(tip);
_currentPopup.OnClose += OnPopupClosed;
_currentTipId = tip.ID;
_ui.RootControl.AddChild(_currentPopup);
// Play the sound
_audio.PlayGlobal(ev.Sound, Filter.Local(), false);
}
private void OnPopupClosed(bool dontShowAgain)
{
if (_currentPopup != null && _currentTipId != null)
{
// Send dismiss event to server
RaiseNetworkEvent(new TipDismissedEvent(_currentTipId.Value, dontShowAgain));
_currentPopup.OnClose -= OnPopupClosed;
_currentPopup?.Close();
_currentPopup = null;
_currentTipId = null;
}
TryShowNextTip();
}
///
/// Closes the current tip popup if one is open.
///
[PublicAPI]
public void CloseCurrentTip()
{
_currentPopup?.Close();
}
///
/// Clears all queued tips without showing them.
///
[PublicAPI]
public void ClearTipQueue()
{
_tipQueue.Clear();
}
}