add ColorRamp type; change everything to use it; maps not yet upgraded

This commit is contained in:
Chris Forbes
2011-01-08 17:10:00 +13:00
parent e2ff40dc7f
commit 3426b52247
22 changed files with 163 additions and 124 deletions

View File

@@ -476,7 +476,7 @@ namespace OpenRA.Editor
{
var pr = Map.Players[name];
var pcpi = Rules.Info["player"].Traits.Get<PlayerColorPaletteInfo>();
var remap = new PlayerColorRemap(pr.Color, pr.Color2, pcpi.PaletteFormat);
var remap = new PlayerColorRemap(pr.ColorRamp, pcpi.PaletteFormat);
return RenderUtils.MakeSystemPalette(new Palette(Palette, remap));
}

View File

@@ -0,0 +1,64 @@
#region Copyright & License Information
/*
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
* 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. For more information,
* see LICENSE.
*/
#endregion
using System.Drawing;
namespace OpenRA.FileFormats
{
public struct ColorRamp
{
public byte H,S,L,R;
public ColorRamp(byte h, byte s, byte l, byte r)
{
H = h; S = s; L = l; R = r;
}
/* returns a color along the Lum ramp */
public Color GetColor( float t )
{
return ColorFromHSL( H / 255f, S / 255f, float2.Lerp( L, R, t ) / 255f );
}
public override string ToString()
{
return "{0},{1},{2},{3}".F(H, S, L, R);
}
// hk is hue in the range [0,1] instead of [0,360]
public static Color ColorFromHSL(float hk, float s, float l)
{
// Convert from HSL to RGB
var q = (l < 0.5f) ? l * (1 + s) : l + s - (l * s);
var p = 2 * l - q;
float[] trgb = { hk + 1 / 3.0f,
hk,
hk - 1/3.0f };
float[] rgb = { 0, 0, 0 };
for (int k = 0; k < 3; k++)
{
while (trgb[k] < 0) trgb[k] += 1.0f;
while (trgb[k] > 1) trgb[k] -= 1.0f;
}
for (int k = 0; k < 3; k++)
{
if (trgb[k] < 1 / 6.0f) { rgb[k] = (p + ((q - p) * 6 * trgb[k])); }
else if (trgb[k] >= 1 / 6.0f && trgb[k] < 0.5) { rgb[k] = q; }
else if (trgb[k] >= 0.5f && trgb[k] < 2.0f / 3) { rgb[k] = (p + ((q - p) * 6 * (2.0f / 3 - trgb[k]))); }
else { rgb[k] = p; }
}
return Color.FromArgb((int)(rgb[0] * 255), (int)(rgb[1] * 255), (int)(rgb[2] * 255));
}
}
}

View File

@@ -126,45 +126,58 @@ namespace OpenRA.FileFormats
return InvalidValueAction(x,fieldType, field);
}
else if (fieldType.IsEnum)
{
if (!Enum.GetNames(fieldType).Select(a => a.ToLower()).Contains(x.ToLower()))
return InvalidValueAction(x,fieldType, field);
return Enum.Parse(fieldType, x, true);
}
else if (fieldType == typeof(ColorRamp))
{
var parts = x.Split(',');
if (parts.Length == 4)
return new ColorRamp(
(byte)int.Parse(parts[0]).Clamp(0, 255),
(byte)int.Parse(parts[1]).Clamp(0, 255),
(byte)int.Parse(parts[2]).Clamp(0, 255),
(byte)int.Parse(parts[3]).Clamp(0, 255));
else if (fieldType == typeof(bool))
return ParseYesNo(x, fieldType, field);
return InvalidValueAction(x, fieldType, field);
}
else if (fieldType.IsArray)
{
if (x == null)
return Array.CreateInstance(fieldType.GetElementType(), 0);
else if (fieldType.IsEnum)
{
if (!Enum.GetNames(fieldType).Select(a => a.ToLower()).Contains(x.ToLower()))
return InvalidValueAction(x, fieldType, field);
return Enum.Parse(fieldType, x, true);
}
var parts = x.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
else if (fieldType == typeof(bool))
return ParseYesNo(x, fieldType, field);
var ret = Array.CreateInstance(fieldType.GetElementType(), parts.Length);
for (int i = 0; i < parts.Length; i++)
ret.SetValue(GetValue(field, fieldType.GetElementType(), parts[i].Trim()), i);
return ret;
}
else if (fieldType == typeof(int2))
{
var parts = x.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
return new int2(int.Parse(parts[0]), int.Parse(parts[1]));
}
else if (fieldType == typeof(float2))
{
var parts = x.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
float xx = 0;
float yy = 0;
float res;
if (float.TryParse(parts[0].Replace("%",""), out res))
xx = res * (parts[0].Contains( '%' ) ? 0.01f : 1f);
if (float.TryParse(parts[1].Replace("%",""), out res))
yy = res * (parts[1].Contains( '%' ) ? 0.01f : 1f);
return new float2(xx,yy);
}
else if (fieldType.IsArray)
{
if (x == null)
return Array.CreateInstance(fieldType.GetElementType(), 0);
var parts = x.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
var ret = Array.CreateInstance(fieldType.GetElementType(), parts.Length);
for (int i = 0; i < parts.Length; i++)
ret.SetValue(GetValue(field, fieldType.GetElementType(), parts[i].Trim()), i);
return ret;
}
else if (fieldType == typeof(int2))
{
var parts = x.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
return new int2(int.Parse(parts[0]), int.Parse(parts[1]));
}
else if (fieldType == typeof(float2))
{
var parts = x.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
float xx = 0;
float yy = 0;
float res;
if (float.TryParse(parts[0].Replace("%", ""), out res))
xx = res * (parts[0].Contains('%') ? 0.01f : 1f);
if (float.TryParse(parts[1].Replace("%", ""), out res))
yy = res * (parts[1].Contains('%') ? 0.01f : 1f);
return new float2(xx, yy);
}
UnknownFieldAction("[Type] {0}".F(x),fieldType);
return null;

