using System; using System.Drawing; namespace PKHeX.Drawing; /// /// Utility class for manipulating values. /// public static class ColorUtil { /// Clamps absurdly high stats to a reasonable cap. private const byte MaxStat = 180; /// Ensures the color does not go below this value. private const byte MinStat = 0; /// Shift the color total down a little as the BST floor isn't 0. private const byte ShiftDownBST = 175; /// Divide by a fudge factor so that we're roughly within the range of a single stat. private const float ShiftDivBST = 3; /// /// Gets the value for the specified value. /// /// Single stat value public static Color ColorBaseStat(int stat) { // Red to Yellow to Green, no Blue component. var x = (uint)stat >= MaxStat ? 1f : ((float)stat) / MaxStat; return GetPastelRYG(x); } /// /// Gets the value for the specified value. /// /// Base Stat Total public static Color ColorBaseStatTotal(int bst) { var sumToSingle = Math.Max(MinStat, bst - ShiftDownBST) / ShiftDivBST; return ColorBaseStat((int)sumToSingle); } /// /// Gets a pastel color from Red to Yellow to Green with a 40%/60% blend with White. /// /// Percentage of the way from Red to Green [0,1] public static Color GetPastelRYG(float x) { var r = x > .5f ? 510 * (1 - x) : 255; var g = x > .5f ? 255 : 510 * x; // Blend with white to make it lighter rather than a darker shade. const float white = 0.4f; const byte b = (byte)(0xFF * (1 - white)); var br = (byte)((r * white) + b); var bg = (byte)((g * white) + b); return Color.FromArgb(br, bg, b); } /// /// Combines two colors together with the specified amount. /// /// New color to layer atop /// Original color to layer beneath /// Amount to prefer over public static Color Blend(Color color, Color backColor, double amount) { byte r = MixComponent(color.R, backColor.R, amount); byte g = MixComponent(color.G, backColor.G, amount); byte b = MixComponent(color.B, backColor.B, amount); return Color.FromArgb(r, g, b); } /// /// Combines two color components with the specified first color percent preference [0,1]. /// /// First color's component /// Second color's component /// Percent preference of over public static byte MixComponent(byte a, byte b, double x) => (byte)((a * x) + (b * (1 - x))); }