mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-22 12:03:10 +00:00
File scoped namespace for drawing projects
Extract color util to separate class as it's not entirely image related.
This commit is contained in:
parent
9f920405df
commit
aa968f56aa
25 changed files with 1095 additions and 1126 deletions
|
@ -53,9 +53,7 @@ public static class ContestStatInfo
|
|||
return initial.CNT_Sheen;
|
||||
|
||||
if (pokeBlock3)
|
||||
{
|
||||
return CalculateMaximumSheen3(s, nature, initial);
|
||||
}
|
||||
|
||||
var avg = GetAverageFeel(s, nature, initial);
|
||||
if (avg <= 0)
|
||||
|
@ -162,7 +160,7 @@ public static class ContestStatInfo
|
|||
|
||||
private static readonly sbyte[] NatureAmpTable =
|
||||
{
|
||||
// Spicy, Dry, Sweet, Bitter, Sour
|
||||
// Spicy, Dry, Sweet, Bitter, Sour
|
||||
0, 0, 0, 0, 0, // Hardy
|
||||
1, 0, 0, 0,-1, // Lonely
|
||||
1, 0,-1, 0, 0, // Brave
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net46</TargetFrameworks>
|
||||
<LangVersion>9</LangVersion>
|
||||
<LangVersion>10</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -5,104 +5,99 @@ using System.Text;
|
|||
using System.Text.RegularExpressions;
|
||||
using PKHeX.Core;
|
||||
|
||||
namespace PKHeX.Drawing.Misc
|
||||
namespace PKHeX.Drawing.Misc;
|
||||
|
||||
public static class QRDecode
|
||||
{
|
||||
public static class QRDecode
|
||||
// QR Utility
|
||||
private const string DecodeAPI = "http://api.qrserver.com/v1/read-qr-code/?fileurl=";
|
||||
|
||||
public static QRDecodeResult GetQRData(string address, out byte[] result)
|
||||
{
|
||||
// QR Utility
|
||||
private const string DecodeAPI = "http://api.qrserver.com/v1/read-qr-code/?fileurl=";
|
||||
result = Array.Empty<byte>();
|
||||
// Fetch data from QR code...
|
||||
|
||||
public static QRDecodeResult GetQRData(string address, out byte[] result)
|
||||
if (!address.StartsWith("http"))
|
||||
return QRDecodeResult.BadPath;
|
||||
|
||||
string url = DecodeAPI + WebUtility.UrlEncode(address);
|
||||
string data;
|
||||
try
|
||||
{
|
||||
result = Array.Empty<byte>();
|
||||
// Fetch data from QR code...
|
||||
var str = NetUtil.GetStringFromURL(url);
|
||||
if (str is null)
|
||||
return QRDecodeResult.BadConnection;
|
||||
|
||||
if (!address.StartsWith("http"))
|
||||
return QRDecodeResult.BadPath;
|
||||
data = str;
|
||||
if (data.Contains("could not find"))
|
||||
return QRDecodeResult.BadImage;
|
||||
|
||||
string url = DecodeAPI + WebUtility.UrlEncode(address);
|
||||
string data;
|
||||
try
|
||||
{
|
||||
var str = NetUtil.GetStringFromURL(url);
|
||||
if (str is null)
|
||||
return QRDecodeResult.BadConnection;
|
||||
|
||||
data = str;
|
||||
if (data.Contains("could not find"))
|
||||
return QRDecodeResult.BadImage;
|
||||
|
||||
if (data.Contains("filetype not supported"))
|
||||
return QRDecodeResult.BadType;
|
||||
}
|
||||
#pragma warning disable CA1031 // Do not catch general exception types
|
||||
catch { return QRDecodeResult.BadConnection; }
|
||||
#pragma warning restore CA1031 // Do not catch general exception types
|
||||
|
||||
// Quickly convert the json response to a data string
|
||||
try
|
||||
{
|
||||
result = DecodeQRJson(data);
|
||||
return QRDecodeResult.Success;
|
||||
}
|
||||
#pragma warning disable CA1031 // Do not catch general exception types
|
||||
catch (Exception e)
|
||||
#pragma warning restore CA1031 // Do not catch general exception types
|
||||
{
|
||||
Debug.WriteLine(e.Message);
|
||||
return QRDecodeResult.BadConversion;
|
||||
}
|
||||
if (data.Contains("filetype not supported"))
|
||||
return QRDecodeResult.BadType;
|
||||
}
|
||||
catch { return QRDecodeResult.BadConnection; }
|
||||
|
||||
private static byte[] DecodeQRJson(string data)
|
||||
// Quickly convert the json response to a data string
|
||||
try
|
||||
{
|
||||
const string cap = "\",\"error\":null}]}]";
|
||||
const string intro = "[{\"type\":\"qrcode\",\"symbol\":[{\"seq\":0,\"data\":\"";
|
||||
const string qrcode = "nQR-Code:";
|
||||
if (!data.StartsWith(intro))
|
||||
throw new FormatException();
|
||||
|
||||
string pkstr = data[intro.Length..];
|
||||
|
||||
// Remove multiple QR codes in same image
|
||||
var qr = pkstr.IndexOf(qrcode, StringComparison.Ordinal);
|
||||
if (qr != -1)
|
||||
pkstr = pkstr[..qr];
|
||||
|
||||
// Trim outro
|
||||
var outroIndex = pkstr.IndexOf(cap, StringComparison.Ordinal);
|
||||
if (outroIndex == -1)
|
||||
throw new FormatException();
|
||||
|
||||
pkstr = pkstr[..outroIndex];
|
||||
|
||||
if (!pkstr.StartsWith("http") && !pkstr.StartsWith("null")) // G7
|
||||
{
|
||||
string fstr = Regex.Unescape(pkstr);
|
||||
byte[] raw = Encoding.Unicode.GetBytes(fstr);
|
||||
|
||||
// Remove 00 interstitials and retrieve from offset 0x30, take PK7 Stored Size (always)
|
||||
byte[] result = new byte[0xE8];
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
result[i] = raw[(i + 0x30) * 2];
|
||||
return result;
|
||||
}
|
||||
// All except G7
|
||||
pkstr = pkstr[(pkstr.IndexOf('#') + 1)..]; // Trim URL
|
||||
pkstr = pkstr.Replace("\\", string.Empty); // Rectify response
|
||||
|
||||
return Convert.FromBase64String(pkstr);
|
||||
result = DecodeQRJson(data);
|
||||
return QRDecodeResult.Success;
|
||||
}
|
||||
|
||||
public static string ConvertMsg(this QRDecodeResult result) => result switch
|
||||
catch (Exception e)
|
||||
{
|
||||
QRDecodeResult.Success => string.Empty,
|
||||
QRDecodeResult.BadPath => MessageStrings.MsgQRUrlFailPath,
|
||||
QRDecodeResult.BadImage => MessageStrings.MsgQRUrlFailImage,
|
||||
QRDecodeResult.BadType => MessageStrings.MsgQRUrlFailType,
|
||||
QRDecodeResult.BadConnection => MessageStrings.MsgQRUrlFailConnection,
|
||||
QRDecodeResult.BadConversion => MessageStrings.MsgQRUrlFailConvert,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(result), result, null),
|
||||
};
|
||||
Debug.WriteLine(e.Message);
|
||||
return QRDecodeResult.BadConversion;
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] DecodeQRJson(string data)
|
||||
{
|
||||
const string cap = "\",\"error\":null}]}]";
|
||||
const string intro = "[{\"type\":\"qrcode\",\"symbol\":[{\"seq\":0,\"data\":\"";
|
||||
const string qrcode = "nQR-Code:";
|
||||
if (!data.StartsWith(intro))
|
||||
throw new FormatException();
|
||||
|
||||
string pkstr = data[intro.Length..];
|
||||
|
||||
// Remove multiple QR codes in same image
|
||||
var qr = pkstr.IndexOf(qrcode, StringComparison.Ordinal);
|
||||
if (qr != -1)
|
||||
pkstr = pkstr[..qr];
|
||||
|
||||
// Trim outro
|
||||
var outroIndex = pkstr.IndexOf(cap, StringComparison.Ordinal);
|
||||
if (outroIndex == -1)
|
||||
throw new FormatException();
|
||||
|
||||
pkstr = pkstr[..outroIndex];
|
||||
|
||||
if (!pkstr.StartsWith("http") && !pkstr.StartsWith("null")) // G7
|
||||
{
|
||||
string fstr = Regex.Unescape(pkstr);
|
||||
byte[] raw = Encoding.Unicode.GetBytes(fstr);
|
||||
|
||||
// Remove 00 interstitials and retrieve from offset 0x30, take PK7 Stored Size (always)
|
||||
byte[] result = new byte[0xE8];
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
result[i] = raw[(i + 0x30) * 2];
|
||||
return result;
|
||||
}
|
||||
// All except G7
|
||||
pkstr = pkstr[(pkstr.IndexOf('#') + 1)..]; // Trim URL
|
||||
pkstr = pkstr.Replace("\\", string.Empty); // Rectify response
|
||||
|
||||
return Convert.FromBase64String(pkstr);
|
||||
}
|
||||
|
||||
public static string ConvertMsg(this QRDecodeResult result) => result switch
|
||||
{
|
||||
QRDecodeResult.Success => string.Empty,
|
||||
QRDecodeResult.BadPath => MessageStrings.MsgQRUrlFailPath,
|
||||
QRDecodeResult.BadImage => MessageStrings.MsgQRUrlFailImage,
|
||||
QRDecodeResult.BadType => MessageStrings.MsgQRUrlFailType,
|
||||
QRDecodeResult.BadConnection => MessageStrings.MsgQRUrlFailConnection,
|
||||
QRDecodeResult.BadConversion => MessageStrings.MsgQRUrlFailConvert,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(result), result, null),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
namespace PKHeX.Drawing.Misc
|
||||
namespace PKHeX.Drawing.Misc;
|
||||
|
||||
public enum QRDecodeResult
|
||||
{
|
||||
public enum QRDecodeResult
|
||||
{
|
||||
Success,
|
||||
BadPath,
|
||||
BadImage,
|
||||
BadType,
|
||||
BadConnection,
|
||||
BadConversion,
|
||||
}
|
||||
}
|
||||
Success,
|
||||
BadPath,
|
||||
BadImage,
|
||||
BadType,
|
||||
BadConnection,
|
||||
BadConversion,
|
||||
}
|
||||
|
|
|
@ -2,26 +2,25 @@
|
|||
using PKHeX.Core;
|
||||
using QRCoder;
|
||||
|
||||
namespace PKHeX.Drawing.Misc
|
||||
namespace PKHeX.Drawing.Misc;
|
||||
|
||||
public static class QREncode
|
||||
{
|
||||
public static class QREncode
|
||||
public static Image GenerateQRCode(DataMysteryGift mg) => GenerateQRCode(QRMessageUtil.GetMessage(mg));
|
||||
public static Image GenerateQRCode(PKM pkm) => GenerateQRCode(QRMessageUtil.GetMessage(pkm));
|
||||
|
||||
public static Image GenerateQRCode7(PK7 pk7, int box = 0, int slot = 0, int copies = 1)
|
||||
{
|
||||
public static Image GenerateQRCode(DataMysteryGift mg) => GenerateQRCode(QRMessageUtil.GetMessage(mg));
|
||||
public static Image GenerateQRCode(PKM pkm) => GenerateQRCode(QRMessageUtil.GetMessage(pkm));
|
||||
|
||||
public static Image GenerateQRCode7(PK7 pk7, int box = 0, int slot = 0, int copies = 1)
|
||||
{
|
||||
byte[] data = QR7.GenerateQRData(pk7, box, slot, copies);
|
||||
var msg = QRMessageUtil.GetMessage(data);
|
||||
return GenerateQRCode(msg, ppm: 4);
|
||||
}
|
||||
|
||||
private static Image GenerateQRCode(string msg, int ppm = 4)
|
||||
{
|
||||
using var generator = new QRCodeGenerator();
|
||||
using var data = generator.CreateQrCode(msg, QRCodeGenerator.ECCLevel.Q);
|
||||
using var code = new QRCode(data);
|
||||
return code.GetGraphic(ppm);
|
||||
}
|
||||
byte[] data = QR7.GenerateQRData(pk7, box, slot, copies);
|
||||
var msg = QRMessageUtil.GetMessage(data);
|
||||
return GenerateQRCode(msg, ppm: 4);
|
||||
}
|
||||
}
|
||||
|
||||
private static Image GenerateQRCode(string msg, int ppm = 4)
|
||||
{
|
||||
using var generator = new QRCodeGenerator();
|
||||
using var data = generator.CreateQrCode(msg, QRCodeGenerator.ECCLevel.Q);
|
||||
using var code = new QRCode(data);
|
||||
return code.GetGraphic(ppm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,51 +1,50 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace PKHeX.Drawing.Misc
|
||||
namespace PKHeX.Drawing.Misc;
|
||||
|
||||
public static class QRImageUtil
|
||||
{
|
||||
public static class QRImageUtil
|
||||
public static Bitmap GetQRImage(Image qr, Image preview)
|
||||
{
|
||||
public static Bitmap GetQRImage(Image qr, Image preview)
|
||||
// create a small area with the pkm sprite, with a white background
|
||||
var foreground = new Bitmap(preview.Width + 4, preview.Height + 4);
|
||||
using (Graphics gfx = Graphics.FromImage(foreground))
|
||||
{
|
||||
// create a small area with the pkm sprite, with a white background
|
||||
var foreground = new Bitmap(preview.Width + 4, preview.Height + 4);
|
||||
using (Graphics gfx = Graphics.FromImage(foreground))
|
||||
{
|
||||
gfx.FillRectangle(new SolidBrush(Color.White), 0, 0, foreground.Width, foreground.Height);
|
||||
int x = (foreground.Width / 2) - (preview.Width / 2);
|
||||
int y = (foreground.Height / 2) - (preview.Height / 2);
|
||||
gfx.DrawImage(preview, x, y);
|
||||
}
|
||||
|
||||
// Layer on Preview Image
|
||||
{
|
||||
int x = (qr.Width / 2) - (foreground.Width / 2);
|
||||
int y = (qr.Height / 2) - (foreground.Height / 2);
|
||||
return ImageUtil.LayerImage(qr, foreground, x, y);
|
||||
}
|
||||
gfx.FillRectangle(new SolidBrush(Color.White), 0, 0, foreground.Width, foreground.Height);
|
||||
int x = (foreground.Width / 2) - (preview.Width / 2);
|
||||
int y = (foreground.Height / 2) - (preview.Height / 2);
|
||||
gfx.DrawImage(preview, x, y);
|
||||
}
|
||||
|
||||
public static Bitmap GetQRImageExtended(Font font, Image qr, Image pkm, int width, int height, string[] lines, string extraText)
|
||||
// Layer on Preview Image
|
||||
{
|
||||
var pic = GetQRImage(qr, pkm);
|
||||
return ExtendImage(font, qr, width, height, pic, lines, extraText);
|
||||
int x = (qr.Width / 2) - (foreground.Width / 2);
|
||||
int y = (qr.Height / 2) - (foreground.Height / 2);
|
||||
return ImageUtil.LayerImage(qr, foreground, x, y);
|
||||
}
|
||||
|
||||
private static Bitmap ExtendImage(Font font, Image qr, int width, int height, Image pic, string[] lines, string extraText)
|
||||
{
|
||||
var newpic = new Bitmap(width, height);
|
||||
using Graphics g = Graphics.FromImage(newpic);
|
||||
g.FillRectangle(new SolidBrush(Color.White), 0, 0, newpic.Width, newpic.Height);
|
||||
g.DrawImage(pic, 0, 0);
|
||||
|
||||
g.DrawString(GetLine(lines, 0), font, Brushes.Black, new PointF(18, qr.Height - 5));
|
||||
g.DrawString(GetLine(lines, 1), font, Brushes.Black, new PointF(18, qr.Height + 8));
|
||||
g.DrawString(GetLine(lines, 2).Replace(Environment.NewLine, "/").Replace("//", " ").Replace(":/", ": "), font,
|
||||
Brushes.Black, new PointF(18, qr.Height + 20));
|
||||
g.DrawString(GetLine(lines, 3) + extraText, font, Brushes.Black, new PointF(18, qr.Height + 32));
|
||||
return newpic;
|
||||
}
|
||||
|
||||
private static string GetLine(string[] lines, int line) => lines.Length <= line ? string.Empty : lines[line];
|
||||
}
|
||||
|
||||
public static Bitmap GetQRImageExtended(Font font, Image qr, Image pkm, int width, int height, string[] lines, string extraText)
|
||||
{
|
||||
var pic = GetQRImage(qr, pkm);
|
||||
return ExtendImage(font, qr, width, height, pic, lines, extraText);
|
||||
}
|
||||
|
||||
private static Bitmap ExtendImage(Font font, Image qr, int width, int height, Image pic, string[] lines, string extraText)
|
||||
{
|
||||
var newpic = new Bitmap(width, height);
|
||||
using Graphics g = Graphics.FromImage(newpic);
|
||||
g.FillRectangle(new SolidBrush(Color.White), 0, 0, newpic.Width, newpic.Height);
|
||||
g.DrawImage(pic, 0, 0);
|
||||
|
||||
g.DrawString(GetLine(lines, 0), font, Brushes.Black, new PointF(18, qr.Height - 5));
|
||||
g.DrawString(GetLine(lines, 1), font, Brushes.Black, new PointF(18, qr.Height + 8));
|
||||
g.DrawString(GetLine(lines, 2).Replace(Environment.NewLine, "/").Replace("//", " ").Replace(":/", ": "), font,
|
||||
Brushes.Black, new PointF(18, qr.Height + 20));
|
||||
g.DrawString(GetLine(lines, 3) + extraText, font, Brushes.Black, new PointF(18, qr.Height + 32));
|
||||
return newpic;
|
||||
}
|
||||
|
||||
private static string GetLine(string[] lines, int line) => lines.Length <= line ? string.Empty : lines[line];
|
||||
}
|
||||
|
|
|
@ -3,40 +3,39 @@ using PKHeX.Core;
|
|||
using PKHeX.Drawing.Misc.Properties;
|
||||
using PKHeX.Drawing.PokeSprite;
|
||||
|
||||
namespace PKHeX.Drawing.Misc
|
||||
namespace PKHeX.Drawing.Misc;
|
||||
|
||||
public static class MysteryGiftSpriteUtil
|
||||
{
|
||||
public static class MysteryGiftSpriteUtil
|
||||
public static Image Sprite(this MysteryGift gift) => GetSprite(gift);
|
||||
|
||||
private static Image GetSprite(MysteryGift gift)
|
||||
{
|
||||
public static Image Sprite(this MysteryGift gift) => GetSprite(gift);
|
||||
if (gift.Empty)
|
||||
return SpriteUtil.Spriter.None;
|
||||
|
||||
private static Image GetSprite(MysteryGift gift)
|
||||
var img = GetBaseImage(gift);
|
||||
if (SpriteBuilder.ShowEncounterColor != SpriteBackgroundType.None)
|
||||
img = SpriteUtil.ApplyEncounterColor(gift, img, SpriteBuilder.ShowEncounterColor);
|
||||
if (gift.GiftUsed)
|
||||
img = ImageUtil.ChangeOpacity(img, 0.3);
|
||||
return img;
|
||||
}
|
||||
|
||||
private static Image GetBaseImage(MysteryGift gift)
|
||||
{
|
||||
if (gift.IsEgg && gift.Species == (int)Species.Manaphy) // Manaphy Egg
|
||||
return SpriteUtil.GetMysteryGiftPreviewPoke(gift);
|
||||
if (gift.IsPokémon)
|
||||
return SpriteUtil.GetMysteryGiftPreviewPoke(gift);
|
||||
|
||||
if (gift.IsItem)
|
||||
{
|
||||
if (gift.Empty)
|
||||
return SpriteUtil.Spriter.None;
|
||||
|
||||
var img = GetBaseImage(gift);
|
||||
if (SpriteBuilder.ShowEncounterColor != SpriteBackgroundType.None)
|
||||
img = SpriteUtil.ApplyEncounterColor(gift, img, SpriteBuilder.ShowEncounterColor);
|
||||
if (gift.GiftUsed)
|
||||
img = ImageUtil.ChangeOpacity(img, 0.3);
|
||||
return img;
|
||||
}
|
||||
|
||||
private static Image GetBaseImage(MysteryGift gift)
|
||||
{
|
||||
if (gift.IsEgg && gift.Species == (int)Species.Manaphy) // Manaphy Egg
|
||||
return SpriteUtil.GetMysteryGiftPreviewPoke(gift);
|
||||
if (gift.IsPokémon)
|
||||
return SpriteUtil.GetMysteryGiftPreviewPoke(gift);
|
||||
|
||||
if (gift.IsItem)
|
||||
{
|
||||
int item = gift.ItemID;
|
||||
if (Legal.ZCrystalDictionary.TryGetValue(item, out int value))
|
||||
item = value;
|
||||
return SpriteUtil.GetItemSprite(item) ?? Resources.Bag_Key;
|
||||
}
|
||||
return PokeSprite.Properties.Resources.b_unknown;
|
||||
int item = gift.ItemID;
|
||||
if (Legal.ZCrystalDictionary.TryGetValue(item, out int value))
|
||||
item = value;
|
||||
return SpriteUtil.GetItemSprite(item) ?? Resources.Bag_Key;
|
||||
}
|
||||
return PokeSprite.Properties.Resources.b_unknown;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,20 +2,19 @@
|
|||
using PKHeX.Core;
|
||||
using PKHeX.Drawing.Misc.Properties;
|
||||
|
||||
namespace PKHeX.Drawing.Misc
|
||||
{
|
||||
public static class PlayerSpriteUtil
|
||||
{
|
||||
public static Image? Sprite(this SaveFile sav) => GetSprite(sav);
|
||||
namespace PKHeX.Drawing.Misc;
|
||||
|
||||
private static Image? GetSprite(SaveFile sav)
|
||||
public static class PlayerSpriteUtil
|
||||
{
|
||||
public static Image? Sprite(this SaveFile sav) => GetSprite(sav);
|
||||
|
||||
private static Image? GetSprite(SaveFile sav)
|
||||
{
|
||||
if (sav is SAV6XY or SAV6AO)
|
||||
{
|
||||
if (sav is SAV6XY or SAV6AO)
|
||||
{
|
||||
string file = $"tr_{sav.MultiplayerSpriteID:00}";
|
||||
return Resources.ResourceManager.GetObject(file) as Image ?? Resources.tr_00;
|
||||
}
|
||||
return null;
|
||||
string file = $"tr_{sav.MultiplayerSpriteID:00}";
|
||||
return Resources.ResourceManager.GetObject(file) as Image ?? Resources.tr_00;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,40 @@
|
|||
using System.Drawing;
|
||||
using PKHeX.Drawing.Misc.Properties;
|
||||
|
||||
namespace PKHeX.Drawing.Misc
|
||||
namespace PKHeX.Drawing.Misc;
|
||||
|
||||
public static class RibbonSpriteUtil
|
||||
{
|
||||
public static class RibbonSpriteUtil
|
||||
public static Image? GetRibbonSprite(string name)
|
||||
{
|
||||
public static Image? GetRibbonSprite(string name)
|
||||
var resource = name.Replace("CountG3", "G3").ToLowerInvariant();
|
||||
return (Bitmap?)Resources.ResourceManager.GetObject(resource);
|
||||
}
|
||||
|
||||
public static Image? GetRibbonSprite(string name, int max, int value)
|
||||
{
|
||||
var resource = GetRibbonSpriteName(name, max, value);
|
||||
return (Bitmap?)Resources.ResourceManager.GetObject(resource);
|
||||
}
|
||||
|
||||
private static string GetRibbonSpriteName(string name, int max, int value)
|
||||
{
|
||||
if (max != 4) // Memory
|
||||
{
|
||||
var resource = name.Replace("CountG3", "G3").ToLowerInvariant();
|
||||
return (Bitmap?)Resources.ResourceManager.GetObject(resource);
|
||||
var sprite = name.ToLowerInvariant();
|
||||
if (max == value)
|
||||
return sprite + "2";
|
||||
return sprite;
|
||||
}
|
||||
|
||||
public static Image? GetRibbonSprite(string name, int max, int value)
|
||||
// Count ribbons
|
||||
string n = name.Replace("Count", string.Empty).ToLowerInvariant();
|
||||
return value switch
|
||||
{
|
||||
var resource = GetRibbonSpriteName(name, max, value);
|
||||
return (Bitmap?)Resources.ResourceManager.GetObject(resource);
|
||||
}
|
||||
|
||||
private static string GetRibbonSpriteName(string name, int max, int value)
|
||||
{
|
||||
if (max != 4) // Memory
|
||||
{
|
||||
var sprite = name.ToLowerInvariant();
|
||||
if (max == value)
|
||||
return sprite + "2";
|
||||
return sprite;
|
||||
}
|
||||
|
||||
// Count ribbons
|
||||
string n = name.Replace("Count", string.Empty).ToLowerInvariant();
|
||||
return value switch
|
||||
{
|
||||
2 => n + "super",
|
||||
3 => n + "hyper",
|
||||
4 => n + "master",
|
||||
_ => n,
|
||||
};
|
||||
}
|
||||
2 => n + "super",
|
||||
3 => n + "hyper",
|
||||
4 => n + "master",
|
||||
_ => n,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,15 +2,14 @@
|
|||
using PKHeX.Core;
|
||||
using PKHeX.Drawing.Misc.Properties;
|
||||
|
||||
namespace PKHeX.Drawing.Misc
|
||||
namespace PKHeX.Drawing.Misc;
|
||||
|
||||
public static class TypeSpriteUtil
|
||||
{
|
||||
public static class TypeSpriteUtil
|
||||
public static Image? GetTypeSprite(int type, int generation = PKX.Generation)
|
||||
{
|
||||
public static Image? GetTypeSprite(int type, int generation = PKX.Generation)
|
||||
{
|
||||
if (generation <= 2)
|
||||
type = (int)((MoveType)type).GetMoveTypeGeneration(generation);
|
||||
return (Bitmap?)Resources.ResourceManager.GetObject($"type_icon_{type:00}");
|
||||
}
|
||||
if (generation <= 2)
|
||||
type = (int)((MoveType)type).GetMoveTypeGeneration(generation);
|
||||
return (Bitmap?)Resources.ResourceManager.GetObject($"type_icon_{type:00}");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,40 +3,39 @@ using PKHeX.Core;
|
|||
using PKHeX.Drawing.Misc.Properties;
|
||||
using static PKHeX.Core.GameVersion;
|
||||
|
||||
namespace PKHeX.Drawing.Misc
|
||||
namespace PKHeX.Drawing.Misc;
|
||||
|
||||
public static class WallpaperUtil
|
||||
{
|
||||
public static class WallpaperUtil
|
||||
public static Image WallpaperImage(this SaveFile sav, int box) => GetWallpaper(sav, box);
|
||||
|
||||
private static Image GetWallpaper(SaveFile sav, int box)
|
||||
{
|
||||
public static Image WallpaperImage(this SaveFile sav, int box) => GetWallpaper(sav, box);
|
||||
|
||||
private static Image GetWallpaper(SaveFile sav, int box)
|
||||
{
|
||||
string s = GetWallpaperResourceName(sav.Version, sav.GetBoxWallpaper(box));
|
||||
return (Bitmap?)Resources.ResourceManager.GetObject(s) ?? Resources.box_wp16xy;
|
||||
}
|
||||
|
||||
public static string GetWallpaperResourceName(GameVersion version, int index)
|
||||
{
|
||||
index++; // start indexes at 1
|
||||
var suffix = GetResourceSuffix(version, index);
|
||||
return $"box_wp{index:00}{suffix}";
|
||||
}
|
||||
|
||||
private static string GetResourceSuffix(GameVersion version, int index) => version.GetGeneration() switch
|
||||
{
|
||||
3 when version == E => "e",
|
||||
3 when FRLG.Contains(version) && index > 12 => "frlg",
|
||||
3 => "rs",
|
||||
|
||||
4 when index < 16 => "dp",
|
||||
4 when version == Pt => "pt",
|
||||
4 when HGSS.Contains(version) => "hgss",
|
||||
|
||||
5 => B2W2.Contains(version) && index > 16 ? "b2w2" : "bw",
|
||||
6 => ORAS.Contains(version) && index > 16 ? "ao" : "xy",
|
||||
7 when !GG.Contains(version) => "xy",
|
||||
8 => BDSP.Contains(version) ? "bdsp" : "swsh",
|
||||
_ => string.Empty,
|
||||
};
|
||||
string s = GetWallpaperResourceName(sav.Version, sav.GetBoxWallpaper(box));
|
||||
return (Bitmap?)Resources.ResourceManager.GetObject(s) ?? Resources.box_wp16xy;
|
||||
}
|
||||
|
||||
public static string GetWallpaperResourceName(GameVersion version, int index)
|
||||
{
|
||||
index++; // start indexes at 1
|
||||
var suffix = GetResourceSuffix(version, index);
|
||||
return $"box_wp{index:00}{suffix}";
|
||||
}
|
||||
|
||||
private static string GetResourceSuffix(GameVersion version, int index) => version.GetGeneration() switch
|
||||
{
|
||||
3 when version == E => "e",
|
||||
3 when FRLG.Contains(version) && index > 12 => "frlg",
|
||||
3 => "rs",
|
||||
|
||||
4 when index < 16 => "dp",
|
||||
4 when version == Pt => "pt",
|
||||
4 when HGSS.Contains(version) => "hgss",
|
||||
|
||||
5 => B2W2.Contains(version) && index > 16 ? "b2w2" : "bw",
|
||||
6 => ORAS.Contains(version) && index > 16 ? "ao" : "xy",
|
||||
7 when !GG.Contains(version) => "xy",
|
||||
8 => BDSP.Contains(version) ? "bdsp" : "swsh",
|
||||
_ => string.Empty,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
namespace PKHeX.Drawing.PokeSprite
|
||||
{
|
||||
public interface ISpriteSettings
|
||||
{
|
||||
bool ShowEggSpriteAsHeldItem { get; set; }
|
||||
bool ShowEncounterBall { get; set; }
|
||||
namespace PKHeX.Drawing.PokeSprite;
|
||||
|
||||
SpriteBackgroundType ShowEncounterColor { get; set; }
|
||||
SpriteBackgroundType ShowEncounterColorPKM { get; set; }
|
||||
int ShowEncounterThicknessStripe { get; set; }
|
||||
byte ShowEncounterOpacityBackground { get; set; }
|
||||
byte ShowEncounterOpacityStripe { get; set; }
|
||||
bool ShowExperiencePercent { get; set; }
|
||||
}
|
||||
public interface ISpriteSettings
|
||||
{
|
||||
bool ShowEggSpriteAsHeldItem { get; set; }
|
||||
bool ShowEncounterBall { get; set; }
|
||||
|
||||
SpriteBackgroundType ShowEncounterColor { get; set; }
|
||||
SpriteBackgroundType ShowEncounterColorPKM { get; set; }
|
||||
int ShowEncounterThicknessStripe { get; set; }
|
||||
byte ShowEncounterOpacityBackground { get; set; }
|
||||
byte ShowEncounterOpacityStripe { get; set; }
|
||||
bool ShowExperiencePercent { get; set; }
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
namespace PKHeX.Drawing.PokeSprite
|
||||
namespace PKHeX.Drawing.PokeSprite;
|
||||
|
||||
public enum SpriteBackgroundType
|
||||
{
|
||||
public enum SpriteBackgroundType
|
||||
{
|
||||
None,
|
||||
BottomStripe,
|
||||
FullBackground,
|
||||
}
|
||||
None,
|
||||
BottomStripe,
|
||||
FullBackground,
|
||||
}
|
||||
|
|
|
@ -2,207 +2,206 @@
|
|||
using PKHeX.Core;
|
||||
using PKHeX.Drawing.PokeSprite.Properties;
|
||||
|
||||
namespace PKHeX.Drawing.PokeSprite
|
||||
namespace PKHeX.Drawing.PokeSprite;
|
||||
|
||||
public abstract class SpriteBuilder : ISpriteBuilder<Image>
|
||||
{
|
||||
public abstract class SpriteBuilder : ISpriteBuilder<Image>
|
||||
public static bool ShowEggSpriteAsItem { get; set; } = true;
|
||||
public static bool ShowEncounterBall { get; set; } = true;
|
||||
public static SpriteBackgroundType ShowEncounterColor { get; set; } = SpriteBackgroundType.FullBackground;
|
||||
public static SpriteBackgroundType ShowEncounterColorPKM { get; set; }
|
||||
public static bool ShowExperiencePercent { get; set; }
|
||||
|
||||
public static byte ShowEncounterOpacityStripe { get; set; }
|
||||
public static byte ShowEncounterOpacityBackground { get; set; }
|
||||
public static int ShowEncounterThicknessStripe { get; set; }
|
||||
|
||||
/// <summary> Width of the generated Sprite image. </summary>
|
||||
public abstract int Width { get; }
|
||||
/// <summary> Height of the generated Sprite image. </summary>
|
||||
public abstract int Height { get; }
|
||||
|
||||
/// <summary> Minimum amount of padding on the right side of the image when layering an item sprite. </summary>
|
||||
protected abstract int ItemShiftX { get; }
|
||||
/// <summary> Minimum amount of padding on the bottom side of the image when layering an item sprite. </summary>
|
||||
protected abstract int ItemShiftY { get; }
|
||||
/// <summary> Max width / height of an item image. </summary>
|
||||
protected abstract int ItemMaxSize { get; }
|
||||
|
||||
protected abstract int EggItemShiftX { get; }
|
||||
protected abstract int EggItemShiftY { get; }
|
||||
|
||||
public abstract Bitmap Hover { get; }
|
||||
public abstract Bitmap View { get; }
|
||||
public abstract Bitmap Set { get; }
|
||||
public abstract Bitmap Delete { get; }
|
||||
public abstract Bitmap Transparent { get; }
|
||||
public abstract Bitmap Drag { get; }
|
||||
public abstract Bitmap UnknownItem { get; }
|
||||
public abstract Bitmap None { get; }
|
||||
public abstract Bitmap ItemTM { get; }
|
||||
public abstract Bitmap ItemTR { get; }
|
||||
|
||||
private const double UnknownFormTransparency = 0.5;
|
||||
private const double ShinyTransparency = 0.7;
|
||||
private const double EggUnderLayerTransparency = 0.33;
|
||||
|
||||
protected abstract string GetSpriteStringSpeciesOnly(int species);
|
||||
|
||||
protected abstract string GetSpriteAll(int species, int form, int gender, uint formarg, bool shiny, int generation);
|
||||
protected abstract string GetItemResourceName(int item);
|
||||
protected abstract Bitmap Unknown { get; }
|
||||
protected abstract Bitmap GetEggSprite(int species);
|
||||
public abstract Bitmap ShadowLugia { get; }
|
||||
|
||||
public void Initialize(SaveFile sav)
|
||||
{
|
||||
public static bool ShowEggSpriteAsItem { get; set; } = true;
|
||||
public static bool ShowEncounterBall { get; set; } = true;
|
||||
public static SpriteBackgroundType ShowEncounterColor { get; set; } = SpriteBackgroundType.FullBackground;
|
||||
public static SpriteBackgroundType ShowEncounterColorPKM { get; set; }
|
||||
public static bool ShowExperiencePercent { get; set; }
|
||||
if (sav.Generation != 3)
|
||||
return;
|
||||
|
||||
public static byte ShowEncounterOpacityStripe { get; set; }
|
||||
public static byte ShowEncounterOpacityBackground { get; set; }
|
||||
public static int ShowEncounterThicknessStripe { get; set; }
|
||||
Game = sav.Version;
|
||||
if (Game == GameVersion.FRLG)
|
||||
Game = sav.Personal == PersonalTable.FR ? GameVersion.FR : GameVersion.LG;
|
||||
}
|
||||
|
||||
/// <summary> Width of the generated Sprite image. </summary>
|
||||
public abstract int Width { get; }
|
||||
/// <summary> Height of the generated Sprite image. </summary>
|
||||
public abstract int Height { get; }
|
||||
private GameVersion Game;
|
||||
|
||||
/// <summary> Minimum amount of padding on the right side of the image when layering an item sprite. </summary>
|
||||
protected abstract int ItemShiftX { get; }
|
||||
/// <summary> Minimum amount of padding on the bottom side of the image when layering an item sprite. </summary>
|
||||
protected abstract int ItemShiftY { get; }
|
||||
/// <summary> Max width / height of an item image. </summary>
|
||||
protected abstract int ItemMaxSize { get; }
|
||||
private static int GetDeoxysForm(GameVersion game) => game switch
|
||||
{
|
||||
GameVersion.FR => 1, // Attack
|
||||
GameVersion.LG => 2, // Defense
|
||||
GameVersion.E => 3, // Speed
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
protected abstract int EggItemShiftX { get; }
|
||||
protected abstract int EggItemShiftY { get; }
|
||||
private static int GetArceusForm4(int form) => form switch
|
||||
{
|
||||
> 9 => form - 1, // Realign to Gen5+ type indexes
|
||||
9 => 999, // Curse, make it show as unrecognized form since we don't have a sprite.
|
||||
_ => form,
|
||||
};
|
||||
|
||||
public abstract Bitmap Hover { get; }
|
||||
public abstract Bitmap View { get; }
|
||||
public abstract Bitmap Set { get; }
|
||||
public abstract Bitmap Delete { get; }
|
||||
public abstract Bitmap Transparent { get; }
|
||||
public abstract Bitmap Drag { get; }
|
||||
public abstract Bitmap UnknownItem { get; }
|
||||
public abstract Bitmap None { get; }
|
||||
public abstract Bitmap ItemTM { get; }
|
||||
public abstract Bitmap ItemTR { get; }
|
||||
public Image GetSprite(int species, int form, int gender, uint formarg, int heldItem, bool isEgg, bool isShiny, int generation = -1, bool isBoxBGRed = false, bool isAltShiny = false)
|
||||
{
|
||||
if (species == 0)
|
||||
return None;
|
||||
|
||||
private const double UnknownFormTransparency = 0.5;
|
||||
private const double ShinyTransparency = 0.7;
|
||||
private const double EggUnderLayerTransparency = 0.33;
|
||||
if (generation == 3 && species == (int)Species.Deoxys) // Depends on Gen3 save file version
|
||||
form = GetDeoxysForm(Game);
|
||||
else if (generation == 4 && species == (int)Species.Arceus) // Curse type's existence in Gen4
|
||||
form = GetArceusForm4(form);
|
||||
|
||||
protected abstract string GetSpriteStringSpeciesOnly(int species);
|
||||
var baseImage = GetBaseImage(species, form, gender, formarg, isShiny, generation);
|
||||
return GetSprite(baseImage, species, heldItem, isEgg, isShiny, generation, isBoxBGRed, isAltShiny);
|
||||
}
|
||||
|
||||
protected abstract string GetSpriteAll(int species, int form, int gender, uint formarg, bool shiny, int generation);
|
||||
protected abstract string GetItemResourceName(int item);
|
||||
protected abstract Bitmap Unknown { get; }
|
||||
protected abstract Bitmap GetEggSprite(int species);
|
||||
public abstract Bitmap ShadowLugia { get; }
|
||||
public Image GetSprite(Image baseSprite, int species, int heldItem, bool isEgg, bool isShiny, int generation = -1, bool isBoxBGRed = false, bool isAltShiny = false)
|
||||
{
|
||||
if (isEgg)
|
||||
baseSprite = LayerOverImageEgg(baseSprite, species, heldItem != 0);
|
||||
if (heldItem > 0)
|
||||
baseSprite = LayerOverImageItem(baseSprite, heldItem, generation);
|
||||
if (isShiny)
|
||||
baseSprite = LayerOverImageShiny(baseSprite, isBoxBGRed, generation >= 8 && isAltShiny);
|
||||
return baseSprite;
|
||||
}
|
||||
|
||||
public void Initialize(SaveFile sav)
|
||||
private Image GetBaseImage(int species, int form, int gender, uint formarg, bool shiny, int generation)
|
||||
{
|
||||
var img = FormInfo.IsTotemForm(species, form, generation)
|
||||
? GetBaseImageTotem(species, form, gender, formarg, shiny, generation)
|
||||
: GetBaseImageDefault(species, form, gender, formarg, shiny, generation);
|
||||
return img ?? GetBaseImageFallback(species, form, gender, formarg, shiny, generation);
|
||||
}
|
||||
|
||||
private Image? GetBaseImageTotem(int species, int form, int gender, uint formarg, bool shiny, int generation)
|
||||
{
|
||||
var baseform = FormInfo.GetTotemBaseForm(species, form);
|
||||
var baseImage = GetBaseImageDefault(species, baseform, gender, formarg, shiny, generation);
|
||||
if (baseImage == null)
|
||||
return null;
|
||||
return ImageUtil.ToGrayscale(baseImage);
|
||||
}
|
||||
|
||||
private Image? GetBaseImageDefault(int species, int form, int gender, uint formarg, bool shiny, int generation)
|
||||
{
|
||||
var file = GetSpriteAll(species, form, gender, formarg, shiny, generation);
|
||||
return (Image?)Resources.ResourceManager.GetObject(file);
|
||||
}
|
||||
|
||||
private Image GetBaseImageFallback(int species, int form, int gender, uint formarg, bool shiny, int generation)
|
||||
{
|
||||
if (shiny) // try again without shiny
|
||||
{
|
||||
if (sav.Generation != 3)
|
||||
return;
|
||||
|
||||
Game = sav.Version;
|
||||
if (Game == GameVersion.FRLG)
|
||||
Game = sav.Personal == PersonalTable.FR ? GameVersion.FR : GameVersion.LG;
|
||||
var img = GetBaseImageDefault(species, form, gender, formarg, false, generation);
|
||||
if (img != null)
|
||||
return img;
|
||||
}
|
||||
|
||||
private GameVersion Game;
|
||||
// try again without form
|
||||
var baseImage = (Image?)Resources.ResourceManager.GetObject(GetSpriteStringSpeciesOnly(species));
|
||||
if (baseImage == null) // failed again
|
||||
return Unknown;
|
||||
return ImageUtil.LayerImage(baseImage, Unknown, 0, 0, UnknownFormTransparency);
|
||||
}
|
||||
|
||||
private static int GetDeoxysForm(GameVersion game) => game switch
|
||||
private Image LayerOverImageItem(Image baseImage, int item, int generation)
|
||||
{
|
||||
Image itemimg = generation switch
|
||||
{
|
||||
GameVersion.FR => 1, // Attack
|
||||
GameVersion.LG => 2, // Defense
|
||||
GameVersion.E => 3, // Speed
|
||||
_ => 0,
|
||||
<= 4 when item is >= 328 and <= 419 => ItemTM, // gen2/3/4 TM
|
||||
8 when item is >= 328 and <= 427 => ItemTM, // BDSP TMs
|
||||
>= 8 when item is >= 1130 and <= 1229 => ItemTR, // Gen8 TR
|
||||
_ => (Image?)Resources.ResourceManager.GetObject(GetItemResourceName(item)) ?? UnknownItem,
|
||||
};
|
||||
|
||||
private static int GetArceusForm4(int form) => form switch
|
||||
{
|
||||
> 9 => form - 1, // Realign to Gen5+ type indexes
|
||||
9 => 999, // Curse, make it show as unrecognized form since we don't have a sprite.
|
||||
_ => form,
|
||||
};
|
||||
// Redraw item in bottom right corner; since images are cropped, try to not have them at the edge
|
||||
int x = baseImage.Width - itemimg.Width - ((ItemMaxSize - itemimg.Width) / 4) - ItemShiftX;
|
||||
int y = baseImage.Height - itemimg.Height - ItemShiftY;
|
||||
return ImageUtil.LayerImage(baseImage, itemimg, x, y);
|
||||
}
|
||||
|
||||
public Image GetSprite(int species, int form, int gender, uint formarg, int heldItem, bool isEgg, bool isShiny, int generation = -1, bool isBoxBGRed = false, bool isAltShiny = false)
|
||||
{
|
||||
if (species == 0)
|
||||
return None;
|
||||
private static Image LayerOverImageShiny(Image baseImage, bool isBoxBGRed, bool altShiny)
|
||||
{
|
||||
// Add shiny star to top left of image.
|
||||
var rare = isBoxBGRed ? Resources.rare_icon_alt : Resources.rare_icon;
|
||||
if (altShiny)
|
||||
rare = Resources.rare_icon_2;
|
||||
return ImageUtil.LayerImage(baseImage, rare, 0, 0, ShinyTransparency);
|
||||
}
|
||||
|
||||
if (generation == 3 && species == (int)Species.Deoxys) // Depends on Gen3 save file version
|
||||
form = GetDeoxysForm(Game);
|
||||
else if (generation == 4 && species == (int)Species.Arceus) // Curse type's existence in Gen4
|
||||
form = GetArceusForm4(form);
|
||||
private Image LayerOverImageEgg(Image baseImage, int species, bool hasItem)
|
||||
{
|
||||
if (ShowEggSpriteAsItem && !hasItem)
|
||||
return LayerOverImageEggAsItem(baseImage, species);
|
||||
return LayerOverImageEggTransparentSpecies(baseImage, species);
|
||||
}
|
||||
|
||||
var baseImage = GetBaseImage(species, form, gender, formarg, isShiny, generation);
|
||||
return GetSprite(baseImage, species, heldItem, isEgg, isShiny, generation, isBoxBGRed, isAltShiny);
|
||||
}
|
||||
private Image LayerOverImageEggTransparentSpecies(Image baseImage, int species)
|
||||
{
|
||||
// Partially transparent species.
|
||||
baseImage = ImageUtil.ChangeOpacity(baseImage, EggUnderLayerTransparency);
|
||||
// Add the egg layer over-top with full opacity.
|
||||
var egg = GetEggSprite(species);
|
||||
return ImageUtil.LayerImage(baseImage, egg, 0, 0);
|
||||
}
|
||||
|
||||
public Image GetSprite(Image baseSprite, int species, int heldItem, bool isEgg, bool isShiny, int generation = -1, bool isBoxBGRed = false, bool isAltShiny = false)
|
||||
{
|
||||
if (isEgg)
|
||||
baseSprite = LayerOverImageEgg(baseSprite, species, heldItem != 0);
|
||||
if (heldItem > 0)
|
||||
baseSprite = LayerOverImageItem(baseSprite, heldItem, generation);
|
||||
if (isShiny)
|
||||
baseSprite = LayerOverImageShiny(baseSprite, isBoxBGRed, generation >= 8 && isAltShiny);
|
||||
return baseSprite;
|
||||
}
|
||||
private Image LayerOverImageEggAsItem(Image baseImage, int species)
|
||||
{
|
||||
var egg = GetEggSprite(species);
|
||||
return ImageUtil.LayerImage(baseImage, egg, EggItemShiftX, EggItemShiftY); // similar to held item, since they can't have any
|
||||
}
|
||||
|
||||
private Image GetBaseImage(int species, int form, int gender, uint formarg, bool shiny, int generation)
|
||||
{
|
||||
var img = FormInfo.IsTotemForm(species, form, generation)
|
||||
? GetBaseImageTotem(species, form, gender, formarg, shiny, generation)
|
||||
: GetBaseImageDefault(species, form, gender, formarg, shiny, generation);
|
||||
return img ?? GetBaseImageFallback(species, form, gender, formarg, shiny, generation);
|
||||
}
|
||||
public static void LoadSettings(ISpriteSettings sprite)
|
||||
{
|
||||
ShowEggSpriteAsItem = sprite.ShowEggSpriteAsHeldItem;
|
||||
ShowEncounterBall = sprite.ShowEncounterBall;
|
||||
|
||||
private Image? GetBaseImageTotem(int species, int form, int gender, uint formarg, bool shiny, int generation)
|
||||
{
|
||||
var baseform = FormInfo.GetTotemBaseForm(species, form);
|
||||
var baseImage = GetBaseImageDefault(species, baseform, gender, formarg, shiny, generation);
|
||||
if (baseImage == null)
|
||||
return null;
|
||||
return ImageUtil.ToGrayscale(baseImage);
|
||||
}
|
||||
|
||||
private Image? GetBaseImageDefault(int species, int form, int gender, uint formarg, bool shiny, int generation)
|
||||
{
|
||||
var file = GetSpriteAll(species, form, gender, formarg, shiny, generation);
|
||||
return (Image?)Resources.ResourceManager.GetObject(file);
|
||||
}
|
||||
|
||||
private Image GetBaseImageFallback(int species, int form, int gender, uint formarg, bool shiny, int generation)
|
||||
{
|
||||
if (shiny) // try again without shiny
|
||||
{
|
||||
var img = GetBaseImageDefault(species, form, gender, formarg, false, generation);
|
||||
if (img != null)
|
||||
return img;
|
||||
}
|
||||
|
||||
// try again without form
|
||||
var baseImage = (Image?)Resources.ResourceManager.GetObject(GetSpriteStringSpeciesOnly(species));
|
||||
if (baseImage == null) // failed again
|
||||
return Unknown;
|
||||
return ImageUtil.LayerImage(baseImage, Unknown, 0, 0, UnknownFormTransparency);
|
||||
}
|
||||
|
||||
private Image LayerOverImageItem(Image baseImage, int item, int generation)
|
||||
{
|
||||
Image itemimg = generation switch
|
||||
{
|
||||
<= 4 when item is >= 328 and <= 419 => ItemTM, // gen2/3/4 TM
|
||||
8 when item is >= 328 and <= 427 => ItemTM, // BDSP TMs
|
||||
>= 8 when item is >= 1130 and <= 1229 => ItemTR, // Gen8 TR
|
||||
_ => (Image?)Resources.ResourceManager.GetObject(GetItemResourceName(item)) ?? UnknownItem,
|
||||
};
|
||||
|
||||
// Redraw item in bottom right corner; since images are cropped, try to not have them at the edge
|
||||
int x = baseImage.Width - itemimg.Width - ((ItemMaxSize - itemimg.Width) / 4) - ItemShiftX;
|
||||
int y = baseImage.Height - itemimg.Height - ItemShiftY;
|
||||
return ImageUtil.LayerImage(baseImage, itemimg, x, y);
|
||||
}
|
||||
|
||||
private static Image LayerOverImageShiny(Image baseImage, bool isBoxBGRed, bool altShiny)
|
||||
{
|
||||
// Add shiny star to top left of image.
|
||||
var rare = isBoxBGRed ? Resources.rare_icon_alt : Resources.rare_icon;
|
||||
if (altShiny)
|
||||
rare = Resources.rare_icon_2;
|
||||
return ImageUtil.LayerImage(baseImage, rare, 0, 0, ShinyTransparency);
|
||||
}
|
||||
|
||||
private Image LayerOverImageEgg(Image baseImage, int species, bool hasItem)
|
||||
{
|
||||
if (ShowEggSpriteAsItem && !hasItem)
|
||||
return LayerOverImageEggAsItem(baseImage, species);
|
||||
return LayerOverImageEggTransparentSpecies(baseImage, species);
|
||||
}
|
||||
|
||||
private Image LayerOverImageEggTransparentSpecies(Image baseImage, int species)
|
||||
{
|
||||
// Partially transparent species.
|
||||
baseImage = ImageUtil.ChangeOpacity(baseImage, EggUnderLayerTransparency);
|
||||
// Add the egg layer over-top with full opacity.
|
||||
var egg = GetEggSprite(species);
|
||||
return ImageUtil.LayerImage(baseImage, egg, 0, 0);
|
||||
}
|
||||
|
||||
private Image LayerOverImageEggAsItem(Image baseImage, int species)
|
||||
{
|
||||
var egg = GetEggSprite(species);
|
||||
return ImageUtil.LayerImage(baseImage, egg, EggItemShiftX, EggItemShiftY); // similar to held item, since they can't have any
|
||||
}
|
||||
|
||||
public static void LoadSettings(ISpriteSettings sprite)
|
||||
{
|
||||
ShowEggSpriteAsItem = sprite.ShowEggSpriteAsHeldItem;
|
||||
ShowEncounterBall = sprite.ShowEncounterBall;
|
||||
|
||||
ShowEncounterColor = sprite.ShowEncounterColor;
|
||||
ShowEncounterColorPKM = sprite.ShowEncounterColorPKM;
|
||||
ShowEncounterThicknessStripe = sprite.ShowEncounterThicknessStripe;
|
||||
ShowEncounterOpacityBackground = sprite.ShowEncounterOpacityBackground;
|
||||
ShowEncounterOpacityStripe = sprite.ShowEncounterOpacityStripe;
|
||||
ShowExperiencePercent = sprite.ShowExperiencePercent;
|
||||
}
|
||||
ShowEncounterColor = sprite.ShowEncounterColor;
|
||||
ShowEncounterColorPKM = sprite.ShowEncounterColorPKM;
|
||||
ShowEncounterThicknessStripe = sprite.ShowEncounterThicknessStripe;
|
||||
ShowEncounterOpacityBackground = sprite.ShowEncounterOpacityBackground;
|
||||
ShowEncounterOpacityStripe = sprite.ShowEncounterOpacityStripe;
|
||||
ShowExperiencePercent = sprite.ShowExperiencePercent;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,38 +2,37 @@
|
|||
using PKHeX.Core;
|
||||
using PKHeX.Drawing.PokeSprite.Properties;
|
||||
|
||||
namespace PKHeX.Drawing.PokeSprite
|
||||
namespace PKHeX.Drawing.PokeSprite;
|
||||
|
||||
/// <summary>
|
||||
/// 56 high, 68 wide sprite builder
|
||||
/// </summary>
|
||||
public sealed class SpriteBuilder5668 : SpriteBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// 56 high, 68 wide sprite builder
|
||||
/// </summary>
|
||||
public sealed class SpriteBuilder5668 : SpriteBuilder
|
||||
{
|
||||
public override int Height => 56;
|
||||
public override int Width => 68;
|
||||
public override int Height => 56;
|
||||
public override int Width => 68;
|
||||
|
||||
protected override int ItemShiftX => 2;
|
||||
protected override int ItemShiftY => 2;
|
||||
protected override int ItemMaxSize => 32;
|
||||
protected override int EggItemShiftX => 18;
|
||||
protected override int EggItemShiftY => 1;
|
||||
protected override int ItemShiftX => 2;
|
||||
protected override int ItemShiftY => 2;
|
||||
protected override int ItemMaxSize => 32;
|
||||
protected override int EggItemShiftX => 18;
|
||||
protected override int EggItemShiftY => 1;
|
||||
|
||||
protected override string GetSpriteStringSpeciesOnly(int species) => 'b' + $"_{species}";
|
||||
protected override string GetSpriteAll(int species, int form, int gender, uint formarg, bool shiny, int generation) => 'b' + SpriteName.GetResourceStringSprite(species, form, gender, formarg, generation, shiny);
|
||||
protected override string GetItemResourceName(int item) => 'b' + $"item_{item}";
|
||||
protected override Bitmap Unknown => Resources.b_unknown;
|
||||
protected override Bitmap GetEggSprite(int species) => species == (int)Species.Manaphy ? Resources.b_490_e : Resources.b_egg;
|
||||
protected override string GetSpriteStringSpeciesOnly(int species) => 'b' + $"_{species}";
|
||||
protected override string GetSpriteAll(int species, int form, int gender, uint formarg, bool shiny, int generation) => 'b' + SpriteName.GetResourceStringSprite(species, form, gender, formarg, generation, shiny);
|
||||
protected override string GetItemResourceName(int item) => 'b' + $"item_{item}";
|
||||
protected override Bitmap Unknown => Resources.b_unknown;
|
||||
protected override Bitmap GetEggSprite(int species) => species == (int)Species.Manaphy ? Resources.b_490_e : Resources.b_egg;
|
||||
|
||||
public override Bitmap Hover => Resources.slotHover68;
|
||||
public override Bitmap View => Resources.slotView68;
|
||||
public override Bitmap Set => Resources.slotSet68;
|
||||
public override Bitmap Delete => Resources.slotDel68;
|
||||
public override Bitmap Transparent => Resources.slotTrans68;
|
||||
public override Bitmap Drag => Resources.slotDrag68;
|
||||
public override Bitmap UnknownItem => Resources.bitem_unk;
|
||||
public override Bitmap None => Resources.b_0;
|
||||
public override Bitmap ItemTM => Resources.bitem_tm;
|
||||
public override Bitmap ItemTR => Resources.bitem_tr;
|
||||
public override Bitmap ShadowLugia => Resources.b_249x;
|
||||
}
|
||||
public override Bitmap Hover => Resources.slotHover68;
|
||||
public override Bitmap View => Resources.slotView68;
|
||||
public override Bitmap Set => Resources.slotSet68;
|
||||
public override Bitmap Delete => Resources.slotDel68;
|
||||
public override Bitmap Transparent => Resources.slotTrans68;
|
||||
public override Bitmap Drag => Resources.slotDrag68;
|
||||
public override Bitmap UnknownItem => Resources.bitem_unk;
|
||||
public override Bitmap None => Resources.b_0;
|
||||
public override Bitmap ItemTM => Resources.bitem_tm;
|
||||
public override Bitmap ItemTR => Resources.bitem_tr;
|
||||
public override Bitmap ShadowLugia => Resources.b_249x;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net46</TargetFrameworks>
|
||||
<LangVersion>9</LangVersion>
|
||||
<LangVersion>10</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,70 +1,54 @@
|
|||
using PKHeX.Core;
|
||||
using static PKHeX.Core.GameVersion;
|
||||
|
||||
namespace PKHeX.Drawing.PokeSprite
|
||||
{
|
||||
internal static class BoxWallpaper
|
||||
{
|
||||
public static bool IsWallpaperRed(GameVersion version, int wallpaperID)
|
||||
{
|
||||
switch (version.GetGeneration())
|
||||
{
|
||||
case 3:
|
||||
if (CXD.Contains(version))
|
||||
return wallpaperID == 7; // flame pattern in XD
|
||||
namespace PKHeX.Drawing.PokeSprite;
|
||||
|
||||
return wallpaperID switch
|
||||
{
|
||||
5 => true, // Volcano
|
||||
13 => E == version, // PokéCenter
|
||||
_ => false,
|
||||
};
|
||||
case 4:
|
||||
return wallpaperID switch
|
||||
{
|
||||
5 => true, // Volcano
|
||||
12 => true, // Checks
|
||||
13 => true, // PokéCenter
|
||||
22 => true, // Special
|
||||
_ => false,
|
||||
};
|
||||
case 5:
|
||||
return wallpaperID switch
|
||||
{
|
||||
5 => true, // Volcano
|
||||
12 => true, // Checks
|
||||
19 => B2W2.Contains(version), // PWT
|
||||
22 => B2W2.Contains(version), // Reshiram
|
||||
21 => BW.Contains(version), // Zoroark
|
||||
23 => BW.Contains(version), // Musical
|
||||
_ => false,
|
||||
};
|
||||
case 6 or 7:
|
||||
return wallpaperID switch
|
||||
{
|
||||
5 => true, // Volcano
|
||||
12 => true, // PokéCenter
|
||||
20 => true, // Special5 Flare/Magma
|
||||
_ => false,
|
||||
};
|
||||
case 8 when BDSP.Contains(version):
|
||||
return wallpaperID switch
|
||||
{
|
||||
6 => true, // Volcano
|
||||
15 => true, // Checks
|
||||
21 => true, // Trio
|
||||
29 => true, // Nostalgic (Platinum)
|
||||
30 => true, // Legend (Platinum)
|
||||
_ => false,
|
||||
};
|
||||
case 8:
|
||||
return wallpaperID switch
|
||||
{
|
||||
_ => true, // Bad contrast with lots of void space, better to just highlight the shiny red.
|
||||
};
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
internal static class BoxWallpaper
|
||||
{
|
||||
public static bool IsWallpaperRed(GameVersion version, int wallpaperID) => version.GetGeneration() switch
|
||||
{
|
||||
3 when CXD.Contains(version) => wallpaperID == 7, // flame pattern in XD
|
||||
3 => wallpaperID switch
|
||||
{
|
||||
5 => true, // Volcano
|
||||
13 => E == version, // PokéCenter
|
||||
_ => false,
|
||||
},
|
||||
4 => wallpaperID switch
|
||||
{
|
||||
5 => true, // Volcano
|
||||
12 => true, // Checks
|
||||
13 => true, // PokéCenter
|
||||
22 => true, // Special
|
||||
_ => false,
|
||||
},
|
||||
5 => wallpaperID switch
|
||||
{
|
||||
5 => true, // Volcano
|
||||
12 => true, // Checks
|
||||
19 => B2W2.Contains(version), // PWT
|
||||
22 => B2W2.Contains(version), // Reshiram
|
||||
21 => BW.Contains(version), // Zoroark
|
||||
23 => BW.Contains(version), // Musical
|
||||
_ => false,
|
||||
},
|
||||
6 or 7 => wallpaperID switch
|
||||
{
|
||||
5 => true, // Volcano
|
||||
12 => true, // PokéCenter
|
||||
20 => true, // Special5 Flare/Magma
|
||||
_ => false,
|
||||
},
|
||||
8 when BDSP.Contains(version) => wallpaperID switch
|
||||
{
|
||||
6 => true, // Volcano
|
||||
15 => true, // Checks
|
||||
21 => true, // Trio
|
||||
29 => true, // Nostalgic (Platinum)
|
||||
30 => true, // Legend (Platinum)
|
||||
_ => false,
|
||||
},
|
||||
8 => true, // Bad contrast with lots of void space, better to just highlight the shiny red.
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,99 +2,98 @@
|
|||
using System.Text;
|
||||
using PKHeX.Core;
|
||||
|
||||
namespace PKHeX.Drawing.PokeSprite
|
||||
namespace PKHeX.Drawing.PokeSprite;
|
||||
|
||||
public static class SpriteName
|
||||
{
|
||||
public static class SpriteName
|
||||
public static bool AllowShinySprite { get; set; }
|
||||
|
||||
private const char Separator = '_';
|
||||
private const char Cosplay = 'c';
|
||||
private const char Shiny = 's';
|
||||
private const char GGStarter = 'p';
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resource name of the <see cref="Ball"/> sprite.
|
||||
/// </summary>
|
||||
public static string GetResourceStringBall(int ball) => $"_ball{ball}";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resource name of the Pokémon sprite.
|
||||
/// </summary>
|
||||
public static string GetResourceStringSprite(int species, int form, int gender, uint formarg, int generation = PKX.Generation, bool shiny = false)
|
||||
{
|
||||
public static bool AllowShinySprite { get; set; }
|
||||
if (SpeciesDefaultFormSprite.Contains(species)) // Species who show their default sprite regardless of Form
|
||||
form = 0;
|
||||
|
||||
private const char Separator = '_';
|
||||
private const char Cosplay = 'c';
|
||||
private const char Shiny = 's';
|
||||
private const char GGStarter = 'p';
|
||||
var sb = new StringBuilder(12); // longest expected string result
|
||||
sb.Append(Separator).Append(species);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resource name of the <see cref="Ball"/> sprite.
|
||||
/// </summary>
|
||||
public static string GetResourceStringBall(int ball) => $"_ball{ball}";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resource name of the Pokémon sprite.
|
||||
/// </summary>
|
||||
public static string GetResourceStringSprite(int species, int form, int gender, uint formarg, int generation = PKX.Generation, bool shiny = false)
|
||||
if (form != 0)
|
||||
{
|
||||
if (SpeciesDefaultFormSprite.Contains(species)) // Species who show their default sprite regardless of Form
|
||||
form = 0;
|
||||
sb.Append(Separator).Append(form);
|
||||
|
||||
var sb = new StringBuilder(12); // longest expected string result
|
||||
sb.Append(Separator).Append(species);
|
||||
|
||||
if (form != 0)
|
||||
if (species == (int) Species.Pikachu)
|
||||
{
|
||||
sb.Append(Separator).Append(form);
|
||||
|
||||
if (species == (int) Species.Pikachu)
|
||||
if (generation == 6)
|
||||
{
|
||||
if (generation == 6)
|
||||
{
|
||||
sb.Append(Cosplay);
|
||||
gender = 1; // Cosplay Pikachu gift can only be Female, but personal entries are set to be either Gender
|
||||
}
|
||||
else if (form == 8)
|
||||
{
|
||||
sb.Append(GGStarter);
|
||||
}
|
||||
sb.Append(Cosplay);
|
||||
gender = 1; // Cosplay Pikachu gift can only be Female, but personal entries are set to be either Gender
|
||||
}
|
||||
else if (species == (int) Species.Eevee)
|
||||
else if (form == 8)
|
||||
{
|
||||
if (form == 1)
|
||||
sb.Append(GGStarter);
|
||||
sb.Append(GGStarter);
|
||||
}
|
||||
}
|
||||
if (gender == 1 && SpeciesGenderedSprite.Contains(species))
|
||||
else if (species == (int) Species.Eevee)
|
||||
{
|
||||
sb.Append('f');
|
||||
if (form == 1)
|
||||
sb.Append(GGStarter);
|
||||
}
|
||||
|
||||
if (species == (int) Species.Alcremie)
|
||||
{
|
||||
if (form == 0)
|
||||
sb.Append(Separator).Append(form);
|
||||
sb.Append(Separator).Append(formarg);
|
||||
}
|
||||
|
||||
if (shiny && AllowShinySprite)
|
||||
sb.Append(Shiny);
|
||||
return sb.ToString();
|
||||
}
|
||||
if (gender == 1 && SpeciesGenderedSprite.Contains(species))
|
||||
{
|
||||
sb.Append('f');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Species that show their default Species sprite regardless of current <see cref="PKM.Form"/>
|
||||
/// </summary>
|
||||
private static readonly HashSet<int> SpeciesDefaultFormSprite = new()
|
||||
if (species == (int) Species.Alcremie)
|
||||
{
|
||||
(int)Species.Mothim,
|
||||
(int)Species.Scatterbug,
|
||||
(int)Species.Spewpa,
|
||||
(int)Species.Rockruff,
|
||||
(int)Species.Mimikyu,
|
||||
(int)Species.Sinistea,
|
||||
(int)Species.Polteageist,
|
||||
(int)Species.Urshifu,
|
||||
};
|
||||
if (form == 0)
|
||||
sb.Append(Separator).Append(form);
|
||||
sb.Append(Separator).Append(formarg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Species that show a <see cref="PKM.Gender"/> specific Sprite
|
||||
/// </summary>
|
||||
private static readonly HashSet<int> SpeciesGenderedSprite = new()
|
||||
{
|
||||
(int)Species.Pikachu,
|
||||
(int)Species.Hippopotas,
|
||||
(int)Species.Hippowdon,
|
||||
(int)Species.Unfezant,
|
||||
(int)Species.Frillish,
|
||||
(int)Species.Jellicent,
|
||||
(int)Species.Pyroar,
|
||||
};
|
||||
if (shiny && AllowShinySprite)
|
||||
sb.Append(Shiny);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Species that show their default Species sprite regardless of current <see cref="PKM.Form"/>
|
||||
/// </summary>
|
||||
private static readonly HashSet<int> SpeciesDefaultFormSprite = new()
|
||||
{
|
||||
(int)Species.Mothim,
|
||||
(int)Species.Scatterbug,
|
||||
(int)Species.Spewpa,
|
||||
(int)Species.Rockruff,
|
||||
(int)Species.Mimikyu,
|
||||
(int)Species.Sinistea,
|
||||
(int)Species.Polteageist,
|
||||
(int)Species.Urshifu,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Species that show a <see cref="PKM.Gender"/> specific Sprite
|
||||
/// </summary>
|
||||
private static readonly HashSet<int> SpeciesGenderedSprite = new()
|
||||
{
|
||||
(int)Species.Pikachu,
|
||||
(int)Species.Hippopotas,
|
||||
(int)Species.Hippowdon,
|
||||
(int)Species.Unfezant,
|
||||
(int)Species.Frillish,
|
||||
(int)Species.Jellicent,
|
||||
(int)Species.Pyroar,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -4,223 +4,222 @@ using System.Linq;
|
|||
using PKHeX.Core;
|
||||
using PKHeX.Drawing.PokeSprite.Properties;
|
||||
|
||||
namespace PKHeX.Drawing.PokeSprite
|
||||
namespace PKHeX.Drawing.PokeSprite;
|
||||
|
||||
public static class SpriteUtil
|
||||
{
|
||||
public static class SpriteUtil
|
||||
public static readonly SpriteBuilder5668 SB8 = new();
|
||||
public static SpriteBuilder Spriter { get; set; } = SB8;
|
||||
|
||||
private const int MaxSlotCount = 30; // slots in a box
|
||||
private static int SpriteWidth => Spriter.Width;
|
||||
private static int SpriteHeight => Spriter.Height;
|
||||
private static int PartyMarkShiftX => SpriteWidth - 16;
|
||||
private static int SlotLockShiftX => SpriteWidth - 14;
|
||||
private static int SlotTeamShiftX => SpriteWidth - 19;
|
||||
private static int FlagIllegalShiftY => SpriteHeight - 16;
|
||||
|
||||
public static void Initialize(SaveFile sav) => Spriter.Initialize(sav);
|
||||
|
||||
public static Image GetBallSprite(int ball)
|
||||
{
|
||||
public static readonly SpriteBuilder5668 SB8 = new();
|
||||
public static SpriteBuilder Spriter { get; set; } = SB8;
|
||||
string resource = SpriteName.GetResourceStringBall(ball);
|
||||
return (Bitmap?)Resources.ResourceManager.GetObject(resource) ?? Resources._ball4; // Poké Ball (default)
|
||||
}
|
||||
|
||||
private const int MaxSlotCount = 30; // slots in a box
|
||||
private static int SpriteWidth => Spriter.Width;
|
||||
private static int SpriteHeight => Spriter.Height;
|
||||
private static int PartyMarkShiftX => SpriteWidth - 16;
|
||||
private static int SlotLockShiftX => SpriteWidth - 14;
|
||||
private static int SlotTeamShiftX => SpriteWidth - 19;
|
||||
private static int FlagIllegalShiftY => SpriteHeight - 16;
|
||||
public static Image? GetItemSprite(int item) => Resources.ResourceManager.GetObject($"item_{item}") as Image;
|
||||
|
||||
public static void Initialize(SaveFile sav) => Spriter.Initialize(sav);
|
||||
public static Image GetSprite(int species, int form, int gender, uint formarg, int item, bool isegg, bool isShiny, int generation = -1, bool isBoxBGRed = false, bool isAltShiny = false)
|
||||
{
|
||||
return Spriter.GetSprite(species, form, gender, formarg, item, isegg, isShiny, generation, isBoxBGRed, isAltShiny);
|
||||
}
|
||||
|
||||
public static Image GetBallSprite(int ball)
|
||||
private static Image GetSprite(PKM pk, bool isBoxBGRed = false)
|
||||
{
|
||||
var formarg = pk is IFormArgument f ? f.FormArgument : 0;
|
||||
bool alt = pk.Format >= 8 && (pk.ShinyXor == 0 || pk.FatefulEncounter || pk.Version == (int)GameVersion.GO);
|
||||
var img = GetSprite(pk.Species, pk.Form, pk.Gender, formarg, pk.SpriteItem, pk.IsEgg, pk.IsShiny, pk.Format, isBoxBGRed, alt);
|
||||
if (pk is IShadowPKM {IsShadow: true})
|
||||
{
|
||||
string resource = SpriteName.GetResourceStringBall(ball);
|
||||
return (Bitmap?)Resources.ResourceManager.GetObject(resource) ?? Resources._ball4; // Poké Ball (default)
|
||||
const int Lugia = (int)Species.Lugia;
|
||||
if (pk.Species == Lugia) // show XD shadow sprite
|
||||
img = Spriter.GetSprite(Spriter.ShadowLugia, Lugia, pk.HeldItem, pk.IsEgg, pk.IsShiny, pk.Format, isBoxBGRed);
|
||||
|
||||
GetSpriteGlow(pk, 75, 0, 130, out var pixels, out var baseSprite, true);
|
||||
var glowImg = ImageUtil.GetBitmap(pixels, baseSprite.Width, baseSprite.Height, baseSprite.PixelFormat);
|
||||
return ImageUtil.LayerImage(glowImg, img, 0, 0);
|
||||
}
|
||||
if (pk is IGigantamax {CanGigantamax: true})
|
||||
{
|
||||
var gm = Resources.dyna;
|
||||
return ImageUtil.LayerImage(img, gm, (img.Width - gm.Width) / 2, 0);
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
private static Image GetSprite(PKM pk, SaveFile sav, int box, int slot, bool flagIllegal = false)
|
||||
{
|
||||
if (!pk.Valid)
|
||||
return Spriter.None;
|
||||
|
||||
bool inBox = (uint)slot < MaxSlotCount;
|
||||
bool empty = pk.Species == 0;
|
||||
var sprite = empty ? Spriter.None : pk.Sprite(isBoxBGRed: inBox && BoxWallpaper.IsWallpaperRed(sav.Version, sav.GetBoxWallpaper(box)));
|
||||
|
||||
if (!empty && flagIllegal)
|
||||
{
|
||||
var la = new LegalityAnalysis(pk, sav.Personal, box != -1 ? SlotOrigin.Box : SlotOrigin.Party);
|
||||
if (!la.Valid)
|
||||
sprite = ImageUtil.LayerImage(sprite, Resources.warn, 0, FlagIllegalShiftY);
|
||||
else if (pk.Format >= 8 && pk.Moves.Any(Legal.GetDummiedMovesHashSet(pk).Contains))
|
||||
sprite = ImageUtil.LayerImage(sprite, Resources.hint, 0, FlagIllegalShiftY);
|
||||
|
||||
if (SpriteBuilder.ShowEncounterColorPKM != SpriteBackgroundType.None)
|
||||
sprite = ApplyEncounterColor(la.EncounterOriginal, sprite, SpriteBuilder.ShowEncounterColorPKM);
|
||||
}
|
||||
if (inBox) // in box
|
||||
{
|
||||
var flags = sav.GetSlotFlags(box, slot);
|
||||
|
||||
// Indicate any battle box teams & according locked state.
|
||||
int team = flags.IsBattleTeam();
|
||||
if (team >= 0)
|
||||
sprite = ImageUtil.LayerImage(sprite, Resources.team, SlotTeamShiftX, 0);
|
||||
if (flags.HasFlagFast(StorageSlotFlag.Locked))
|
||||
sprite = ImageUtil.LayerImage(sprite, Resources.locked, SlotLockShiftX, 0);
|
||||
|
||||
// Some games store Party directly in the list of pokemon data (LGP/E). Indicate accordingly.
|
||||
int party = flags.IsParty();
|
||||
if (party >= 0)
|
||||
sprite = ImageUtil.LayerImage(sprite, PartyMarks[party], PartyMarkShiftX, 0);
|
||||
if (flags.HasFlagFast(StorageSlotFlag.Starter))
|
||||
sprite = ImageUtil.LayerImage(sprite, Resources.starter, 0, 0);
|
||||
}
|
||||
|
||||
public static Image? GetItemSprite(int item) => Resources.ResourceManager.GetObject($"item_{item}") as Image;
|
||||
if (SpriteBuilder.ShowExperiencePercent)
|
||||
sprite = ApplyExperience(pk, sprite);
|
||||
|
||||
public static Image GetSprite(int species, int form, int gender, uint formarg, int item, bool isegg, bool isShiny, int generation = -1, bool isBoxBGRed = false, bool isAltShiny = false)
|
||||
return sprite;
|
||||
}
|
||||
|
||||
public static Image ApplyEncounterColor(IEncounterTemplate enc, Image img, SpriteBackgroundType type)
|
||||
{
|
||||
var index = (enc.GetType().Name.GetHashCode() * 0x43FD43FD);
|
||||
var color = Color.FromArgb(index);
|
||||
if (type == SpriteBackgroundType.BottomStripe)
|
||||
{
|
||||
return Spriter.GetSprite(species, form, gender, formarg, item, isegg, isShiny, generation, isBoxBGRed, isAltShiny);
|
||||
int stripeHeight = SpriteBuilder.ShowEncounterThicknessStripe; // from bottom
|
||||
byte opacity = SpriteBuilder.ShowEncounterOpacityStripe;
|
||||
return ImageUtil.ChangeTransparentTo(img, color, opacity, img.Width * 4 * (img.Height - stripeHeight));
|
||||
}
|
||||
|
||||
private static Image GetSprite(PKM pk, bool isBoxBGRed = false)
|
||||
else // full background
|
||||
{
|
||||
var formarg = pk is IFormArgument f ? f.FormArgument : 0;
|
||||
bool alt = pk.Format >= 8 && (pk.ShinyXor == 0 || pk.FatefulEncounter || pk.Version == (int)GameVersion.GO);
|
||||
var img = GetSprite(pk.Species, pk.Form, pk.Gender, formarg, pk.SpriteItem, pk.IsEgg, pk.IsShiny, pk.Format, isBoxBGRed, alt);
|
||||
if (pk is IShadowPKM {IsShadow: true})
|
||||
{
|
||||
const int Lugia = (int)Species.Lugia;
|
||||
if (pk.Species == Lugia) // show XD shadow sprite
|
||||
img = Spriter.GetSprite(Spriter.ShadowLugia, Lugia, pk.HeldItem, pk.IsEgg, pk.IsShiny, pk.Format, isBoxBGRed);
|
||||
|
||||
GetSpriteGlow(pk, 75, 0, 130, out var pixels, out var baseSprite, true);
|
||||
var glowImg = ImageUtil.GetBitmap(pixels, baseSprite.Width, baseSprite.Height, baseSprite.PixelFormat);
|
||||
return ImageUtil.LayerImage(glowImg, img, 0, 0);
|
||||
}
|
||||
if (pk is IGigantamax {CanGigantamax: true})
|
||||
{
|
||||
var gm = Resources.dyna;
|
||||
return ImageUtil.LayerImage(img, gm, (img.Width - gm.Width) / 2, 0);
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
private static Image GetSprite(PKM pk, SaveFile sav, int box, int slot, bool flagIllegal = false)
|
||||
{
|
||||
if (!pk.Valid)
|
||||
return Spriter.None;
|
||||
|
||||
bool inBox = (uint)slot < MaxSlotCount;
|
||||
bool empty = pk.Species == 0;
|
||||
var sprite = empty ? Spriter.None : pk.Sprite(isBoxBGRed: inBox && BoxWallpaper.IsWallpaperRed(sav.Version, sav.GetBoxWallpaper(box)));
|
||||
|
||||
if (!empty && flagIllegal)
|
||||
{
|
||||
var la = new LegalityAnalysis(pk, sav.Personal, box != -1 ? SlotOrigin.Box : SlotOrigin.Party);
|
||||
if (!la.Valid)
|
||||
sprite = ImageUtil.LayerImage(sprite, Resources.warn, 0, FlagIllegalShiftY);
|
||||
else if (pk.Format >= 8 && pk.Moves.Any(Legal.GetDummiedMovesHashSet(pk).Contains))
|
||||
sprite = ImageUtil.LayerImage(sprite, Resources.hint, 0, FlagIllegalShiftY);
|
||||
|
||||
if (SpriteBuilder.ShowEncounterColorPKM != SpriteBackgroundType.None)
|
||||
sprite = ApplyEncounterColor(la.EncounterOriginal, sprite, SpriteBuilder.ShowEncounterColorPKM);
|
||||
}
|
||||
if (inBox) // in box
|
||||
{
|
||||
var flags = sav.GetSlotFlags(box, slot);
|
||||
|
||||
// Indicate any battle box teams & according locked state.
|
||||
int team = flags.IsBattleTeam();
|
||||
if (team >= 0)
|
||||
sprite = ImageUtil.LayerImage(sprite, Resources.team, SlotTeamShiftX, 0);
|
||||
if (flags.HasFlagFast(StorageSlotFlag.Locked))
|
||||
sprite = ImageUtil.LayerImage(sprite, Resources.locked, SlotLockShiftX, 0);
|
||||
|
||||
// Some games store Party directly in the list of pokemon data (LGP/E). Indicate accordingly.
|
||||
int party = flags.IsParty();
|
||||
if (party >= 0)
|
||||
sprite = ImageUtil.LayerImage(sprite, PartyMarks[party], PartyMarkShiftX, 0);
|
||||
if (flags.HasFlagFast(StorageSlotFlag.Starter))
|
||||
sprite = ImageUtil.LayerImage(sprite, Resources.starter, 0, 0);
|
||||
}
|
||||
|
||||
if (SpriteBuilder.ShowExperiencePercent)
|
||||
sprite = ApplyExperience(pk, sprite);
|
||||
|
||||
return sprite;
|
||||
}
|
||||
|
||||
public static Image ApplyEncounterColor(IEncounterTemplate enc, Image img, SpriteBackgroundType type)
|
||||
{
|
||||
var index = (enc.GetType().Name.GetHashCode() * 0x43FD43FD);
|
||||
var color = Color.FromArgb(index);
|
||||
if (type == SpriteBackgroundType.BottomStripe)
|
||||
{
|
||||
int stripeHeight = SpriteBuilder.ShowEncounterThicknessStripe; // from bottom
|
||||
byte opacity = SpriteBuilder.ShowEncounterOpacityStripe;
|
||||
return ImageUtil.ChangeTransparentTo(img, color, opacity, img.Width * 4 * (img.Height - stripeHeight));
|
||||
}
|
||||
else // full background
|
||||
{
|
||||
byte opacity = SpriteBuilder.ShowEncounterOpacityBackground;
|
||||
return ImageUtil.ChangeTransparentTo(img, color, opacity);
|
||||
}
|
||||
}
|
||||
|
||||
private static Image ApplyExperience(PKM pk, Image img)
|
||||
{
|
||||
const int bpp = 4;
|
||||
int start = bpp * SpriteWidth * (SpriteHeight - 1);
|
||||
var level = pk.CurrentLevel;
|
||||
if (level == 100)
|
||||
return ImageUtil.WritePixels(img, Color.Lime, start, start + (SpriteWidth * bpp));
|
||||
|
||||
var pct = Experience.GetEXPToLevelUpPercentage(level, pk.EXP, pk.PersonalInfo.EXPGrowth);
|
||||
if (pct is 0)
|
||||
return ImageUtil.WritePixels(img, Color.Yellow, start, start + (SpriteWidth * bpp));
|
||||
return ImageUtil.WritePixels(img, Color.DodgerBlue, start, start + (int)(SpriteWidth * pct * bpp));
|
||||
}
|
||||
|
||||
private static readonly Bitmap[] PartyMarks =
|
||||
{
|
||||
Resources.party1, Resources.party2, Resources.party3, Resources.party4, Resources.party5, Resources.party6,
|
||||
};
|
||||
|
||||
public static void GetSpriteGlow(PKM pk, byte blue, byte green, byte red, out byte[] pixels, out Image baseSprite, bool forceHollow = false)
|
||||
{
|
||||
bool egg = pk.IsEgg;
|
||||
var formarg = pk is IFormArgument f ? f.FormArgument : 0;
|
||||
baseSprite = GetSprite(pk.Species, pk.Form, pk.Gender, formarg, 0, egg, false, pk.Format);
|
||||
GetSpriteGlow(baseSprite, blue, green, red, out pixels, forceHollow || egg);
|
||||
}
|
||||
|
||||
public static void GetSpriteGlow(Image baseSprite, byte blue, byte green, byte red, out byte[] pixels, bool forceHollow = false)
|
||||
{
|
||||
pixels = ImageUtil.GetPixelData((Bitmap)baseSprite);
|
||||
if (!forceHollow)
|
||||
{
|
||||
ImageUtil.GlowEdges(pixels, blue, green, red, baseSprite.Width);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the image has any transparency, any derived background will bleed into it.
|
||||
// Need to undo any transparency values if any present.
|
||||
// Remove opaque pixels from original image, leaving only the glow effect pixels.
|
||||
var original = (byte[])pixels.Clone();
|
||||
ImageUtil.SetAllUsedPixelsOpaque(pixels);
|
||||
ImageUtil.GlowEdges(pixels, blue, green, red, baseSprite.Width);
|
||||
ImageUtil.RemovePixels(pixels, original);
|
||||
}
|
||||
|
||||
public static Image GetLegalIndicator(bool valid) => valid ? Resources.valid : Resources.warn;
|
||||
|
||||
// Extension Methods
|
||||
public static Image Sprite(this PKM pk, bool isBoxBGRed = false) => GetSprite(pk, isBoxBGRed);
|
||||
|
||||
public static Image Sprite(this IEncounterTemplate enc)
|
||||
{
|
||||
if (enc is MysteryGift g)
|
||||
return GetMysteryGiftPreviewPoke(g);
|
||||
var gender = GetDisplayGender(enc);
|
||||
var img = GetSprite(enc.Species, enc.Form, gender, 0, 0, enc.EggEncounter, enc.IsShiny, enc.Generation);
|
||||
if (SpriteBuilder.ShowEncounterBall && enc is IFixedBall {FixedBall: not Ball.None} b)
|
||||
{
|
||||
var ballSprite = GetBallSprite((int)b.FixedBall);
|
||||
img = ImageUtil.LayerImage(img, ballSprite, 0, img.Height - ballSprite.Height);
|
||||
}
|
||||
if (enc is IGigantamax {CanGigantamax: true})
|
||||
{
|
||||
var gm = Resources.dyna;
|
||||
img = ImageUtil.LayerImage(img, gm, (img.Width - gm.Width) / 2, 0);
|
||||
}
|
||||
if (SpriteBuilder.ShowEncounterColor != SpriteBackgroundType.None)
|
||||
img = ApplyEncounterColor(enc, img, SpriteBuilder.ShowEncounterColor);
|
||||
return img;
|
||||
}
|
||||
|
||||
public static int GetDisplayGender(IEncounterTemplate enc) => enc switch
|
||||
{
|
||||
EncounterSlotGO g => (int)g.Gender & 1,
|
||||
EncounterStatic s => Math.Max(0, s.Gender),
|
||||
EncounterTrade t => Math.Max(0, t.Gender),
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
public static Image Sprite(this PKM pk, SaveFile sav, int box, int slot, bool flagIllegal = false)
|
||||
=> GetSprite(pk, sav, box, slot, flagIllegal);
|
||||
|
||||
public static Image GetMysteryGiftPreviewPoke(MysteryGift gift)
|
||||
{
|
||||
if (gift.IsEgg && gift.Species == (int)Species.Manaphy) // Manaphy Egg
|
||||
return GetSprite((int)Species.Manaphy, 0, 2, 0, 0, true, false, gift.Generation);
|
||||
|
||||
var gender = Math.Max(0, gift.Gender);
|
||||
var img = GetSprite(gift.Species, gift.Form, gender, 0, gift.HeldItem, gift.IsEgg, gift.IsShiny, gift.Generation);
|
||||
|
||||
if (SpriteBuilder.ShowEncounterBall && gift is IFixedBall { FixedBall: not Ball.None } b)
|
||||
{
|
||||
var ballSprite = GetBallSprite((int)b.FixedBall);
|
||||
img = ImageUtil.LayerImage(img, ballSprite, 0, img.Height - ballSprite.Height);
|
||||
}
|
||||
|
||||
if (gift is IGigantamax { CanGigantamax: true })
|
||||
{
|
||||
var gm = Resources.dyna;
|
||||
img = ImageUtil.LayerImage(img, gm, (img.Width - gm.Width) / 2, 0);
|
||||
}
|
||||
return img;
|
||||
byte opacity = SpriteBuilder.ShowEncounterOpacityBackground;
|
||||
return ImageUtil.ChangeTransparentTo(img, color, opacity);
|
||||
}
|
||||
}
|
||||
|
||||
private static Image ApplyExperience(PKM pk, Image img)
|
||||
{
|
||||
const int bpp = 4;
|
||||
int start = bpp * SpriteWidth * (SpriteHeight - 1);
|
||||
var level = pk.CurrentLevel;
|
||||
if (level == 100)
|
||||
return ImageUtil.WritePixels(img, Color.Lime, start, start + (SpriteWidth * bpp));
|
||||
|
||||
var pct = Experience.GetEXPToLevelUpPercentage(level, pk.EXP, pk.PersonalInfo.EXPGrowth);
|
||||
if (pct is 0)
|
||||
return ImageUtil.WritePixels(img, Color.Yellow, start, start + (SpriteWidth * bpp));
|
||||
return ImageUtil.WritePixels(img, Color.DodgerBlue, start, start + (int)(SpriteWidth * pct * bpp));
|
||||
}
|
||||
|
||||
private static readonly Bitmap[] PartyMarks =
|
||||
{
|
||||
Resources.party1, Resources.party2, Resources.party3, Resources.party4, Resources.party5, Resources.party6,
|
||||
};
|
||||
|
||||
public static void GetSpriteGlow(PKM pk, byte blue, byte green, byte red, out byte[] pixels, out Image baseSprite, bool forceHollow = false)
|
||||
{
|
||||
bool egg = pk.IsEgg;
|
||||
var formarg = pk is IFormArgument f ? f.FormArgument : 0;
|
||||
baseSprite = GetSprite(pk.Species, pk.Form, pk.Gender, formarg, 0, egg, false, pk.Format);
|
||||
GetSpriteGlow(baseSprite, blue, green, red, out pixels, forceHollow || egg);
|
||||
}
|
||||
|
||||
public static void GetSpriteGlow(Image baseSprite, byte blue, byte green, byte red, out byte[] pixels, bool forceHollow = false)
|
||||
{
|
||||
pixels = ImageUtil.GetPixelData((Bitmap)baseSprite);
|
||||
if (!forceHollow)
|
||||
{
|
||||
ImageUtil.GlowEdges(pixels, blue, green, red, baseSprite.Width);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the image has any transparency, any derived background will bleed into it.
|
||||
// Need to undo any transparency values if any present.
|
||||
// Remove opaque pixels from original image, leaving only the glow effect pixels.
|
||||
var original = (byte[])pixels.Clone();
|
||||
ImageUtil.SetAllUsedPixelsOpaque(pixels);
|
||||
ImageUtil.GlowEdges(pixels, blue, green, red, baseSprite.Width);
|
||||
ImageUtil.RemovePixels(pixels, original);
|
||||
}
|
||||
|
||||
public static Image GetLegalIndicator(bool valid) => valid ? Resources.valid : Resources.warn;
|
||||
|
||||
// Extension Methods
|
||||
public static Image Sprite(this PKM pk, bool isBoxBGRed = false) => GetSprite(pk, isBoxBGRed);
|
||||
|
||||
public static Image Sprite(this IEncounterTemplate enc)
|
||||
{
|
||||
if (enc is MysteryGift g)
|
||||
return GetMysteryGiftPreviewPoke(g);
|
||||
var gender = GetDisplayGender(enc);
|
||||
var img = GetSprite(enc.Species, enc.Form, gender, 0, 0, enc.EggEncounter, enc.IsShiny, enc.Generation);
|
||||
if (SpriteBuilder.ShowEncounterBall && enc is IFixedBall {FixedBall: not Ball.None} b)
|
||||
{
|
||||
var ballSprite = GetBallSprite((int)b.FixedBall);
|
||||
img = ImageUtil.LayerImage(img, ballSprite, 0, img.Height - ballSprite.Height);
|
||||
}
|
||||
if (enc is IGigantamax {CanGigantamax: true})
|
||||
{
|
||||
var gm = Resources.dyna;
|
||||
img = ImageUtil.LayerImage(img, gm, (img.Width - gm.Width) / 2, 0);
|
||||
}
|
||||
if (SpriteBuilder.ShowEncounterColor != SpriteBackgroundType.None)
|
||||
img = ApplyEncounterColor(enc, img, SpriteBuilder.ShowEncounterColor);
|
||||
return img;
|
||||
}
|
||||
|
||||
public static int GetDisplayGender(IEncounterTemplate enc) => enc switch
|
||||
{
|
||||
EncounterSlotGO g => (int)g.Gender & 1,
|
||||
EncounterStatic s => Math.Max(0, s.Gender),
|
||||
EncounterTrade t => Math.Max(0, t.Gender),
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
public static Image Sprite(this PKM pk, SaveFile sav, int box, int slot, bool flagIllegal = false)
|
||||
=> GetSprite(pk, sav, box, slot, flagIllegal);
|
||||
|
||||
public static Image GetMysteryGiftPreviewPoke(MysteryGift gift)
|
||||
{
|
||||
if (gift.IsEgg && gift.Species == (int)Species.Manaphy) // Manaphy Egg
|
||||
return GetSprite((int)Species.Manaphy, 0, 2, 0, 0, true, false, gift.Generation);
|
||||
|
||||
var gender = Math.Max(0, gift.Gender);
|
||||
var img = GetSprite(gift.Species, gift.Form, gender, 0, gift.HeldItem, gift.IsEgg, gift.IsShiny, gift.Generation);
|
||||
|
||||
if (SpriteBuilder.ShowEncounterBall && gift is IFixedBall { FixedBall: not Ball.None } b)
|
||||
{
|
||||
var ballSprite = GetBallSprite((int)b.FixedBall);
|
||||
img = ImageUtil.LayerImage(img, ballSprite, 0, img.Height - ballSprite.Height);
|
||||
}
|
||||
|
||||
if (gift is IGigantamax { CanGigantamax: true })
|
||||
{
|
||||
var gm = Resources.dyna;
|
||||
img = ImageUtil.LayerImage(img, gm, (img.Width - gm.Width) / 2, 0);
|
||||
}
|
||||
return img;
|
||||
}
|
||||
}
|
||||
|
|
29
PKHeX.Drawing/ColorUtil.cs
Normal file
29
PKHeX.Drawing/ColorUtil.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace PKHeX.Drawing;
|
||||
|
||||
public static class ColorUtil
|
||||
{
|
||||
public static Color ColorBaseStat(int v)
|
||||
{
|
||||
const float maxval = 180; // shift the green cap down
|
||||
float x = 100f * v / maxval;
|
||||
if (x > 100)
|
||||
x = 100;
|
||||
double red = 255f * (x > 50 ? 1 - (2 * (x - 50) / 100.0) : 1.0);
|
||||
double green = 255f * (x > 50 ? 1.0 : 2 * x / 100.0);
|
||||
|
||||
return Blend(Color.FromArgb((int)red, (int)green, 0), Color.White, 0.4);
|
||||
}
|
||||
|
||||
public static Color ColorBaseStatTotal(int tot) => ColorBaseStat((int) (Math.Max(0, tot - 175) / 3f));
|
||||
|
||||
public static Color Blend(Color color, Color backColor, double amount)
|
||||
{
|
||||
byte r = (byte)((color.R * amount) + (backColor.R * (1 - amount)));
|
||||
byte g = (byte)((color.G * amount) + (backColor.G * (1 - amount)));
|
||||
byte b = (byte)((color.B * amount) + (backColor.B * (1 - amount)));
|
||||
return Color.FromArgb(r, g, b);
|
||||
}
|
||||
}
|
|
@ -3,285 +3,262 @@ using System.Drawing;
|
|||
using System.Drawing.Imaging;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace PKHeX.Drawing
|
||||
namespace PKHeX.Drawing;
|
||||
|
||||
/// <summary>
|
||||
/// Image Layering/Blending Utility
|
||||
/// </summary>
|
||||
public static class ImageUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// Image Layering/Blending Utility
|
||||
/// </summary>
|
||||
public static class ImageUtil
|
||||
public static Bitmap LayerImage(Image baseLayer, Image overLayer, int x, int y, double transparency)
|
||||
{
|
||||
public static Bitmap LayerImage(Image baseLayer, Image overLayer, int x, int y, double transparency)
|
||||
overLayer = ChangeOpacity(overLayer, transparency);
|
||||
return LayerImage(baseLayer, overLayer, x, y);
|
||||
}
|
||||
|
||||
public static Bitmap LayerImage(Image baseLayer, Image overLayer, int x, int y)
|
||||
{
|
||||
Bitmap img = new(baseLayer);
|
||||
using Graphics gr = Graphics.FromImage(img);
|
||||
gr.DrawImage(overLayer, x, y, overLayer.Width, overLayer.Height);
|
||||
return img;
|
||||
}
|
||||
|
||||
public static Bitmap ChangeOpacity(Image img, double trans)
|
||||
{
|
||||
var bmp = (Bitmap)img.Clone();
|
||||
GetBitmapData(bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data);
|
||||
|
||||
Marshal.Copy(ptr, data, 0, data.Length);
|
||||
SetAllTransparencyTo(data, trans);
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static Bitmap ChangeAllColorTo(Image img, Color c)
|
||||
{
|
||||
var bmp = (Bitmap)img.Clone();
|
||||
GetBitmapData(bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data);
|
||||
|
||||
Marshal.Copy(ptr, data, 0, data.Length);
|
||||
ChangeAllColorTo(data, c);
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static Bitmap ChangeTransparentTo(Image img, Color c, byte trans, int start = 0)
|
||||
{
|
||||
var bmp = (Bitmap)img.Clone();
|
||||
GetBitmapData(bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data);
|
||||
|
||||
Marshal.Copy(ptr, data, 0, data.Length);
|
||||
SetAllTransparencyTo(data, c, trans, start);
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static Bitmap WritePixels(Image img, Color c, int start, int end)
|
||||
{
|
||||
var bmp = (Bitmap)img.Clone();
|
||||
GetBitmapData(bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data);
|
||||
|
||||
Marshal.Copy(ptr, data, 0, data.Length);
|
||||
ChangeAllTo(data, c, start, end);
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static Bitmap ToGrayscale(Image img)
|
||||
{
|
||||
var bmp = (Bitmap)img.Clone();
|
||||
GetBitmapData(bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data);
|
||||
|
||||
Marshal.Copy(ptr, data, 0, data.Length);
|
||||
SetAllColorToGrayScale(data);
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
private static void GetBitmapData(Bitmap bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data)
|
||||
{
|
||||
bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||||
ptr = bmpData.Scan0;
|
||||
data = new byte[bmp.Width * bmp.Height * 4];
|
||||
}
|
||||
|
||||
public static Bitmap GetBitmap(byte[] data, int width, int height, PixelFormat format = PixelFormat.Format32bppArgb)
|
||||
{
|
||||
var bmp = new Bitmap(width, height, format);
|
||||
var bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, format);
|
||||
var ptr = bmpData.Scan0;
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static byte[] GetPixelData(Bitmap bitmap)
|
||||
{
|
||||
var argbData = new byte[bitmap.Width * bitmap.Height * 4];
|
||||
var bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
||||
Marshal.Copy(bd.Scan0, argbData, 0, bitmap.Width * bitmap.Height * 4);
|
||||
bitmap.UnlockBits(bd);
|
||||
return argbData;
|
||||
}
|
||||
|
||||
public static void SetAllUsedPixelsOpaque(byte[] data)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
{
|
||||
overLayer = ChangeOpacity(overLayer, transparency);
|
||||
return LayerImage(baseLayer, overLayer, x, y);
|
||||
if (data[i + 3] != 0)
|
||||
data[i + 3] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemovePixels(byte[] pixels, byte[] original)
|
||||
{
|
||||
for (int i = 0; i < original.Length; i += 4)
|
||||
{
|
||||
if (original[i + 3] == 0)
|
||||
continue;
|
||||
pixels[i + 0] = 0;
|
||||
pixels[i + 1] = 0;
|
||||
pixels[i + 2] = 0;
|
||||
pixels[i + 3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetAllTransparencyTo(byte[] data, double trans)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
data[i + 3] = (byte)(data[i + 3] * trans);
|
||||
}
|
||||
|
||||
public static void SetAllTransparencyTo(byte[] data, Color c, byte trans, int start)
|
||||
{
|
||||
byte R = c.R;
|
||||
byte G = c.G;
|
||||
byte B = c.B;
|
||||
for (int i = start; i < data.Length; i += 4)
|
||||
{
|
||||
if (data[i + 3] != 0)
|
||||
continue;
|
||||
data[i + 0] = B;
|
||||
data[i + 1] = G;
|
||||
data[i + 2] = R;
|
||||
data[i + 3] = trans;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ChangeAllTo(byte[] data, Color c, int start, int end)
|
||||
{
|
||||
byte R = c.R;
|
||||
byte G = c.G;
|
||||
byte B = c.B;
|
||||
byte A = c.A;
|
||||
for (int i = start; i < end; i += 4)
|
||||
{
|
||||
data[i + 3] = A;
|
||||
data[i + 2] = R;
|
||||
data[i + 1] = G;
|
||||
data[i + 0] = B;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ChangeAllColorTo(byte[] data, Color c)
|
||||
{
|
||||
byte R = c.R;
|
||||
byte G = c.G;
|
||||
byte B = c.B;
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
{
|
||||
if (data[i + 3] == 0)
|
||||
continue;
|
||||
data[i + 0] = B;
|
||||
data[i + 1] = G;
|
||||
data[i + 2] = R;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetAllColorToGrayScale(byte[] data)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
{
|
||||
if (data[i + 3] == 0)
|
||||
continue;
|
||||
byte greyS = (byte)(((0.3 * data[i + 2]) + (0.59 * data[i + 1]) + (0.11 * data[i + 0])) / 3);
|
||||
data[i + 0] = greyS;
|
||||
data[i + 1] = greyS;
|
||||
data[i + 2] = greyS;
|
||||
}
|
||||
}
|
||||
|
||||
public static void GlowEdges(byte[] data, byte blue, byte green, byte red, int width, int reach = 3, double amount = 0.0777)
|
||||
{
|
||||
PollutePixels(data, width, reach, amount);
|
||||
CleanPollutedPixels(data, blue, green, red);
|
||||
}
|
||||
|
||||
private static void PollutePixels(byte[] data, int width, int reach, double amount)
|
||||
{
|
||||
int stride = width * 4;
|
||||
int height = data.Length / stride;
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
{
|
||||
// only pollute outwards if the current pixel isn't transparent
|
||||
if (data[i + 3] == 0)
|
||||
continue;
|
||||
|
||||
int x = (i % stride) / 4;
|
||||
int y = (i / stride);
|
||||
Pollute(x, y);
|
||||
}
|
||||
|
||||
public static Bitmap LayerImage(Image baseLayer, Image overLayer, int x, int y)
|
||||
void Pollute(int x, int y)
|
||||
{
|
||||
Bitmap img = new(baseLayer);
|
||||
using Graphics gr = Graphics.FromImage(img);
|
||||
gr.DrawImage(overLayer, x, y, overLayer.Width, overLayer.Height);
|
||||
return img;
|
||||
}
|
||||
|
||||
public static Bitmap ChangeOpacity(Image img, double trans)
|
||||
{
|
||||
var bmp = (Bitmap)img.Clone();
|
||||
GetBitmapData(bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data);
|
||||
|
||||
Marshal.Copy(ptr, data, 0, data.Length);
|
||||
SetAllTransparencyTo(data, trans);
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static Bitmap ChangeAllColorTo(Image img, Color c)
|
||||
{
|
||||
var bmp = (Bitmap)img.Clone();
|
||||
GetBitmapData(bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data);
|
||||
|
||||
Marshal.Copy(ptr, data, 0, data.Length);
|
||||
ChangeAllColorTo(data, c);
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static Bitmap ChangeTransparentTo(Image img, Color c, byte trans, int start = 0)
|
||||
{
|
||||
var bmp = (Bitmap)img.Clone();
|
||||
GetBitmapData(bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data);
|
||||
|
||||
Marshal.Copy(ptr, data, 0, data.Length);
|
||||
SetAllTransparencyTo(data, c, trans, start);
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static Bitmap WritePixels(Image img, Color c, int start, int end)
|
||||
{
|
||||
var bmp = (Bitmap)img.Clone();
|
||||
GetBitmapData(bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data);
|
||||
|
||||
Marshal.Copy(ptr, data, 0, data.Length);
|
||||
ChangeAllTo(data, c, start, end);
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static Bitmap ToGrayscale(Image img)
|
||||
{
|
||||
var bmp = (Bitmap)img.Clone();
|
||||
GetBitmapData(bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data);
|
||||
|
||||
Marshal.Copy(ptr, data, 0, data.Length);
|
||||
SetAllColorToGrayScale(data);
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
private static void GetBitmapData(Bitmap bmp, out BitmapData bmpData, out IntPtr ptr, out byte[] data)
|
||||
{
|
||||
bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||||
ptr = bmpData.Scan0;
|
||||
data = new byte[bmp.Width * bmp.Height * 4];
|
||||
}
|
||||
|
||||
public static Bitmap GetBitmap(byte[] data, int width, int height, PixelFormat format = PixelFormat.Format32bppArgb)
|
||||
{
|
||||
var bmp = new Bitmap(width, height, format);
|
||||
var bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, format);
|
||||
var ptr = bmpData.Scan0;
|
||||
Marshal.Copy(data, 0, ptr, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
return bmp;
|
||||
}
|
||||
|
||||
public static byte[] GetPixelData(Bitmap bitmap)
|
||||
{
|
||||
var argbData = new byte[bitmap.Width * bitmap.Height * 4];
|
||||
var bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
||||
Marshal.Copy(bd.Scan0, argbData, 0, bitmap.Width * bitmap.Height * 4);
|
||||
bitmap.UnlockBits(bd);
|
||||
return argbData;
|
||||
}
|
||||
|
||||
public static void SetAllUsedPixelsOpaque(byte[] data)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
int left = Math.Max(0, x - reach);
|
||||
int right = Math.Min(width - 1, x + reach);
|
||||
int top = Math.Max(0, y - reach);
|
||||
int bottom = Math.Min(height - 1, y + reach);
|
||||
for (int i = left; i <= right; i++)
|
||||
{
|
||||
if (data[i + 3] != 0)
|
||||
data[i + 3] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemovePixels(byte[] pixels, byte[] original)
|
||||
{
|
||||
for (int i = 0; i < original.Length; i += 4)
|
||||
{
|
||||
if (original[i + 3] == 0)
|
||||
continue;
|
||||
pixels[i + 0] = 0;
|
||||
pixels[i + 1] = 0;
|
||||
pixels[i + 2] = 0;
|
||||
pixels[i + 3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetAllTransparencyTo(byte[] data, double trans)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
data[i + 3] = (byte)(data[i + 3] * trans);
|
||||
}
|
||||
|
||||
public static void SetAllTransparencyTo(byte[] data, Color c, byte trans, int start)
|
||||
{
|
||||
byte R = c.R;
|
||||
byte G = c.G;
|
||||
byte B = c.B;
|
||||
for (int i = start; i < data.Length; i += 4)
|
||||
{
|
||||
if (data[i + 3] != 0)
|
||||
continue;
|
||||
data[i + 0] = B;
|
||||
data[i + 1] = G;
|
||||
data[i + 2] = R;
|
||||
data[i + 3] = trans;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ChangeAllTo(byte[] data, Color c, int start, int end)
|
||||
{
|
||||
byte R = c.R;
|
||||
byte G = c.G;
|
||||
byte B = c.B;
|
||||
byte A = c.A;
|
||||
for (int i = start; i < end; i += 4)
|
||||
{
|
||||
data[i + 3] = A;
|
||||
data[i + 2] = R;
|
||||
data[i + 1] = G;
|
||||
data[i + 0] = B;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ChangeAllColorTo(byte[] data, Color c)
|
||||
{
|
||||
byte R = c.R;
|
||||
byte G = c.G;
|
||||
byte B = c.B;
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
{
|
||||
if (data[i + 3] == 0)
|
||||
continue;
|
||||
data[i + 0] = B;
|
||||
data[i + 1] = G;
|
||||
data[i + 2] = R;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetAllColorToGrayScale(byte[] data)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
{
|
||||
if (data[i + 3] == 0)
|
||||
continue;
|
||||
byte greyS = (byte)(((0.3 * data[i + 2]) + (0.59 * data[i + 1]) + (0.11 * data[i + 0])) / 3);
|
||||
data[i + 0] = greyS;
|
||||
data[i + 1] = greyS;
|
||||
data[i + 2] = greyS;
|
||||
}
|
||||
}
|
||||
|
||||
public static void GlowEdges(byte[] data, byte blue, byte green, byte red, int width, int reach = 3, double amount = 0.0777)
|
||||
{
|
||||
PollutePixels(data, width, reach, amount);
|
||||
CleanPollutedPixels(data, blue, green, red);
|
||||
}
|
||||
|
||||
private static void PollutePixels(byte[] data, int width, int reach, double amount)
|
||||
{
|
||||
int stride = width * 4;
|
||||
int height = data.Length / stride;
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
{
|
||||
// only pollute outwards if the current pixel isn't transparent
|
||||
if (data[i + 3] == 0)
|
||||
continue;
|
||||
|
||||
int x = (i % stride) / 4;
|
||||
int y = (i / stride);
|
||||
Pollute(x, y);
|
||||
}
|
||||
|
||||
void Pollute(int x, int y)
|
||||
{
|
||||
int left = Math.Max(0, x - reach);
|
||||
int right = Math.Min(width - 1, x + reach);
|
||||
int top = Math.Max(0, y - reach);
|
||||
int bottom = Math.Min(height - 1, y + reach);
|
||||
for (int i = left; i <= right; i++)
|
||||
for (int j = top; j <= bottom; j++)
|
||||
{
|
||||
for (int j = top; j <= bottom; j++)
|
||||
{
|
||||
// update one of the color bits
|
||||
// it is expected that a transparent pixel RGBA value is 0.
|
||||
var c = 4 * (i + (j * width));
|
||||
data[c + 0] += (byte)(amount * (0xFF - data[c + 0]));
|
||||
}
|
||||
// update one of the color bits
|
||||
// it is expected that a transparent pixel RGBA value is 0.
|
||||
var c = 4 * (i + (j * width));
|
||||
data[c + 0] += (byte)(amount * (0xFF - data[c + 0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void CleanPollutedPixels(byte[] data, byte blue, byte green, byte red)
|
||||
private static void CleanPollutedPixels(byte[] data, byte blue, byte green, byte red)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
{
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
{
|
||||
// only clean if the current pixel isn't transparent
|
||||
if (data[i + 3] != 0)
|
||||
continue;
|
||||
// only clean if the current pixel isn't transparent
|
||||
if (data[i + 3] != 0)
|
||||
continue;
|
||||
|
||||
// grab the transparency from the donor byte
|
||||
var transparency = data[i + 0];
|
||||
if (transparency == 0)
|
||||
continue;
|
||||
// grab the transparency from the donor byte
|
||||
var transparency = data[i + 0];
|
||||
if (transparency == 0)
|
||||
continue;
|
||||
|
||||
data[i + 0] = blue;
|
||||
data[i + 1] = green;
|
||||
data[i + 2] = red;
|
||||
data[i + 3] = transparency;
|
||||
}
|
||||
}
|
||||
|
||||
public static Color ColorBaseStat(int v)
|
||||
{
|
||||
const float maxval = 180; // shift the green cap down
|
||||
float x = 100f * v / maxval;
|
||||
if (x > 100)
|
||||
x = 100;
|
||||
double red = 255f * (x > 50 ? 1 - (2 * (x - 50) / 100.0) : 1.0);
|
||||
double green = 255f * (x > 50 ? 1.0 : 2 * x / 100.0);
|
||||
|
||||
return Blend(Color.FromArgb((int)red, (int)green, 0), Color.White, 0.4);
|
||||
}
|
||||
|
||||
public static Color ColorBaseStatTotal(int tot) => ColorBaseStat((int) (Math.Max(0, tot - 175) / 3f));
|
||||
|
||||
public static Color Blend(Color color, Color backColor, double amount)
|
||||
{
|
||||
byte r = (byte)((color.R * amount) + (backColor.R * (1 - amount)));
|
||||
byte g = (byte)((color.G * amount) + (backColor.G * (1 - amount)));
|
||||
byte b = (byte)((color.B * amount) + (backColor.B * (1 - amount)));
|
||||
return Color.FromArgb(r, g, b);
|
||||
data[i + 0] = blue;
|
||||
data[i + 1] = green;
|
||||
data[i + 2] = red;
|
||||
data[i + 3] = transparency;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net46</TargetFrameworks>
|
||||
<LangVersion>9</LangVersion>
|
||||
<LangVersion>10</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -368,11 +368,11 @@ namespace PKHeX.WinForms.Controls
|
|||
for (int i = 0; i < stats.Count; i++)
|
||||
{
|
||||
MT_Base[i].Text = stats[i].ToString("000");
|
||||
MT_Base[i].BackColor = ImageUtil.ColorBaseStat(stats[i]);
|
||||
MT_Base[i].BackColor = ColorUtil.ColorBaseStat(stats[i]);
|
||||
}
|
||||
var bst = pi.Stats.Sum();
|
||||
TB_BST.Text = bst.ToString("000");
|
||||
TB_BST.BackColor = ImageUtil.ColorBaseStatTotal(bst);
|
||||
TB_BST.BackColor = ColorUtil.ColorBaseStatTotal(bst);
|
||||
}
|
||||
|
||||
public void UpdateRandomIVs(object sender, EventArgs e)
|
||||
|
|
|
@ -114,6 +114,6 @@ namespace PKHeX.WinForms.Controls
|
|||
return cache[frameIndex] = frame;
|
||||
}
|
||||
|
||||
private Color GetFrameColor(double elapsedFraction) => ImageUtil.Blend(GlowToColor, GlowFromColor, elapsedFraction);
|
||||
private Color GetFrameColor(double elapsedFraction) => ColorUtil.Blend(GlowToColor, GlowFromColor, elapsedFraction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,22 +55,22 @@ namespace PKHeX.WinForms
|
|||
row.Cells[r++].Value = SpriteUtil.GetSprite(s, f, 0, 0, 0, false, false, SAV.Generation);
|
||||
row.Cells[r++].Value = species[index];
|
||||
row.Cells[r++].Value = GetIsNative(p, s);
|
||||
row.Cells[r].Style.BackColor = ImageUtil.ColorBaseStatTotal(p.BST);
|
||||
row.Cells[r].Style.BackColor = ColorUtil.ColorBaseStatTotal(p.BST);
|
||||
row.Cells[r++].Value = p.BST.ToString("000");
|
||||
row.Cells[r++].Value = p.CatchRate.ToString("000");
|
||||
row.Cells[r++].Value = TypeSpriteUtil.GetTypeSprite(p.Type1, SAV.Generation);
|
||||
row.Cells[r++].Value = p.Type1 == p.Type2 ? SpriteUtil.Spriter.Transparent : TypeSpriteUtil.GetTypeSprite(p.Type2, SAV.Generation);
|
||||
row.Cells[r].Style.BackColor = ImageUtil.ColorBaseStat(p.HP);
|
||||
row.Cells[r].Style.BackColor = ColorUtil.ColorBaseStat(p.HP);
|
||||
row.Cells[r++].Value = p.HP.ToString("000");
|
||||
row.Cells[r].Style.BackColor = ImageUtil.ColorBaseStat(p.ATK);
|
||||
row.Cells[r].Style.BackColor = ColorUtil.ColorBaseStat(p.ATK);
|
||||
row.Cells[r++].Value = p.ATK.ToString("000");
|
||||
row.Cells[r].Style.BackColor = ImageUtil.ColorBaseStat(p.DEF);
|
||||
row.Cells[r].Style.BackColor = ColorUtil.ColorBaseStat(p.DEF);
|
||||
row.Cells[r++].Value = p.DEF.ToString("000");
|
||||
row.Cells[r].Style.BackColor = ImageUtil.ColorBaseStat(p.SPA);
|
||||
row.Cells[r].Style.BackColor = ColorUtil.ColorBaseStat(p.SPA);
|
||||
row.Cells[r++].Value = p.SPA.ToString("000");
|
||||
row.Cells[r].Style.BackColor = ImageUtil.ColorBaseStat(p.SPD);
|
||||
row.Cells[r].Style.BackColor = ColorUtil.ColorBaseStat(p.SPD);
|
||||
row.Cells[r++].Value = p.SPD.ToString("000");
|
||||
row.Cells[r].Style.BackColor = ImageUtil.ColorBaseStat(p.SPE);
|
||||
row.Cells[r].Style.BackColor = ColorUtil.ColorBaseStat(p.SPE);
|
||||
row.Cells[r++].Value = p.SPE.ToString("000");
|
||||
var abils = p.Abilities;
|
||||
row.Cells[r++].Value = GetAbility(abils, 0);
|
||||
|
|
Loading…
Reference in a new issue