View File

@@ -8,7 +8,8 @@
*/
#endregion
using System.Drawing;
using System.Drawing;
using System;
namespace OpenRA.FileFormats
{
@@ -26,8 +27,9 @@ namespace OpenRA.FileFormats
public string Race;
public bool LockColor = false;
public Color Color = Color.FromArgb(238,238,238);
public Color Color2 = Color.FromArgb(44,28,24);
[Obsolete] public Color Color = Color.FromArgb(238,238,238);
[Obsolete] public Color Color2 = Color.FromArgb(44,28,24);
public ColorRamp ColorRamp = new ColorRamp(75, 255, 180, 25);
public int InitialCash = 0;
public string[] Allies = {};

View File

@@ -60,6 +60,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ColorHSLR.cs" />
<Compile Include="Evaluator.cs" />
<Compile Include="Exts.cs" />
<Compile Include="FieldLoader.cs" />

View File

@@ -21,8 +21,11 @@ namespace OpenRA.FileFormats
{
Dictionary<int, Color> remapColors;
public PlayerColorRemap(Color c1, Color c2, PaletteFormat fmt)
public PlayerColorRemap(ColorRamp c, PaletteFormat fmt)
{
var c1 = c.GetColor(0);
var c2 = c.GetColor(1); /* temptemp: this can be expressed better */
var baseIndex = (fmt == PaletteFormat.cnc) ? 0xb0 : (fmt == PaletteFormat.d2k) ? 240 : 80;
var ramp = (fmt == PaletteFormat.cnc)
? new[] { 0, 2, 4, 6, 8, 10, 13, 15, 1, 3, 5, 7, 9, 11, 12, 14 }
@@ -46,34 +49,5 @@ namespace OpenRA.FileFormats
return remapColors.TryGetValue(index, out c)
? c : original;
}
// hk is hue in the range [0,1] instead of [0,360]
public static Color ColorFromHSL(float hk, float s, float l)
{
// Convert from HSL to RGB
var q = (l < 0.5f) ? l * (1 + s) : l + s - (l * s);
var p = 2 * l - q;
float[] trgb = { hk + 1 / 3.0f,
hk,
hk - 1/3.0f };
float[] rgb = { 0, 0, 0 };
for (int k = 0; k < 3; k++)
{
while (trgb[k] < 0) trgb[k] += 1.0f;
while (trgb[k] > 1) trgb[k] -= 1.0f;
}
for (int k = 0; k < 3; k++)
{
if (trgb[k] < 1 / 6.0f) { rgb[k] = (p + ((q - p) * 6 * trgb[k])); }
else if (trgb[k] >= 1 / 6.0f && trgb[k] < 0.5) { rgb[k] = q; }
else if (trgb[k] >= 0.5f && trgb[k] < 2.0f / 3) { rgb[k] = (p + ((q - p) * 6 * (2.0f / 3 - trgb[k]))); }
else { rgb[k] = p; }
}
return Color.FromArgb((int)(rgb[0] * 255), (int)(rgb[1] * 255), (int)(rgb[2] * 255));
}
}
}

View File

