From cd52641be9fa14d5d4a4f4a10e119f33d9f4ffa6 Mon Sep 17 00:00:00 2001 From: VMSolidus Date: Fri, 4 Apr 2025 18:50:31 +0300 Subject: [PATCH] Various Bugfixes (Mostly Traits System) (#2154) # Description ![faridaiscute](https://github.com/user-attachments/assets/a251d7d5-b80c-4ba5-9d03-3071ffdb8c94) Mfw a downstream fixes things only for themselves, leaving me to hear hundreds of complaints constantly about bugs that I don't have the time or manpower to fix upstream. # Changelog :cl: - fix: Fixed an issue that prevented players from saving item customizations if they didn't have enough loadout points to buy the item a second time. - add: Traits can now define the order in which they are applied. - fix: Fixed RGBee pushie not working. (cherry picked from commit bf3a0ec705acb9781ca5f5c2d200857b6a964a07) --- Content.Client/Light/RgbLightControllerSystem.cs | 5 ++++- .../Lobby/UI/HumanoidProfileEditor.xaml.cs | 9 +++++---- .../Lobby/UI/LoadoutPreferenceSelector.xaml.cs | 6 ++++++ Content.Server/Traits/TraitSystem.cs | 12 +++++++++++- .../Traits/Prototypes/TraitPrototype.cs | 16 ++++++++++++++-- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/Content.Client/Light/RgbLightControllerSystem.cs b/Content.Client/Light/RgbLightControllerSystem.cs index 7d55bcebf1..85b6114830 100644 --- a/Content.Client/Light/RgbLightControllerSystem.cs +++ b/Content.Client/Light/RgbLightControllerSystem.cs @@ -207,8 +207,11 @@ namespace Content.Client.Light public static Color GetCurrentRgbColor(TimeSpan curTime, TimeSpan offset, Entity rgb) { + var delta = (float)(curTime - offset).TotalSeconds; + var entOffset = Math.Abs(rgb.Owner.Id * 0.09817f); + var hue = (delta * rgb.Comp.CycleRate + entOffset) % 1; return Color.FromHsv(new Vector4( - (float) (((curTime.TotalSeconds - offset.TotalSeconds) * rgb.Comp.CycleRate + Math.Abs(rgb.Owner.Id * 0.1)) % 1), + MathF.Abs(hue), 1.0f, 1.0f, 1.0f diff --git a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs index 0ad24a7ad7..2cbfea2f69 100644 --- a/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs +++ b/Content.Client/Lobby/UI/HumanoidProfileEditor.xaml.cs @@ -2760,9 +2760,10 @@ namespace Content.Client.Lobby.UI selector.PreferenceChanged += preference => { // Make sure they have enough loadout points - var selected = preference.Selected - ? CheckPoints(-selector.Loadout.Cost, preference.Selected) - : CheckPoints(selector.Loadout.Cost, preference.Selected); + var wasSelected = Profile?.LoadoutPreferences + .FirstOrDefault(it => it.LoadoutName == selector.Loadout.ID) + ?.Selected ?? false; + var selected = preference.Selected && (wasSelected || CheckPoints(-selector.Loadout.Cost, true)); // Update Preferences Profile = Profile?.WithLoadoutPreference( @@ -2781,7 +2782,7 @@ namespace Content.Client.Lobby.UI bool CheckPoints(int points, bool preference) { var temp = LoadoutPointsBar.Value + points; - return preference ? !(temp < 0) : temp < 0; + return preference ? temp >= 0 : temp < 0; } } diff --git a/Content.Client/Lobby/UI/LoadoutPreferenceSelector.xaml.cs b/Content.Client/Lobby/UI/LoadoutPreferenceSelector.xaml.cs index 1765a47bc3..f4b3218592 100644 --- a/Content.Client/Lobby/UI/LoadoutPreferenceSelector.xaml.cs +++ b/Content.Client/Lobby/UI/LoadoutPreferenceSelector.xaml.cs @@ -207,11 +207,17 @@ public sealed partial class LoadoutPreferenceSelector : Control }); PreferenceButton.OnToggled += args => { + if (args.Pressed == _preference.Selected) + return; + _preference.Selected = args.Pressed; PreferenceChanged?.Invoke(Preference); }; HeirloomButton.OnToggled += args => { + if (args.Pressed == _preference.Selected) + return; + _preference.CustomHeirloom = args.Pressed ? true : null; PreferenceChanged?.Invoke(Preference); }; diff --git a/Content.Server/Traits/TraitSystem.cs b/Content.Server/Traits/TraitSystem.cs index 7c924b0fc1..252476f1aa 100644 --- a/Content.Server/Traits/TraitSystem.cs +++ b/Content.Server/Traits/TraitSystem.cs @@ -63,15 +63,25 @@ public sealed class TraitSystem : EntitySystem return; var jobPrototypeToUse = _prototype.Index(jobId ?? _prototype.EnumeratePrototypes().First().ID); + var sortedTraits = new List(); foreach (var traitId in profile.TraitPreferences) { - if (!_prototype.TryIndex(traitId, out var traitPrototype)) + if (_prototype.TryIndex(traitId, out var traitPrototype)) + { + sortedTraits.Add(traitPrototype); + } + else { DebugTools.Assert($"No trait found with ID {traitId}!"); return; } + } + sortedTraits.Sort(); + + foreach (var traitPrototype in sortedTraits) + { if (!traitPrototype.Enable || // WD EDIT !_characterRequirements.CheckRequirementsValid( traitPrototype.Requirements, diff --git a/Content.Shared/Traits/Prototypes/TraitPrototype.cs b/Content.Shared/Traits/Prototypes/TraitPrototype.cs index f5ea98ccd2..0bfe290ff1 100644 --- a/Content.Shared/Traits/Prototypes/TraitPrototype.cs +++ b/Content.Shared/Traits/Prototypes/TraitPrototype.cs @@ -1,7 +1,6 @@ using Content.Shared.Customization.Systems; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.Manager; -using Robust.Shared.Serialization; namespace Content.Shared.Traits; @@ -10,7 +9,7 @@ namespace Content.Shared.Traits; /// Describes a trait. /// [Prototype("trait")] -public sealed partial class TraitPrototype : IPrototype +public sealed partial class TraitPrototype : IPrototype, IComparable { [ViewVariables] [IdDataField] @@ -35,6 +34,19 @@ public sealed partial class TraitPrototype : IPrototype [DataField(serverOnly: true)] public TraitFunction[] Functions { get; private set; } = Array.Empty(); + /// + /// Should this trait be loaded earlier/later than other traits? + /// + [DataField] + public int Priority = 0; + public int CompareTo(object? obj) // Compare function to allow for some traits to specify they need to load earlier than others + { + if (obj is not TraitPrototype other) + return -1; + + return Priority.CompareTo(other.Priority); // No need for total ordering, only care about things that want to be loaded earlier or later. + } + // WD EDIT START [DataField] public bool Enable = true;