mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-05-09 04:24:36 -05:00
Refactoring
WinForms->Core logic absorbing (CommonEdits) loading ShowdownSet now applies properties to PKM instead of PKMEditor Contest/IVs for Static/Trades are no longer set by default (less object allocations), and are now checked by the encounter generator
This commit is contained in:
parent
9da1913f1b
commit
2bd9d99d9e
|
|
@ -26,10 +26,10 @@ public class EncounterStatic : IEncounterable, IMoveset, IGeneration, ILocation
|
|||
public bool Gift { get; set; }
|
||||
public int Ball { get; set; } = 4; // Only checked when is Gift
|
||||
public GameVersion Version = GameVersion.Any;
|
||||
public int[] IVs { get; set; } = { -1, -1, -1, -1, -1, -1 };
|
||||
public int[] IVs { get; set; }
|
||||
public int FlawlessIVCount { get; internal set; }
|
||||
public bool IV3 { set => FlawlessIVCount = value ? 3 : 0; }
|
||||
public int[] Contest { get; set; } = { 0, 0, 0, 0, 0, 0 };
|
||||
public int[] Contest { get; set; }
|
||||
public int HeldItem { get; set; }
|
||||
public int EggCycles { get; set; }
|
||||
|
||||
|
|
@ -44,8 +44,8 @@ private void CloneArrays()
|
|||
// dereference original arrays with new copies
|
||||
Moves = (int[])Moves?.Clone();
|
||||
Relearn = (int[])Relearn.Clone();
|
||||
IVs = (int[])IVs.Clone();
|
||||
Contest = (int[])Contest.Clone();
|
||||
IVs = (int[])IVs?.Clone();
|
||||
Contest = (int[])Contest?.Clone();
|
||||
}
|
||||
internal virtual EncounterStatic Clone()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ public class EncounterTrade : IEncounterable, IMoveset, IGeneration, ILocation
|
|||
public int TID { get; set; }
|
||||
public int SID { get; set; }
|
||||
public GameVersion Version { get; set; } = GameVersion.Any;
|
||||
public int[] IVs { get; set; } = { -1, -1, -1, -1, -1, -1 };
|
||||
public int[] Contest { get; set; } = { 0, 0, 0, 0, 0, 0 };
|
||||
public int[] IVs { get; set; }
|
||||
public int[] Contest { get; set; }
|
||||
public int Form { get; set; }
|
||||
public bool Shiny { get; set; } = false;
|
||||
public int Gender { get; set; } = -1;
|
||||
|
|
|
|||
|
|
@ -513,11 +513,16 @@ private static bool GetIsMatchStatic(PKM pkm, EncounterStatic e, int lvl)
|
|||
if (e.EggLocation == 60002 && e.Relearn[0] == 0 && pkm.RelearnMoves.Any(z => z != 0)) // gen7 eevee edge case
|
||||
return false;
|
||||
|
||||
if (e.Generation > 2 || pkm.Format <= 2) // 1,2->7 regenerates IVs, only check if original IVs still exist
|
||||
if (e.IVs != null && (e.Generation > 2 || pkm.Format <= 2)) // 1,2->7 regenerates IVs, only check if original IVs still exist
|
||||
for (int i = 0; i < 6; i++)
|
||||
if (e.IVs[i] != -1 && e.IVs[i] != pkm.IVs[i])
|
||||
return false;
|
||||
|
||||
if (e.Contest != null)
|
||||
for (int i = 0; i < 6; i++)
|
||||
if (e.Contest[i] > pkm.Contest[i])
|
||||
return false;
|
||||
|
||||
// Defer to EC/PID check
|
||||
// if (e.Shiny != null && e.Shiny != pkm.IsShiny)
|
||||
// continue;
|
||||
|
|
@ -907,7 +912,7 @@ private static IEnumerable<EncounterTrade> GetValidEncounterTradesVC2(PKM pkm, D
|
|||
continue;
|
||||
if (z.Gender >= 0 && z.Gender != pkm.Gender && pkm.Format <= 2)
|
||||
continue;
|
||||
if (z.IVs[0] >= 0 && !z.IVs.SequenceEqual(pkm.IVs) && pkm.Format <= 2)
|
||||
if (z.IVs != null && !z.IVs.SequenceEqual(pkm.IVs) && pkm.Format <= 2)
|
||||
continue;
|
||||
if (pkm.Met_Location != 0 && pkm.Format == 2 && pkm.Met_Location != 126)
|
||||
continue;
|
||||
|
|
@ -995,6 +1000,7 @@ private static IEnumerable<EncounterTrade> GetValidEncounterTrades(PKM pkm, Game
|
|||
}
|
||||
private static bool IsEncounterTradeValid(PKM pkm, EncounterTrade z, int lvl)
|
||||
{
|
||||
if (z.IVs != null)
|
||||
for (int i = 0; i < 6; i++)
|
||||
if (z.IVs[i] != -1 && z.IVs[i] != pkm.IVs[i])
|
||||
return false;
|
||||
|
|
@ -1047,6 +1053,11 @@ private static bool IsEncounterTradeValid(PKM pkm, EncounterTrade z, int lvl)
|
|||
// if (z.Ability == 4 ^ pkm.AbilityNumber == 4) // defer to Ability
|
||||
// countinue;
|
||||
|
||||
if (z.Contest != null)
|
||||
for (int i = 0; i < 6; i++)
|
||||
if (z.Contest[i] > pkm.Contest[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
432
PKHeX.Core/PKM/Editing/CommonEdits.cs
Normal file
432
PKHeX.Core/PKM/Editing/CommonEdits.cs
Normal file
|
|
@ -0,0 +1,432 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension logic for modifying <see cref="PKM"/> data.
|
||||
/// </summary>
|
||||
public static class CommonEdits
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM.Nickname"/> to the provided value.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="nick"><see cref="PKM.Nickname"/> to set. If no nickname is provided, the <see cref="PKM.Nickname"/> is set to the default value for its current language and format.</param>
|
||||
public static void SetNickname(this PKM pk, string nick = null)
|
||||
{
|
||||
if (nick != null)
|
||||
{
|
||||
pk.IsNicknamed = true;
|
||||
pk.Nickname = nick;
|
||||
}
|
||||
else
|
||||
{
|
||||
pk.IsNicknamed = false;
|
||||
pk.Nickname = PKX.GetSpeciesNameGeneration(pk.Species, pk.Language, pk.Format);
|
||||
if (pk is PK1 pk1) pk1.SetNotNicknamed();
|
||||
if (pk is PK2 pk2) pk2.SetNotNicknamed();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM.AltForm"/> value, with special consideration for <see cref="PKM.Format"/> values which derive the <see cref="PKM.AltForm"/> value.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="form">Desired <see cref="PKM.AltForm"/> value to set.</param>
|
||||
public static void SetAltForm(this PKM pk, int form)
|
||||
{
|
||||
switch (pk.Format)
|
||||
{
|
||||
case 2:
|
||||
while (pk.AltForm != form)
|
||||
pk.SetRandomIVs();
|
||||
break;
|
||||
case 3:
|
||||
pk.SetPIDUnown3(form);
|
||||
break;
|
||||
default:
|
||||
pk.AltForm = form;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM.Ability"/> value by sanity checking the provided <see cref="PKM.Ability"/> against the possible pool of abilities.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="abil">Desired <see cref="PKM.Ability"/> to set.</param>
|
||||
public static void SetAbility(this PKM pk, int abil)
|
||||
{
|
||||
var abilities = pk.PersonalInfo.Abilities;
|
||||
int abilIndex = Array.IndexOf(abilities, abil);
|
||||
abilIndex = Math.Max(0, abilIndex);
|
||||
|
||||
if (pk is PK5 pk5 && abilIndex == 2)
|
||||
pk5.HiddenAbility = true;
|
||||
else if (pk.Format <= 5)
|
||||
pk.PID = PKX.GetRandomPID(pk.Species, pk.Gender, pk.Version, pk.Nature, pk.Format, (uint)(abilIndex * 0x10001));
|
||||
pk.RefreshAbility(abilIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a Random <see cref="PKM.EncryptionConstant"/> value. The <see cref="PKM.EncryptionConstant"/> is not updated if the value should match the <see cref="PKM.PID"/> instead.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
public static void SetRandomEC(this PKM pk)
|
||||
{
|
||||
int gen = pk.GenNumber;
|
||||
if (gen < 6 && gen > 2)
|
||||
pk.EncryptionConstant = pk.PID;
|
||||
else
|
||||
pk.EncryptionConstant = Util.Rand32();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM.IsShiny"/> derived value.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="shiny">Desired <see cref="PKM.IsShiny"/> state to set.</param>
|
||||
/// <returns></returns>
|
||||
public static bool SetIsShiny(this PKM pk, bool shiny) => shiny ? pk.SetShiny() : pk.SetUnshiny();
|
||||
|
||||
/// <summary>
|
||||
/// Makes a <see cref="PKM"/> shiny.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <returns>Returns <see cref="bool.True"/> if the <see cref="PKM"/> data was modified.</returns>
|
||||
public static bool SetShiny(this PKM pk)
|
||||
{
|
||||
if (pk.IsShiny)
|
||||
return false;
|
||||
|
||||
if (pk.Format > 2)
|
||||
pk.SetShinyPID();
|
||||
else
|
||||
pk.SetShinyIVs();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes a <see cref="PKM"/> not-shiny.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <returns>Returns <see cref="bool.True"/> if the <see cref="PKM"/> data was modified.</returns>
|
||||
public static bool SetUnshiny(this PKM pk)
|
||||
{
|
||||
if (!pk.IsShiny)
|
||||
return false;
|
||||
|
||||
pk.SetPIDGender(pk.Gender);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM.Nature"/> value, with special consideration for the <see cref="PKM.Format"/> values which derive the <see cref="PKM.Nature"/> value.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="nature">Desired <see cref="PKM.Nature"/> value to set.</param>
|
||||
public static void SetNature(this PKM pk, int nature)
|
||||
{
|
||||
if (pk.Format <= 4)
|
||||
pk.SetPIDNature(Math.Max(0, nature));
|
||||
else
|
||||
pk.Nature = Math.Max(0, nature);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM.Nature"/> value, with special consideration for the <see cref="PKM.Format"/> values which derive the <see cref="PKM.Nature"/> value.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="nature">Desired <see cref="PKM.Nature"/> value to set.</param>
|
||||
public static void SetNature(this PKM pk, Nature nature) => pk.SetNature((int) nature);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the individual PP Up count values depending if a Move is present in the moveslot or not.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="Moves"><see cref="PKM.Moves"/> to use (if already known). Will fetch the current <see cref="PKM.Moves"/> if not provided.</param>
|
||||
public static void SetPPUps(this PKM pk, int[] Moves = null)
|
||||
{
|
||||
if (Moves == null)
|
||||
Moves = pk.Moves;
|
||||
|
||||
pk.Move1_PP = pk.GetMovePP(Moves[0], pk.Move1_PPUps = GetPPUpCount(Moves[0]));
|
||||
pk.Move2_PP = pk.GetMovePP(Moves[1], pk.Move2_PPUps = GetPPUpCount(Moves[1]));
|
||||
pk.Move3_PP = pk.GetMovePP(Moves[2], pk.Move3_PPUps = GetPPUpCount(Moves[2]));
|
||||
pk.Move4_PP = pk.GetMovePP(Moves[3], pk.Move4_PPUps = GetPPUpCount(Moves[3]));
|
||||
|
||||
int GetPPUpCount(int moveID) => moveID > 0 ? 3 : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM.Gender"/> value, with special consideration for the <see cref="PKM.Format"/> values which derive the <see cref="PKM.Gender"/> value.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="gender">Desired <see cref="PKM.Gender"/> value to set.</param>
|
||||
public static void SetGender(this PKM pk, string gender)
|
||||
{
|
||||
if (gender == null)
|
||||
return;
|
||||
|
||||
int Gender = PKX.GetGenderFromString(gender);
|
||||
pk.SetGender(Gender);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM.Gender"/> value, with special consideration for the <see cref="PKM.Format"/> values which derive the <see cref="PKM.Gender"/> value.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="gender">Desired <see cref="PKM.Gender"/> value to set.</param>
|
||||
public static void SetGender(this PKM pk, int gender)
|
||||
{
|
||||
gender = Math.Min(2, Math.Max(0, gender));
|
||||
if (pk.Format <= 2)
|
||||
pk.SetATKIVGender(gender);
|
||||
else if (pk.Format <= 4)
|
||||
pk.SetPIDGender(gender);
|
||||
else
|
||||
pk.Gender = gender;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets <see cref="PKM.HyperTrainFlags"/> to valid values which may best enhance the <see cref="PKM"/> stats.
|
||||
/// </summary>
|
||||
/// <param name="pkm"></param>
|
||||
/// <param name="IVs"><see cref="PKM.IVs"/> to use (if already known). Will fetch the current <see cref="PKM.IVs"/> if not provided.</param>
|
||||
public static void SetSuggestedHyperTrainingData(this PKM pkm, int[] IVs = null)
|
||||
{
|
||||
if (pkm.Format < 7)
|
||||
return;
|
||||
if (pkm.CurrentLevel < 100)
|
||||
{
|
||||
pkm.HyperTrainFlags = 0;
|
||||
return;
|
||||
}
|
||||
if (IVs == null)
|
||||
IVs = pkm.IVs;
|
||||
|
||||
pkm.HT_HP = IVs[0] != 31;
|
||||
pkm.HT_ATK = IVs[1] != 31 && IVs[1] > 2;
|
||||
pkm.HT_DEF = IVs[2] != 31;
|
||||
pkm.HT_SPE = IVs[3] != 31 && IVs[3] > 2;
|
||||
pkm.HT_SPA = IVs[4] != 31;
|
||||
pkm.HT_SPD = IVs[5] != 31;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches <see cref="PKM.RelearnMoves"/> based on the provided <see cref="LegalityAnalysis"/>.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="legal"><see cref="LegalityAnalysis"/> which contains parsed information pertaining to legality.</param>
|
||||
/// <returns><see cref="PKM.RelearnMoves"/> best suited for the current <see cref="PKM"/> data.</returns>
|
||||
public static int[] GetSuggestedRelearnMoves(this PKM pk, LegalityAnalysis legal)
|
||||
{
|
||||
int[] m = legal.GetSuggestedRelearn();
|
||||
if (!m.All(z => z == 0))
|
||||
return m;
|
||||
|
||||
if (pk.WasEgg || pk.WasEvent || pk.WasEventEgg || pk.WasLink)
|
||||
return m;
|
||||
|
||||
var encounter = legal.GetSuggestedMetInfo();
|
||||
if (encounter != null)
|
||||
m = encounter.Relearn;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sanity checks the provided <see cref="PKM.Gender"/> value, and returns a sane value.
|
||||
/// </summary>
|
||||
/// <param name="pkm"></param>
|
||||
/// <param name="cg">Current <see cref="PKM.Gender"/> preference</param>
|
||||
/// <returns>Most-legal <see cref="PKM.Gender"/> value</returns>
|
||||
public static int GetSaneGender(this PKM pkm, int cg)
|
||||
{
|
||||
int gt = pkm.PersonalInfo.Gender;
|
||||
switch (gt)
|
||||
{
|
||||
case 255: return 2; // Genderless
|
||||
case 254: return 1; // Female-Only
|
||||
case 0: return 0; // Male-Only
|
||||
}
|
||||
if (cg == 2 || pkm.GenNumber < 6)
|
||||
return (byte)pkm.PID <= gt ? 1 : 0;
|
||||
return cg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies <see cref="ShowdownSet"/> details to the <see cref="PKM"/>.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="Set"><see cref="ShowdownSet"/> details to copy from.</param>
|
||||
public static void ApplySetDetails(this PKM pk, ShowdownSet Set)
|
||||
{
|
||||
pk.Species = Set.Species;
|
||||
pk.Moves = Set.Moves;
|
||||
pk.HeldItem = Set.HeldItem < 0 ? 0 : Set.HeldItem;
|
||||
pk.CurrentLevel = Set.Level;
|
||||
pk.CurrentFriendship = Set.Friendship;
|
||||
pk.IVs = Set.IVs;
|
||||
pk.EVs = Set.EVs;
|
||||
|
||||
pk.ApplyMarkings();
|
||||
pk.SetSuggestedHyperTrainingData(Set.IVs);
|
||||
|
||||
pk.SetNickname(Set.Nickname);
|
||||
pk.SetGender(Set.Gender);
|
||||
pk.SetAltForm(Set.FormIndex);
|
||||
pk.SetPPUps(Set.Moves);
|
||||
pk.SetAbility(Set.Ability);
|
||||
pk.SetNature(Set.Nature);
|
||||
pk.SetIsShiny(Set.Shiny);
|
||||
pk.SetRandomEC();
|
||||
|
||||
var legal = new LegalityAnalysis(pk);
|
||||
if (legal.Info.Relearn.Any(z => !z.Valid))
|
||||
pk.RelearnMoves = pk.GetSuggestedRelearnMoves(legal);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets all Memory related data to the default value (zero).
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
public static void ClearMemories(this PKM pk)
|
||||
{
|
||||
pk.OT_Memory = pk.OT_Affection = pk.OT_Feeling = pk.OT_Intensity = pk.OT_TextVar =
|
||||
pk.HT_Memory = pk.HT_Affection = pk.HT_Feeling = pk.HT_Intensity = pk.HT_TextVar = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM.Markings"/> to indicate flawless (or near-flawless) <see cref="PKM.IVs"/>.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="IVs"><see cref="PKM.IVs"/> to use (if already known). Will fetch the current <see cref="PKM.IVs"/> if not provided.</param>
|
||||
public static void ApplyMarkings(this PKM pk, int[] IVs = null)
|
||||
{
|
||||
if (pk.Format <= 3)
|
||||
return; // no markings (gen3 only has 4; can't mark stats intelligently
|
||||
|
||||
if (IVs == null)
|
||||
IVs = pk.IVs;
|
||||
|
||||
var remapper = pk.Format < 7 ? (Func<int, int>)GetSimpleMarking : GetComplexMarking;
|
||||
pk.Markings = IVs.Select(remapper).ToArray();
|
||||
|
||||
int GetSimpleMarking(int val) => val == 31 ? 1 : 0;
|
||||
int GetComplexMarking(int val)
|
||||
{
|
||||
if (val == 31 || val == 1)
|
||||
return 1;
|
||||
if (val == 30 || val == 0)
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets one of the <see cref="PKM.EVs"/> based on its index within the array.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="index">Index to set to</param>
|
||||
/// <param name="value">Value to set</param>
|
||||
public static void SetEV(this PKM pk, int index, int value)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: pk.EV_HP = value; break;
|
||||
case 1: pk.EV_ATK = value; break;
|
||||
case 2: pk.EV_DEF = value; break;
|
||||
case 3: pk.EV_SPE = value; break;
|
||||
case 4: pk.EV_SPA = value; break;
|
||||
case 5: pk.EV_SPD = value; break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets one of the <see cref="PKM.IVs"/> based on its index within the array.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="index">Index to set to</param>
|
||||
/// <param name="value">Value to set</param>
|
||||
public static void SetIV(this PKM pk, int index, int value)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: pk.IV_HP = value; break;
|
||||
case 1: pk.IV_ATK = value; break;
|
||||
case 2: pk.IV_DEF = value; break;
|
||||
case 3: pk.IV_SPE = value; break;
|
||||
case 4: pk.IV_SPA = value; break;
|
||||
case 5: pk.IV_SPD = value; break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the <see cref="PKM.IV_ATK"/> for a Generation 1/2 format <see cref="PKM"/>.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="gender">Desired <see cref="PKM.Gender"/>.</param>
|
||||
public static void SetATKIVGender(this PKM pk, int gender)
|
||||
{
|
||||
do { pk.IV_ATK = (int)(Util.Rand32() & pk.MaxIV); }
|
||||
while (pk.Gender != gender);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the highest value the provided <see cref="PKM.EVs"/> index can be while considering others.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="index">Index to fetch for</param>
|
||||
/// <returns>Highest value the value can be.</returns>
|
||||
public static int GetMaximumEV(this PKM pk, int index)
|
||||
{
|
||||
if (pk.Format < 3)
|
||||
return ushort.MaxValue;
|
||||
|
||||
var EVs = pk.EVs;
|
||||
EVs[index] = 0;
|
||||
var sum = EVs.Sum();
|
||||
int remaining = 510 - sum;
|
||||
var newEV = Math.Min(Math.Max(remaining, 0), 252);
|
||||
return newEV;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetches the highest value the provided <see cref="PKM.IVs"/>.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="index">Index to fetch for</param>
|
||||
/// <param name="Allow30">Causes the returned value to be dropped down -1 if the value is already at a maxmimum.</param>
|
||||
/// <returns>Highest value the value can be.</returns>
|
||||
public static int GetMaximumIV(this PKM pk, int index, bool Allow30 = false)
|
||||
{
|
||||
if (pk.IVs[index] == pk.MaxIV && Allow30)
|
||||
return pk.MaxIV - 1;
|
||||
return pk.MaxIV;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM.IVs"/> to match a provided <see cref="hptype"/>.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="hptype">Desired Hidden Power typing.</param>
|
||||
public static void SetHiddenPower(this PKM pk, int hptype)
|
||||
{
|
||||
var IVs = pk.IVs;
|
||||
HiddenPower.SetIVsForType(hptype, pk.IVs);
|
||||
pk.IVs = IVs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="PKM.IVs"/> to match a provided <see cref="hptype"/>.
|
||||
/// </summary>
|
||||
/// <param name="pk">Pokémon to modify.</param>
|
||||
/// <param name="hptype">Desired Hidden Power typing.</param>
|
||||
public static void SetHiddenPower(this PKM pk, MoveType hptype) => pk.SetHiddenPower((int) hptype);
|
||||
}
|
||||
}
|
||||
76
PKHeX.Core/PKM/Editing/HiddenPower.cs
Normal file
76
PKHeX.Core/PKM/Editing/HiddenPower.cs
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
public static class HiddenPower
|
||||
{
|
||||
public static int GetType(IReadOnlyList<int> IVs)
|
||||
{
|
||||
int hp = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
hp |= (IVs[i] & 1) << i;
|
||||
hp *= 0xF;
|
||||
hp /= 0x3F;
|
||||
return hp;
|
||||
}
|
||||
public static bool SetIVsForType(int hpVal, int[] IVs)
|
||||
{
|
||||
if (IVs.All(z => z == 31))
|
||||
{
|
||||
PKX.SetHPIVs(hpVal, IVs); // Get IVs
|
||||
return true;
|
||||
}
|
||||
|
||||
int current = GetType(IVs);
|
||||
if (current == hpVal)
|
||||
return true; // no mods necessary
|
||||
|
||||
// Required HP type doesn't match IVs. Make currently-flawless IVs flawed.
|
||||
int[] best = GetSuggestedHiddenPowerIVs(hpVal, IVs);
|
||||
if (best == null)
|
||||
return false; // can't force hidden power?
|
||||
|
||||
// set IVs back to array
|
||||
for (int i = 0; i < IVs.Length; i++)
|
||||
IVs[i] = best[i];
|
||||
return true;
|
||||
}
|
||||
private static int[] GetSuggestedHiddenPowerIVs(int hpVal, int[] IVs)
|
||||
{
|
||||
var flawless = IVs.Select((v, i) => v == 31 ? i : -1).Where(v => v != -1).ToArray();
|
||||
var permutations = GetPermutations(flawless, flawless.Length);
|
||||
int flawedCount = 0;
|
||||
int[] best = null;
|
||||
foreach (var permute in permutations)
|
||||
{
|
||||
var ivs = (int[])IVs.Clone();
|
||||
foreach (var item in permute)
|
||||
{
|
||||
ivs[item] ^= 1;
|
||||
if (hpVal != GetType(ivs))
|
||||
continue;
|
||||
|
||||
int ct = ivs.Count(z => z == 31);
|
||||
if (ct <= flawedCount)
|
||||
break; // any further flaws are always worse
|
||||
|
||||
flawedCount = ct;
|
||||
best = ivs;
|
||||
break; // any further flaws are always worse
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
private static IEnumerable<IEnumerable<T>> GetPermutations<T>(IList<T> list, int length)
|
||||
{
|
||||
// https://stackoverflow.com/a/10630026
|
||||
if (length == 1)
|
||||
return list.Select(t => new[] { t });
|
||||
|
||||
return GetPermutations(list, length - 1)
|
||||
.SelectMany(t => list.Where(e => !t.Contains(e)),
|
||||
(t1, t2) => t1.Concat(new[] { t2 }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -400,6 +400,16 @@ public int[] RelearnMoves
|
|||
if (value.Length > 3) RelearnMove4 = value[3];
|
||||
}
|
||||
}
|
||||
public int[] Contest
|
||||
{
|
||||
get => new[] { CNT_Cool, CNT_Beauty, CNT_Cute, CNT_Smart, CNT_Tough, CNT_Sheen };
|
||||
set
|
||||
{
|
||||
if (value?.Length != 6) return;
|
||||
CNT_Cool = value[0]; CNT_Beauty = value[1]; CNT_Cute = value[2];
|
||||
CNT_Smart = value[3]; CNT_Tough = value[4]; CNT_Sheen = value[5];
|
||||
}
|
||||
}
|
||||
public int PIDAbility
|
||||
{
|
||||
get
|
||||
|
|
|
|||
|
|
@ -217,10 +217,7 @@ private IEnumerable<string> GetStringMoves()
|
|||
{
|
||||
var str = $"- {moves[move]}";
|
||||
if (move == 237) // Hidden Power
|
||||
{
|
||||
int hp = GetHiddenPowerType(IVs);
|
||||
str += $" [{hptypes[hp]}]";
|
||||
}
|
||||
str += $" [{hptypes[HiddenPower.GetType(IVs)]}]";
|
||||
yield return str;
|
||||
}
|
||||
}
|
||||
|
|
@ -354,7 +351,7 @@ private string ParseLineMove(string line)
|
|||
|
||||
if (IVs.Any(z => z != 31))
|
||||
{
|
||||
if (!SetIVsForHiddenPower(hpVal, IVs))
|
||||
if (!HiddenPower.SetIVsForType(hpVal, IVs))
|
||||
InvalidLines.Add($"Invalid IVs for Hidden Power Type: {type}");
|
||||
}
|
||||
else if (hpVal >= 0)
|
||||
|
|
@ -365,73 +362,6 @@ private string ParseLineMove(string line)
|
|||
moveString = "Hidden Power";
|
||||
return moveString;
|
||||
}
|
||||
private static int GetHiddenPowerType(IReadOnlyList<int> IVs)
|
||||
{
|
||||
int hp = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
hp |= (IVs[i] & 1) << i;
|
||||
hp *= 0xF;
|
||||
hp /= 0x3F;
|
||||
return hp;
|
||||
}
|
||||
private static bool SetIVsForHiddenPower(int hpVal, int[] IVs)
|
||||
{
|
||||
if (IVs.All(z => z == 31))
|
||||
{
|
||||
PKX.SetHPIVs(hpVal, IVs); // Get IVs
|
||||
return true;
|
||||
}
|
||||
|
||||
int current = GetHiddenPowerType(IVs);
|
||||
if (current == hpVal)
|
||||
return true; // no mods necessary
|
||||
|
||||
// Required HP type doesn't match IVs. Make currently-flawless IVs flawed.
|
||||
int[] best = GetSuggestedHiddenPowerIVs(hpVal, IVs);
|
||||
if (best == null)
|
||||
return false; // can't force hidden power?
|
||||
|
||||
// set IVs back to array
|
||||
for (int i = 0; i < IVs.Length; i++)
|
||||
IVs[i] = best[i];
|
||||
return true;
|
||||
}
|
||||
private static int[] GetSuggestedHiddenPowerIVs(int hpVal, int[] IVs)
|
||||
{
|
||||
var flawless = IVs.Select((v, i) => v == 31 ? i : -1).Where(v => v != -1).ToArray();
|
||||
var permutations = GetPermutations(flawless, flawless.Length);
|
||||
int flawedCount = 0;
|
||||
int[] best = null;
|
||||
foreach (var permute in permutations)
|
||||
{
|
||||
var ivs = (int[])IVs.Clone();
|
||||
foreach (var item in permute)
|
||||
{
|
||||
ivs[item] ^= 1;
|
||||
if (hpVal != GetHiddenPowerType(ivs))
|
||||
continue;
|
||||
|
||||
int ct = ivs.Count(z => z == 31);
|
||||
if (ct <= flawedCount)
|
||||
break; // any further flaws are always worse
|
||||
|
||||
flawedCount = ct;
|
||||
best = ivs;
|
||||
break; // any further flaws are always worse
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
private static IEnumerable<IEnumerable<T>> GetPermutations<T>(IList<T> list, int length)
|
||||
{
|
||||
// https://stackoverflow.com/a/10630026
|
||||
if (length == 1)
|
||||
return list.Select(t => new[] { t });
|
||||
|
||||
return GetPermutations(list, length - 1)
|
||||
.SelectMany(t => list.Where(e => !t.Contains(e)),
|
||||
(t1, t2) => t1.Concat(new[] { t2 }));
|
||||
}
|
||||
private void ParseLineEVs(string line)
|
||||
{
|
||||
string[] evlist = SplitLineStats(line);
|
||||
|
|
@ -563,41 +493,5 @@ private static string ReplaceAll(string original, string to, params string[] toB
|
|||
{
|
||||
return toBeReplaced.Aggregate(original, (current, v) => current.Replace(v, to));
|
||||
}
|
||||
|
||||
public void ApplyToPKM(PKM pkm)
|
||||
{
|
||||
if (Species < 0)
|
||||
return;
|
||||
pkm.Species = Species;
|
||||
|
||||
if (Nickname != null && Nickname.Length <= pkm.NickLength)
|
||||
pkm.Nickname = Nickname;
|
||||
else
|
||||
pkm.Nickname = PKX.GetSpeciesName(pkm.Species, pkm.Language);
|
||||
|
||||
int gender = PKX.GetGenderFromString(Gender);
|
||||
pkm.Gender = Math.Max(0, gender);
|
||||
|
||||
var list = PKX.GetFormList(pkm.Species, types, forms, genders);
|
||||
int formnum = Array.IndexOf(list, Form);
|
||||
pkm.AltForm = Math.Max(0, formnum);
|
||||
|
||||
var abils = pkm.PersonalInfo.Abilities;
|
||||
int index = Array.IndexOf(abils, Ability);
|
||||
pkm.RefreshAbility(Math.Max(0, Math.Min(2, index)));
|
||||
|
||||
if (Shiny && !pkm.IsShiny)
|
||||
pkm.SetShinyPID();
|
||||
else if (!Shiny && pkm.IsShiny)
|
||||
pkm.PID = Util.Rand32();
|
||||
|
||||
pkm.CurrentLevel = Level;
|
||||
pkm.HeldItem = Math.Max(0, HeldItem);
|
||||
pkm.CurrentFriendship = Friendship;
|
||||
pkm.Nature = Nature;
|
||||
pkm.EVs = EVs;
|
||||
pkm.IVs = IVs;
|
||||
pkm.Moves = Moves;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,16 @@ public PKMEditor()
|
|||
TB_OT.Font = (Font)TB_Nickname.Font.Clone();
|
||||
TB_OTt2.Font = (Font)TB_Nickname.Font.Clone();
|
||||
|
||||
// Commonly reused Control arrays
|
||||
Moves = new[] { CB_Move1, CB_Move2, CB_Move3, CB_Move4 };
|
||||
Relearn = new[] { CB_RelearnMove1, CB_RelearnMove2, CB_RelearnMove3, CB_RelearnMove4 };
|
||||
PPUps = new[] { CB_PPu1, CB_PPu2, CB_PPu3, CB_PPu4 };
|
||||
MovePP = new[] { TB_PP1, TB_PP2, TB_PP3, TB_PP4 };
|
||||
ValidationRequired = Moves.Concat(Relearn).Concat(new[]
|
||||
{
|
||||
CB_Species, CB_Nature, CB_HeldItem, CB_Ability, // Main Tab
|
||||
CB_MetLocation, CB_EggLocation, CB_Ball, // Met Tab
|
||||
}).ToArray();
|
||||
relearnPB = new[] { PB_WarnRelearn1, PB_WarnRelearn2, PB_WarnRelearn3, PB_WarnRelearn4 };
|
||||
movePB = new[] { PB_WarnMove1, PB_WarnMove2, PB_WarnMove3, PB_WarnMove4 };
|
||||
foreach (var c in WinFormsUtil.GetAllControlsOfType(this, typeof(ComboBox)))
|
||||
|
|
@ -33,6 +43,7 @@ public PKMEditor()
|
|||
|
||||
Stats.SetMainEditor(this);
|
||||
LoadShowdownSet = LoadShowdownSetDefault;
|
||||
|
||||
}
|
||||
|
||||
private void UpdateStats() => Stats.UpdateStats();
|
||||
|
|
@ -75,6 +86,9 @@ private void SavePartyStats(PKM pk)
|
|||
public bool PKMIsUnsaved => FieldsInitialized && FieldsLoaded && LastData != null && LastData.Any(b => b != 0) && !LastData.SequenceEqual(CurrentPKM.Data);
|
||||
public bool IsEmptyOrEgg => CHK_IsEgg.Checked || CB_Species.SelectedIndex == 0;
|
||||
|
||||
private readonly ComboBox[] Moves, Relearn, ValidationRequired, PPUps;
|
||||
private readonly MaskedTextBox[] MovePP;
|
||||
|
||||
private bool forceValidation;
|
||||
public PKM PreparePKM(bool click = true)
|
||||
{
|
||||
|
|
@ -92,14 +106,8 @@ public bool VerifiedPKM()
|
|||
if (ModifierKeys == (Keys.Control | Keys.Shift | Keys.Alt))
|
||||
return true; // Override
|
||||
// Make sure the PKX Fields are filled out properly (color check)
|
||||
ComboBox[] cba = {
|
||||
CB_Species, CB_Nature, CB_HeldItem, CB_Ability, // Main Tab
|
||||
CB_MetLocation, CB_EggLocation, CB_Ball, // Met Tab
|
||||
CB_Move1, CB_Move2, CB_Move3, CB_Move4, // Moves
|
||||
CB_RelearnMove1, CB_RelearnMove2, CB_RelearnMove3, CB_RelearnMove4 // Moves
|
||||
};
|
||||
|
||||
ComboBox cb = cba.FirstOrDefault(c => c.BackColor == Color.DarkSalmon && c.Items.Count != 0);
|
||||
var cb = ValidationRequired.FirstOrDefault(c => c.BackColor == Color.DarkSalmon && c.Items.Count != 0);
|
||||
if (cb != null)
|
||||
{
|
||||
Control c = cb.Parent; while (!(c is TabPage)) c = c.Parent;
|
||||
|
|
@ -232,6 +240,7 @@ public void UpdateLegality(LegalityAnalysis la = null, bool skipMoveRepop = fals
|
|||
{
|
||||
PB_WarnMove1.Visible = PB_WarnMove2.Visible = PB_WarnMove3.Visible = PB_WarnMove4.Visible =
|
||||
PB_WarnRelearn1.Visible = PB_WarnRelearn2.Visible = PB_WarnRelearn3.Visible = PB_WarnRelearn4.Visible = false;
|
||||
LegalityChanged?.Invoke(Legality.Valid, null);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -248,10 +257,9 @@ public void UpdateLegality(LegalityAnalysis la = null, bool skipMoveRepop = fals
|
|||
// Resort moves
|
||||
bool tmp = FieldsLoaded;
|
||||
FieldsLoaded = false;
|
||||
var cb = new[] { CB_Move1, CB_Move2, CB_Move3, CB_Move4 };
|
||||
var moves = Legality.AllSuggestedMovesAndRelearn;
|
||||
var moveList = GameInfo.MoveDataSource.OrderByDescending(m => moves.Contains(m.Value)).ToList();
|
||||
foreach (ComboBox c in cb)
|
||||
foreach (var c in Moves)
|
||||
{
|
||||
var index = WinFormsUtil.GetIndex(c);
|
||||
c.DataSource = new BindingSource(moveList, null);
|
||||
|
|
@ -465,8 +473,7 @@ private static bool GetMarkingColor(int markval, out Color c)
|
|||
private void UpdateGender()
|
||||
{
|
||||
int cg = PKX.GetGenderFromString(Label_Gender.Text);
|
||||
int Gender = GetSaneGender(pkm, cg);
|
||||
|
||||
int Gender = pkm.GetSaneGender(cg);
|
||||
Label_Gender.Text = gendersymbols[Gender];
|
||||
Label_Gender.ForeColor = GetGenderColor(Gender);
|
||||
}
|
||||
|
|
@ -660,25 +667,16 @@ private bool SetSuggestedMoves(bool random = false, bool silent = false)
|
|||
return false;
|
||||
}
|
||||
|
||||
CB_Move1.SelectedValue = m[0];
|
||||
CB_Move2.SelectedValue = m[1];
|
||||
CB_Move3.SelectedValue = m[2];
|
||||
CB_Move4.SelectedValue = m[3];
|
||||
pkm.Moves = m;
|
||||
pkm.SetPPUps(m);
|
||||
LoadMoves(pkm);
|
||||
return true;
|
||||
}
|
||||
private bool SetSuggestedRelearnMoves(bool silent = false)
|
||||
{
|
||||
if (pkm.Format < 6)
|
||||
return false;
|
||||
|
||||
int[] m = Legality.GetSuggestedRelearn();
|
||||
if (m.All(z => z == 0))
|
||||
if (!pkm.WasEgg && !pkm.WasEvent && !pkm.WasEventEgg && !pkm.WasLink)
|
||||
{
|
||||
var encounter = Legality.GetSuggestedMetInfo();
|
||||
if (encounter != null)
|
||||
m = encounter.Relearn;
|
||||
}
|
||||
int[] m = pkm.GetSuggestedRelearnMoves(Legality);
|
||||
|
||||
if (pkm.RelearnMoves.SequenceEqual(m))
|
||||
return false;
|
||||
|
|
@ -720,17 +718,7 @@ private bool SetSuggestedMetLocation(bool silent = false)
|
|||
|
||||
if (!silent)
|
||||
{
|
||||
var suggestion = new List<string> { "Suggested:" };
|
||||
if (pkm.Format >= 3)
|
||||
{
|
||||
var met_list = GameInfo.GetLocationList((GameVersion)pkm.Version, pkm.Format, egg: false);
|
||||
var locstr = met_list.FirstOrDefault(loc => loc.Value == location).Text;
|
||||
suggestion.Add($"Met Location: {locstr}");
|
||||
suggestion.Add($"Met Level: {level}");
|
||||
}
|
||||
if (pkm.CurrentLevel < minlvl)
|
||||
suggestion.Add($"Current Level: {minlvl}");
|
||||
|
||||
List<string> suggestion = GetSuggestionMessage(pkm, level, location, minlvl);
|
||||
if (suggestion.Count == 1) // no suggestion
|
||||
return false;
|
||||
|
||||
|
|
@ -910,23 +898,21 @@ private void UpdateHaXForm(object sender, EventArgs e)
|
|||
}
|
||||
private void UpdatePP(object sender, EventArgs e)
|
||||
{
|
||||
ComboBox[] cbs = { CB_Move1, CB_Move2, CB_Move3, CB_Move4 };
|
||||
ComboBox[] pps = { CB_PPu1, CB_PPu2, CB_PPu3, CB_PPu4 };
|
||||
MaskedTextBox[] tbs = { TB_PP1, TB_PP2, TB_PP3, TB_PP4 };
|
||||
int index = Array.IndexOf(cbs, sender);
|
||||
if (!(sender is ComboBox cb))
|
||||
return;
|
||||
int index = Array.IndexOf(Moves, cb);
|
||||
if (index < 0)
|
||||
index = Array.IndexOf(pps, sender);
|
||||
index = Array.IndexOf(PPUps, cb);
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
int move = WinFormsUtil.GetIndex(cbs[index]);
|
||||
int pp = pps[index].SelectedIndex;
|
||||
if (move == 0 && pp != 0)
|
||||
{
|
||||
pps[index].SelectedIndex = 0;
|
||||
return; // recursively triggers
|
||||
}
|
||||
tbs[index].Text = pkm.GetMovePP(move, pp).ToString();
|
||||
int move = WinFormsUtil.GetIndex(Moves[index]);
|
||||
var ppctrl = PPUps[index];
|
||||
int ppups = ppctrl.SelectedIndex;
|
||||
if (move <= 0)
|
||||
ppctrl.SelectedIndex = 0;
|
||||
else
|
||||
MovePP[index].Text = pkm.GetMovePP(move, ppups).ToString();
|
||||
}
|
||||
private void UpdatePKRSstrain(object sender, EventArgs e)
|
||||
{
|
||||
|
|
@ -1104,13 +1090,13 @@ private void UpdateOriginGame(object sender, EventArgs e)
|
|||
}
|
||||
private void UpdateExtraByteValue(object sender, EventArgs e)
|
||||
{
|
||||
if (CB_ExtraBytes.Items.Count == 0)
|
||||
if (CB_ExtraBytes.Items.Count == 0 || !(sender is MaskedTextBox mtb))
|
||||
return;
|
||||
// Changed Extra Byte's Value
|
||||
if (Util.ToInt32(((MaskedTextBox)sender).Text) > byte.MaxValue)
|
||||
((MaskedTextBox)sender).Text = "255";
|
||||
if (Util.ToInt32(mtb.Text) > byte.MaxValue)
|
||||
mtb.Text = "255";
|
||||
|
||||
int value = Util.ToInt32(TB_ExtraByte.Text);
|
||||
int value = Util.ToInt32(mtb.Text);
|
||||
int offset = Convert.ToInt32(CB_ExtraBytes.Text, 16);
|
||||
pkm.Data[offset] = (byte)value;
|
||||
}
|
||||
|
|
@ -1269,8 +1255,7 @@ private void UpdateIsEgg(object sender, EventArgs e)
|
|||
|
||||
// Wipe egg memories
|
||||
if (pkm.Format >= 6 && ModifyPKM)
|
||||
pkm.OT_Memory = pkm.OT_Affection = pkm.OT_Feeling = pkm.OT_Intensity = pkm.OT_TextVar =
|
||||
pkm.HT_Memory = pkm.HT_Affection = pkm.HT_Feeling = pkm.HT_Intensity = pkm.HT_TextVar = 0;
|
||||
pkm.ClearMemories();
|
||||
}
|
||||
else // Not Egg
|
||||
{
|
||||
|
|
@ -1467,12 +1452,12 @@ private void ValidateMove(object sender, EventArgs e)
|
|||
if (!FieldsLoaded)
|
||||
return;
|
||||
|
||||
if (new[] { CB_Move1, CB_Move2, CB_Move3, CB_Move4 }.Contains(sender)) // Move
|
||||
if (Moves.Contains(sender)) // Move
|
||||
UpdatePP(sender, e);
|
||||
|
||||
// Legality
|
||||
pkm.Moves = new[] { CB_Move1, CB_Move2, CB_Move3, CB_Move4 }.Select(WinFormsUtil.GetIndex).ToArray();
|
||||
pkm.RelearnMoves = new[] { CB_RelearnMove1, CB_RelearnMove2, CB_RelearnMove3, CB_RelearnMove4 }.Select(WinFormsUtil.GetIndex).ToArray();
|
||||
pkm.Moves = Moves.Select(WinFormsUtil.GetIndex).ToArray();
|
||||
pkm.RelearnMoves = Relearn.Select(WinFormsUtil.GetIndex).ToArray();
|
||||
UpdateLegality(skipMoveRepop: true);
|
||||
}
|
||||
private void ValidateMovePaint(object sender, DrawItemEventArgs e)
|
||||
|
|
@ -1673,56 +1658,9 @@ public void EnableDragDrop(DragEventHandler enter, DragEventHandler drop)
|
|||
public Action<ShowdownSet> LoadShowdownSet;
|
||||
private void LoadShowdownSetDefault(ShowdownSet Set)
|
||||
{
|
||||
CB_Species.SelectedValue = Set.Species;
|
||||
CHK_Nicknamed.Checked = Set.Nickname != null;
|
||||
if (Set.Nickname != null)
|
||||
TB_Nickname.Text = Set.Nickname;
|
||||
if (Set.Gender != null)
|
||||
{
|
||||
int Gender = PKX.GetGenderFromString(Set.Gender);
|
||||
Label_Gender.Text = gendersymbols[Gender];
|
||||
Label_Gender.ForeColor = GetGenderColor(Gender);
|
||||
}
|
||||
|
||||
CB_Form.SelectedIndex = Math.Min(CB_Form.Items.Count - 1, Set.FormIndex);
|
||||
|
||||
// Set Ability and Moves
|
||||
int abil = Math.Max(0, Array.IndexOf(pkm.PersonalInfo.Abilities, Set.Ability));
|
||||
CB_Ability.SelectedIndex = Math.Min(CB_Ability.Items.Count - 1, abil);
|
||||
ComboBox[] m = { CB_Move1, CB_Move2, CB_Move3, CB_Move4 };
|
||||
ComboBox[] p = { CB_PPu1, CB_PPu2, CB_PPu3, CB_PPu4 };
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m[i].SelectedValue = Set.Moves[i];
|
||||
p[i].SelectedIndex = Set.Moves[i] != 0 ? 3 : 0; // max PP
|
||||
}
|
||||
|
||||
// Set Item and Nature
|
||||
CB_HeldItem.SelectedValue = Set.HeldItem < 0 ? 0 : Set.HeldItem;
|
||||
CB_Nature.SelectedValue = Set.Nature < 0 ? 0 : Set.Nature;
|
||||
|
||||
// Set Level and Friendship
|
||||
TB_Level.Text = Set.Level.ToString();
|
||||
TB_Friendship.Text = Set.Friendship.ToString();
|
||||
SetSuggestedHyperTrainingData(pkm, Set.IVs);
|
||||
|
||||
// Set IVs
|
||||
Stats.LoadIVs(Set.IVs);
|
||||
Stats.LoadEVs(Set.EVs);
|
||||
|
||||
UpdateRandomEC(null, null);
|
||||
if (Set.Shiny && !pkm.IsShiny)
|
||||
UpdateShiny(true);
|
||||
else if (!Set.Shiny && pkm.IsShiny)
|
||||
UpdateRandomPID(BTN_RerollPID, null);
|
||||
else
|
||||
UpdateRandomPID(null, null);
|
||||
|
||||
pkm = PreparePKM();
|
||||
UpdateLegality();
|
||||
|
||||
if (Legality.Info.Relearn.Any(z => !z.Valid))
|
||||
SetSuggestedRelearnMoves(silent: true);
|
||||
var pk = PreparePKM();
|
||||
pk.ApplySetDetails(Set);
|
||||
PopulateFields(pk);
|
||||
}
|
||||
|
||||
public void ChangeLanguage(SaveFile sav, PKM pk)
|
||||
|
|
@ -1786,42 +1724,26 @@ private void PopulateFilteredDataSources(SaveFile SAV)
|
|||
|
||||
// Set the Move ComboBoxes too..
|
||||
GameInfo.MoveDataSource = (HaX ? GameInfo.HaXMoveDataSource : GameInfo.LegalMoveDataSource).Where(m => m.Value <= SAV.MaxMoveID).ToList(); // Filter Z-Moves if appropriate
|
||||
foreach (ComboBox cb in new[] { CB_Move1, CB_Move2, CB_Move3, CB_Move4, CB_RelearnMove1, CB_RelearnMove2, CB_RelearnMove3, CB_RelearnMove4 })
|
||||
foreach (var cb in Moves.Concat(Relearn))
|
||||
{
|
||||
cb.DisplayMember = "Text"; cb.ValueMember = "Value";
|
||||
cb.DataSource = new BindingSource(GameInfo.MoveDataSource, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetSaneGender(PKM pkm, int cg)
|
||||
private static List<string> GetSuggestionMessage(PKM pkm, int level, int location, int minlvl)
|
||||
{
|
||||
int gt = pkm.PersonalInfo.Gender;
|
||||
if (gt == 255) // Genderless
|
||||
return 2;
|
||||
if (gt == 254) // Female Only
|
||||
return 1;
|
||||
if (gt == 0) // Male Only
|
||||
return 0;
|
||||
if (cg == 2 || pkm.GenNumber < 6)
|
||||
return (byte)pkm.PID <= gt ? 1 : 0;
|
||||
return cg;
|
||||
}
|
||||
private static void SetSuggestedHyperTrainingData(PKM pkm, int[] IVs)
|
||||
{
|
||||
if (pkm.Format < 7)
|
||||
return;
|
||||
if (pkm.CurrentLevel < 100)
|
||||
var suggestion = new List<string> { "Suggested:" };
|
||||
if (pkm.Format >= 3)
|
||||
{
|
||||
pkm.HyperTrainFlags = 0;
|
||||
return;
|
||||
var met_list = GameInfo.GetLocationList((GameVersion)pkm.Version, pkm.Format, egg: false);
|
||||
var locstr = met_list.FirstOrDefault(loc => loc.Value == location).Text;
|
||||
suggestion.Add($"Met Location: {locstr}");
|
||||
suggestion.Add($"Met Level: {level}");
|
||||
}
|
||||
|
||||
pkm.HT_HP = IVs[0] != 31;
|
||||
pkm.HT_ATK = IVs[1] != 31 && IVs[1] > 2;
|
||||
pkm.HT_DEF = IVs[2] != 31;
|
||||
pkm.HT_SPE = IVs[3] != 31 && IVs[3] > 2;
|
||||
pkm.HT_SPA = IVs[4] != 31;
|
||||
pkm.HT_SPD = IVs[5] != 31;
|
||||
if (pkm.CurrentLevel < minlvl)
|
||||
suggestion.Add($"Current Level: {minlvl}");
|
||||
return suggestion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -397,59 +397,5 @@ public static string GetPotentialString(this PKM pkm, bool unicode = true)
|
|||
var arr = unicode ? PotentialUnicode : PotentialNoUnicode;
|
||||
return arr[pkm.PotentialRating];
|
||||
}
|
||||
|
||||
public static void SetEV(this PKM pk, int index, int value)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: pk.EV_HP = value; break;
|
||||
case 1: pk.EV_ATK = value; break;
|
||||
case 2: pk.EV_DEF = value; break;
|
||||
case 3: pk.EV_SPE = value; break;
|
||||
case 4: pk.EV_SPA = value; break;
|
||||
case 5: pk.EV_SPD = value; break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
}
|
||||
public static void SetIV(this PKM pk, int index, int value)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: pk.IV_HP = value; break;
|
||||
case 1: pk.IV_ATK = value; break;
|
||||
case 2: pk.IV_DEF = value; break;
|
||||
case 3: pk.IV_SPE = value; break;
|
||||
case 4: pk.IV_SPA = value; break;
|
||||
case 5: pk.IV_SPD = value; break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetATKIVGender(this PKM pk, int gender)
|
||||
{
|
||||
do { pk.IV_ATK = (int)(Util.Rand32() & pk.MaxIV); }
|
||||
while (pk.Gender != gender);
|
||||
}
|
||||
|
||||
public static int GetMaximumEV(this PKM pkm, int index)
|
||||
{
|
||||
if (pkm.Format < 3)
|
||||
return ushort.MaxValue;
|
||||
|
||||
var EVs = pkm.EVs;
|
||||
EVs[index] = 0;
|
||||
var sum = EVs.Sum();
|
||||
int remaining = 510 - sum;
|
||||
var newEV = Math.Min(Math.Max(remaining, 0), 252);
|
||||
return newEV;
|
||||
}
|
||||
public static int GetMaximumIV(this PKM pkm, int index, bool Allow30 = false)
|
||||
{
|
||||
if (pkm.IVs[index] == pkm.MaxIV && Allow30)
|
||||
return pkm.MaxIV - 1;
|
||||
return pkm.MaxIV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user