@@ -58,8 +58,9 @@ namespace OpenRA.GameRules
public class PlayerSettings
{
public string Name = "Newbie";
public Color Color1 = Color.FromArgb(255,160,238);
public Color Color2 = Color.FromArgb(68,0,56);
[Obsolete] public Color Color1 = Color.FromArgb(255,160,238);
[Obsolete] public Color Color2 = Color.FromArgb(68,0,56);
public ColorRamp ColorRamp = new ColorRamp(75, 255, 180, 25);
public string LastServer = "localhost:1234";
}

View File

@@ -41,8 +41,7 @@ namespace OpenRA.Network
public class Client
{
public int Index;
public Color Color1;
public Color Color2;
public ColorRamp ColorRamp;
public string Country;
public int SpawnPoint;
public string Name;

View File

@@ -45,7 +45,7 @@ namespace OpenRA.Network
{
var player = world != null ? world.FindPlayerByClient(client) : null;
var suffix = (player != null && player.WinState == WinState.Lost) ? " (Dead)" : "";
Game.AddChatLine(client.Color1, client.Name + suffix, order.TargetString);
Game.AddChatLine(client.ColorRamp.GetColor(1), client.Name + suffix, order.TargetString);
}
else
Game.AddChatLine(Color.White, "(player {0})".F(clientId), order.TargetString);
@@ -69,7 +69,7 @@ namespace OpenRA.Network
if (world == null)
{
if (client.Team == orderManager.LocalClient.Team)
Game.AddChatLine(client.Color1, client.Name + " (Team)",
Game.AddChatLine(client.ColorRamp.GetColor(1), client.Name + " (Team)",
order.TargetString);
}
else
@@ -86,7 +86,7 @@ namespace OpenRA.Network
var suffix = (player != null && player.WinState == WinState.Lost)
? " (Dead)"
: " (Team)";
Game.AddChatLine(client.Color1, client.Name + suffix, order.TargetString);
Game.AddChatLine(client.ColorRamp.GetColor(1), client.Name + suffix, order.TargetString);
}
}
}
@@ -110,8 +110,7 @@ namespace OpenRA.Network
var info = new Session.Client()
{
Name = Game.Settings.Player.Name,
Color1 = Game.Settings.Player.Color1,
Color2 = Game.Settings.Player.Color2,
ColorRamp = Game.Settings.Player.ColorRamp,
Country = "random",
SpawnPoint = 0,
Team = 0,

View File

@@ -28,8 +28,7 @@ namespace OpenRA
public WinState WinState = WinState.Undefined;
public readonly string Palette;
public readonly Color Color;
public readonly Color Color2;
public readonly ColorRamp ColorRamp;
public readonly string PlayerName;
public readonly string InternalName;
@@ -50,8 +49,7 @@ namespace OpenRA
Index = index;
Palette = "player" + index;
Color = pr.Color;
Color2 = pr.Color2;
ColorRamp = pr.ColorRamp;
ClientIndex = 0; /* it's a map player, "owned" by host */
PlayerName = InternalName = pr.Name;
@@ -70,8 +68,7 @@ namespace OpenRA
World = world;
Index = index;
Palette = "player" + index;
Color = client.Color1;
Color2 = client.Color2;
ColorRamp = client.ColorRamp;
PlayerName = client.Name;
InternalName = pr.Name;

View File

@@ -245,10 +245,7 @@ namespace OpenRA.Server
if (pr == null)
return;
if (pr.LockColor)
{
c.Color1 = pr.Color;
c.Color2 = pr.Color2;
}
c.ColorRamp = pr.ColorRamp;
if (pr.LockRace)
c.Country = pr.Race;
}

View File

@@ -35,7 +35,7 @@ namespace OpenRA.Traits
{
var paletteName = "{0}{1}".F( info.BaseName, owner.Index );
var newpal = new Palette(wr.GetPalette(info.BasePalette),
new PlayerColorRemap(owner.Color, owner.Color2, info.PaletteFormat));
new PlayerColorRemap(owner.ColorRamp, info.PaletteFormat));
wr.AddPalette(paletteName, newpal);
}
}

View File

@@ -46,7 +46,7 @@ namespace OpenRA.Mods.RA
if (mod != null)
return mod.RadarColorOverride(self);
return self.Owner.Color;
return self.Owner.ColorRamp.GetColor(0);
}
}
}

View File

