diff --git a/Content.Client/Entry/EntryPoint.cs b/Content.Client/Entry/EntryPoint.cs index b6200dd8aaea6..0b206c2c6b7eb 100644 --- a/Content.Client/Entry/EntryPoint.cs +++ b/Content.Client/Entry/EntryPoint.cs @@ -68,12 +68,16 @@ // SPDX-FileCopyrightText: 2024 nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com> // SPDX-FileCopyrightText: 2024 no <165581243+pissdemon@users.noreply.github.com> // SPDX-FileCopyrightText: 2024 slarticodefast <161409025+slarticodefast@users.noreply.github.com> +// SPDX-FileCopyrightText: 2025 Errant <35878406+Errant-4@users.noreply.github.com> // SPDX-FileCopyrightText: 2025 McBosserson <148172569+McBosserson@users.noreply.github.com> // SPDX-FileCopyrightText: 2025 Mish +// SPDX-FileCopyrightText: 2025 Nikita (Nick) <174215049+nikitosych@users.noreply.github.com> // SPDX-FileCopyrightText: 2025 Pieter-Jan Briers // SPDX-FileCopyrightText: 2025 deathride58 // SPDX-FileCopyrightText: 2025 misghast <51974455+misterghast@users.noreply.github.com> // SPDX-FileCopyrightText: 2025 taydeo +// SPDX-FileCopyrightText: 2026 Polonium-bot +// SPDX-FileCopyrightText: 2026 nikitosych <174215049+nikitosych@users.noreply.github.com> // // SPDX-License-Identifier: MIT @@ -87,6 +91,7 @@ using Content.Client.GhostKick; using Content.Client.Guidebook; using Content.Client.Input; +using Content.Client._Polonium.Introduction; using Content.Client.IoC; using Content.Client.Launcher; using Content.Client.Lobby; @@ -155,6 +160,7 @@ public sealed class EntryPoint : GameClient [Dependency] private readonly TitleWindowManager _titleWindowManager = default!; [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!; [Dependency] private readonly ClientsidePlaytimeTrackingManager _clientsidePlaytimeManager = default!; + [Dependency] private readonly IntroductionManager _introManager = default!; public override void Init() { @@ -187,7 +193,6 @@ public override void Init() _prototypeManager.RegisterIgnore("holiday"); _prototypeManager.RegisterIgnore("htnCompound"); _prototypeManager.RegisterIgnore("htnPrimitive"); - _prototypeManager.RegisterIgnore("gameMap"); _prototypeManager.RegisterIgnore("gameMapPool"); _prototypeManager.RegisterIgnore("lobbyBackground"); _prototypeManager.RegisterIgnore("gamePreset"); @@ -256,6 +261,7 @@ public override void PostInit() _userInterfaceManager.SetActiveTheme(_configManager.GetCVar(CVars.InterfaceTheme)); _documentParsingManager.Initialize(); _titleWindowManager.Initialize(); + _introManager.Initialize(); _baseClient.RunLevelChanged += (_, args) => { diff --git a/Content.Client/Info/LinkBanner.cs b/Content.Client/Info/LinkBanner.cs index 415c21e091a2e..5ffed5f15c84a 100644 --- a/Content.Client/Info/LinkBanner.cs +++ b/Content.Client/Info/LinkBanner.cs @@ -6,12 +6,16 @@ // SPDX-FileCopyrightText: 2024 Tadeo // SPDX-FileCopyrightText: 2024 metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> // SPDX-FileCopyrightText: 2025 taydeo +// SPDX-FileCopyrightText: 2026 Polonium-bot +// SPDX-FileCopyrightText: 2026 nikitosych <174215049+nikitosych@users.noreply.github.com> // // SPDX-License-Identifier: MIT +using Content.Client._Polonium.Introduction; using Content.Client.Changelog; using Content.Client.UserInterface.Systems.EscapeMenu; using Content.Client.UserInterface.Systems.Guidebook; +using Content.Shared._Polonium.Introduction; using Content.Shared.CCVar; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; @@ -22,6 +26,9 @@ namespace Content.Client.Info { public sealed class LinkBanner : BoxContainer { + [Access(typeof(IClientsideNavIntroductionStep), typeof(SharedIntroductionManager))] + public Button? IntroButton { get; } + private readonly IConfigurationManager _cfg; private ValueList<(CVarDef cVar, Button button)> _infoLinks; @@ -59,6 +66,14 @@ public LinkBanner() changelogButton.OnPressed += args => UserInterfaceManager.GetUIController().ToggleWindow(); buttons.AddChild(changelogButton); + var introductionManager = IoCManager.Resolve(); + IntroButton = new Button() { Text = Loc.GetString("server-info-introduction-button") }; + IntroButton.OnPressed += _ => + { + introductionManager.StartIntroduction(); + }; + buttons.AddChild(IntroButton); + void AddInfoButton(string loc, CVarDef cVar) { var button = new Button { Text = Loc.GetString(loc) }; @@ -79,6 +94,11 @@ protected override void EnteredTree() { link.Visible = _cfg.GetCVar(cVar) != ""; } + + if (IntroButton != null) + { + IntroButton.Visible = _cfg.GetCVar(CCVars.IntroEnabled); + } } } } diff --git a/Content.Client/IoC/ClientContentIoC.cs b/Content.Client/IoC/ClientContentIoC.cs index 1310c49a9e416..3e7316fff39d7 100644 --- a/Content.Client/IoC/ClientContentIoC.cs +++ b/Content.Client/IoC/ClientContentIoC.cs @@ -29,7 +29,9 @@ // SPDX-FileCopyrightText: 2024 slarticodefast <161409025+slarticodefast@users.noreply.github.com> // SPDX-FileCopyrightText: 2025 Mish // SPDX-FileCopyrightText: 2025 deathride58 +// SPDX-FileCopyrightText: 2025 nikitosych <174215049+nikitosych@users.noreply.github.com> // SPDX-FileCopyrightText: 2025 taydeo +// SPDX-FileCopyrightText: 2026 Polonium-bot // // SPDX-License-Identifier: MIT @@ -43,6 +45,7 @@ using Content.Client.GameTicking.Managers; using Content.Client.GhostKick; using Content.Client.Guidebook; +using Content.Client._Polonium.Introduction; using Content.Client.Launcher; using Content.Client.Mapping; using Content.Client.Parallax.Managers; @@ -96,6 +99,7 @@ public static void Register() collection.Register(); collection.Register(); collection.Register(); + collection.Register(); } } } diff --git a/Content.Client/Lobby/LobbyUIController.cs b/Content.Client/Lobby/LobbyUIController.cs index 6e2bd888dde19..4dae34a5f9316 100644 --- a/Content.Client/Lobby/LobbyUIController.cs +++ b/Content.Client/Lobby/LobbyUIController.cs @@ -7,8 +7,10 @@ // SPDX-FileCopyrightText: 2025 Quantum-cross <7065792+Quantum-cross@users.noreply.github.com> // SPDX-FileCopyrightText: 2025 Robert Cross <7065792+Quantum-cross@users.noreply.github.com> // SPDX-FileCopyrightText: 2025 Tay +// SPDX-FileCopyrightText: 2025 nikitosych <174215049+nikitosych@users.noreply.github.com> // SPDX-FileCopyrightText: 2025 slarticodefast <161409025+slarticodefast@users.noreply.github.com> // SPDX-FileCopyrightText: 2025 taydeo +// SPDX-FileCopyrightText: 2026 Polonium-bot // // SPDX-License-Identifier: MIT @@ -53,11 +55,23 @@ public sealed class LobbyUIController : UIController, IOnStateEntered + /// Gets the editor used to configure job priority settings, if available. + /// + public JobPriorityEditor? JobPriorityEditor { get; private set; } + + /// + /// Gets the editor instance used to modify the humanoid profile, if available. + /// + public HumanoidProfileEditor? ProfileEditor { get; private set; } + + /// + /// Gets the user interface component for configuring character settings, if available. + /// + public CharacterSetupGui? CharacterSetup { get; private set; } + /// /// Event invoked when any character or job selection or job priority is changed. /// Basically anything that might change round start character/job selection. @@ -72,9 +86,9 @@ public sealed class LobbyUIController : UIController, IOnStateEntered /// This is the modified profile currently being edited. /// - private HumanoidCharacterProfile? EditedProfile => _profileEditor?.Profile; + private HumanoidCharacterProfile? EditedProfile => ProfileEditor?.Profile; - private int? EditedSlot => _profileEditor?.CharacterSlot; + private int? EditedSlot => ProfileEditor?.CharacterSlot; public override void Initialize() { @@ -85,7 +99,7 @@ public override void Initialize() _configurationManager.OnValueChanged(CCVars.FlavorText, args => { - _profileEditor?.RefreshFlavorText(); + ProfileEditor?.RefreshFlavorText(); }); _configurationManager.OnValueChanged(CCVars.GameRoleTimers, _ => RefreshEditors()); @@ -105,41 +119,41 @@ public override void Initialize() private void OnRequirementsUpdated() { - _profileEditor?.RefreshAntags(); - _profileEditor?.RefreshJobs(); - _jobPriorityEditor?.RefreshJobs(); + ProfileEditor?.RefreshAntags(); + ProfileEditor?.RefreshJobs(); + JobPriorityEditor?.RefreshJobs(); } private void OnProtoReload(PrototypesReloadedEventArgs obj) { - if (_profileEditor != null) + if (ProfileEditor != null) { if (obj.WasModified()) { - _profileEditor.RefreshAntags(); + ProfileEditor.RefreshAntags(); } if (obj.WasModified() || obj.WasModified()) { - _profileEditor.RefreshJobs(); + ProfileEditor.RefreshJobs(); } if (obj.WasModified() || obj.WasModified() || obj.WasModified()) { - _profileEditor.RefreshLoadouts(); + ProfileEditor.RefreshLoadouts(); } if (obj.WasModified()) { - _profileEditor.RefreshSpecies(); + ProfileEditor.RefreshSpecies(); } if (obj.WasModified()) { - _profileEditor.RefreshTraits(); + ProfileEditor.RefreshTraits(); } } OnAnyCharacterOrJobChange?.Invoke(); @@ -152,16 +166,16 @@ private void PreferencesDataLoaded() if (_stateManager.CurrentState is not LobbyState) return; - if (_characterSetup != null) - _characterSetup.SelectedCharacterSlot = null; + if (CharacterSetup != null) + CharacterSetup.SelectedCharacterSlot = null; ReloadCharacterSetup(); } public void OnStateEntered(LobbyState state) { PreviewPanel?.SetLoaded(_preferencesManager.ServerDataLoaded); - if (_characterSetup != null) - _characterSetup.SelectedCharacterSlot = null; + if (CharacterSetup != null) + CharacterSetup.SelectedCharacterSlot = null; ReloadCharacterSetup(); } @@ -184,7 +198,7 @@ public void ReloadCharacterSetup() var (characterGui, profileEditor) = EnsureGui(); characterGui.ReloadCharacterPickers(); profileEditor.ResetToDefault(); - _jobPriorityEditor?.LoadJobPriorities(); + JobPriorityEditor?.LoadJobPriorities(); } /// @@ -197,10 +211,10 @@ private void RefreshLobbyPreview() private void RefreshEditors() { - _profileEditor?.RefreshAntags(); - _profileEditor?.RefreshJobs(); - _profileEditor?.RefreshLoadouts(); - _jobPriorityEditor?.RefreshJobs(); + ProfileEditor?.RefreshAntags(); + ProfileEditor?.RefreshJobs(); + ProfileEditor?.RefreshLoadouts(); + JobPriorityEditor?.RefreshJobs(); } /// @@ -208,9 +222,9 @@ private void RefreshEditors() /// private void SaveJobPriorities() { - if (_jobPriorityEditor == null) + if (JobPriorityEditor == null) return; - SaveJobPriorities(_jobPriorityEditor.SelectedJobPriorities); + SaveJobPriorities(JobPriorityEditor.SelectedJobPriorities); } /// @@ -221,7 +235,7 @@ private void SaveJobPriorities(Dictionary, JobPriority> ne { _preferencesManager.UpdateJobPriorities(newJobPriorities); OnAnyCharacterOrJobChange?.Invoke(); - _jobPriorityEditor?.LoadJobPriorities(); + JobPriorityEditor?.LoadJobPriorities(); var (characterGui, _) = EnsureGui(); characterGui.ReloadCharacterPickers(selectJobPriorities: true); } @@ -239,17 +253,17 @@ private void SaveProfile() _preferencesManager.UpdateCharacter(fixedProfile, EditedSlot.Value); OnAnyCharacterOrJobChange?.Invoke(); - _profileEditor?.SetProfile(EditedSlot.Value); + ProfileEditor?.SetProfile(EditedSlot.Value); ReloadCharacterSetup(); } private void CloseProfileEditor() { - if (_profileEditor == null) + if (ProfileEditor == null) return; - _profileEditor.SetProfile(null, null); - _profileEditor.Visible = false; + ProfileEditor.SetProfile(null, null); + ProfileEditor.Visible = false; if (_stateManager.CurrentState is LobbyState lobbyGui) { @@ -286,14 +300,14 @@ private void OpenSavePanel(Action saveAction) private (CharacterSetupGui, HumanoidProfileEditor) EnsureGui() { - if (_characterSetup != null && _profileEditor != null) + if (CharacterSetup != null && ProfileEditor != null) { - _characterSetup.Visible = true; - _profileEditor.Visible = true; - return (_characterSetup, _profileEditor); + CharacterSetup.Visible = true; + ProfileEditor.Visible = true; + return (CharacterSetup, ProfileEditor); } - _profileEditor = new HumanoidProfileEditor( + ProfileEditor = new HumanoidProfileEditor( _preferencesManager, _configurationManager, EntityManager, @@ -305,25 +319,25 @@ private void OpenSavePanel(Action saveAction) _requirements, _markings); - _jobPriorityEditor = new JobPriorityEditor(_preferencesManager, _prototypeManager, _requirements); + JobPriorityEditor = new JobPriorityEditor(_preferencesManager, _prototypeManager, _requirements); - _jobPriorityEditor.Save += SaveJobPriorities; + JobPriorityEditor.Save += SaveJobPriorities; - _profileEditor.OnOpenGuidebook += _guide.OpenHelp; + ProfileEditor.OnOpenGuidebook += _guide.OpenHelp; - _characterSetup = new CharacterSetupGui(_profileEditor, _jobPriorityEditor); + CharacterSetup = new CharacterSetupGui(ProfileEditor, JobPriorityEditor); - _characterSetup.CloseButton.OnPressed += _ => + CharacterSetup.CloseButton.OnPressed += _ => { // Open the save panel if we have unsaved changes. - if( _profileEditor.Visible && _profileEditor.Profile != null && _profileEditor.IsDirty) + if( ProfileEditor.Visible && ProfileEditor.Profile != null && ProfileEditor.IsDirty) { OpenSavePanel(SaveProfile); return; } - if (_jobPriorityEditor.Visible && _jobPriorityEditor.IsDirty()) + if (JobPriorityEditor.Visible && JobPriorityEditor.IsDirty()) { OpenSavePanel(SaveJobPriorities); @@ -334,17 +348,17 @@ private void OpenSavePanel(Action saveAction) CloseProfileEditor(); }; - _profileEditor.Save += SaveProfile; + ProfileEditor.Save += SaveProfile; - _characterSetup.SelectCharacter += args => + CharacterSetup.SelectCharacter += args => { - _profileEditor.SetProfile(args); - if (_characterSetup != null) - _characterSetup.SelectedCharacterSlot = args; + ProfileEditor.SetProfile(args); + if (CharacterSetup != null) + CharacterSetup.SelectedCharacterSlot = args; ReloadCharacterSetup(); }; - _characterSetup.DeleteCharacter += args => + CharacterSetup.DeleteCharacter += args => { _preferencesManager.DeleteCharacter(args); @@ -356,22 +370,22 @@ private void OpenSavePanel(Action saveAction) else { // Only need to reload character pickers - _characterSetup?.ReloadCharacterPickers(); + CharacterSetup?.ReloadCharacterPickers(); } }; - _characterSetup.SetCharacterEnable += args => + CharacterSetup.SetCharacterEnable += args => { _preferencesManager.SetCharacterEnable(args.Item1, args.Item2); OnAnyCharacterOrJobChange?.Invoke(); - _characterSetup?.ReloadCharacterPickers(); + CharacterSetup?.ReloadCharacterPickers(); }; if (_stateManager.CurrentState is LobbyState lobby) { - lobby.Lobby?.CharacterSetupState.AddChild(_characterSetup); + lobby.Lobby?.CharacterSetupState.AddChild(CharacterSetup); } - return (_characterSetup, _profileEditor); + return (CharacterSetup, ProfileEditor); } } diff --git a/Content.Client/Lobby/UI/CharacterSetupGui.xaml b/Content.Client/Lobby/UI/CharacterSetupGui.xaml index d1271dcd401e2..bf7eb936d7258 100644 --- a/Content.Client/Lobby/UI/CharacterSetupGui.xaml +++ b/Content.Client/Lobby/UI/CharacterSetupGui.xaml @@ -11,82 +11,105 @@ SPDX-FileCopyrightText: 2025 taydeo SPDX-License-Identifier: MIT --> - + - - -