]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
LobbyUI fixes (#27033)
authormetalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Wed, 17 Apr 2024 02:54:54 +0000 (12:54 +1000)
committerGitHub <noreply@github.com>
Wed, 17 Apr 2024 02:54:54 +0000 (12:54 +1000)
* LobbyUI fixes

I have no idea which were bugs prior but anyway fix stuff.

* More fixes

* Test moment

Content.Client/Lobby/LobbyState.cs
Content.Client/Lobby/LobbyUIController.cs
Content.Client/Preferences/UI/CharacterSetupGui.xaml.cs
Content.Client/Preferences/UI/HumanoidProfileEditor.xaml.cs
Content.Client/Preferences/UI/RequirementsSelector.cs
Content.Shared/Preferences/HumanoidCharacterProfile.cs
Content.Shared/Preferences/Loadouts/RoleLoadout.cs

index 98c109afde18f30ef1a19fbad0bcab00cd1937d0..91730020a4e1c499e397c6a20e740459647050f9 100644 (file)
@@ -64,13 +64,19 @@ namespace Content.Client.Lobby
 
             _characterSetup.CloseButton.OnPressed += _ =>
             {
+                // Reset sliders etc.
+                _characterSetup?.UpdateControls();
+
+                var controller = _userInterfaceManager.GetUIController<LobbyUIController>();
+                controller.SetClothes(true);
+                controller.UpdateProfile();
                 _lobby.SwitchState(LobbyGui.LobbyGuiState.Default);
             };
 
             _characterSetup.SaveButton.OnPressed += _ =>
             {
                 _characterSetup.Save();
-                _userInterfaceManager.GetUIController<LobbyUIController>().UpdateCharacterUI();
+                _userInterfaceManager.GetUIController<LobbyUIController>().ReloadProfile();
             };
 
             LayoutContainer.SetAnchorPreset(_lobby, LayoutContainer.LayoutPreset.Wide);
index 19f43e05752bbfdac150fe9f371b2cde23bc16f5..9eb259657dc34b6b691f9ec4cd52892b2a90e2f2 100644 (file)
@@ -3,6 +3,7 @@ using Content.Client.Humanoid;
 using Content.Client.Inventory;
 using Content.Client.Lobby.UI;
 using Content.Client.Preferences;
+using Content.Client.Preferences.UI;
 using Content.Client.Station;
 using Content.Shared.Clothing;
 using Content.Shared.GameTicking;
@@ -30,6 +31,8 @@ public sealed class LobbyUIController : UIController, IOnStateEntered<LobbyState
 
     private LobbyCharacterPreviewPanel? _previewPanel;
 
+    private bool _showClothes = true;
+
     /*
      * Each character profile has its own dummy. There is also a dummy for the lobby screen + character editor
      * that is shared too.
@@ -41,13 +44,15 @@ public sealed class LobbyUIController : UIController, IOnStateEntered<LobbyState
     private EntityUid? _previewDummy;
 
     /// <summary>
-    /// If we currently have a loadout selected.
+    /// If we currently have a job prototype selected.
     /// </summary>
     private JobPrototype? _dummyJob;
 
     // TODO: Load the species directly and don't update entity ever.
     public event Action<EntityUid>? PreviewDummyUpdated;
 
+    private HumanoidCharacterProfile? _profile;
+
     public override void Initialize()
     {
         base.Initialize();
@@ -56,7 +61,7 @@ public sealed class LobbyUIController : UIController, IOnStateEntered<LobbyState
 
     private void PreferencesDataLoaded()
     {
-        UpdateCharacterUI();
+        UpdateProfile();
     }
 
     public void OnStateEntered(LobbyState state)
@@ -72,44 +77,102 @@ public sealed class LobbyUIController : UIController, IOnStateEntered<LobbyState
     public void SetPreviewPanel(LobbyCharacterPreviewPanel? panel)
     {
         _previewPanel = panel;
-        UpdateCharacterUI();
+        ReloadProfile();
+    }
+
+    public void SetClothes(bool value)
+    {
+        if (_showClothes == value)
+            return;
+
+        _showClothes = value;
+        ReloadCharacterUI();
     }
 
     public void SetDummyJob(JobPrototype? job)
     {
         _dummyJob = job;
-        UpdateCharacterUI();
+        ReloadCharacterUI();
     }
 
-    public void UpdateCharacterUI()
+    /// <summary>
+    /// Updates the character only with the specified profile change.
+    /// </summary>
+    public void ReloadProfile()
     {
         // Test moment
-        if (_stateManager.CurrentState is not LobbyState)
+        if (_profile == null || _stateManager.CurrentState is not LobbyState)
+            return;
+
+        // Ignore job clothes and the likes so we don't spam entities out every frame of color changes.
+        var previewDummy = EnsurePreviewDummy(_profile);
+        _humanoid.LoadProfile(previewDummy, _profile);
+    }
+
+    /// <summary>
+    /// Updates the currently selected character's preview.
+    /// </summary>
+    public void ReloadCharacterUI()
+    {
+        // Test moment
+        if (_profile == null || _stateManager.CurrentState is not LobbyState)
             return;
 
+        EntityManager.DeleteEntity(_previewDummy);
+        _previewDummy = null;
+        _previewDummy = EnsurePreviewDummy(_profile);
+        _previewPanel?.SetSprite(_previewDummy.Value);
+        _previewPanel?.SetSummaryText(_profile.Summary);
+        _humanoid.LoadProfile(_previewDummy.Value, _profile);
+
+        if (_showClothes)
+            GiveDummyJobClothesLoadout(_previewDummy.Value, _profile);
+    }
+
+    /// <summary>
+    /// Updates character profile to the default.
+    /// </summary>
+    public void UpdateProfile()
+    {
         if (!_preferencesManager.ServerDataLoaded)
         {
-            _previewPanel?.SetLoaded(false);
+            _profile = null;
             return;
         }
 
-        _previewPanel?.SetLoaded(true);
-
-        if (_preferencesManager.Preferences?.SelectedCharacter is not HumanoidCharacterProfile selectedCharacter)
+        if (_preferencesManager.Preferences?.SelectedCharacter is HumanoidCharacterProfile selectedCharacter)
         {
-            _previewPanel?.SetSummaryText(string.Empty);
+            _profile = selectedCharacter;
+            _previewPanel?.SetLoaded(true);
         }
         else
         {
-            EntityManager.DeleteEntity(_previewDummy);
-            _previewDummy = EntityManager.SpawnEntity(_prototypeManager.Index<SpeciesPrototype>(selectedCharacter.Species).DollPrototype, MapCoordinates.Nullspace);
-            _previewPanel?.SetSprite(_previewDummy.Value);
-            _previewPanel?.SetSummaryText(selectedCharacter.Summary);
-            _humanoid.LoadProfile(_previewDummy.Value, selectedCharacter);
-
-            GiveDummyJobClothesLoadout(_previewDummy.Value, selectedCharacter);
-            PreviewDummyUpdated?.Invoke(_previewDummy.Value);
+            _previewPanel?.SetSummaryText(string.Empty);
+            _previewPanel?.SetLoaded(false);
         }
+
+        ReloadCharacterUI();
+    }
+
+    public void UpdateProfile(HumanoidCharacterProfile? profile)
+    {
+        if (_profile?.Equals(profile) == true)
+            return;
+
+        if (_stateManager.CurrentState is not LobbyState)
+            return;
+
+        _profile = profile;
+    }
+
+    private EntityUid EnsurePreviewDummy(HumanoidCharacterProfile profile)
+    {
+        if (_previewDummy != null)
+            return _previewDummy.Value;
+
+        _previewDummy = EntityManager.SpawnEntity(_prototypeManager.Index<SpeciesPrototype>(profile.Species).DollPrototype, MapCoordinates.Nullspace);
+        PreviewDummyUpdated?.Invoke(_previewDummy.Value);
+        return _previewDummy.Value;
     }
 
     /// <summary>
index 0dcd5e6ad30d9bba601b22af6c3d963cac0c6479..ea8de09ab5c588fda2566a939631f5e42fd894dc 100644 (file)
@@ -97,9 +97,14 @@ namespace Content.Client.Preferences.UI
             UpdateUI();
         }
 
+        public void UpdateControls()
+        {
+            // Reset sliders etc. upon going going back to GUI.
+            _humanoidProfileEditor.LoadServerData();
+        }
+
         private void UpdateUI()
         {
-            UserInterfaceManager.GetUIController<LobbyUIController>().UpdateCharacterUI();
             var numberOfFullSlots = 0;
             var characterButtonsGroup = new ButtonGroup();
             Characters.RemoveAllChildren();
index e1135523f1ab68851643dbcc68a58bf5837a8690..59a44d0e4bfabff4fec179308bbc2e62e932e550 100644 (file)
@@ -190,7 +190,7 @@ namespace Content.Client.Preferences.UI
                     return;
                 Profile = Profile.WithCharacterAppearance(
                     Profile.Appearance.WithHairStyleName(newStyle.id));
-                IsDirty = true;
+                SetDirty();
             };
 
             _hairPicker.OnColorChanged += newColor =>
@@ -200,7 +200,7 @@ namespace Content.Client.Preferences.UI
                 Profile = Profile.WithCharacterAppearance(
                     Profile.Appearance.WithHairColor(newColor.marking.MarkingColors[0]));
                 UpdateCMarkingsHair();
-                IsDirty = true;
+                SetDirty();
             };
 
             _facialHairPicker.OnMarkingSelect += newStyle =>
@@ -209,7 +209,7 @@ namespace Content.Client.Preferences.UI
                     return;
                 Profile = Profile.WithCharacterAppearance(
                     Profile.Appearance.WithFacialHairStyleName(newStyle.id));
-                IsDirty = true;
+                SetDirty();
             };
 
             _facialHairPicker.OnColorChanged += newColor =>
@@ -219,7 +219,7 @@ namespace Content.Client.Preferences.UI
                 Profile = Profile.WithCharacterAppearance(
                     Profile.Appearance.WithFacialHairColor(newColor.marking.MarkingColors[0]));
                 UpdateCMarkingsFacialHair();
-                IsDirty = true;
+                SetDirty();
             };
 
             _hairPicker.OnSlotRemove += _ =>
@@ -231,7 +231,7 @@ namespace Content.Client.Preferences.UI
                 );
                 UpdateHairPickers();
                 UpdateCMarkingsHair();
-                IsDirty = true;
+                SetDirty();
             };
 
             _facialHairPicker.OnSlotRemove += _ =>
@@ -243,7 +243,7 @@ namespace Content.Client.Preferences.UI
                 );
                 UpdateHairPickers();
                 UpdateCMarkingsFacialHair();
-                IsDirty = true;
+                SetDirty();
             };
 
             _hairPicker.OnSlotAdd += delegate()
@@ -263,7 +263,7 @@ namespace Content.Client.Preferences.UI
 
                 UpdateHairPickers();
                 UpdateCMarkingsHair();
-                IsDirty = true;
+                SetDirty();
             };
 
             _facialHairPicker.OnSlotAdd += delegate()
@@ -283,7 +283,7 @@ namespace Content.Client.Preferences.UI
 
                 UpdateHairPickers();
                 UpdateCMarkingsFacialHair();
-                IsDirty = true;
+                SetDirty();
             };
 
             #endregion Hair
@@ -312,7 +312,7 @@ namespace Content.Client.Preferences.UI
                 Profile = Profile.WithCharacterAppearance(
                     Profile.Appearance.WithEyeColor(newColor));
                 CMarkings.CurrentEyeColor = Profile.Appearance.EyeColor;
-                IsDirty = true;
+                SetDirty();
             };
 
             #endregion Eyes
@@ -336,7 +336,7 @@ namespace Content.Client.Preferences.UI
                 _preferenceUnavailableButton.SelectId(args.Id);
 
                 Profile = Profile?.WithPreferenceUnavailable((PreferenceUnavailableMode) args.Id);
-                IsDirty = true;
+                SetDirty();
             };
 
             _jobPriorities = new List<JobPrioritySelector>();
@@ -369,7 +369,7 @@ namespace Content.Client.Preferences.UI
                     selector.PreferenceChanged += preference =>
                     {
                         Profile = Profile?.WithTraitPreference(trait.ID, preference);
-                        IsDirty = true;
+                        SetDirty();
                     };
                 }
             }
@@ -436,6 +436,13 @@ namespace Content.Client.Preferences.UI
                 LoadServerData();
             }
 
+            ShowClothes.OnToggled += args =>
+            {
+                var lobby = UserInterfaceManager.GetUIController<LobbyUIController>();
+                lobby.SetClothes(args.Pressed);
+                SetDirty();
+            };
+
             preferencesManager.OnServerDataLoaded += LoadServerData;
 
             SpeciesInfoButton.OnPressed += OnSpeciesInfoButtonPressed;
@@ -443,6 +450,15 @@ namespace Content.Client.Preferences.UI
             UpdateSpeciesGuidebookIcon();
 
             IsDirty = false;
+            controller.UpdateProfile();
+        }
+
+        private void SetDirty()
+        {
+            var controller = UserInterfaceManager.GetUIController<LobbyUIController>();
+            controller.UpdateProfile(Profile);
+            controller.ReloadCharacterUI();
+            IsDirty = true;
         }
 
         private void OnSpeciesInfoButtonPressed(BaseButton.ButtonEventArgs args)
@@ -487,13 +503,13 @@ namespace Content.Client.Preferences.UI
                 if (selector.Disabled)
                 {
                     Profile = Profile?.WithAntagPreference(antag.ID, false);
-                    IsDirty = true;
+                    SetDirty();
                 }
 
                 selector.PreferenceChanged += preference =>
                 {
                     Profile = Profile?.WithAntagPreference(antag.ID, preference);
-                    IsDirty = true;
+                    SetDirty();
                 };
             }
 
@@ -562,7 +578,10 @@ namespace Content.Client.Preferences.UI
                 foreach (var job in jobs)
                 {
                     RoleLoadout? loadout = null;
+
+                    // Clone so we don't modify the underlying loadout.
                     Profile?.Loadouts.TryGetValue(LoadoutSystem.GetJobPrototype(job.ID), out loadout);
+                    loadout = loadout?.Clone();
                     var selector = new JobPrioritySelector(loadout, job, jobLoadoutGroup, _prototypeManager)
                     {
                         Margin = new Thickness(3f, 3f, 3f, 0f),
@@ -578,15 +597,13 @@ namespace Content.Client.Preferences.UI
 
                     selector.LoadoutUpdated += args =>
                     {
-                        Profile?.SetLoadout(args);
-                        UserInterfaceManager.GetUIController<LobbyUIController>().UpdateCharacterUI();
-                        IsDirty = true;
+                        Profile = Profile?.WithLoadout(args);
+                        SetDirty();
                     };
 
                     selector.PriorityChanged += priority =>
                     {
                         Profile = Profile?.WithJobPriority(job.ID, priority);
-                        IsDirty = true;
 
                         foreach (var jobSelector in _jobPriorities)
                         {
@@ -602,6 +619,8 @@ namespace Content.Client.Preferences.UI
                                 Profile = Profile?.WithJobPriority(jobSelector.Proto.ID, JobPriority.Medium);
                             }
                         }
+
+                        SetDirty();
                     };
 
                 }
@@ -619,7 +638,7 @@ namespace Content.Client.Preferences.UI
                 return;
 
             Profile = Profile.WithFlavorText(content);
-            IsDirty = true;
+            SetDirty();
         }
 
         private void OnMarkingChange(MarkingSet markings)
@@ -628,8 +647,10 @@ namespace Content.Client.Preferences.UI
                 return;
 
             Profile = Profile.WithCharacterAppearance(Profile.Appearance.WithMarkings(markings.GetForwardEnumerator().ToList()));
-            UpdatePreview();
             IsDirty = true;
+            var controller = UserInterfaceManager.GetUIController<LobbyUIController>();
+            controller.UpdateProfile(Profile);
+            controller.ReloadProfile();
         }
 
         private void OnSkinColorOnValueChanged()
@@ -683,6 +704,9 @@ namespace Content.Client.Preferences.UI
             }
 
             IsDirty = true;
+            var controller = UserInterfaceManager.GetUIController<LobbyUIController>();
+            controller.UpdateProfile(Profile);
+            controller.ReloadProfile();
         }
 
         protected override void Dispose(bool disposing)
@@ -698,7 +722,7 @@ namespace Content.Client.Preferences.UI
             _preferencesManager.OnServerDataLoaded -= LoadServerData;
         }
 
-        private void LoadServerData()
+        public void LoadServerData()
         {
             Profile = (HumanoidCharacterProfile) _preferencesManager.Preferences!.SelectedCharacter;
             CharacterSlot = _preferencesManager.Preferences.SelectedCharacterIndex;
@@ -706,12 +730,13 @@ namespace Content.Client.Preferences.UI
             UpdateAntagRequirements();
             UpdateRoleRequirements();
             UpdateControls();
+            ShowClothes.Pressed = true;
         }
 
         private void SetAge(int newAge)
         {
             Profile = Profile?.WithAge(newAge);
-            IsDirty = true;
+            SetDirty();
         }
 
         private void SetSex(Sex newSex)
@@ -732,13 +757,13 @@ namespace Content.Client.Preferences.UI
             }
             UpdateGenderControls();
             CMarkings.SetSex(newSex);
-            IsDirty = true;
+            SetDirty();
         }
 
         private void SetGender(Gender newGender)
         {
             Profile = Profile?.WithGender(newGender);
-            IsDirty = true;
+            SetDirty();
         }
 
         private void SetSpecies(string newSpecies)
@@ -748,20 +773,20 @@ namespace Content.Client.Preferences.UI
             CMarkings.SetSpecies(newSpecies); // Repopulate the markings tab as well.
             UpdateSexControls(); // update sex for new species
             UpdateSpeciesGuidebookIcon();
-            IsDirty = true;
+            SetDirty();
             UpdatePreview();
         }
 
         private void SetName(string newName)
         {
             Profile = Profile?.WithName(newName);
-            IsDirty = true;
+            SetDirty();
         }
 
         private void SetSpawnPriority(SpawnPriorityPreference newSpawnPriority)
         {
             Profile = Profile?.WithSpawnPriorityPreference(newSpawnPriority);
-            IsDirty = true;
+            SetDirty();
         }
 
         public void Save()
@@ -773,6 +798,8 @@ namespace Content.Client.Preferences.UI
 
             _preferencesManager.UpdateCharacter(Profile, CharacterSlot);
             OnProfileChanged?.Invoke(Profile, CharacterSlot);
+            // Reset profile to default.
+            UserInterfaceManager.GetUIController<LobbyUIController>().UpdateProfile();
         }
 
         private bool IsDirty
@@ -1065,7 +1092,7 @@ namespace Content.Client.Preferences.UI
             if (Profile is null)
                 return;
 
-            UserInterfaceManager.GetUIController<LobbyUIController>().UpdateCharacterUI();
+            UserInterfaceManager.GetUIController<LobbyUIController>().ReloadProfile();
             SetPreviewRotation(_previewRotation);
         }
 
index 97c75f338086284740122e034c0f92111521f0a5..e016661ee6ca9cefb845b226c533e09f355e6b29 100644 (file)
@@ -153,7 +153,7 @@ public abstract class RequirementsSelector<T> : BoxContainer where T : IPrototyp
                         _loadout.EnsureValid(session, collection);
                         _loadoutWindow.RefreshLoadouts(_loadout, session, collection);
                         var controller = UserInterfaceManager.GetUIController<LobbyUIController>();
-                        controller.UpdateCharacterUI();
+                        controller.ReloadProfile();
                         LoadoutUpdated?.Invoke(_loadout);
                     };
 
@@ -165,7 +165,7 @@ public abstract class RequirementsSelector<T> : BoxContainer where T : IPrototyp
                         _loadout.EnsureValid(session, collection);
                         _loadoutWindow.RefreshLoadouts(_loadout, session, collection);
                         var controller = UserInterfaceManager.GetUIController<LobbyUIController>();
-                        controller.UpdateCharacterUI();
+                        controller.ReloadProfile();
                         LoadoutUpdated?.Invoke(_loadout);
                     };
 
index 3f3521fda6ad5bb12496657e3c0521e79bd2863f..bd2a7f329aa3a34a68dc9d4f92ed7dbc236993c4 100644 (file)
@@ -315,6 +315,7 @@ namespace Content.Shared.Preferences
                     list.Remove(antagId);
                 }
             }
+
             return new(this, _jobPriorities, list, _traitPreferences, _loadouts);
         }
 
@@ -565,6 +566,23 @@ namespace Content.Shared.Preferences
             _loadouts[loadout.Role.Id] = loadout;
         }
 
+        public HumanoidCharacterProfile WithLoadout(RoleLoadout loadout)
+        {
+            // Deep copies so we don't modify the DB profile.
+            var copied = new Dictionary<string, RoleLoadout>();
+
+            foreach (var proto in _loadouts)
+            {
+                if (proto.Key == loadout.Role)
+                    continue;
+
+                copied[proto.Key] = proto.Value.Clone();
+            }
+
+            copied[loadout.Role] = loadout.Clone();
+            return new(this, _jobPriorities, _antagPreferences, _traitPreferences, copied);
+        }
+
         public RoleLoadout GetLoadoutOrDefault(string id, IEntityManager entManager, IPrototypeManager protoManager)
         {
             if (!_loadouts.TryGetValue(id, out var loadout))
index 78cd376c85911844b0ffa02b9af486bd0bbe65a5..e1c6f8395d0481b0b2ef65733b91d7f3410991dc 100644 (file)
@@ -29,6 +29,18 @@ public sealed class RoleLoadout
         Role = role;
     }
 
+    public RoleLoadout Clone()
+    {
+        var weh = new RoleLoadout(Role);
+
+        foreach (var selected in SelectedLoadouts)
+        {
+            weh.SelectedLoadouts.Add(selected.Key, new List<Loadout>(selected.Value));
+        }
+
+        return weh;
+    }
+
     /// <summary>
     /// Ensures all prototypes exist and effects can be applied.
     /// </summary>