@@ -111,7 +111,7 @@ namespace OpenRA.Mods.RA
public Color RadarColorOverride(Actor self)
{
var c = self.Owner.Color;
var c = self.Owner.ColorRamp.GetColor(0);
if (self.Owner == self.World.LocalPlayer && Cloaked)
c = Color.FromArgb(128, c);
return c;

View File

@@ -11,8 +11,8 @@
using System.Collections.Generic;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Traits;
using OpenRA.Mods.RA.Widgets.Delegates;
using OpenRA.Traits;
namespace OpenRA.Mods.RA
{
@@ -31,8 +31,7 @@ namespace OpenRA.Mods.RA
public void AdjustPalette(Dictionary<string, Palette> palettes)
{
palettes["colorpicker"] = new Palette(palettes["colorpicker"],
new PlayerColorRemap(LobbyDelegate.CurrentColorPreview1,
LobbyDelegate.CurrentColorPreview2, format));
new PlayerColorRemap(LobbyDelegate.CurrentColorPreview, format));
}
}
}

View File

@@ -50,9 +50,8 @@ namespace OpenRA.Mods.RA
/* spawn a bot in this slot, "owned" by the host */
/* pick a random color for the bot */
var hue = (float)w.SharedRandom.NextDouble();
w.Map.Players[slot.MapPlayer].Color = PlayerColorRemap.ColorFromHSL(hue, 1.0f, 0.7f);
w.Map.Players[slot.MapPlayer].Color2 = PlayerColorRemap.ColorFromHSL(hue, 1.0f, 0.2f);
var hue = (byte)w.SharedRandom.Next(256);
w.Map.Players[slot.MapPlayer].ColorRamp = new ColorRamp(hue, 255, 180, 25);
/* todo: pick a random name from the pool */

View File

@@ -47,7 +47,7 @@ namespace OpenRA.Mods.RA
if (Info.UsePlayerColor)
{
var ownerColor = Color.FromArgb(255, self.Owner.Color);
var ownerColor = Color.FromArgb(255, self.Owner.ColorRamp.GetColor(0));
TrailColor = PlayerColorRemap.ColorLerp(0.5f, ownerColor, Color.White);
}
}

View File

@@ -23,7 +23,7 @@ namespace OpenRA.Mods.RA.Effects
public IEffect Create(ProjectileArgs args)
{
Color c = UsePlayerColor ? args.firedBy.Owner.Color : Color.Red;
Color c = UsePlayerColor ? args.firedBy.Owner.ColorRamp.GetColor(0) : Color.Red;
return new LaserZap(args, BeamRadius, c);
}
}

View File

@@ -25,7 +25,7 @@ namespace OpenRA.Mods.RA
public Color RadarColorOverride(Actor self)
{
return Color.FromArgb(128, self.Owner.Color);
return Color.FromArgb(128, self.Owner.ColorRamp.GetColor(0));
}
public IEnumerable<Renderable> ModifyRender(Actor self, IEnumerable<Renderable> r)

View File

@@ -15,6 +15,7 @@ using System.Linq;
using OpenRA.Network;
using OpenRA.Server;
using S = OpenRA.Server.Server;
using OpenRA.FileFormats;
namespace OpenRA.Mods.RA.Server
{
@@ -84,8 +85,7 @@ namespace OpenRA.Mods.RA.Server
s =>
{
var c = s.Split(',').Select(cc => int.Parse(cc)).ToArray();
client.Color1 = Color.FromArgb(c[0],c[1],c[2]);
client.Color2 = Color.FromArgb(c[3],c[4],c[5]);
client.ColorRamp = new ColorRamp((byte)c[0], (byte)c[1], (byte)c[2], (byte)c[3]);
server.SyncLobbyInfo();
return true;
}}

View File

