mirror of
https://github.com/kwsch/PKHeX
synced 2025-02-17 05:48:44 +00:00
clean up batch editor
refactor some logic to make it easier to reuse add some xmldoc
This commit is contained in:
parent
2a877bfb9e
commit
8cf70770cf
6 changed files with 278 additions and 167 deletions
|
@ -17,6 +17,7 @@ namespace PKHeX.Core
|
|||
typeof (PK3), typeof (XK3), typeof (CK3),
|
||||
typeof (PK2), typeof (PK1),
|
||||
};
|
||||
|
||||
public static readonly string[] CustomProperties = { PROP_LEGAL };
|
||||
public static readonly string[][] Properties = GetPropArray();
|
||||
|
||||
|
@ -30,6 +31,7 @@ namespace PKHeX.Core
|
|||
private const string CONST_BYTES = "$[]";
|
||||
|
||||
private const string PROP_LEGAL = "Legal";
|
||||
private const string IdentifierContains = nameof(PKM.Identifier) + "Contains";
|
||||
|
||||
private static string[][] GetPropArray()
|
||||
{
|
||||
|
@ -53,22 +55,25 @@ namespace PKHeX.Core
|
|||
return p1;
|
||||
}
|
||||
|
||||
public static bool TryGetHasProperty(PKM pk, string name, out PropertyInfo pi)
|
||||
/// <summary>
|
||||
/// Tries to fetch the <see cref="PKM"/> property from the cache of available properties.
|
||||
/// </summary>
|
||||
/// <param name="pkm">Pokémon to check</param>
|
||||
/// <param name="name">Property Name to check</param>
|
||||
/// <param name="pi">Property Info retrieved (if any).</param>
|
||||
/// <returns>True if has property, false if does not.</returns>
|
||||
public static bool TryGetHasProperty(PKM pkm, string name, out PropertyInfo pi)
|
||||
{
|
||||
var props = Props[Array.IndexOf(Types, pk.GetType())];
|
||||
var props = Props[Array.IndexOf(Types, pkm.GetType())];
|
||||
return props.TryGetValue(name, out pi);
|
||||
}
|
||||
public static bool TryGetPropertyValue(PKM pk, string name, out object value)
|
||||
{
|
||||
if (TryGetHasProperty(pk, name, out var pi))
|
||||
{
|
||||
value = pi.GetValue(pk);
|
||||
return true;
|
||||
}
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the <see cref="PKM"/> property using the saved cache of properties.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">Property Name to fetch the type for</param>
|
||||
/// <param name="typeIndex">Type index (within <see cref="Types"/>. Leave empty (0) for a nonspecific format.</param>
|
||||
/// <returns>Short name of the property's type.</returns>
|
||||
public static string GetPropertyType(string propertyName, int typeIndex = 0)
|
||||
{
|
||||
if (CustomProperties.Contains(propertyName))
|
||||
|
@ -83,12 +88,16 @@ namespace PKHeX.Core
|
|||
}
|
||||
|
||||
int index = typeIndex == Props.Length - 1 ? 0 : typeIndex - 1; // All vs Specific
|
||||
var pr = Props[typeIndex - 1];
|
||||
var pr = Props[index];
|
||||
if (!pr.TryGetValue(propertyName, out var info))
|
||||
return null;
|
||||
return info.PropertyType.Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the <see cref="StringInstruction"/> list with a context-sensitive value. If the provided value is a string, it will attempt to convert that string to its corresponding index.
|
||||
/// </summary>
|
||||
/// <param name="il">Instructions to initialize.</param>
|
||||
public static void ScreenStrings(IEnumerable<StringInstruction> il)
|
||||
{
|
||||
foreach (var i in il.Where(i => !i.PropertyValue.All(char.IsDigit)))
|
||||
|
@ -101,6 +110,10 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the <see cref="StringInstruction"/> with a context-sensitive value. If the provided value is a string, it will attempt to convert that string to its corresponding index.
|
||||
/// </summary>
|
||||
/// <param name="i">Instruction to initialize.</param>
|
||||
private static void SetInstructionScreenedValue(StringInstruction i)
|
||||
{
|
||||
switch (i.PropertyName)
|
||||
|
@ -122,30 +135,80 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
|
||||
internal static ModifyResult TryModifyPKM(PKM PKM, IEnumerable<StringInstruction> Filters, IEnumerable<StringInstruction> Instructions)
|
||||
/// <summary>
|
||||
/// Checks if the object is filtered by the provided <see cref="filters"/>.
|
||||
/// </summary>
|
||||
/// <param name="filters">Filters which must be satisfied.</param>
|
||||
/// <param name="pkm">Object to check.</param>
|
||||
/// <returns>True if <see cref="pkm"/> matches all filters.</returns>
|
||||
public static bool IsFiltered(IEnumerable<StringInstruction> filters, PKM pkm) => filters.All(z => IsPKMFiltered(z, pkm));
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the object is filtered by the provided <see cref="filters"/>.
|
||||
/// </summary>
|
||||
/// <param name="filters">Filters which must be satisfied.</param>
|
||||
/// <param name="obj">Object to check.</param>
|
||||
/// <returns>True if <see cref="obj"/> matches all filters.</returns>
|
||||
public static bool IsFiltered(IEnumerable<StringInstruction> filters, object obj)
|
||||
{
|
||||
if (!PKM.ChecksumValid || PKM.Species == 0)
|
||||
foreach (var cmd in filters)
|
||||
{
|
||||
if (!ReflectUtil.HasProperty(obj, cmd.PropertyName, out var pi))
|
||||
return false;
|
||||
try { if (pi.IsValueEqual(obj, cmd.PropertyValue) == cmd.Evaluator) continue; }
|
||||
catch { Debug.WriteLine($"Unable to compare {cmd.PropertyName} to {cmd.PropertyValue}."); }
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to modify the <see cref="PKM"/>.
|
||||
/// </summary>
|
||||
/// <param name="pkm">Object to modify.</param>
|
||||
/// <param name="filters">Filters which must be satisfied prior to any modifications being made.</param>
|
||||
/// <param name="modifications">Modifications to perform on the <see cref="pkm"/>.</param>
|
||||
/// <returns>Result of the attempted modification.</returns>
|
||||
public static bool TryModify(PKM pkm, IEnumerable<StringInstruction> filters, IEnumerable<StringInstruction> modifications)
|
||||
{
|
||||
var result = TryModifyPKM(pkm, filters, modifications);
|
||||
return result == ModifyResult.Modified;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to modify the <see cref="PKMInfo"/>.
|
||||
/// </summary>
|
||||
/// <param name="pkm">Command Filter</param>
|
||||
/// <param name="filters">Filters which must be satisfied prior to any modifications being made.</param>
|
||||
/// <param name="modifications">Modifications to perform on the <see cref="pkm"/>.</param>
|
||||
/// <returns>Result of the attempted modification.</returns>
|
||||
internal static ModifyResult TryModifyPKM(PKM pkm, IEnumerable<StringInstruction> filters, IEnumerable<StringInstruction> modifications)
|
||||
{
|
||||
if (!pkm.ChecksumValid || pkm.Species == 0)
|
||||
return ModifyResult.Invalid;
|
||||
|
||||
PKMInfo info = new PKMInfo(PKM);
|
||||
var pi = Props[Array.IndexOf(Types, PKM.GetType())];
|
||||
foreach (var cmd in Filters)
|
||||
PKMInfo info = new PKMInfo(pkm);
|
||||
var pi = Props[Array.IndexOf(Types, pkm.GetType())];
|
||||
foreach (var cmd in filters)
|
||||
{
|
||||
try
|
||||
{
|
||||
var filter = IsPKMFiltered(cmd, info, pi);
|
||||
if (filter != ModifyResult.None)
|
||||
return filter; // why it was filtered out
|
||||
if (IsPKMFiltered(cmd, info, pi))
|
||||
return ModifyResult.Filtered;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(MsgBEModifyFailCompare + " " + ex.Message, cmd.PropertyName, cmd.PropertyValue);
|
||||
return ModifyResult.Error;
|
||||
}
|
||||
catch (Exception ex) { Debug.WriteLine(MsgBEModifyFailCompare + " " + ex.Message, cmd.PropertyName, cmd.PropertyValue); }
|
||||
}
|
||||
|
||||
ModifyResult result = ModifyResult.Modified;
|
||||
foreach (var cmd in Instructions)
|
||||
foreach (var cmd in modifications)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tmp = SetPKMProperty(PKM, info, cmd, pi);
|
||||
var tmp = SetPKMProperty(cmd, info, pi);
|
||||
if (result != ModifyResult.Modified)
|
||||
result = tmp;
|
||||
}
|
||||
|
@ -153,61 +216,127 @@ namespace PKHeX.Core
|
|||
}
|
||||
return result;
|
||||
}
|
||||
private static ModifyResult SetPKMProperty(PKM PKM, PKMInfo info, StringInstruction cmd, Dictionary<string, PropertyInfo> props)
|
||||
|
||||
/// <summary>
|
||||
/// Sets the if the <see cref="PKMInfo"/> should be filtered due to the <see cref="StringInstruction"/> provided.
|
||||
/// </summary>
|
||||
/// <param name="cmd">Command Filter</param>
|
||||
/// <param name="info">Pokémon to check.</param>
|
||||
/// <param name="props">PropertyInfo cache (optional)</param>
|
||||
/// <returns>True if filtered, else false.</returns>
|
||||
private static ModifyResult SetPKMProperty(StringInstruction cmd, PKMInfo info, IReadOnlyDictionary<string, PropertyInfo> props)
|
||||
{
|
||||
var pkm = info.pkm;
|
||||
if (cmd.PropertyValue.StartsWith(CONST_BYTES))
|
||||
return SetByteArrayProperty(PKM, cmd)
|
||||
? ModifyResult.Modified
|
||||
: ModifyResult.Error;
|
||||
return SetByteArrayProperty(pkm, cmd);
|
||||
|
||||
if (cmd.PropertyValue == CONST_SUGGEST)
|
||||
return SetSuggestedPKMProperty(cmd, info)
|
||||
? ModifyResult.Modified
|
||||
: ModifyResult.Error;
|
||||
return SetSuggestedPKMProperty(cmd.PropertyName, info);
|
||||
|
||||
if (SetComplexProperty(PKM, cmd))
|
||||
if (SetComplexProperty(pkm, cmd))
|
||||
return ModifyResult.Modified;
|
||||
|
||||
object val = cmd.Random ? (object)cmd.RandomValue : cmd.PropertyValue;
|
||||
if (TryGetHasProperty(PKM, cmd.PropertyName, out var pi))
|
||||
{
|
||||
ReflectUtil.SetValue(pi, PKM, val);
|
||||
return ModifyResult.Modified;
|
||||
}
|
||||
return ModifyResult.Error;
|
||||
}
|
||||
private static ModifyResult IsPKMFiltered(StringInstruction cmd, PKMInfo info, Dictionary<string, PropertyInfo> props)
|
||||
{
|
||||
if (cmd.PropertyName == PROP_LEGAL)
|
||||
{
|
||||
if (!bool.TryParse(cmd.PropertyValue, out bool legal))
|
||||
return ModifyResult.Error;
|
||||
if (legal == info.Legal == cmd.Evaluator)
|
||||
return ModifyResult.None;
|
||||
return ModifyResult.Filtered;
|
||||
}
|
||||
|
||||
if (!props.TryGetValue(cmd.PropertyName, out var pi))
|
||||
return ModifyResult.Filtered;
|
||||
if (pi.IsValueEqual(info.pkm, cmd.PropertyValue) != cmd.Evaluator)
|
||||
return ModifyResult.Filtered;
|
||||
return ModifyResult.None;
|
||||
return ModifyResult.Error;
|
||||
|
||||
object val = cmd.Random ? (object)cmd.RandomValue : cmd.PropertyValue;
|
||||
ReflectUtil.SetValue(pi, pkm, val);
|
||||
return ModifyResult.Modified;
|
||||
}
|
||||
private static bool SetSuggestedPKMProperty(StringInstruction cmd, PKMInfo info)
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the <see cref="PKMInfo"/> should be filtered due to the <see cref="StringInstruction"/> provided.
|
||||
/// </summary>
|
||||
/// <param name="cmd">Command Filter</param>
|
||||
/// <param name="info">Pokémon to check.</param>
|
||||
/// <param name="props">PropertyInfo cache (optional)</param>
|
||||
/// <returns>True if filtered, else false.</returns>
|
||||
private static bool IsPKMFiltered(StringInstruction cmd, PKMInfo info, IReadOnlyDictionary<string, PropertyInfo> props = null)
|
||||
{
|
||||
if (IsLegalFiltered(cmd, () => info.Legal))
|
||||
return true;
|
||||
return IsPropertyFiltered(cmd, info.pkm, props);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the <see cref="PKM"/> should be filtered due to the <see cref="StringInstruction"/> provided.
|
||||
/// </summary>
|
||||
/// <param name="cmd">Command Filter</param>
|
||||
/// <param name="pkm">Pokémon to check.</param>
|
||||
/// <param name="props">PropertyInfo cache (optional)</param>
|
||||
/// <returns>True if filtered, else false.</returns>
|
||||
private static bool IsPKMFiltered(StringInstruction cmd, PKM pkm, IReadOnlyDictionary<string, PropertyInfo> props = null)
|
||||
{
|
||||
if (IsLegalFiltered(cmd, () => new LegalityAnalysis(pkm).Valid))
|
||||
return true;
|
||||
return IsPropertyFiltered(cmd, pkm, props);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the <see cref="PKM"/> should be filtered due to the <see cref="StringInstruction"/> provided.
|
||||
/// </summary>
|
||||
/// <param name="cmd">Command Filter</param>
|
||||
/// <param name="pkm">Pokémon to check.</param>
|
||||
/// <param name="props">PropertyInfo cache (optional)</param>
|
||||
/// <returns>True if filtered, else false.</returns>
|
||||
private static bool IsPropertyFiltered(StringInstruction cmd, PKM pkm, IReadOnlyDictionary<string, PropertyInfo> props = null)
|
||||
{
|
||||
if (IsIdentifierFiltered(cmd, pkm))
|
||||
return true;
|
||||
return !props?.TryGetValue(cmd.PropertyName, out _) ?? !ReflectUtil.HasProperty(pkm, cmd.PropertyName, out _);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the <see cref="PKM"/> should be filtered due to its <see cref="PKM.Identifier"/> containing a value.
|
||||
/// </summary>
|
||||
/// <param name="cmd">Command Filter</param>
|
||||
/// <param name="pkm">Pokémon to check.</param>
|
||||
/// <returns>True if filtered, else false.</returns>
|
||||
private static bool IsIdentifierFiltered(StringInstruction cmd, PKM pkm)
|
||||
{
|
||||
if (cmd.PropertyName != IdentifierContains)
|
||||
return false;
|
||||
|
||||
bool result = pkm.Identifier.Contains(cmd.PropertyValue);
|
||||
return result != cmd.Evaluator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the <see cref="PKM"/> should be filtered due to its legality.
|
||||
/// </summary>
|
||||
/// <param name="cmd">Command Filter</param>
|
||||
/// <param name="isLegal">Function to check if the <see cref="PKM"/> is legal.</param>
|
||||
/// <returns>True if filtered, else false.</returns>
|
||||
private static bool IsLegalFiltered(StringInstruction cmd, Func<bool> isLegal)
|
||||
{
|
||||
if (cmd.PropertyName != PROP_LEGAL)
|
||||
return false;
|
||||
|
||||
if (!bool.TryParse(cmd.PropertyValue, out bool legal))
|
||||
return true;
|
||||
return legal == isLegal() != cmd.Evaluator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM"/> data with a suggested value based on its <see cref="LegalityAnalysis"/>.
|
||||
/// </summary>
|
||||
/// <param name="name">Property to modify.</param>
|
||||
/// <param name="info">Cached info storing Legal data.</param>
|
||||
private static ModifyResult SetSuggestedPKMProperty(string name, PKMInfo info)
|
||||
{
|
||||
var PKM = info.pkm;
|
||||
switch (cmd.PropertyName)
|
||||
switch (name)
|
||||
{
|
||||
case nameof(PKM.HyperTrainFlags):
|
||||
PKM.HyperTrainFlags = GetSuggestedHyperTrainingStatus(PKM);
|
||||
return true;
|
||||
PKM.SetSuggestedHyperTrainingData();
|
||||
return ModifyResult.Modified;
|
||||
case nameof(PKM.RelearnMoves):
|
||||
PKM.RelearnMoves = info.SuggestedRelearn;
|
||||
return true;
|
||||
return ModifyResult.Modified;
|
||||
case nameof(PKM.Met_Location):
|
||||
var encounter = info.SuggestedEncounter;
|
||||
if (encounter == null)
|
||||
return false;
|
||||
return ModifyResult.Error;
|
||||
|
||||
int level = encounter.Level;
|
||||
int location = encounter.Location;
|
||||
|
@ -217,92 +346,88 @@ namespace PKHeX.Core
|
|||
PKM.Met_Location = location;
|
||||
PKM.CurrentLevel = Math.Max(minlvl, level);
|
||||
|
||||
return true;
|
||||
return ModifyResult.Modified;
|
||||
|
||||
case nameof(PKM.Moves):
|
||||
var moves = info.SuggestedMoves;
|
||||
Util.Shuffle(moves);
|
||||
PKM.SetMoves(moves);
|
||||
return true;
|
||||
return ModifyResult.Modified;
|
||||
|
||||
default:
|
||||
return false;
|
||||
return ModifyResult.Error;
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetSuggestedHyperTrainingStatus(PKM pkm)
|
||||
{
|
||||
if (pkm.Format < 7 || pkm.CurrentLevel != 100)
|
||||
return 0;
|
||||
|
||||
int val = 0;
|
||||
if (pkm.IV_HP != 31)
|
||||
val |= 1 << 0;
|
||||
if (pkm.IV_ATK < 31 && pkm.IV_ATK > 1)
|
||||
val |= 1 << 1;
|
||||
if (pkm.IV_DEF != 31)
|
||||
val |= 1 << 2;
|
||||
if (pkm.IV_SPE < 31 && pkm.IV_SPE > 1)
|
||||
val |= 1 << 3;
|
||||
if (pkm.IV_SPA != 31)
|
||||
val |= 1 << 4;
|
||||
if (pkm.IV_SPD != 31)
|
||||
val |= 1 << 5;
|
||||
return val;
|
||||
}
|
||||
|
||||
private static bool SetByteArrayProperty(PKM PKM, StringInstruction cmd)
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM"/> byte array propery to a specified value.
|
||||
/// </summary>
|
||||
/// <param name="pkm">Pokémon to modify.</param>
|
||||
/// <param name="cmd">Modification</param>
|
||||
private static ModifyResult SetByteArrayProperty(PKM pkm, StringInstruction cmd)
|
||||
{
|
||||
switch (cmd.PropertyName)
|
||||
{
|
||||
case nameof(PKM.Nickname_Trash):
|
||||
PKM.Nickname_Trash = string2arr(cmd.PropertyValue);
|
||||
return true;
|
||||
case nameof(PKM.OT_Trash):
|
||||
PKM.OT_Trash = string2arr(cmd.PropertyValue);
|
||||
return true;
|
||||
case nameof(pkm.Nickname_Trash):
|
||||
pkm.Nickname_Trash = string2arr(cmd.PropertyValue);
|
||||
return ModifyResult.Modified;
|
||||
case nameof(pkm.OT_Trash):
|
||||
pkm.OT_Trash = string2arr(cmd.PropertyValue);
|
||||
return ModifyResult.Modified;
|
||||
default:
|
||||
return false;
|
||||
return ModifyResult.Error;
|
||||
}
|
||||
byte[] string2arr(string str) => str.Substring(CONST_BYTES.Length).Split(',').Select(z => Convert.ToByte(z.Trim(), 16)).ToArray();
|
||||
}
|
||||
private static bool SetComplexProperty(PKM PKM, StringInstruction cmd)
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM"/> property to a non-specific smart value.
|
||||
/// </summary>
|
||||
/// <param name="pkm">Pokémon to modify.</param>
|
||||
/// <param name="cmd">Modification</param>
|
||||
private static bool SetComplexProperty(PKM pkm, StringInstruction cmd)
|
||||
{
|
||||
if (cmd.PropertyName == nameof(PKM.MetDate))
|
||||
PKM.MetDate = DateTime.ParseExact(cmd.PropertyValue, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None);
|
||||
else if (cmd.PropertyName == nameof(PKM.EggMetDate))
|
||||
PKM.EggMetDate = DateTime.ParseExact(cmd.PropertyValue, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None);
|
||||
else if (cmd.PropertyName == nameof(PKM.EncryptionConstant) && cmd.PropertyValue == CONST_RAND)
|
||||
PKM.EncryptionConstant = Util.Rand32();
|
||||
else if ((cmd.PropertyName == nameof(PKM.Ability) || cmd.PropertyName == nameof(PKM.AbilityNumber)) && cmd.PropertyValue.StartsWith("$"))
|
||||
PKM.RefreshAbility(Convert.ToInt16(cmd.PropertyValue[1]) - 0x30);
|
||||
else if (cmd.PropertyName == nameof(PKM.PID) && cmd.PropertyValue == CONST_RAND)
|
||||
PKM.SetPIDGender(PKM.Gender);
|
||||
else if (cmd.PropertyName == nameof(PKM.EncryptionConstant) && cmd.PropertyValue == nameof(PKM.PID))
|
||||
PKM.EncryptionConstant = PKM.PID;
|
||||
else if (cmd.PropertyName == nameof(PKM.PID) && cmd.PropertyValue == CONST_SHINY)
|
||||
PKM.SetShinyPID();
|
||||
else if (cmd.PropertyName == nameof(PKM.Species) && cmd.PropertyValue == "0")
|
||||
PKM.Data = new byte[PKM.Data.Length];
|
||||
if (cmd.PropertyName == nameof(pkm.MetDate))
|
||||
pkm.MetDate = DateTime.ParseExact(cmd.PropertyValue, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None);
|
||||
else if (cmd.PropertyName == nameof(pkm.EggMetDate))
|
||||
pkm.EggMetDate = DateTime.ParseExact(cmd.PropertyValue, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None);
|
||||
else if (cmd.PropertyName == nameof(pkm.EncryptionConstant) && cmd.PropertyValue == CONST_RAND)
|
||||
pkm.EncryptionConstant = Util.Rand32();
|
||||
else if ((cmd.PropertyName == nameof(pkm.Ability) || cmd.PropertyName == nameof(pkm.AbilityNumber)) && cmd.PropertyValue.StartsWith("$"))
|
||||
pkm.RefreshAbility(Convert.ToInt16(cmd.PropertyValue[1]) - 0x30);
|
||||
else if (cmd.PropertyName == nameof(pkm.PID) && cmd.PropertyValue == CONST_RAND)
|
||||
pkm.SetPIDGender(pkm.Gender);
|
||||
else if (cmd.PropertyName == nameof(pkm.EncryptionConstant) && cmd.PropertyValue == nameof(pkm.PID))
|
||||
pkm.EncryptionConstant = pkm.PID;
|
||||
else if (cmd.PropertyName == nameof(pkm.PID) && cmd.PropertyValue == CONST_SHINY)
|
||||
pkm.SetShinyPID();
|
||||
else if (cmd.PropertyName == nameof(pkm.Species) && cmd.PropertyValue == "0")
|
||||
pkm.Data = new byte[pkm.Data.Length];
|
||||
else if (cmd.PropertyName.StartsWith("IV") && cmd.PropertyValue == CONST_RAND)
|
||||
SetRandomIVs(PKM, cmd);
|
||||
else if (cmd.PropertyName == nameof(PKM.IsNicknamed) && string.Equals(cmd.PropertyValue, "false", StringComparison.OrdinalIgnoreCase))
|
||||
{ PKM.IsNicknamed = false; PKM.Nickname = PKX.GetSpeciesNameGeneration(PKM.Species, PKM.Language, PKM.Format); }
|
||||
SetRandomIVs(pkm, cmd);
|
||||
else if (cmd.PropertyName == nameof(pkm.IsNicknamed) && string.Equals(cmd.PropertyValue, "false", StringComparison.OrdinalIgnoreCase))
|
||||
{ pkm.IsNicknamed = false; pkm.Nickname = PKX.GetSpeciesNameGeneration(pkm.Species, pkm.Language, pkm.Format); }
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
private static void SetRandomIVs(PKM PKM, StringInstruction cmd)
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM"/> IV(s) to a random value.
|
||||
/// </summary>
|
||||
/// <param name="pkm">Pokémon to modify.</param>
|
||||
/// <param name="cmd">Modification</param>
|
||||
private static void SetRandomIVs(PKM pkm, StringInstruction cmd)
|
||||
{
|
||||
if (cmd.PropertyName == nameof(PKM.IVs))
|
||||
if (cmd.PropertyName == nameof(pkm.IVs))
|
||||
{
|
||||
PKM.SetRandomIVs();
|
||||
pkm.SetRandomIVs();
|
||||
return;
|
||||
}
|
||||
|
||||
if (TryGetHasProperty(PKM, cmd.PropertyName, out var pi))
|
||||
ReflectUtil.SetValue(pi, PKM, Util.Rand32() & PKM.MaxIV);
|
||||
if (TryGetHasProperty(pkm, cmd.PropertyName, out var pi))
|
||||
ReflectUtil.SetValue(pi, pkm, Util.Rand32() & pkm.MaxIV);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,14 @@ namespace PKHeX.Core
|
|||
private int Iterated { get; set; }
|
||||
private int Errored { get; set; }
|
||||
|
||||
public bool ProcessPKM(PKM pkm, IEnumerable<StringInstruction> Filters, IEnumerable<StringInstruction> Instructions)
|
||||
/// <summary>
|
||||
/// Tries to modify the <see cref="PKM"/>.
|
||||
/// </summary>
|
||||
/// <param name="pkm">Object to modify.</param>
|
||||
/// <param name="filters">Filters which must be satisfied prior to any modifications being made.</param>
|
||||
/// <param name="modifications">Modifications to perform on the <see cref="pkm"/>.</param>
|
||||
/// <returns>Result of the attempted modification.</returns>
|
||||
public bool ProcessPKM(PKM pkm, IEnumerable<StringInstruction> filters, IEnumerable<StringInstruction> modifications)
|
||||
{
|
||||
if (pkm.Species <= 0)
|
||||
return false;
|
||||
|
@ -24,7 +31,7 @@ namespace PKHeX.Core
|
|||
return false;
|
||||
}
|
||||
|
||||
var r = BatchEditing.TryModifyPKM(pkm, Filters, Instructions);
|
||||
var r = BatchEditing.TryModifyPKM(pkm, filters, modifications);
|
||||
if (r != ModifyResult.Invalid)
|
||||
Iterated++;
|
||||
if (r == ModifyResult.Error)
|
||||
|
@ -37,6 +44,11 @@ namespace PKHeX.Core
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a message indicating the overall result of all modifications performed across multiple Batch Edit jobs.
|
||||
/// </summary>
|
||||
/// <param name="sets">Collection of modifications.</param>
|
||||
/// <returns>Friendly (multi-line) string indicating the result of the batch edits.</returns>
|
||||
public string GetEditorResults(ICollection<StringInstructionSet> sets)
|
||||
{
|
||||
int ctr = Modified / sets.Count;
|
||||
|
@ -44,7 +56,7 @@ namespace PKHeX.Core
|
|||
string maybe = sets.Count == 1 ? string.Empty : "~";
|
||||
string result = string.Format(MsgBEModifySuccess, maybe, ctr, len);
|
||||
if (Errored > 0)
|
||||
result += $"{Environment.NewLine}{maybe}" + string.Format(MsgBEModifyFailError, Errored);
|
||||
result += Environment.NewLine + maybe + string.Format(MsgBEModifyFailError, Errored);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,23 +7,31 @@ namespace PKHeX.Core
|
|||
{
|
||||
public class StringInstruction
|
||||
{
|
||||
public string PropertyName { get; set; }
|
||||
public string PropertyValue { get; set; }
|
||||
public bool Evaluator { get; set; }
|
||||
public string PropertyName { get; private set; }
|
||||
public string PropertyValue { get; private set; }
|
||||
public bool Evaluator { get; private set; }
|
||||
public void SetScreenedValue(string[] arr)
|
||||
{
|
||||
int index = Array.IndexOf(arr, PropertyValue);
|
||||
PropertyValue = index > -1 ? index.ToString() : PropertyValue;
|
||||
}
|
||||
|
||||
public static readonly char[] Prefixes = { Apply, Require, Exclude };
|
||||
private const char Exclude = '!';
|
||||
private const char Require = '=';
|
||||
private const char Apply = '.';
|
||||
private const char SplitRange = ',';
|
||||
private const char SplitInstruction = '=';
|
||||
|
||||
// Extra Functionality
|
||||
private int Min, Max;
|
||||
public bool Random { get; private set; }
|
||||
public int RandomValue => Util.Rand.Next(Min, Max + 1);
|
||||
|
||||
public void SetRandRange(string pv)
|
||||
{
|
||||
string str = pv.Substring(1);
|
||||
var split = str.Split(',');
|
||||
var split = str.Split(SplitRange);
|
||||
int.TryParse(split[0], out Min);
|
||||
int.TryParse(split[1], out Max);
|
||||
|
||||
|
@ -38,18 +46,18 @@ namespace PKHeX.Core
|
|||
|
||||
public static IEnumerable<StringInstruction> GetFilters(IEnumerable<string> lines)
|
||||
{
|
||||
var raw = GetRelevantStrings(lines, '!', '=');
|
||||
var raw = GetRelevantStrings(lines, Exclude, Require);
|
||||
return from line in raw
|
||||
let eval = line[0] == '='
|
||||
let split = line.Substring(1).Split('=')
|
||||
let eval = line[0] == Require
|
||||
let split = line.Substring(1).Split(SplitInstruction)
|
||||
where split.Length == 2 && !string.IsNullOrWhiteSpace(split[0])
|
||||
select new StringInstruction { PropertyName = split[0], PropertyValue = split[1], Evaluator = eval };
|
||||
}
|
||||
public static IEnumerable<StringInstruction> GetInstructions(IEnumerable<string> lines)
|
||||
{
|
||||
var raw = GetRelevantStrings(lines, '.').Select(line => line.Substring(1));
|
||||
var raw = GetRelevantStrings(lines, Apply).Select(line => line.Substring(1));
|
||||
return from line in raw
|
||||
select line.Split('=') into split
|
||||
select line.Split(SplitInstruction) into split
|
||||
where split.Length == 2
|
||||
select new StringInstruction { PropertyName = split[0], PropertyValue = split[1] };
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ namespace PKHeX.WinForms
|
|||
if (CB_Property.SelectedIndex < 0)
|
||||
{ WinFormsUtil.Alert(MsgBEPropertyInvalid); return; }
|
||||
|
||||
char[] prefix = { '.', '=', '!' };
|
||||
char[] prefix = StringInstruction.Prefixes;
|
||||
string s = prefix[CB_Require.SelectedIndex] + CB_Property.Items[CB_Property.SelectedIndex].ToString() + "=";
|
||||
if (RTB_Instructions.Lines.Length != 0 && RTB_Instructions.Lines.Last().Length > 0)
|
||||
s = Environment.NewLine + s;
|
||||
|
|
|
@ -511,7 +511,7 @@ namespace PKHeX.WinForms
|
|||
{
|
||||
var filters = StringInstruction.GetFilters(RTB_Instructions.Lines).ToArray();
|
||||
BatchEditing.ScreenStrings(filters);
|
||||
res = res.Where(pkm => IsPKMFiltered(pkm, filters)); // Compare across all filters
|
||||
res = res.Where(pkm => BatchEditing.IsFiltered(filters, pkm)); // Compare across all filters
|
||||
}
|
||||
|
||||
if (Menu_SearchClones.Checked)
|
||||
|
@ -520,27 +520,6 @@ namespace PKHeX.WinForms
|
|||
return res;
|
||||
}
|
||||
|
||||
private static bool IsPKMFiltered(PKM pkm, IEnumerable<StringInstruction> filters)
|
||||
{
|
||||
foreach (var cmd in filters)
|
||||
{
|
||||
if (cmd.PropertyName == nameof(PKM.Identifier) + "Contains")
|
||||
{
|
||||
bool result = pkm.Identifier.Contains(cmd.PropertyValue);
|
||||
if (result != cmd.Evaluator)
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ReflectUtil.HasProperty(pkm, cmd.PropertyName, out var pi))
|
||||
return false;
|
||||
try { if (pi.IsValueEqual(pkm, cmd.PropertyValue) == cmd.Evaluator) continue; }
|
||||
catch { Debug.WriteLine($"Unable to compare {cmd.PropertyName} to {cmd.PropertyValue}."); }
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static IEnumerable<PKM> FilterByLVL(IEnumerable<PKM> res, int option, string lvl)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(lvl))
|
||||
|
|
|
@ -283,7 +283,7 @@ namespace PKHeX.WinForms
|
|||
{
|
||||
var filters = StringInstruction.GetFilters(RTB_Instructions.Lines).ToArray();
|
||||
BatchEditing.ScreenStrings(filters);
|
||||
res = res.Where(pkm => IsPKMFiltered(pkm, filters)); // Compare across all filters
|
||||
res = res.Where(pkm => BatchEditing.IsFiltered(filters, pkm)); // Compare across all filters
|
||||
}
|
||||
|
||||
var results = res.ToArray();
|
||||
|
@ -294,19 +294,6 @@ namespace PKHeX.WinForms
|
|||
System.Media.SystemSounds.Asterisk.Play();
|
||||
}
|
||||
|
||||
private static bool IsPKMFiltered(MysteryGift gift, StringInstruction[] filters)
|
||||
{
|
||||
foreach (var cmd in filters)
|
||||
{
|
||||
if (!ReflectUtil.HasProperty(gift, cmd.PropertyName, out var pi))
|
||||
return false;
|
||||
try { if (pi.IsValueEqual(gift, cmd.PropertyValue) == cmd.Evaluator) continue; }
|
||||
catch { Debug.WriteLine($"Unable to compare {cmd.PropertyName} to {cmd.PropertyValue}."); }
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void UpdateScroll(object sender, ScrollEventArgs e)
|
||||
{
|
||||
if (e.OldValue != e.NewValue)
|
||||
|
|
Loading…
Add table
Reference in a new issue