Add IColorPickerManagerInfo interface
This commit is contained in:
@@ -529,10 +529,11 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Pick a random color for the bot
|
// Pick a random color for the bot
|
||||||
var colorManager = server.ModData.DefaultRules.Actors[SystemActors.World].TraitInfo<ColorPickerManagerInfo>();
|
var colorManager = server.ModData.DefaultRules.Actors[SystemActors.World].TraitInfo<IColorPickerManagerInfo>();
|
||||||
var terrainColors = server.ModData.DefaultTerrainInfo[server.Map.TileSet].RestrictedPlayerColors;
|
var terrainColors = server.ModData.DefaultTerrainInfo[server.Map.TileSet].RestrictedPlayerColors;
|
||||||
var playerColors = server.LobbyInfo.Clients.Select(c => c.Color)
|
var playerColors = server.LobbyInfo.Clients.Select(c => c.Color)
|
||||||
.Concat(server.Map.Players.Players.Values.Select(p => p.Color));
|
.Concat(server.Map.Players.Players.Values.Select(p => p.Color));
|
||||||
|
|
||||||
bot.Color = bot.PreferredColor = colorManager.RandomPresetColor(server.Random, terrainColors, playerColors);
|
bot.Color = bot.PreferredColor = colorManager.RandomPresetColor(server.Random, terrainColors, playerColors);
|
||||||
|
|
||||||
server.LobbyInfo.Clients.Add(bot);
|
server.LobbyInfo.Clients.Add(bot);
|
||||||
@@ -1239,7 +1240,7 @@ namespace OpenRA.Mods.Common.Server
|
|||||||
{
|
{
|
||||||
lock (server.LobbyInfo)
|
lock (server.LobbyInfo)
|
||||||
{
|
{
|
||||||
var colorManager = server.ModData.DefaultRules.Actors[SystemActors.World].TraitInfo<ColorPickerManagerInfo>();
|
var colorManager = server.ModData.DefaultRules.Actors[SystemActors.World].TraitInfo<IColorPickerManagerInfo>();
|
||||||
var askColor = askedColor;
|
var askColor = askedColor;
|
||||||
|
|
||||||
void OnError(string message)
|
void OnError(string message)
|
||||||
|
|||||||
@@ -44,19 +44,22 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
class ColorPickerPalette : ILoadsPalettes, IProvidesAssetBrowserColorPickerPalettes, ITickRender
|
class ColorPickerPalette : ILoadsPalettes, IProvidesAssetBrowserColorPickerPalettes, ITickRender
|
||||||
{
|
{
|
||||||
readonly ColorPickerPaletteInfo info;
|
readonly ColorPickerPaletteInfo info;
|
||||||
readonly ColorPickerManagerInfo colorManager;
|
|
||||||
Color color;
|
Color color;
|
||||||
|
Color preferredColor;
|
||||||
|
|
||||||
public ColorPickerPalette(ColorPickerPaletteInfo info)
|
public ColorPickerPalette(ColorPickerPaletteInfo info)
|
||||||
{
|
{
|
||||||
// All users need to use the same TraitInfo instance, chosen as the default mod rules
|
|
||||||
colorManager = Game.ModData.DefaultRules.Actors[SystemActors.World].TraitInfo<ColorPickerManagerInfo>();
|
|
||||||
this.info = info;
|
this.info = info;
|
||||||
|
|
||||||
|
// All users need to use the same TraitInfo instance, chosen as the default mod rules
|
||||||
|
var colorManager = Game.ModData.DefaultRules.Actors[SystemActors.World].TraitInfo<IColorPickerManagerInfo>();
|
||||||
|
colorManager.OnColorPickerColorUpdate += c => preferredColor = c;
|
||||||
|
preferredColor = Game.Settings.Player.Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ILoadsPalettes.LoadPalettes(WorldRenderer wr)
|
void ILoadsPalettes.LoadPalettes(WorldRenderer wr)
|
||||||
{
|
{
|
||||||
color = colorManager.Color;
|
color = preferredColor;
|
||||||
var remap = new PlayerColorRemap(info.RemapIndex.Length == 0 ? Enumerable.Range(0, 256).ToArray() : info.RemapIndex, color);
|
var remap = new PlayerColorRemap(info.RemapIndex.Length == 0 ? Enumerable.Range(0, 256).ToArray() : info.RemapIndex, color);
|
||||||
wr.AddPalette(info.Name, new ImmutablePalette(wr.Palette(info.BasePalette).Palette, remap), info.AllowModifiers);
|
wr.AddPalette(info.Name, new ImmutablePalette(wr.Palette(info.BasePalette).Palette, remap), info.AllowModifiers);
|
||||||
}
|
}
|
||||||
@@ -65,10 +68,10 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
void ITickRender.TickRender(WorldRenderer wr, Actor self)
|
void ITickRender.TickRender(WorldRenderer wr, Actor self)
|
||||||
{
|
{
|
||||||
if (color == colorManager.Color)
|
if (color == preferredColor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
color = colorManager.Color;
|
color = preferredColor;
|
||||||
var remap = new PlayerColorRemap(info.RemapIndex.Length == 0 ? Enumerable.Range(0, 256).ToArray() : info.RemapIndex, color);
|
var remap = new PlayerColorRemap(info.RemapIndex.Length == 0 ? Enumerable.Range(0, 256).ToArray() : info.RemapIndex, color);
|
||||||
wr.ReplacePalette(info.Name, new ImmutablePalette(wr.Palette(info.BasePalette).Palette, remap));
|
wr.ReplacePalette(info.Name, new ImmutablePalette(wr.Palette(info.BasePalette).Palette, remap));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,15 +12,18 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using OpenRA.Graphics;
|
||||||
|
using OpenRA.Mods.Common.Widgets;
|
||||||
using OpenRA.Primitives;
|
using OpenRA.Primitives;
|
||||||
using OpenRA.Support;
|
using OpenRA.Support;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
using OpenRA.Widgets;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
namespace OpenRA.Mods.Common.Traits
|
||||||
{
|
{
|
||||||
[TraitLocation(SystemActors.World)]
|
[TraitLocation(SystemActors.World)]
|
||||||
[Desc("Configuration options for the lobby player color picker. Attach this to the world actor.")]
|
[Desc("Configuration options for the lobby player color picker. Attach this to the world actor.")]
|
||||||
public class ColorPickerManagerInfo : TraitInfo<ColorPickerManager>
|
public class ColorPickerManagerInfo : TraitInfo<ColorPickerManager>, IColorPickerManagerInfo
|
||||||
{
|
{
|
||||||
[TranslationReference]
|
[TranslationReference]
|
||||||
const string PlayerColorTerrain = "notification-player-color-terrain";
|
const string PlayerColorTerrain = "notification-player-color-terrain";
|
||||||
@@ -52,9 +55,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
"A dictionary of [faction name]: [actor name].")]
|
"A dictionary of [faction name]: [actor name].")]
|
||||||
public readonly Dictionary<string, string> FactionPreviewActors = new();
|
public readonly Dictionary<string, string> FactionPreviewActors = new();
|
||||||
|
|
||||||
public Color Color;
|
public 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)
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
var closestDistance = SimilarityThreshold;
|
var closestDistance = SimilarityThreshold;
|
||||||
closestBlocker = default;
|
closestBlocker = default;
|
||||||
@@ -82,40 +83,6 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return closestDistance < SimilarityThreshold;
|
return closestDistance < SimilarityThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Color RandomPresetColor(MersenneTwister random, IEnumerable<Color> terrainColors, IEnumerable<Color> playerColors)
|
|
||||||
{
|
|
||||||
var terrainLinear = terrainColors.Select(c => c.ToLinear()).ToList();
|
|
||||||
var playerLinear = playerColors.Select(c => c.ToLinear()).ToList();
|
|
||||||
|
|
||||||
foreach (var color in PresetColors.Shuffle(random))
|
|
||||||
{
|
|
||||||
// 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());
|
|
||||||
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<Color> terrainColors, IEnumerable<Color> playerColors)
|
|
||||||
{
|
|
||||||
var h = random.NextFloat();
|
|
||||||
var s = float2.Lerp(HsvSaturationRange[0], HsvSaturationRange[1], random.NextFloat());
|
|
||||||
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<Color> terrainColors, IEnumerable<Color> playerColors, Action<string> onError = null)
|
|
||||||
{
|
|
||||||
var (_, h, s, v) = color.ToAhsv();
|
|
||||||
return MakeValid(h, s, v, random, terrainColors, playerColors, onError);
|
|
||||||
}
|
|
||||||
|
|
||||||
Color MakeValid(float hue, float sat, float val, MersenneTwister random, IEnumerable<Color> terrainColors, IEnumerable<Color> playerColors, Action<string> onError)
|
Color MakeValid(float hue, float sat, float val, MersenneTwister random, IEnumerable<Color> terrainColors, IEnumerable<Color> playerColors, Action<string> onError)
|
||||||
{
|
{
|
||||||
var terrainLinear = terrainColors.Select(c => c.ToLinear()).ToList();
|
var terrainLinear = terrainColors.Select(c => c.ToLinear()).ToList();
|
||||||
@@ -164,6 +131,97 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
var randomVal = float2.Lerp(HsvValueRange[0], HsvValueRange[1], random.NextFloat());
|
var randomVal = float2.Lerp(HsvValueRange[0], HsvValueRange[1], random.NextFloat());
|
||||||
return Color.FromAhsv(random.NextFloat(), randomSat, randomVal);
|
return Color.FromAhsv(random.NextFloat(), randomSat, randomVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region IColorPickerManagerInfo
|
||||||
|
|
||||||
|
public event Action<Color> OnColorPickerColorUpdate;
|
||||||
|
|
||||||
|
(float sMin, float sMax) IColorPickerManagerInfo.SaturationRange => (HsvSaturationRange[0], HsvSaturationRange[1]);
|
||||||
|
(float vMin, float vMax) IColorPickerManagerInfo.ValueRange => (HsvValueRange[0], HsvValueRange[1]);
|
||||||
|
|
||||||
|
Color[] IColorPickerManagerInfo.PresetColors => PresetColors;
|
||||||
|
|
||||||
|
Color IColorPickerManagerInfo.RandomPresetColor(MersenneTwister random, IEnumerable<Color> terrainColors, IEnumerable<Color> playerColors)
|
||||||
|
{
|
||||||
|
var terrainLinear = terrainColors.Select(c => c.ToLinear()).ToList();
|
||||||
|
var playerLinear = playerColors.Select(c => c.ToLinear()).ToList();
|
||||||
|
|
||||||
|
foreach (var color in PresetColors.Shuffle(random))
|
||||||
|
{
|
||||||
|
// 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());
|
||||||
|
var randomVal = float2.Lerp(HsvValueRange[0], HsvValueRange[1], random.NextFloat());
|
||||||
|
return MakeValid(randomHue, randomSat, randomVal, random, terrainLinear, playerLinear, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color IColorPickerManagerInfo.MakeValid(Color color, MersenneTwister random, IEnumerable<Color> terrainColors, IEnumerable<Color> playerColors, Action<string> onError)
|
||||||
|
{
|
||||||
|
var (_, h, s, v) = color.ToAhsv();
|
||||||
|
return MakeValid(h, s, v, random, terrainColors, playerColors, onError);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color IColorPickerManagerInfo.RandomValidColor(MersenneTwister random, IEnumerable<Color> terrainColors, IEnumerable<Color> playerColors)
|
||||||
|
{
|
||||||
|
var h = random.NextFloat();
|
||||||
|
var s = float2.Lerp(HsvSaturationRange[0], HsvSaturationRange[1], random.NextFloat());
|
||||||
|
var v = float2.Lerp(HsvValueRange[0], HsvValueRange[1], random.NextFloat());
|
||||||
|
return MakeValid(h, s, v, random, terrainColors, playerColors, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IColorPickerManagerInfo.ShowColorDropDown(DropDownButtonWidget dropdownButton, Color initialColor, string initialFaction, WorldRenderer worldRenderer, Action<Color> onExit)
|
||||||
|
{
|
||||||
|
dropdownButton.RemovePanel();
|
||||||
|
|
||||||
|
// We do not want to force other ColorPickerManager implementations to have an Actor preview.
|
||||||
|
// We achieve this by fully encapsulating its initialisation.
|
||||||
|
void AddActorPreview(Widget parent)
|
||||||
|
{
|
||||||
|
var preview = parent.GetOrNull<ActorPreviewWidget>("PREVIEW");
|
||||||
|
if (preview == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (initialFaction == null || !FactionPreviewActors.TryGetValue(initialFaction, out var actorType))
|
||||||
|
{
|
||||||
|
if (PreviewActor == null)
|
||||||
|
throw new YamlException($"{nameof(ColorPickerManager)} does not define a preview actor" + (initialFaction == null ? "." : $"for faction {initialFaction}."));
|
||||||
|
|
||||||
|
actorType = PreviewActor;
|
||||||
|
}
|
||||||
|
|
||||||
|
var actor = worldRenderer.World.Map.Rules.Actors[actorType];
|
||||||
|
|
||||||
|
var td = new TypeDictionary
|
||||||
|
{
|
||||||
|
new OwnerInit(worldRenderer.World.WorldActor.Owner),
|
||||||
|
new FactionInit(worldRenderer.World.WorldActor.Owner.PlayerReference.Faction)
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var api in actor.TraitInfos<IActorPreviewInitInfo>())
|
||||||
|
foreach (var o in api.ActorPreviewInits(actor, ActorPreviewType.ColorPicker))
|
||||||
|
td.Add(o);
|
||||||
|
|
||||||
|
preview.SetPreview(actor, td);
|
||||||
|
}
|
||||||
|
|
||||||
|
var finalColor = initialColor;
|
||||||
|
var colorChooser = Game.LoadWidget(worldRenderer.World, "COLOR_CHOOSER", null, new WidgetArgs()
|
||||||
|
{
|
||||||
|
{ "onChange", (Action<Color>)(c => { finalColor = c; OnColorPickerColorUpdate(c); }) },
|
||||||
|
{ "initialColor", initialColor },
|
||||||
|
{ "extraLogic", (Action<Widget>)AddActorPreview },
|
||||||
|
});
|
||||||
|
|
||||||
|
dropdownButton.AttachPanel(colorChooser, () => onExit(finalColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ColorPickerManager { }
|
public class ColorPickerManager { }
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ using OpenRA.Graphics;
|
|||||||
using OpenRA.Mods.Common.Activities;
|
using OpenRA.Mods.Common.Activities;
|
||||||
using OpenRA.Mods.Common.Graphics;
|
using OpenRA.Mods.Common.Graphics;
|
||||||
using OpenRA.Mods.Common.Terrain;
|
using OpenRA.Mods.Common.Terrain;
|
||||||
|
using OpenRA.Mods.Common.Widgets;
|
||||||
using OpenRA.Primitives;
|
using OpenRA.Primitives;
|
||||||
|
using OpenRA.Support;
|
||||||
using OpenRA.Traits;
|
using OpenRA.Traits;
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
namespace OpenRA.Mods.Common.Traits
|
||||||
@@ -290,6 +292,18 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
IEnumerable<string> ColorPickerPaletteNames { get; }
|
IEnumerable<string> ColorPickerPaletteNames { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface IColorPickerManagerInfo : ITraitInfoInterface
|
||||||
|
{
|
||||||
|
(float sMin, float sMax) SaturationRange { get; }
|
||||||
|
(float vMin, float vMax) ValueRange { get; }
|
||||||
|
event Action<Color> OnColorPickerColorUpdate;
|
||||||
|
Color[] PresetColors { get; }
|
||||||
|
Color RandomPresetColor(MersenneTwister random, IEnumerable<Color> terrainColors, IEnumerable<Color> playerColors);
|
||||||
|
Color RandomValidColor(MersenneTwister random, IEnumerable<Color> terrainColors, IEnumerable<Color> playerColors);
|
||||||
|
Color MakeValid(Color color, MersenneTwister random, IEnumerable<Color> terrainColors, IEnumerable<Color> playerColors, Action<string> onError = null);
|
||||||
|
void ShowColorDropDown(DropDownButtonWidget dropdownButton, Color initialColor, string initialFaction, WorldRenderer worldRenderer, Action<Color> onExit);
|
||||||
|
}
|
||||||
|
|
||||||
public interface ICallForTransport
|
public interface ICallForTransport
|
||||||
{
|
{
|
||||||
WDist MinimumDistance { get; }
|
WDist MinimumDistance { get; }
|
||||||
|
|||||||
@@ -177,16 +177,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
panel.GetOrNull<LabelWidget>("PALETTE_DESC").IsVisible = () => currentSprites != null || currentVoxel != null;
|
panel.GetOrNull<LabelWidget>("PALETTE_DESC").IsVisible = () => currentSprites != null || currentVoxel != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var colorManager = modData.DefaultRules.Actors[SystemActors.World].TraitInfo<ColorPickerManagerInfo>();
|
var colorManager = modData.DefaultRules.Actors[SystemActors.World].TraitInfo<IColorPickerManagerInfo>();
|
||||||
colorManager.Color = Game.Settings.Player.Color;
|
|
||||||
|
|
||||||
var colorDropdown = panel.GetOrNull<DropDownButtonWidget>("COLOR");
|
var colorDropdown = panel.GetOrNull<DropDownButtonWidget>("COLOR");
|
||||||
if (colorDropdown != null)
|
if (colorDropdown != null)
|
||||||
{
|
{
|
||||||
|
var color = Game.Settings.Player.Color;
|
||||||
colorDropdown.IsDisabled = () => !colorPickerPalettes.Contains(currentPalette);
|
colorDropdown.IsDisabled = () => !colorPickerPalettes.Contains(currentPalette);
|
||||||
colorDropdown.OnMouseDown = _ => ColorPickerLogic.ShowColorDropDown(colorDropdown, colorManager, worldRenderer);
|
colorDropdown.OnMouseDown = _ => colorManager.ShowColorDropDown(colorDropdown, color, null, worldRenderer, c => color = c);
|
||||||
colorDropdown.IsVisible = () => currentSprites != null || currentVoxel != null;
|
colorDropdown.IsVisible = () => currentSprites != null || currentVoxel != null;
|
||||||
panel.Get<ColorBlockWidget>("COLORBLOCK").GetColor = () => colorManager.Color;
|
|
||||||
|
panel.Get<ColorBlockWidget>("COLORBLOCK").GetColor = () => color;
|
||||||
}
|
}
|
||||||
|
|
||||||
filenameInput = panel.Get<TextFieldWidget>("FILENAME_INPUT");
|
filenameInput = panel.Get<TextFieldWidget>("FILENAME_INPUT");
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.Graphics;
|
|
||||||
using OpenRA.Mods.Common.Traits;
|
using OpenRA.Mods.Common.Traits;
|
||||||
using OpenRA.Primitives;
|
using OpenRA.Primitives;
|
||||||
using OpenRA.Widgets;
|
using OpenRA.Widgets;
|
||||||
@@ -25,7 +24,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
int paletteTabHighlighted = 0;
|
int paletteTabHighlighted = 0;
|
||||||
|
|
||||||
[ObjectCreator.UseCtor]
|
[ObjectCreator.UseCtor]
|
||||||
public ColorPickerLogic(Widget widget, ModData modData, World world, Color initialColor, string initialFaction, Action<Color> onChange,
|
public ColorPickerLogic(Widget widget, ModData modData, World world, Color initialColor, Action<Color> onChange, Action<Widget> extraLogic,
|
||||||
Dictionary<string, MiniYaml> logicArgs)
|
Dictionary<string, MiniYaml> logicArgs)
|
||||||
{
|
{
|
||||||
var mixer = widget.Get<ColorMixerWidget>("MIXER");
|
var mixer = widget.Get<ColorMixerWidget>("MIXER");
|
||||||
@@ -33,14 +32,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
|
|
||||||
// Set the initial state
|
// Set the initial state
|
||||||
// All users need to use the same TraitInfo instance, chosen as the default mod rules
|
// All users need to use the same TraitInfo instance, chosen as the default mod rules
|
||||||
var colorManager = modData.DefaultRules.Actors[SystemActors.World].TraitInfo<ColorPickerManagerInfo>();
|
var colorManager = modData.DefaultRules.Actors[SystemActors.World].TraitInfo<IColorPickerManagerInfo>();
|
||||||
mixer.SetColorLimits(colorManager.HsvSaturationRange[0], colorManager.HsvSaturationRange[1], colorManager.HsvValueRange[0], colorManager.HsvValueRange[1]);
|
|
||||||
|
var (sMin, sMax) = colorManager.SaturationRange;
|
||||||
|
var (vMin, vMax) = colorManager.ValueRange;
|
||||||
|
mixer.SetColorLimits(sMin, sMax, vMin, vMax);
|
||||||
mixer.OnChange += () => onChange(mixer.Color);
|
mixer.OnChange += () => onChange(mixer.Color);
|
||||||
mixer.Set(initialColor);
|
mixer.Set(initialColor);
|
||||||
|
|
||||||
hueSlider.OnChange += h =>
|
hueSlider.OnChange += h =>
|
||||||
{
|
{
|
||||||
mixer.SetColorLimits(colorManager.HsvSaturationRange[0], colorManager.HsvSaturationRange[1], colorManager.HsvValueRange[0], colorManager.HsvValueRange[1], h);
|
mixer.SetColorLimits(sMin, sMax, vMin, vMax, h);
|
||||||
var (_, _, s, v) = mixer.Color.ToAhsv();
|
var (_, _, s, v) = mixer.Color.ToAhsv();
|
||||||
mixer.Set(Color.FromAhsv(h, s, v));
|
mixer.Set(Color.FromAhsv(h, s, v));
|
||||||
onChange(mixer.Color);
|
onChange(mixer.Color);
|
||||||
@@ -64,34 +66,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initialFaction == null || !colorManager.FactionPreviewActors.TryGetValue(initialFaction, out var actorType))
|
|
||||||
actorType = colorManager.PreviewActor;
|
|
||||||
|
|
||||||
if (actorType == null)
|
|
||||||
{
|
|
||||||
var message = "ColorPickerManager does not define a preview actor";
|
|
||||||
if (initialFaction != null)
|
|
||||||
message += " for faction " + initialFaction;
|
|
||||||
message += "!";
|
|
||||||
|
|
||||||
throw new YamlException(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
var preview = widget.GetOrNull<ActorPreviewWidget>("PREVIEW");
|
|
||||||
var actor = world.Map.Rules.Actors[actorType];
|
|
||||||
|
|
||||||
var td = new TypeDictionary
|
|
||||||
{
|
|
||||||
new OwnerInit(world.WorldActor.Owner),
|
|
||||||
new FactionInit(world.WorldActor.Owner.PlayerReference.Faction)
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var api in actor.TraitInfos<IActorPreviewInitInfo>())
|
|
||||||
foreach (var o in api.ActorPreviewInits(actor, ActorPreviewType.ColorPicker))
|
|
||||||
td.Add(o);
|
|
||||||
|
|
||||||
preview?.SetPreview(actor, td);
|
|
||||||
|
|
||||||
// HACK: the value returned from the color mixer will generally not
|
// HACK: the value returned from the color mixer will generally not
|
||||||
// be equal to the given initialColor due to its internal RGB -> HSL -> RGB
|
// be equal to the given initialColor due to its internal RGB -> HSL -> RGB
|
||||||
// conversion. This conversion can sometimes convert a valid initial value
|
// conversion. This conversion can sometimes convert a valid initial value
|
||||||
@@ -205,20 +179,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
paletteTabHighlighted = 4;
|
paletteTabHighlighted = 4;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static void ShowColorDropDown(DropDownButtonWidget color, ColorPickerManagerInfo colorManager, WorldRenderer worldRenderer, Action onExit = null)
|
// Attach logic to preview actor.
|
||||||
{
|
extraLogic(widget);
|
||||||
color.RemovePanel();
|
|
||||||
|
|
||||||
var colorChooser = Game.LoadWidget(worldRenderer.World, "COLOR_CHOOSER", null, new WidgetArgs()
|
|
||||||
{
|
|
||||||
{ "onChange", (Action<Color>)(c => colorManager.Color = c) },
|
|
||||||
{ "initialColor", colorManager.Color },
|
|
||||||
{ "initialFaction", null }
|
|
||||||
});
|
|
||||||
|
|
||||||
color.AttachPanel(colorChooser, onExit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Tick()
|
public override void Tick()
|
||||||
|
|||||||
@@ -76,9 +76,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
var colorManager = modData.DefaultRules.Actors[SystemActors.World].TraitInfo<ColorPickerManagerInfo>();
|
|
||||||
colorManager.Color = ps.Color;
|
|
||||||
|
|
||||||
var mouseControlDescClassic = widget.Get("MOUSE_CONTROL_DESC_CLASSIC");
|
var mouseControlDescClassic = widget.Get("MOUSE_CONTROL_DESC_CLASSIC");
|
||||||
mouseControlDescClassic.IsVisible = () => gs.UseClassicMouseStyle;
|
mouseControlDescClassic.IsVisible = () => gs.UseClassicMouseStyle;
|
||||||
|
|
||||||
@@ -114,11 +111,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
|
|
||||||
SettingsUtils.BindCheckboxPref(widget, "EDGESCROLL_CHECKBOX", gs, "ViewportEdgeScroll");
|
SettingsUtils.BindCheckboxPref(widget, "EDGESCROLL_CHECKBOX", gs, "ViewportEdgeScroll");
|
||||||
|
|
||||||
|
var colorManager = modData.DefaultRules.Actors[SystemActors.World].TraitInfo<IColorPickerManagerInfo>();
|
||||||
|
|
||||||
var colorDropdown = widget.Get<DropDownButtonWidget>("PLAYERCOLOR");
|
var colorDropdown = widget.Get<DropDownButtonWidget>("PLAYERCOLOR");
|
||||||
colorDropdown.IsDisabled = () => worldRenderer.World.Type != WorldType.Shellmap;
|
colorDropdown.IsDisabled = () => worldRenderer.World.Type != WorldType.Shellmap;
|
||||||
colorDropdown.OnMouseDown = _ => ColorPickerLogic.ShowColorDropDown(colorDropdown, colorManager, worldRenderer, () =>
|
colorDropdown.OnMouseDown = _ => colorManager.ShowColorDropDown(colorDropdown, ps.Color, null, worldRenderer, color =>
|
||||||
{
|
{
|
||||||
Game.Settings.Player.Color = colorManager.Color;
|
ps.Color = color;
|
||||||
Game.Settings.Save();
|
Game.Settings.Save();
|
||||||
});
|
});
|
||||||
colorDropdown.Get<ColorBlockWidget>("COLORBLOCK").GetColor = () => ps.Color;
|
colorDropdown.Get<ColorBlockWidget>("COLORBLOCK").GetColor = () => ps.Color;
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
|
|
||||||
readonly Dictionary<string, LobbyFaction> factions = new();
|
readonly Dictionary<string, LobbyFaction> factions = new();
|
||||||
|
|
||||||
readonly ColorPickerManagerInfo colorManager;
|
readonly IColorPickerManagerInfo colorManager;
|
||||||
|
|
||||||
readonly TabCompletionLogic tabCompletion = new();
|
readonly TabCompletionLogic tabCompletion = new();
|
||||||
|
|
||||||
@@ -198,8 +198,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
editableSpectatorTemplate = players.Get("TEMPLATE_EDITABLE_SPECTATOR");
|
editableSpectatorTemplate = players.Get("TEMPLATE_EDITABLE_SPECTATOR");
|
||||||
nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
|
nonEditableSpectatorTemplate = players.Get("TEMPLATE_NONEDITABLE_SPECTATOR");
|
||||||
newSpectatorTemplate = players.Get("TEMPLATE_NEW_SPECTATOR");
|
newSpectatorTemplate = players.Get("TEMPLATE_NEW_SPECTATOR");
|
||||||
colorManager = modRules.Actors[SystemActors.World].TraitInfo<ColorPickerManagerInfo>();
|
colorManager = modRules.Actors[SystemActors.World].TraitInfo<IColorPickerManagerInfo>();
|
||||||
colorManager.Color = Game.Settings.Player.Color;
|
|
||||||
|
|
||||||
foreach (var f in modRules.Actors[SystemActors.World].TraitInfos<FactionInfo>())
|
foreach (var f in modRules.Actors[SystemActors.World].TraitInfos<FactionInfo>())
|
||||||
factions.Add(f.InternalName, new LobbyFaction { Selectable = f.Selectable, Name = f.Name, Side = f.Side, Description = f.Description });
|
factions.Add(f.InternalName, new LobbyFaction { Selectable = f.Selectable, Name = f.Name, Side = f.Side, Description = f.Description });
|
||||||
|
|||||||
@@ -241,31 +241,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
dropdown.ShowDropDown("FACTION_DROPDOWN_TEMPLATE", 154, options, SetupItem);
|
dropdown.ShowDropDown("FACTION_DROPDOWN_TEMPLATE", 154, options, SetupItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ShowColorDropDown(DropDownButtonWidget color, Session.Client client,
|
|
||||||
OrderManager orderManager, WorldRenderer worldRenderer, ColorPickerManagerInfo colorManager)
|
|
||||||
{
|
|
||||||
void OnExit()
|
|
||||||
{
|
|
||||||
if (client == orderManager.LocalClient)
|
|
||||||
{
|
|
||||||
Game.Settings.Player.Color = colorManager.Color;
|
|
||||||
Game.Settings.Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
color.RemovePanel();
|
|
||||||
orderManager.IssueOrder(Order.Command($"color {client.Index} {colorManager.Color}"));
|
|
||||||
}
|
|
||||||
|
|
||||||
var colorChooser = Game.LoadWidget(worldRenderer.World, "COLOR_CHOOSER", null, new WidgetArgs()
|
|
||||||
{
|
|
||||||
{ "onChange", (Action<Color>)(c => colorManager.Color = c) },
|
|
||||||
{ "initialColor", client.Color },
|
|
||||||
{ "initialFaction", client.Faction }
|
|
||||||
});
|
|
||||||
|
|
||||||
color.AttachPanel(colorChooser, OnExit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SelectSpawnPoint(OrderManager orderManager, MapPreviewWidget mapPreview, MapPreview preview, MouseInput mi)
|
public static void SelectSpawnPoint(OrderManager orderManager, MapPreviewWidget mapPreview, MapPreview preview, MouseInput mi)
|
||||||
{
|
{
|
||||||
if (orderManager.LocalClient.State == Session.ClientState.Ready)
|
if (orderManager.LocalClient.State == Session.ClientState.Ready)
|
||||||
@@ -544,13 +519,22 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetupEditableColorWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, WorldRenderer worldRenderer, ColorPickerManagerInfo colorManager)
|
public static void SetupEditableColorWidget(Widget parent, Session.Slot s, Session.Client c, OrderManager orderManager, WorldRenderer worldRenderer, IColorPickerManagerInfo colorManager)
|
||||||
{
|
{
|
||||||
var color = parent.Get<DropDownButtonWidget>("COLOR");
|
var colorDropdown = parent.Get<DropDownButtonWidget>("COLOR");
|
||||||
color.IsDisabled = () => (s != null && s.LockColor) || orderManager.LocalClient.IsReady;
|
colorDropdown.IsDisabled = () => (s != null && s.LockColor) || orderManager.LocalClient.IsReady;
|
||||||
color.OnMouseDown = _ => ShowColorDropDown(color, c, orderManager, worldRenderer, colorManager);
|
colorDropdown.OnMouseDown = _ => colorManager.ShowColorDropDown(colorDropdown, c.Color, c.Faction, worldRenderer, color =>
|
||||||
|
{
|
||||||
|
if (c == orderManager.LocalClient)
|
||||||
|
{
|
||||||
|
Game.Settings.Player.Color = color;
|
||||||
|
Game.Settings.Save();
|
||||||
|
}
|
||||||
|
|
||||||
SetupColorWidget(color, c);
|
orderManager.IssueOrder(Order.Command($"color {c.Index} {color}"));
|
||||||
|
});
|
||||||
|
|
||||||
|
SetupColorWidget(colorDropdown, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetupColorWidget(Widget parent, Session.Client c)
|
public static void SetupColorWidget(Widget parent, Session.Client c)
|
||||||
|
|||||||
@@ -268,14 +268,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
var colorManager = modData.DefaultRules.Actors[SystemActors.World].TraitInfo<ColorPickerManagerInfo>();
|
var colorManager = modData.DefaultRules.Actors[SystemActors.World].TraitInfo<IColorPickerManagerInfo>();
|
||||||
colorManager.Color = ps.Color;
|
|
||||||
|
|
||||||
var colorDropdown = panel.Get<DropDownButtonWidget>("PLAYERCOLOR");
|
var colorDropdown = panel.Get<DropDownButtonWidget>("PLAYERCOLOR");
|
||||||
colorDropdown.IsDisabled = () => worldRenderer.World.Type != WorldType.Shellmap;
|
colorDropdown.IsDisabled = () => worldRenderer.World.Type != WorldType.Shellmap;
|
||||||
colorDropdown.OnMouseDown = _ => ColorPickerLogic.ShowColorDropDown(colorDropdown, colorManager, worldRenderer, () =>
|
colorDropdown.OnMouseDown = _ => colorManager.ShowColorDropDown(colorDropdown, ps.Color, null, worldRenderer, color =>
|
||||||
{
|
{
|
||||||
Game.Settings.Player.Color = colorManager.Color;
|
ps.Color = color;
|
||||||
Game.Settings.Save();
|
Game.Settings.Save();
|
||||||
});
|
});
|
||||||
colorDropdown.Get<ColorBlockWidget>("COLORBLOCK").GetColor = () => ps.Color;
|
colorDropdown.Get<ColorBlockWidget>("COLORBLOCK").GetColor = () => ps.Color;
|
||||||
|
|||||||
Reference in New Issue
Block a user