@@ -26,9 +26,8 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
Dictionary<string, string> CountryNames;
string MapUid;
Map Map;
public static Color CurrentColorPreview1;
public static Color CurrentColorPreview2;
public static ColorRamp CurrentColorPreview;
readonly OrderManager orderManager;
[ObjectCreator.UseCtor]
@@ -38,8 +37,7 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
Game.LobbyInfoChanged += UpdateCurrentMap;
UpdateCurrentMap();
CurrentColorPreview1 = Game.Settings.Player.Color1;
CurrentColorPreview2 = Game.Settings.Player.Color2;
CurrentColorPreview = Game.Settings.Player.ColorRamp;
Players = lobby.GetWidget<ScrollPanelWidget>("PLAYERS");
LocalPlayerTemplate = Players.GetWidget("TEMPLATE_LOCAL");
@@ -79,7 +77,7 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
var client = orderManager.LobbyInfo.Clients.FirstOrDefault(c => c.SpawnPoint == i);
if (client == null)
continue;
sc.Add(spawns.ElementAt(i - 1), client.Color1);
sc.Add(spawns.ElementAt(i - 1), client.ColorRamp.GetColor(0));
}
return sc;
};
@@ -152,19 +150,15 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
void UpdatePlayerColor(float hf, float sf, float lf, float r)
{
var c1 = PlayerColorRemap.ColorFromHSL(hf, sf, lf);
var c2 = PlayerColorRemap.ColorFromHSL(hf, sf, r * lf);
Game.Settings.Player.Color1 = c1;
Game.Settings.Player.Color2 = c2;
var ramp = new ColorRamp((byte) (hf*255), (byte) (sf*255), (byte) (lf*255), (byte)(r*255));
Game.Settings.Player.ColorRamp = ramp;
Game.Settings.Save();
orderManager.IssueOrder(Order.Command("color {0},{1},{2},{3},{4},{5}".F(c1.R,c1.G,c1.B,c2.R,c2.G,c2.B)));
orderManager.IssueOrder(Order.Command("color {0}".F(ramp)));
}
void UpdateColorPreview(float hf, float sf, float lf, float r)
{
CurrentColorPreview1 = PlayerColorRemap.ColorFromHSL(hf, sf, lf);
CurrentColorPreview2 = PlayerColorRemap.ColorFromHSL(hf, sf, r * lf);
CurrentColorPreview = new ColorRamp((byte)(hf * 255), (byte)(sf * 255), (byte)(lf * 255), (byte)(r * 255));
}
void UpdateCurrentMap()
@@ -274,16 +268,16 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
var colorChooser = Game.modData.WidgetLoader.LoadWidget( new Dictionary<string,object>(), null, "COLOR_CHOOSER" );
var hueSlider = colorChooser.GetWidget<SliderWidget>("HUE_SLIDER");
hueSlider.SetOffset(orderManager.LocalClient.Color1.GetHue()/360f);
hueSlider.SetOffset(orderManager.LocalClient.ColorRamp.H / 255f);
var satSlider = colorChooser.GetWidget<SliderWidget>("SAT_SLIDER");
satSlider.SetOffset(orderManager.LocalClient.Color1.GetSaturation());
satSlider.SetOffset(orderManager.LocalClient.ColorRamp.S / 255f);
var lumSlider = colorChooser.GetWidget<SliderWidget>("LUM_SLIDER");
lumSlider.SetOffset(orderManager.LocalClient.Color1.GetBrightness());
var lumSlider = colorChooser.GetWidget<SliderWidget>("LUM_SLIDER");
lumSlider.SetOffset(orderManager.LocalClient.ColorRamp.L / 255f);
var rangeSlider = colorChooser.GetWidget<SliderWidget>("RANGE_SLIDER");
rangeSlider.SetOffset(orderManager.LocalClient.Color1.GetBrightness() == 0 ? 0 : orderManager.LocalClient.Color2.GetBrightness()/orderManager.LocalClient.Color1.GetBrightness());
rangeSlider.SetOffset(orderManager.LocalClient.ColorRamp.R / 255f);
hueSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset());
satSlider.OnChange += _ => UpdateColorPreview(hueSlider.GetOffset(), satSlider.GetOffset(), lumSlider.GetOffset(), rangeSlider.GetOffset());
@@ -382,7 +376,7 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
color.OnMouseUp = _ => ShowColorDropDown(s, color);
var colorBlock = color.GetWidget<ColorBlockWidget>("COLORBLOCK");
colorBlock.GetColor = () => c.Color1;
colorBlock.GetColor = () => c.ColorRamp.GetColor(0);
var faction = template.GetWidget<ButtonWidget>("FACTION");
faction.OnMouseDown = _ => ShowRaceDropDown(s, faction);
@@ -417,7 +411,7 @@ namespace OpenRA.Mods.RA.Widgets.Delegates
template = RemotePlayerTemplate.Clone();
template.GetWidget<LabelWidget>("NAME").GetText = () => c.Name;
var color = template.GetWidget<ColorBlockWidget>("COLOR");
color.GetColor = () => c.Color1;
color.GetColor = () => c.ColorRamp.GetColor(0);
var faction = template.GetWidget<LabelWidget>("FACTION");
var factionname = faction.GetWidget<LabelWidget>("FACTIONNAME");

View File

@@ -82,7 +82,7 @@ namespace OpenRA.Mods.RA.Widgets
if (text2 != "")
{
Game.Renderer.RegularFont.DrawText(text2,
new float2(Viewport.LastMousePos.X + 65, Viewport.LastMousePos.Y + 50), actor.Owner.Color);
new float2(Viewport.LastMousePos.X + 65, Viewport.LastMousePos.Y + 50), actor.Owner.ColorRamp.GetColor(0));
Game.Renderer.RegularFont.DrawText(text3,
new float2(Viewport.LastMousePos.X + 65 + sz2.X, Viewport.LastMousePos.Y + 50), Color.White);