diff --git a/OpenRA.Mods.Common/Traits/World/ColorPickerManager.cs b/OpenRA.Mods.Common/Traits/World/ColorPickerManager.cs index 8e3d78cc25..fba52d08d9 100644 --- a/OpenRA.Mods.Common/Traits/World/ColorPickerManager.cs +++ b/OpenRA.Mods.Common/Traits/World/ColorPickerManager.cs @@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Traits { [TraitLocation(SystemActors.World)] [Desc("Configuration options for the lobby player color picker. Attach this to the world actor.")] - public class ColorPickerManagerInfo : TraitInfo, IRulesetLoaded + public class ColorPickerManagerInfo : TraitInfo { [TranslationReference] const string PlayerColorTerrain = "notification-player-color-terrain"; @@ -34,17 +34,14 @@ namespace OpenRA.Mods.Common.Traits [Desc("Minimum and maximum saturation levels that are valid for use.")] public readonly float[] HsvSaturationRange = { 0.3f, 0.95f }; - [Desc("HSV value component for player colors.")] - public readonly float V = 0.95f; + [Desc("Minimum and maximum value levels that are valid for use.")] + public readonly float[] HsvValueRange = { 0.3f, 0.95f }; [Desc("Perceptual color threshold for determining whether two colors are too similar.")] public readonly float SimilarityThreshold = 0.314f; - [Desc("List of hue components for the preset colors in the palette tab. Each entry must have a corresponding PresetSaturations definition.")] - public readonly float[] PresetHues = Array.Empty(); - - [Desc("List of saturation components for the preset colors in the palette tab. Each entry must have a corresponding PresetHues definition.")] - public readonly float[] PresetSaturations = Array.Empty(); + [Desc("List of colors to be displayed in the palette tab.")] + public readonly Color[] PresetColors = Array.Empty(); [ActorReference] [Desc("Actor type to show in the color picker. This can be overridden for specific factions with FactionPreviewActors.")] @@ -55,18 +52,6 @@ namespace OpenRA.Mods.Common.Traits "A dictionary of [faction name]: [actor name].")] public readonly Dictionary FactionPreviewActors = new(); - public void RulesetLoaded(Ruleset rules, ActorInfo ai) - { - if (PresetHues.Length != PresetSaturations.Length) - throw new YamlException("PresetHues and PresetSaturations must have the same number of elements."); - } - - public IEnumerable PresetColors() - { - for (var i = 0; i < PresetHues.Length; i++) - yield return Color.FromAhsv(PresetHues[i], PresetSaturations[i], V); - } - public Color Color; bool TryGetBlockingColor((float R, float G, float B) color, List<(float R, float G, float B)> candidateBlockers, out (float R, float G, float B) closestBlocker) @@ -102,60 +87,56 @@ namespace OpenRA.Mods.Common.Traits var terrainLinear = terrainColors.Select(c => c.ToLinear()).ToList(); var playerLinear = playerColors.Select(c => c.ToLinear()).ToList(); - if (PresetHues.Length > 0) + foreach (var color in PresetColors.Shuffle(random)) { - foreach (var i in Exts.MakeArray(PresetHues.Length, x => x).Shuffle(random)) - { - var h = PresetHues[i]; - var s = PresetSaturations[i]; - var preset = Color.FromAhsv(h, s, V); - - // Color may already be taken - var linear = preset.ToLinear(); - if (!TryGetBlockingColor(linear, terrainLinear, out _) && !TryGetBlockingColor(linear, playerLinear, out _)) - return preset; - } + // Color may already be taken + var linear = color.ToLinear(); + if (!TryGetBlockingColor(linear, terrainLinear, out _) && !TryGetBlockingColor(linear, playerLinear, out _)) + return color; } // Fall back to a random non-preset color var randomHue = random.NextFloat(); var randomSat = float2.Lerp(HsvSaturationRange[0], HsvSaturationRange[1], random.NextFloat()); - return MakeValid(randomHue, randomSat, random, terrainLinear, playerLinear, null); + var randomVal = float2.Lerp(HsvValueRange[0], HsvValueRange[1], random.NextFloat()); + return MakeValid(randomHue, randomSat, randomVal, random, terrainLinear, playerLinear, null); } public Color RandomValidColor(MersenneTwister random, IEnumerable terrainColors, IEnumerable playerColors) { var h = random.NextFloat(); var s = float2.Lerp(HsvSaturationRange[0], HsvSaturationRange[1], random.NextFloat()); - return MakeValid(h, s, random, terrainColors, playerColors, null); + var v = float2.Lerp(HsvValueRange[0], HsvValueRange[1], random.NextFloat()); + return MakeValid(h, s, v, random, terrainColors, playerColors, null); } public Color MakeValid(Color color, MersenneTwister random, IEnumerable terrainColors, IEnumerable playerColors, Action onError = null) { - var (_, h, s, _) = color.ToAhsv(); - return MakeValid(h, s, random, terrainColors, playerColors, onError); + var (_, h, s, v) = color.ToAhsv(); + return MakeValid(h, s, v, random, terrainColors, playerColors, onError); } - Color MakeValid(float hue, float sat, MersenneTwister random, IEnumerable terrainColors, IEnumerable playerColors, Action onError) + Color MakeValid(float hue, float sat, float val, MersenneTwister random, IEnumerable terrainColors, IEnumerable playerColors, Action onError) { var terrainLinear = terrainColors.Select(c => c.ToLinear()).ToList(); var playerLinear = playerColors.Select(c => c.ToLinear()).ToList(); - return MakeValid(hue, sat, random, terrainLinear, playerLinear, onError); + return MakeValid(hue, sat, val, random, terrainLinear, playerLinear, onError); } - Color MakeValid(float hue, float sat, MersenneTwister random, List<(float R, float G, float B)> terrainLinear, List<(float R, float G, float B)> playerLinear, Action onError) + Color MakeValid(float hue, float sat, float val, MersenneTwister random, List<(float R, float G, float B)> terrainLinear, List<(float R, float G, float B)> playerLinear, Action onError) { // Clamp saturation without triggering a warning // This can only happen due to rounding errors (common) or modified clients (rare) sat = sat.Clamp(HsvSaturationRange[0], HsvSaturationRange[1]); + val = val.Clamp(HsvValueRange[0], HsvValueRange[1]); // Limit to 100 attempts, which is enough to move all the way around the hue range string errorMessage = null; var stepSign = 0; for (var i = 0; i < 101; i++) { - var linear = Color.FromAhsv(hue, sat, V).ToLinear(); + var linear = Color.FromAhsv(hue, sat, val).ToLinear(); if (TryGetBlockingColor(linear, terrainLinear, out var blocker)) errorMessage = PlayerColorTerrain; else if (TryGetBlockingColor(linear, playerLinear, out blocker)) @@ -165,7 +146,7 @@ namespace OpenRA.Mods.Common.Traits if (errorMessage != null) onError?.Invoke(errorMessage); - return Color.FromAhsv(hue, sat, V); + return Color.FromAhsv(hue, sat, val); } // Pick a direction based on the first blocking color and step in hue @@ -179,7 +160,9 @@ namespace OpenRA.Mods.Common.Traits // Failed to find a solution within a reasonable time: return a random color without any validation onError?.Invoke(InvalidPlayerColor); - return Color.FromAhsv(random.NextFloat(), float2.Lerp(HsvSaturationRange[0], HsvSaturationRange[1], random.NextFloat()), V); + var randomSat = float2.Lerp(HsvSaturationRange[0], HsvSaturationRange[1], random.NextFloat()); + var randomVal = float2.Lerp(HsvValueRange[0], HsvValueRange[1], random.NextFloat()); + return Color.FromAhsv(random.NextFloat(), randomSat, randomVal); } } diff --git a/OpenRA.Mods.Common/UpdateRules/Rules/20221203/AddColorPickerValueRange.cs b/OpenRA.Mods.Common/UpdateRules/Rules/20221203/AddColorPickerValueRange.cs new file mode 100644 index 0000000000..b4d933a782 --- /dev/null +++ b/OpenRA.Mods.Common/UpdateRules/Rules/20221203/AddColorPickerValueRange.cs @@ -0,0 +1,48 @@ +#region Copyright & License Information +/* + * Copyright (c) The OpenRA Developers and Contributors + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System.Collections.Generic; +using OpenRA.Primitives; + +namespace OpenRA.Mods.Common.UpdateRules.Rules +{ + public class AddColorPickerValueRange : UpdateRule + { + public override string Name => "ColorPickerManager's PresetHues, PresetSaturations and V were replaced with PresetColors."; + + public override string Description => + "Each preset color can now have their brightness specified."; + + public override IEnumerable UpdateActorNode(ModData modData, MiniYamlNode actorNode) + { + var manager = actorNode.LastChildMatching("ColorPickerManager"); + if (manager == null) + yield break; + + var v = manager.LastChildMatching("V")?.NodeValue() ?? 0.95f; + var hues = manager.LastChildMatching("PresetHues")?.NodeValue(); + var saturations = manager.LastChildMatching("PresetSaturations")?.NodeValue(); + + manager.RemoveNodes("V"); + manager.RemoveNodes("PresetHues"); + manager.RemoveNodes("PresetSaturations"); + + if (hues == null || saturations == null) + yield break; + + var colors = new Color[hues.Length]; + for (var i = 0; i < colors.Length; i++) + colors[i] = Color.FromAhsv(hues[i], saturations[i], v); + + manager.AddNode("PresetColors", colors); + } + } +} diff --git a/OpenRA.Mods.Common/Widgets/ColorMixerWidget.cs b/OpenRA.Mods.Common/Widgets/ColorMixerWidget.cs index d9e395aee1..4f2bf04e3f 100644 --- a/OpenRA.Mods.Common/Widgets/ColorMixerWidget.cs +++ b/OpenRA.Mods.Common/Widgets/ColorMixerWidget.cs @@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Widgets public float H { get; private set; } public float S { get; private set; } public float V { get; private set; } - float minSat, maxSat; + float minSat, maxSat, minVal, maxVal; Sheet mixerSheet; Sprite mixerSprite; @@ -37,7 +37,6 @@ namespace OpenRA.Mods.Common.Widgets public ColorMixerWidget(ModData modData) { modRules = modData.DefaultRules; - V = 1.0f; } public ColorMixerWidget(ColorMixerWidget other) @@ -51,13 +50,19 @@ namespace OpenRA.Mods.Common.Widgets V = other.V; minSat = other.minSat; maxSat = other.maxSat; + minVal = other.minVal; + maxVal = other.maxVal; } - public void SetColorLimits(float minSaturation, float maxSaturation, float v) + public void SetColorLimits(float minSaturation, float maxSaturation, float minValue, float maxValue, float? newHue = null) { minSat = minSaturation; maxSat = maxSaturation; - V = v; + minVal = minValue; + maxVal = maxValue; + + if (newHue == null) + newHue = H; var buffer = new byte[4 * 256 * 256]; unsafe @@ -66,19 +71,25 @@ namespace OpenRA.Mods.Common.Widgets fixed (byte* cc = &buffer[0]) { var c = (int*)cc; - for (var s = 0; s < 256; s++) - for (var h = 0; h < 256; h++) + for (var v = 0; v < 256; v++) + { + for (var s = 0; s < 256; s++) { #pragma warning disable IDE0047 - (*(c + s * 256 + h)) = Color.FromAhsv(h / 255f, 1 - s / 255f, V).ToArgb(); + (*(c + s * 256 + v)) = Color.FromAhsv(newHue.Value, 1 - s / 255f, v / 255f).ToArgb(); #pragma warning restore IDE0047 } + } } } - var rect = new Rectangle(0, (int)(255 * (1 - maxSat)), 255, (int)(255 * (maxSat - minSat)) + 1); - mixerSprite = new Sprite(mixerSheet, rect, TextureChannel.RGBA); + var rect = new Rectangle( + (int)(255 * minVal), + (int)(255 * (1 - maxSat)), + (int)(255 * (maxVal - minVal)), + (int)(255 * (maxSat - minSat)) + 1); + mixerSprite = new Sprite(mixerSheet, rect, TextureChannel.RGBA); mixerSheet.GetTexture().SetData(buffer, 256, 256); } @@ -87,7 +98,7 @@ namespace OpenRA.Mods.Common.Widgets base.Initialize(args); mixerSheet = new Sheet(SheetType.BGRA, new Size(256, 256)); - SetColorLimits(minSat, maxSat, V); + SetColorLimits(minSat, maxSat, minVal, maxVal); } public override void Draw() @@ -103,17 +114,17 @@ namespace OpenRA.Mods.Common.Widgets void SetValueFromPx(int2 xy) { var rb = RenderBounds; - var h = xy.X * 1f / rb.Width; + var v = float2.Lerp(minVal, maxVal, xy.X * 1f / rb.Width); var s = float2.Lerp(minSat, maxSat, 1 - xy.Y * 1f / rb.Height); - H = h.Clamp(0, 1f); + V = v.Clamp(minVal, maxVal); S = s.Clamp(minSat, maxSat); } int2 PxFromValue() { var rb = RenderBounds; - var x = RenderBounds.Width * H; - var y = RenderBounds.Height * (1 - (S - minSat) / (maxSat - minSat)); + var x = rb.Width * (V - minVal) / (maxVal - minVal); + var y = rb.Height * (1 - (S - minSat) / (maxSat - minSat)); return new int2((int)x.Clamp(0, rb.Width), (int)y.Clamp(0, rb.Height)); } @@ -162,12 +173,13 @@ namespace OpenRA.Mods.Common.Widgets /// public void Set(Color color) { - var (_, h, s, _) = color.ToAhsv(); + var (_, h, s, v) = color.ToAhsv(); - if (H != h || S != s) + if (H != h || S != s || V != v) { H = h; S = s.Clamp(minSat, maxSat); + V = v.Clamp(minVal, maxVal); OnChange(); } } diff --git a/OpenRA.Mods.Common/Widgets/HueSliderWidget.cs b/OpenRA.Mods.Common/Widgets/HueSliderWidget.cs new file mode 100644 index 0000000000..2c9f9dca10 --- /dev/null +++ b/OpenRA.Mods.Common/Widgets/HueSliderWidget.cs @@ -0,0 +1,69 @@ +#region Copyright & License Information +/* + * Copyright (c) The OpenRA Developers and Contributors + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using OpenRA.Graphics; +using OpenRA.Primitives; +using OpenRA.Widgets; + +namespace OpenRA.Mods.Common.Widgets +{ + public class HueSliderWidget : SliderWidget + { + Sprite hueSprite; + Sprite pickerSprite; + + public HueSliderWidget() { } + public HueSliderWidget(HueSliderWidget other) + : base(other) { } + + public override void Initialize(WidgetArgs args) + { + base.Initialize(args); + + var hueSheet = new Sheet(SheetType.BGRA, new Size(256, 1)); + + var buffer = new byte[4 * 256]; + + unsafe + { + fixed (byte* cc = &buffer[0]) + { + var c = (int*)cc; + for (var h = 0; h < 256; h++) + { + #pragma warning disable IDE0047 + (*(c + 0 * 256 + h)) = Color.FromAhsv(h / 255f, 1, 1).ToArgb(); + #pragma warning restore IDE0047 + } + } + } + + var rect = new Rectangle(0, 0, 256, 1); + hueSprite = new Sprite(hueSheet, new Rectangle(0, 0, 256, 1), TextureChannel.RGBA); + hueSheet.GetTexture().SetData(buffer, 256, 1); + + pickerSprite = ChromeProvider.GetImage("lobby-bits", "huepicker"); + } + + public override void Draw() + { + if (!IsVisible()) + return; + + var ro = RenderOrigin; + var rb = RenderBounds; + WidgetUtils.DrawSprite(hueSprite, ro, rb.Size); + + var pos = RenderOrigin + new int2(PxFromValue(Value).Clamp(0, rb.Width - 1) - (int)pickerSprite.Size.X / 2, (rb.Height - (int)pickerSprite.Size.Y) / 2); + WidgetUtils.DrawSprite(pickerSprite, pos); + } + } +} diff --git a/OpenRA.Mods.Common/Widgets/Logic/ColorPickerLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/ColorPickerLogic.cs index 37c6c4e0e5..dbaa17d31f 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/ColorPickerLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/ColorPickerLogic.cs @@ -29,14 +29,25 @@ namespace OpenRA.Mods.Common.Widgets.Logic Dictionary logicArgs) { var mixer = widget.Get("MIXER"); + var hueSlider = widget.Get("HUE_SLIDER"); // Set the initial state // All users need to use the same TraitInfo instance, chosen as the default mod rules var colorManager = modData.DefaultRules.Actors[SystemActors.World].TraitInfo(); - mixer.SetColorLimits(colorManager.HsvSaturationRange[0], colorManager.HsvSaturationRange[1], colorManager.V); + mixer.SetColorLimits(colorManager.HsvSaturationRange[0], colorManager.HsvSaturationRange[1], colorManager.HsvValueRange[0], colorManager.HsvValueRange[1]); mixer.OnChange += () => onChange(mixer.Color); mixer.Set(initialColor); + hueSlider.OnChange += h => + { + mixer.SetColorLimits(colorManager.HsvSaturationRange[0], colorManager.HsvSaturationRange[1], colorManager.HsvValueRange[0], colorManager.HsvValueRange[1], h); + var (_, _, s, v) = mixer.Color.ToAhsv(); + mixer.Set(Color.FromAhsv(h, s, v)); + onChange(mixer.Color); + }; + + hueSlider.UpdateValue(initialColor.ToAhsv().H); + var randomButton = widget.GetOrNull("RANDOM_BUTTON"); if (randomButton != null) { @@ -45,7 +56,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic .Distinct() .ToList(); var playerColors = Enumerable.Empty(); - randomButton.OnClick = () => mixer.Set(colorManager.RandomValidColor(world.LocalRandom, terrainColors, playerColors)); + randomButton.OnClick = () => + { + var randomColor = colorManager.RandomValidColor(world.LocalRandom, terrainColors, playerColors); + mixer.Set(randomColor); + hueSlider.UpdateValue(randomColor.ToAhsv().H); + }; } if (initialFaction == null || !colorManager.FactionPreviewActors.TryGetValue(initialFaction, out var actorType)) @@ -117,13 +133,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (!int.TryParse(yaml.Value, out paletteCustomRows)) throw new YamlException($"Invalid value for PaletteCustomRows: {yaml.Value}"); - var presetColors = colorManager.PresetColors().ToList(); + var presetColors = colorManager.PresetColors; for (var j = 0; j < palettePresetRows; j++) { for (var i = 0; i < paletteCols; i++) { var colorIndex = j * paletteCols + i; - if (colorIndex >= presetColors.Count) + if (colorIndex >= presetColors.Length) break; var color = presetColors[colorIndex]; @@ -136,7 +152,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic newSwatch.OnMouseUp = m => { mixer.Set(color); - onChange(color); + hueSlider.UpdateValue(color.ToAhsv().H); }; presetArea.AddChild(newSwatch); @@ -160,7 +176,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic { var color = newSwatch.GetColor(); mixer.Set(color); - onChange(color); + hueSlider.UpdateValue(color.ToAhsv().H); }; customArea.AddChild(newSwatch); diff --git a/mods/cnc/chrome/color-picker.yaml b/mods/cnc/chrome/color-picker.yaml index 0ef367706f..5fe0eea0a3 100644 --- a/mods/cnc/chrome/color-picker.yaml +++ b/mods/cnc/chrome/color-picker.yaml @@ -47,12 +47,25 @@ Background@COLOR_CHOOSER: Width: PARENT_RIGHT - 91 Height: PARENT_BOTTOM - 34 Children: - Background@MIXERBG: + Background@HUEBG: Background: panel-black X: 0 Y: 0 Width: PARENT_RIGHT - Height: 114 + Height: 17 + Children: + HueSlider@HUE_SLIDER: + X: 2 + Y: 2 + Width: PARENT_RIGHT - 4 + Height: PARENT_BOTTOM - 4 + Ticks: 5 + Background@MIXERBG: + Background: panel-black + X: 0 + Y: 21 + Width: PARENT_RIGHT + Height: PARENT_BOTTOM - 21 Children: ColorMixer@MIXER: X: 2 diff --git a/mods/cnc/rules/world.yaml b/mods/cnc/rules/world.yaml index 4db955887c..3f77179c1a 100644 --- a/mods/cnc/rules/world.yaml +++ b/mods/cnc/rules/world.yaml @@ -269,8 +269,7 @@ World: TimeLimitDisplayOrder: 2 ColorPickerManager: PreviewActor: fact.colorpicker - PresetHues: 0, 0.125, 0.185, 0.4, 0.54, 0.66, 0.79, 0.875, 0, 0.14, 0.23, 0.43, 0.54, 0.625, 0.77, 0.85 - PresetSaturations: 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.4, 0.5, 0.4, 0.5, 0.4, 0.5, 0.4, 0.5 + PresetColors: F21818, F2BC18, DAF218, 18F26F, 18BEF2, 1821F2, BA18F2, F218BC, F29191, F2DF79, CDF291, 79F2BF, 91DBF2, 7997F2, CD91F2, F279E6 OrderEffects: TerrainFlashImage: moveflsh TerrainFlashSequence: idle diff --git a/mods/cnc/sequences/civilian.yaml b/mods/cnc/sequences/civilian.yaml index 5d27f7f56c..e42f181384 100644 --- a/mods/cnc/sequences/civilian.yaml +++ b/mods/cnc/sequences/civilian.yaml @@ -145,7 +145,7 @@ moebius: Length: 4 Tick: 1600 -chan: +chan: Inherits: moebius Defaults: Filename: chan.shp diff --git a/mods/common/chrome/color-picker.yaml b/mods/common/chrome/color-picker.yaml index 346ee832f8..299125d98f 100644 --- a/mods/common/chrome/color-picker.yaml +++ b/mods/common/chrome/color-picker.yaml @@ -41,18 +41,37 @@ Background@COLOR_CHOOSER: Width: 80 Text: Palette Font: Bold - Background@MIXER_TAB: - Background: dialog3 + Container@MIXER_TAB: X: 5 Y: 5 Width: PARENT_RIGHT - 90 Height: PARENT_BOTTOM - 34 Children: - ColorMixer@MIXER: - X: 2 - Y: 2 - Width: PARENT_RIGHT - 4 - Height: PARENT_BOTTOM - 4 + Background@HUEBG: + Background: dialog3 + X: 0 + Y: 0 + Width: PARENT_RIGHT + Height: 17 + Children: + HueSlider@HUE_SLIDER: + X: 2 + Y: 2 + Width: PARENT_RIGHT - 4 + Height: PARENT_BOTTOM - 4 + Ticks: 5 + Background@MIXERBG: + Background: dialog3 + X: 0 + Y: 22 + Width: PARENT_RIGHT + Height: PARENT_BOTTOM - 22 + Children: + ColorMixer@MIXER: + X: 2 + Y: 2 + Width: PARENT_RIGHT - 4 + Height: PARENT_BOTTOM - 4 Background@PALETTE_TAB: Background: dialog3 X: 5 diff --git a/mods/d2k/rules/world.yaml b/mods/d2k/rules/world.yaml index 63b0bcb657..f1bfe2a6e7 100644 --- a/mods/d2k/rules/world.yaml +++ b/mods/d2k/rules/world.yaml @@ -240,8 +240,7 @@ World: TimeLimitDisplayOrder: 2 ColorPickerManager: PreviewActor: carryall.colorpicker - PresetHues: 0, 0.13, 0.18, 0.3, 0.475, 0.625, 0.82, 0.89, 0.97, 0.05, 0.23, 0.375, 0.525, 0.6, 0.75, 0.85 - PresetSaturations: 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.5, 0.35, 0.4, 0.4, 0.5, 0.5, 0.4, 0.35 + PresetColors: F21818, F2C218, E1F218, 44F218, 18F2D2, 184FF2, E118F2, F218A8, F2798F, F2B79D, CDF291, 91F2AA, 79E0F2, 79AAF2, C291F2, F29DEA OrderEffects: TerrainFlashImage: moveflsh TerrainFlashSequence: idle diff --git a/mods/ra/rules/world.yaml b/mods/ra/rules/world.yaml index c60c5ca1ac..7048e03fe3 100644 --- a/mods/ra/rules/world.yaml +++ b/mods/ra/rules/world.yaml @@ -290,8 +290,7 @@ World: 1: WarningOneMinuteRemaining ColorPickerManager: PreviewActor: fact.colorpicker - PresetHues: 0, 0.125, 0.22, 0.375, 0.5, 0.56, 0.8, 0.88, 0, 0.15, 0.235, 0.4, 0.47, 0.55, 0.75, 0.85 - PresetSaturations: 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.4, 0.5, 0.4, 0.5, 0.4, 0.5, 0.4, 0.5 + PresetColors: F21818, F2BC18, ACF218, 18F24F, 18F2F2, 18A4F2, C718F2, F218B5, F29191, F2E679, CBF291, 79F2AA, 91F2E1, 79CEF2, C291F2, F279E6 OrderEffects: TerrainFlashImage: moveflsh TerrainFlashSequence: idle diff --git a/mods/ts/chrome/color-picker.yaml b/mods/ts/chrome/color-picker.yaml index 29dae33527..2de266df87 100644 --- a/mods/ts/chrome/color-picker.yaml +++ b/mods/ts/chrome/color-picker.yaml @@ -42,18 +42,37 @@ Background@COLOR_CHOOSER: Width: 80 Text: Palette Font: Bold - Background@MIXER_TAB: - Background: dialog3 + Container@MIXER_TAB: X: 5 Y: 5 Width: PARENT_RIGHT - 94 Height: PARENT_BOTTOM - 34 Children: - ColorMixer@MIXER: - X: 2 - Y: 2 - Width: PARENT_RIGHT - 4 - Height: PARENT_BOTTOM - 4 + Background@HUEBG: + Background: dialog3 + X: 0 + Y: 0 + Width: PARENT_RIGHT + Height: 17 + Children: + HueSlider@HUE_SLIDER: + X: 2 + Y: 2 + Width: PARENT_RIGHT - 4 + Height: PARENT_BOTTOM - 4 + Ticks: 5 + Background@MIXERBG: + Background: dialog3 + X: 0 + Y: 22 + Width: PARENT_RIGHT + Height: PARENT_BOTTOM - 22 + Children: + ColorMixer@MIXER: + X: 2 + Y: 2 + Width: PARENT_RIGHT - 4 + Height: PARENT_BOTTOM - 4 Background@PALETTE_TAB: Background: dialog3 X: 5 diff --git a/mods/ts/rules/world.yaml b/mods/ts/rules/world.yaml index 7f6967bcf1..9513f5f7b9 100644 --- a/mods/ts/rules/world.yaml +++ b/mods/ts/rules/world.yaml @@ -388,8 +388,7 @@ World: FactionPreviewActors: gdi: hvr.colorpicker nod: stnk.colorpicker - PresetHues: 0, 0.125, 0.185, 0.4, 0.54, 0.66, 0.79, 0.875, 0, 0.14, 0.23, 0.43, 0.54, 0.625, 0.77, 0.85 - PresetSaturations: 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.4, 0.5, 0.4, 0.5, 0.4, 0.5, 0.4, 0.5 + PresetColors: F21818, F2BC18, DAF218, 18F26F, 18BEF2, 1821F2, BA18F2, F218BC, F29191, F2DF79, CDF291, 79F2BF, 91DBF2, 7997F2, CD91F2, F279E6 OrderEffects: TerrainFlashImage: moveflsh TerrainFlashSequence: idle