Color picker update with team color presets. Bots added will use available team color presets by default
This commit is contained in:
@@ -24,6 +24,7 @@ namespace OpenRA.Mods.Common
|
||||
public readonly int Threshold = 0x50;
|
||||
public readonly float[] HsvSaturationRange = new[] { 0.25f, 1f };
|
||||
public readonly float[] HsvValueRange = new[] { 0.2f, 1.0f };
|
||||
public readonly HSLColor[] TeamColorPresets = { };
|
||||
|
||||
double GetColorDelta(Color colorA, Color colorB)
|
||||
{
|
||||
@@ -86,6 +87,20 @@ namespace OpenRA.Mods.Common
|
||||
return true;
|
||||
}
|
||||
|
||||
public HSLColor RandomPresetColor(MersenneTwister random, IEnumerable<Color> terrainColors, IEnumerable<Color> playerColors)
|
||||
{
|
||||
if (TeamColorPresets.Any())
|
||||
{
|
||||
Color forbidden;
|
||||
Action<string> ignoreError = _ => { };
|
||||
foreach (var c in TeamColorPresets.Shuffle(random))
|
||||
if (IsValid(c.RGB, out forbidden, terrainColors, playerColors, ignoreError))
|
||||
return c;
|
||||
}
|
||||
|
||||
return RandomValidColor(random, terrainColors, playerColors);
|
||||
}
|
||||
|
||||
public HSLColor RandomValidColor(MersenneTwister random, IEnumerable<Color> terrainColors, IEnumerable<Color> playerColors)
|
||||
{
|
||||
HSLColor color;
|
||||
@@ -142,7 +157,7 @@ namespace OpenRA.Mods.Common
|
||||
// If we reached the limit (The ii >= 255 prevents too much calculations)
|
||||
if (attempt >= 255)
|
||||
{
|
||||
color = RandomValidColor(random, terrainColors, playerColors);
|
||||
color = RandomPresetColor(random, terrainColors, playerColors);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -321,7 +321,7 @@ namespace OpenRA.Mods.Common.Server
|
||||
var terrainColors = tileset.TerrainInfo.Where(ti => ti.RestrictPlayerColor).Select(ti => ti.Color);
|
||||
var playerColors = server.LobbyInfo.Clients.Select(c => c.Color.RGB)
|
||||
.Concat(server.Map.Players.Players.Values.Select(p => p.Color.RGB));
|
||||
bot.Color = bot.PreferredColor = validator.RandomValidColor(server.Random, terrainColors, playerColors);
|
||||
bot.Color = bot.PreferredColor = validator.RandomPresetColor(server.Random, terrainColors, playerColors);
|
||||
|
||||
server.LobbyInfo.Clients.Add(bot);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
{
|
||||
public Func<Color> GetColor;
|
||||
|
||||
public Action<MouseInput> OnMouseDown = _ => { };
|
||||
public Action<MouseInput> OnMouseUp = _ => { };
|
||||
|
||||
public ColorBlockWidget()
|
||||
{
|
||||
GetColor = () => Color.White;
|
||||
@@ -39,5 +42,30 @@ namespace OpenRA.Mods.Common.Widgets
|
||||
{
|
||||
WidgetUtils.FillRectWithColor(RenderBounds, GetColor());
|
||||
}
|
||||
|
||||
public override bool HandleMouseInput(MouseInput mi)
|
||||
{
|
||||
if (mi.Button != MouseButton.Left)
|
||||
return false;
|
||||
|
||||
if (mi.Event == MouseInputEvent.Down && !TakeMouseFocus(mi))
|
||||
return false;
|
||||
|
||||
if (HasMouseFocus && mi.Event == MouseInputEvent.Up)
|
||||
{
|
||||
// Only fire the onMouseUp event if we successfully lost focus, and were pressed
|
||||
OnMouseUp(mi);
|
||||
|
||||
return YieldMouseFocus(mi);
|
||||
}
|
||||
|
||||
if (mi.Event == MouseInputEvent.Down)
|
||||
{
|
||||
// OnMouseDown returns false if the button shouldn't be pressed
|
||||
OnMouseDown(mi);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
using OpenRA.Mods.Common.Lint;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Widgets;
|
||||
@@ -19,8 +23,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
{
|
||||
public class ColorPickerLogic : ChromeLogic
|
||||
{
|
||||
static bool paletteTabOpenedLast;
|
||||
|
||||
[ObjectCreator.UseCtor]
|
||||
public ColorPickerLogic(Widget widget, ModData modData, World world, HSLColor initialColor, Action<HSLColor> onChange, WorldRenderer worldRenderer)
|
||||
public ColorPickerLogic(Widget widget, ModData modData, World world, HSLColor initialColor, Action<HSLColor> onChange, Dictionary<string, MiniYaml> logicArgs)
|
||||
{
|
||||
string actorType;
|
||||
if (!ChromeMetrics.TryGet("ColorPickerActorType", out actorType))
|
||||
@@ -47,6 +53,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
mixer.OnChange += () => onChange(mixer.Color);
|
||||
|
||||
if (randomButton != null)
|
||||
{
|
||||
randomButton.OnClick = () =>
|
||||
{
|
||||
// Avoid colors with low sat or lum
|
||||
@@ -57,6 +64,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
mixer.Set(new HSLColor(hue, sat, lum));
|
||||
hueSlider.Value = hue / 255f;
|
||||
};
|
||||
}
|
||||
|
||||
// Set the initial state
|
||||
var validator = modData.Manifest.Get<ColorValidator>();
|
||||
@@ -65,6 +73,107 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
||||
|
||||
hueSlider.Value = initialColor.H / 255f;
|
||||
onChange(mixer.Color);
|
||||
|
||||
// Setup tab controls
|
||||
var mixerTab = widget.Get("MIXER_TAB");
|
||||
var paletteTab = widget.Get("PALETTE_TAB");
|
||||
var paletteTabPanel = widget.Get("PALETTE_TAB_PANEL");
|
||||
var mixerTabButton = widget.Get<ButtonWidget>("MIXER_TAB_BUTTON");
|
||||
var paletteTabButton = widget.Get<ButtonWidget>("PALETTE_TAB_BUTTON");
|
||||
var presetArea = paletteTabPanel.Get<ContainerWidget>("PRESET_AREA");
|
||||
var customArea = paletteTabPanel.Get<ContainerWidget>("CUSTOM_AREA");
|
||||
var presetColorTemplate = paletteTabPanel.Get<ColorBlockWidget>("COLORPRESET");
|
||||
var customColorTemplate = paletteTabPanel.Get<ColorBlockWidget>("COLORCUSTOM");
|
||||
|
||||
mixerTab.IsVisible = () => !paletteTabOpenedLast;
|
||||
mixerTabButton.OnClick = () => paletteTabOpenedLast = false;
|
||||
mixerTabButton.IsHighlighted = mixerTab.IsVisible;
|
||||
|
||||
paletteTab.IsVisible = () => paletteTabOpenedLast;
|
||||
paletteTabButton.OnClick = () => paletteTabOpenedLast = true;
|
||||
paletteTabButton.IsHighlighted = paletteTab.IsVisible;
|
||||
|
||||
var paletteCols = 8;
|
||||
var palettePresetRows = 2;
|
||||
var paletteCustomRows = 1;
|
||||
|
||||
MiniYaml yaml;
|
||||
if (logicArgs.TryGetValue("PaletteColumns", out yaml))
|
||||
if (!int.TryParse(yaml.Value, out paletteCols))
|
||||
throw new YamlException("Invalid value for PaletteColumns: {0}".F(yaml.Value));
|
||||
if (logicArgs.TryGetValue("PalettePresetRows", out yaml))
|
||||
if (!int.TryParse(yaml.Value, out palettePresetRows))
|
||||
throw new YamlException("Invalid value for PalettePresetRows: {0}".F(yaml.Value));
|
||||
if (logicArgs.TryGetValue("PaletteCustomRows", out yaml))
|
||||
if (!int.TryParse(yaml.Value, out paletteCustomRows))
|
||||
throw new YamlException("Invalid value for PaletteCustomRows: {0}".F(yaml.Value));
|
||||
|
||||
for (var j = 0; j < palettePresetRows; j++)
|
||||
{
|
||||
for (var i = 0; i < paletteCols; i++)
|
||||
{
|
||||
var colorIndex = j * paletteCols + i;
|
||||
if (colorIndex >= validator.TeamColorPresets.Length)
|
||||
break;
|
||||
|
||||
var color = validator.TeamColorPresets[colorIndex];
|
||||
var rgbColor = color.RGB;
|
||||
|
||||
var newSwatch = (ColorBlockWidget)presetColorTemplate.Clone();
|
||||
newSwatch.GetColor = () => rgbColor;
|
||||
newSwatch.IsVisible = () => true;
|
||||
newSwatch.Bounds.X = i * newSwatch.Bounds.Width;
|
||||
newSwatch.Bounds.Y = j * newSwatch.Bounds.Height;
|
||||
newSwatch.OnMouseUp = m =>
|
||||
{
|
||||
mixer.Set(color);
|
||||
onChange(color);
|
||||
};
|
||||
|
||||
presetArea.AddChild(newSwatch);
|
||||
}
|
||||
}
|
||||
|
||||
for (var j = 0; j < paletteCustomRows; j++)
|
||||
{
|
||||
for (var i = 0; i < paletteCols; i++)
|
||||
{
|
||||
var colorIndex = j * paletteCols + i;
|
||||
|
||||
var newSwatch = (ColorBlockWidget)customColorTemplate.Clone();
|
||||
newSwatch.GetColor = () => Game.Settings.Player.CustomColors[colorIndex].RGB;
|
||||
newSwatch.IsVisible = () => Game.Settings.Player.CustomColors.Length > colorIndex;
|
||||
newSwatch.Bounds.X = i * newSwatch.Bounds.Width;
|
||||
newSwatch.Bounds.Y = j * newSwatch.Bounds.Height;
|
||||
newSwatch.OnMouseUp = m =>
|
||||
{
|
||||
var color = Game.Settings.Player.CustomColors[colorIndex];
|
||||
mixer.Set(color);
|
||||
onChange(color);
|
||||
};
|
||||
|
||||
customArea.AddChild(newSwatch);
|
||||
}
|
||||
}
|
||||
|
||||
// Store color button
|
||||
var storeButton = widget.Get<ButtonWidget>("STORE_BUTTON");
|
||||
if (storeButton != null)
|
||||
{
|
||||
storeButton.OnClick = () =>
|
||||
{
|
||||
// Update the custom color list:
|
||||
// - Remove any duplicates of the new color
|
||||
// - Add the new color to the end
|
||||
// - Save the last N colors
|
||||
Game.Settings.Player.CustomColors = Game.Settings.Player.CustomColors
|
||||
.Where(c => c != mixer.Color)
|
||||
.Append(mixer.Color)
|
||||
.Reverse().Take(paletteCustomRows * paletteCols).Reverse()
|
||||
.ToArray();
|
||||
Game.Settings.Save();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowColorDropDown(DropDownButtonWidget color, ColorPreviewManagerWidget preview, World world)
|
||||
|
||||
Reference in New Issue
Block a user