Respacening

Style guidelines, handle a bunch of files
no functional change
This commit is contained in:
Kurt 2018-07-26 19:34:27 -07:00
parent 9551d4e707
commit c8563a3737
67 changed files with 838 additions and 204 deletions

View file

@ -67,6 +67,7 @@ namespace PKHeX.Core
return _allSuggestedMoves = GetSuggestedMoves(true, true, true);
}
}
private IEnumerable<int> AllSuggestedRelearnMoves
{
get
@ -76,12 +77,14 @@ namespace PKHeX.Core
if (Error || Info == null)
return new int[4];
var gender = pkm.PersonalInfo.Gender;
var inheritLvlMoves = gender > 0 && gender < 255 || Legal.MixedGenderBreeding.Contains(Info.EncounterMatch.Species);
var inheritLvlMoves = (gender > 0 && gender < 255) || Legal.MixedGenderBreeding.Contains(Info.EncounterMatch.Species);
return _allSuggestedRelearnMoves = Legal.GetValidRelearn(pkm, Info.EncounterMatch.Species, inheritLvlMoves).ToArray();
}
}
private int[] _allSuggestedMoves, _allSuggestedRelearnMoves;
public int[] AllSuggestedMovesAndRelearn => AllSuggestedMoves.Concat(AllSuggestedRelearnMoves).ToArray();
private string EncounterName
{
get
@ -90,6 +93,7 @@ namespace PKHeX.Core
return $"{enc.GetEncounterTypeName()} ({SpeciesStrings[enc.Species]})";
}
}
private string EncounterLocation
{
get
@ -135,6 +139,7 @@ namespace PKHeX.Core
#endif
Parsed = true;
}
private void ParseLegality()
{
if (!pkm.IsOriginValid)
@ -156,6 +161,7 @@ namespace PKHeX.Core
case 7: ParsePK7(); return;
}
}
private void ParsePK1()
{
pkm.TradebackStatus = Legal.GetTradebackStatusInitial(pkm);
@ -171,6 +177,7 @@ namespace PKHeX.Core
if (pkm.Format == 2)
Item.Verify(this);
}
private void ParsePK3()
{
UpdateInfo();
@ -184,6 +191,7 @@ namespace PKHeX.Core
if (Info.EncounterMatch is WC3 z && z.NotDistributed)
AddLine(Severity.Invalid, V413, CheckIdentifier.Encounter);
}
private void ParsePK4()
{
UpdateInfo();
@ -191,17 +199,20 @@ namespace PKHeX.Core
if (pkm.Format > 4)
Transfer.VerifyTransferLegalityG4(this);
}
private void ParsePK5()
{
UpdateInfo();
UpdateChecks();
NHarmonia.Verify(this);
}
private void ParsePK6()
{
UpdateInfo();
UpdateChecks();
}
private void ParsePK7()
{
UpdateInfo();
@ -221,6 +232,7 @@ namespace PKHeX.Core
/// <summary>
/// Adds a new Check parse value.
/// </summary>
/// <param name="chk">Check result to add.</param>
internal void AddLine(CheckResult chk) => Parse.Add(chk);
private void UpdateVCTransferInfo()
@ -235,11 +247,13 @@ namespace PKHeX.Core
foreach (var z in Transfer.VerifyVCEncounter(pkm, EncounterOriginalGB, s, Info.Moves))
AddLine(z);
}
private void UpdateInfo()
{
Info = EncounterFinder.FindVerifiedEncounter(pkm);
Parse.AddRange(Info.Parse);
}
private void UpdateChecks()
{
PIDEC.Verify(this);
@ -272,6 +286,7 @@ namespace PKHeX.Core
Misc.VerifyVersionEvolution(this);
}
}
private string GetLegalityReport()
{
if (!Parsed || Info == null)
@ -281,13 +296,19 @@ namespace PKHeX.Core
var vMoves = Info.Moves;
var vRelearn = Info.Relearn;
for (int i = 0; i < 4; i++)
{
if (!vMoves[i].Valid)
lines.Add(string.Format(V191, vMoves[i].Rating, i + 1, vMoves[i].Comment));
}
if (pkm.Format >= 6)
for (int i = 0; i < 4; i++)
if (!vRelearn[i].Valid)
lines.Add(string.Format(V192, vRelearn[i].Rating, i + 1, vRelearn[i].Comment));
{
for (int i = 0; i < 4; i++)
{
if (!vRelearn[i].Valid)
lines.Add(string.Format(V192, vRelearn[i].Rating, i + 1, vRelearn[i].Comment));
}
}
if (lines.Count == 0 && Parse.All(chk => chk.Valid) && Valid)
return V193;
@ -301,6 +322,7 @@ namespace PKHeX.Core
return string.Join(Environment.NewLine, lines);
}
private string GetVerboseLegalityReport()
{
if (!Parsed || Info == null)
@ -315,13 +337,19 @@ namespace PKHeX.Core
var vMoves = Info.Moves;
var vRelearn = Info.Relearn;
for (int i = 0; i < 4; i++)
{
if (vMoves[i].Valid)
lines.Add(string.Format(V191, vMoves[i].Rating, i + 1, vMoves[i].Comment));
}
if (pkm.Format >= 6)
for (int i = 0; i < 4; i++)
if (vRelearn[i].Valid)
{
for (int i = 0; i < 4; i++)
{
if (vRelearn[i].Valid)
lines.Add(string.Format(V192, vRelearn[i].Rating, i + 1, vRelearn[i].Comment));
}
}
if (rl != lines.Count) // move info added, break for next section
lines.Add(br[1]);

View file

@ -25,10 +25,13 @@ namespace PKHeX.Core
/// <summary> e-Reader Berry originates from a Japanese SaveFile </summary>
public static bool SavegameJapanese => ActiveTrainer.Language == 1;
/// <summary> e-Reader Berry is Enigma or special berry </summary>
public static bool EReaderBerryIsEnigma { get; set; } = true;
/// <summary> e-Reader Berry Name </summary>
public static string EReaderBerryName { get; set; } = string.Empty;
/// <summary> e-Reader Berry Name formatted in Title Case </summary>
public static string EReaderBerryDisplayName => string.Format(V372, Util.ToTitleCase(EReaderBerryName.ToLower()));
@ -93,6 +96,7 @@ namespace PKHeX.Core
r[i] = MoveLevelUp.GetIsLevelUp1(species, moves[i], 100, 0, 0).Level;
return r;
}
internal static int[] GetMaxLevelLearnMoveG1(int species, List<int> moves)
{
var r = new int[moves.Count];
@ -112,6 +116,7 @@ namespace PKHeX.Core
}
return r;
}
internal static List<int>[] GetExclusiveMovesG1(int species1, int species2, IEnumerable<int> tmhm, IEnumerable<int> moves)
{
// Return from two species the exclusive moves that only one could learn and also the current pokemon have it in its current moveset
@ -125,6 +130,7 @@ namespace PKHeX.Core
moves2.RemoveAll(x => !hashMoves.Contains(x) || common.Contains(x));
return new[] { moves1, moves2 };
}
internal static List<int>[] GetValidMovesAllGens(PKM pkm, IReadOnlyList<EvoCriteria>[] evoChains, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
{
var Moves = new List<int>[evoChains.Length];
@ -137,6 +143,7 @@ namespace PKHeX.Core
}
return Moves;
}
internal static IEnumerable<int> GetValidMoves(PKM pkm, IReadOnlyList<EvoCriteria>[] evoChains, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
{
GameVersion version = (GameVersion)pkm.Version;
@ -144,6 +151,7 @@ namespace PKHeX.Core
version = GameVersion.Any;
return GetValidMoves(pkm, version, evoChains, minLvLG1: 1, minLvLG2: 1, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM);
}
internal static IEnumerable<int> GetValidMoves(PKM pkm, IReadOnlyList<EvoCriteria> evoChain, int generation, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
{
GameVersion version = (GameVersion)pkm.Version;
@ -151,6 +159,7 @@ namespace PKHeX.Core
version = GameVersion.Any;
return GetValidMoves(pkm, version, evoChain, generation, minLvLG1: minLvLG1, minLvLG2: minLvLG2, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM);
}
internal static IEnumerable<int> GetValidRelearn(PKM pkm, int species, bool inheritlvlmoves, GameVersion version = GameVersion.Any)
{
List<int> r = new List<int> { 0 };
@ -168,6 +177,7 @@ namespace PKHeX.Core
r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 100, pkm.AltForm, version));
return r.Distinct();
}
internal static IList<int> GetShedinjaEvolveMoves(PKM pkm, int lvl = -1, int generation = 0)
{
if (lvl == -1)
@ -194,12 +204,14 @@ namespace PKHeX.Core
}
return new List<int>();
}
internal static int GetShedinjaMoveLevel(int species, int move, int generation)
{
var src = generation == 4 ? LevelUpPt : LevelUpE;
var moves = src[species];
return moves.GetLevelLearnMove(move);
}
internal static int[] GetBaseEggMoves(PKM pkm, int species, GameVersion gameSource, int lvl)
{
if (gameSource == GameVersion.Any)
@ -306,17 +318,22 @@ namespace PKHeX.Core
}
return new int[0];
}
internal static List<int> GetValidPostEvolutionMoves(PKM pkm, int Species, IReadOnlyList<EvoCriteria>[] evoChains, GameVersion Version)
{
// Return moves that the pokemon could learn after evolving
var moves = new List<int>();
for (int i = 1; i < evoChains.Length; i++)
{
if (evoChains[i].Count != 0)
moves.AddRange(GetValidPostEvolutionMoves(pkm, Species, evoChains[i], i, Version));
}
if (pkm.GenNumber >= 6)
moves.AddRange(pkm.RelearnMoves.Where(m => m != 0));
return moves.Distinct().ToList();
}
private static List<int> GetValidPostEvolutionMoves(PKM pkm, int Species, IReadOnlyList<EvoCriteria> evoChain, int Generation, GameVersion Version)
{
var evomoves = new List<int>();
@ -330,6 +347,7 @@ namespace PKHeX.Core
}
return evomoves;
}
internal static IEnumerable<int> GetExclusivePreEvolutionMoves(PKM pkm, int Species, IReadOnlyList<EvoCriteria> evoChain, int Generation, GameVersion Version)
{
var preevomoves = new List<int>();
@ -355,6 +373,7 @@ namespace PKHeX.Core
// it is sufficient to check just GS's case
yield return GameVersion.GS;
}
internal static IEnumerable<GameVersion> GetGen1Versions(LegalInfo Info)
{
if (Info.EncounterMatch.Species == 133 && Info.Game == GameVersion.Stadium)
@ -362,14 +381,19 @@ namespace PKHeX.Core
// Stadium Eevee; check for RB and yellow initial moves
yield return GameVersion.RB;
yield return GameVersion.YW;
yield break;
}
else if (Info.Game == GameVersion.YW)
if (Info.Game == GameVersion.YW)
{
yield return GameVersion.YW;
yield break;
}
// Any encounter marked with version RBY is for pokemon with the same moves and catch rate in RB and Y,
// it is sufficient to check just RB's case
yield return GameVersion.RB;
}
internal static int GetRequiredMoveCount(PKM pk, int[] moves, LegalInfo info, int[] initialmoves)
{
if (pk.Format != 1 || !pk.Gen1_NotTradeback) // No Move Deleter in Gen 1
@ -389,6 +413,7 @@ namespace PKHeX.Core
return Math.Min(4, required);
}
private static int GetRequiredMoveCount(PKM pk, int[] moves, List<int>[] learn, int[] initialmoves)
{
if (SpecialMinMoveSlots.Contains(pk.Species))
@ -399,6 +424,7 @@ namespace PKHeX.Core
int required = GetRequiredMoveSlotsRegular(pk, moves, learn, initialmoves);
return required != 0 ? required : GetRequiredMoveCountDecrement(pk, moves, learn, initialmoves);
}
private static int GetRequiredMoveSlotsRegular(PKM pk, int[] moves, List<int>[] learn, int[] initialmoves)
{
int species = pk.Species;
@ -422,6 +448,7 @@ namespace PKHeX.Core
return IsMoveCountRequired3(species, pk.CurrentLevel, moves) ? 3 : 0; // no match
}
private static bool IsMoveCountRequired3(int species, int level, int[] moves)
{
// Species that evolve and learn the 4th move as evolved species at a greather level than base species
@ -440,6 +467,7 @@ namespace PKHeX.Core
}
return false;
}
private static int GetRequiredMoveCountDecrement(PKM pk, int[] moves, List<int>[] learn, int[] initialmoves)
{
int usedslots = initialmoves.Union(learn[1]).Where(m => m != 0).Distinct().Count();
@ -480,6 +508,7 @@ namespace PKHeX.Core
}
return usedslots;
}
private static int GetRequiredMoveCountSpecial(PKM pk, int[] moves, List<int>[] learn)
{
// Species with few mandatory slots, species with stone evolutions that could evolve at lower level and do not learn any more moves
@ -506,6 +535,7 @@ namespace PKHeX.Core
// Add to used slots the non-mandatory moves from the learnset table that the pokemon have learned
return mandatory.Count + moves.Count(m => m != 0 && mandatory.All(l => l != m) && learn[1].Any(t => t == m));
}
private static List<int> GetRequiredMoveCountLevel(PKM pk)
{
int species = pk.Species;
@ -602,6 +632,7 @@ namespace PKHeX.Core
default: return Enumerable.Empty<EncounterStatic>();
}
}
internal static IEnumerable<EncounterArea> GetEncounterTable(PKM pkm, GameVersion gameSource = GameVersion.Any)
{
if (gameSource == GameVersion.Any)
@ -653,6 +684,7 @@ namespace PKHeX.Core
default: return Enumerable.Empty<EncounterArea>();
}
}
private static IEnumerable<EncounterStatic> GetEncounterStaticTableGSC(PKM pkm)
{
if (!AllowGen2Crystal(pkm))
@ -664,22 +696,23 @@ namespace PKHeX.Core
return StaticC;
return StaticGSC;
}
private static IEnumerable<EncounterArea> GetEncounterTableGSC(PKM pkm)
{
if (!AllowGen2Crystal(pkm))
return SlotsGS;
// Gen 2 met location is lost outside gen 2 games
if (pkm.Format != 2)
// Gen 2 met location is lost outside gen 2 games
return SlotsGSC;
// Format 2 with met location, encounter should be from Crystal
if (pkm.HasOriginalMetLocation)
// Format 2 with met location, encounter should be from Crystal
return SlotsC;
// Format 2 without met location but pokemon could not be tradeback to gen 1,
// encounter should be from gold or silver
if (pkm.Species > 151 && !FutureEvolutionsGen1.Contains(pkm.Species))
// Format 2 without met location but pokemon could not be tradeback to gen 1,
// encounter should be from gold or silver
return SlotsGS;
// Encounter could be any gen 2 game, it can have empty met location for have a g/s origin
@ -702,6 +735,7 @@ namespace PKHeX.Core
default: return null;
}
}
internal static int GetEggHatchLevel(PKM pkm) => GetEggHatchLevel(pkm.Format);
internal static int GetEggHatchLevel(int gen) => gen <= 3 ? 5 : 1;
@ -709,6 +743,7 @@ namespace PKHeX.Core
{
return GetSplitBreedGeneration(pkm.GenNumber);
}
private static ICollection<int> GetSplitBreedGeneration(int generation)
{
switch (generation)
@ -723,6 +758,7 @@ namespace PKHeX.Core
default: return Empty;
}
}
internal static int GetMaxSpeciesOrigin(PKM pkm)
{
if (pkm.Format == 1)
@ -731,6 +767,7 @@ namespace PKHeX.Core
return GetMaxSpeciesOrigin(2);
return GetMaxSpeciesOrigin(pkm.GenNumber);
}
internal static int GetMaxSpeciesOrigin(int generation)
{
switch (generation)
@ -745,6 +782,7 @@ namespace PKHeX.Core
default: return -1;
}
}
internal static IEnumerable<int> GetFutureGenEvolutions(int generation)
{
switch (generation)
@ -757,6 +795,7 @@ namespace PKHeX.Core
default: return Enumerable.Empty<int>();
}
}
internal static int GetDebutGeneration(int species)
{
if (species <= MaxSpeciesID_1)
@ -793,6 +832,7 @@ namespace PKHeX.Core
}
return -1;
}
private static bool[] GetReleasedHeldItems(int generation)
{
switch (generation)
@ -806,10 +846,12 @@ namespace PKHeX.Core
default: return new bool[0];
}
}
internal static bool IsHeldItemAllowed(PKM pkm)
{
return IsHeldItemAllowed(pkm.HeldItem, pkm.Format);
}
private static bool IsHeldItemAllowed(int item, int generation)
{
if (item < 0)
@ -830,15 +872,16 @@ namespace PKHeX.Core
return pkm.AltForm == 1;
if (pkm.Species == 678 && pkm.Gender == 1)
return pkm.AltForm == 1;
if (pkm.Species == 773)
return true;
return false;
return pkm.Species == 773;
}
internal static bool IsTradeEvolved(IReadOnlyList<EvoCriteria>[] chain, int pkmFormat)
{
return chain[pkmFormat].Any(IsTradeEvolved);
}
internal static bool IsTradeEvolved(EvoCriteria z) => EvolutionMethod.TradeMethods.Contains(z.Method);
internal static bool IsEvolutionValid(PKM pkm, int minSpecies = -1, int minLevel = -1)
{
var curr = EvolutionChain.GetValidPreEvolutions(pkm);
@ -856,6 +899,7 @@ namespace PKHeX.Core
return curr.Count >= poss.Count - 1;
return curr.Count >= poss.Count;
}
internal static bool IsEvolutionValidWithMove(PKM pkm, LegalInfo info)
{
// Exclude species that do not evolve leveling with a move
@ -872,8 +916,10 @@ namespace PKHeX.Core
// Get the minimum level in any generation when the pokemon could learn the evolve move
var LearnLevel = 101;
for (int g = pkm.GenNumber; g <= pkm.Format; g++)
{
if (pkm.InhabitedGeneration(g) && levels[g] > 0)
LearnLevel = Math.Min(LearnLevel, levels[g]);
}
// Check also if the current encounter include the evolve move as an special move
// That means the pokemon have the move from the encounter level
@ -891,13 +937,14 @@ namespace PKHeX.Core
// Gen 3 pokemon in gen 4 games: minimum level is one level after transfer to generation 4
// VC pokemon: minimum level is one level after transfer to generation 7
// Sylveon: always one level after met level, for gen 4 and 5 eevees in gen 6 games minimum for evolution is one level after transfer to generation 5
if (pkm.HasOriginalMetLocation || pkm.Format == 4 && pkm.Gen3 || pkm.VC || pkm.Species == 700)
if (pkm.HasOriginalMetLocation || (pkm.Format == 4 && pkm.Gen3) || pkm.VC || pkm.Species == 700)
LearnLevel = Math.Max(pkm.Met_Level + 1, LearnLevel);
// Current level must be at least one the minimum learn level
// the level-up event that triggers the learning of the move also triggers evolution with no further level-up required
return pkm.CurrentLevel >= LearnLevel;
}
private static bool IsMoveInherited(PKM pkm, LegalInfo info, int[] moves)
{
// In 3DS games, the inherited move must be in the relearn moves.
@ -912,6 +959,7 @@ namespace PKHeX.Core
// This requires the pokemon to not have 4 other moves identified as egg moves or inherited level up moves.
return 4 > info.Moves.Count(m => m.Source == MoveSource.EggMove || m.Source == MoveSource.InheritLevelUp);
}
internal static bool IsFormChangeable(PKM pkm, int species)
{
if (FormChange.Contains(species))
@ -934,6 +982,7 @@ namespace PKHeX.Core
return true;
return false;
}
public static int GetLowestLevel(PKM pkm, int startLevel)
{
if (startLevel == -1)
@ -950,6 +999,7 @@ namespace PKHeX.Core
}
return startLevel;
}
internal static bool GetCanBeCaptured(int species, int gen, GameVersion version = GameVersion.Any)
{
switch (gen)
@ -980,6 +1030,7 @@ namespace PKHeX.Core
}
return false;
}
private static bool GetCanBeCaptured(int species, IEnumerable<EncounterArea> area, IEnumerable<EncounterStatic> statics)
{
if (area.Any(loc => loc.Slots.Any(slot => slot.Species == species)))
@ -988,26 +1039,31 @@ namespace PKHeX.Core
return true;
return false;
}
internal static bool GetCanLearnMachineMove(PKM pkm, int move, int generation, GameVersion version = GameVersion.Any)
{
return GetValidMoves(pkm, version, EvolutionChain.GetValidPreEvolutions(pkm), generation, Machine: true).Contains(move);
}
internal static bool GetCanRelearnMove(PKM pkm, int move, int generation, GameVersion version = GameVersion.Any)
{
return GetValidMoves(pkm, version, EvolutionChain.GetValidPreEvolutions(pkm), generation, LVL: true, Relearn: true).Contains(move);
}
internal static bool GetCanKnowMove(PKM pkm, int move, int generation, GameVersion version = GameVersion.Any)
{
if (pkm.Species == 235 && !InvalidSketch.Contains(move))
return true;
return GetValidMoves(pkm, version, EvolutionChain.GetValidPreEvolutions(pkm), generation, LVL: true, Relearn: true, Tutor: true, Machine: true).Contains(move);
}
internal static int GetBaseEggSpecies(PKM pkm, int skipOption = 0)
{
if (pkm.Format == 1)
return GetBaseSpecies(pkm, generation: 2);
return GetBaseSpecies(pkm, skipOption);
}
internal static int GetBaseSpecies(PKM pkm, int skipOption = 0, int generation = -1)
{
int tree = generation != -1 ? generation : pkm.Format;
@ -1016,6 +1072,7 @@ namespace PKHeX.Core
var evos = table.GetValidPreEvolutions(pkm, maxLevel: 100, maxSpeciesOrigin: maxSpeciesOrigin, skipChecks: true);
return GetBaseSpecies(pkm, evos, skipOption);
}
internal static int GetBaseSpecies(PKM pkm, IReadOnlyList<DexLevel> evos, int skipOption = 0)
{
if (pkm.Species == 292)
@ -1027,10 +1084,12 @@ namespace PKHeX.Core
default: return evos.Count <= 0 ? pkm.Species : evos[evos.Count - 1].Species;
}
}
private static int GetMaxLevelGeneration(PKM pkm)
{
return GetMaxLevelGeneration(pkm, pkm.GenNumber);
}
private static int GetMaxLevelGeneration(PKM pkm, int generation)
{
if (!pkm.InhabitedGeneration(generation))
@ -1054,16 +1113,20 @@ namespace PKHeX.Core
return pkm.CurrentLevel;
}
internal static int GetMinLevelEncounter(PKM pkm)
{
// Only for gen 3 pokemon in format 3, after transfer to gen 4 it should return transfer level
if (pkm.Format == 3 && pkm.WasEgg)
// Only for gen 3 pokemon in format 3, after transfer to gen 4 it should return transfer level
return 5;
// Only for gen 4 pokemon in format 4, after transfer to gen 5 it should return transfer level
if (pkm.Format == 4 && pkm.Gen4 && pkm.WasEgg)
// Only for gen 4 pokemon in format 4, after transfer to gen 5 it should return transfer level
return 1;
return pkm.HasOriginalMetLocation ? pkm.Met_Level : GetMaxLevelGeneration(pkm);
}
private static bool GetCatchRateMatchesPreEvolution(PKM pkm, int catch_rate, IEnumerable<int> gen1)
{
// For species catch rate, discard any species that has no valid encounters and a different catch rate than their pre-evolutions
@ -1071,7 +1134,7 @@ namespace PKHeX.Core
return IsCatchRateRBY(Lineage) || IsCatchRateTrade() || IsCatchRateStadium();
// Dragonite's Catch Rate is different than Dragonair's in Yellow, but there is no Dragonite encounter.
bool IsCatchRateRBY(IEnumerable<int> ds) => ds.Any(s => catch_rate == PersonalTable.RB[s].CatchRate || s != 149 && catch_rate == PersonalTable.Y[s].CatchRate);
bool IsCatchRateRBY(IEnumerable<int> ds) => ds.Any(s => catch_rate == PersonalTable.RB[s].CatchRate || (s != 149 && catch_rate == PersonalTable.Y[s].CatchRate));
// Krabby encounter trade special catch rate
bool IsCatchRateTrade() => (pkm.Species == 098 || pkm.Species == 099) && catch_rate == 204;
bool IsCatchRateStadium() => Stadium_GiftSpecies.Contains(pkm.Species) && Stadium_CatchRate.Contains(catch_rate);
@ -1080,6 +1143,7 @@ namespace PKHeX.Core
/// <summary>
/// Gets the Tradeback status depending on various values.
/// </summary>
/// <param name="pkm">Pokémon to guess the tradeback status from.</param>
internal static TradebackType GetTradebackStatusInitial(PKM pkm)
{
if (pkm is PK1 pk1)
@ -1097,6 +1161,7 @@ namespace PKHeX.Core
/// <summary>
/// Gets the Tradeback status depending on the <see cref="PK1.Catch_Rate"/>
/// </summary>
/// <param name="pkm">Pokémon to guess the tradeback status from.</param>
internal static TradebackType GetTradebackStatusRBY(PK1 pkm)
{
if (!AllowGen1Tradeback)
@ -1130,11 +1195,14 @@ namespace PKHeX.Core
r.AddRange(pkm.RelearnMoves);
for (int gen = pkm.GenNumber; gen <= pkm.Format; gen++)
{
if (vs[gen].Count != 0)
r.AddRange(GetValidMoves(pkm, Version, vs[gen], gen, minLvLG1: minLvLG1, minLvLG2: minLvLG2, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM));
}
return r.Distinct();
}
private static IEnumerable<int> GetValidMoves(PKM pkm, GameVersion Version, IReadOnlyList<EvoCriteria> vs, int Generation, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true, bool RemoveTransferHM = true)
{
List<int> r = new List<int> { 0 };
@ -1148,9 +1216,11 @@ namespace PKHeX.Core
if (FormChangeMoves.Contains(species)) // Deoxys & Shaymin & Giratina (others don't have extra but whatever)
{
int formcount = pkm.PersonalInfo.FormeCount;
// In gen 3 deoxys has different forms depending on the current game, in personal info there is no alter form info
if (species == 386 && pkm.Format == 3)
// In gen 3 deoxys has different forms depending on the current game, in personal info there is no alter form info
formcount = 4;
for (int i = 0; i < formcount; i++)
r.AddRange(GetMoves(pkm, species, minLvLG1, minLvLG2, vs[0].Level, i, moveTutor, Version, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, Generation));
if (Relearn)
@ -1176,6 +1246,7 @@ namespace PKHeX.Core
r.AddRange(pkm.RelearnMoves);
return r.Distinct();
}
private static IEnumerable<int> GetEvoMoves(PKM pkm, GameVersion Version, IReadOnlyList<EvoCriteria> vs, int Generation, int minLvLG1, int minLvLG2, bool LVL, bool Tutor, bool Machine, bool MoveReminder, bool RemoveTransferHM, bool moveTutor, int i, EvoCriteria evo)
{
int minlvlevo1 = GetEvoMoveMinLevel1(pkm, Generation, minLvLG1, evo);
@ -1196,6 +1267,7 @@ namespace PKHeX.Core
return Math.Min(pkm.CurrentLevel, evo.MinLevel);
return minLvLG1;
}
private static int GetEvoMoveMinLevel2(PKM pkm, int Generation, int minLvLG2, EvoCriteria evo)
{
if (Generation != 2 || AllowGen2MoveReminder(pkm))

View file

@ -14,6 +14,7 @@ namespace PKHeX.Core
var dl = EvolutionChain.GetValidPreEvolutions(pkm, maxID);
return GetPossible(pkm, dl, gameSource);
}
public static IEnumerable<EncounterStatic> GetPossible(PKM pkm, IReadOnlyList<DexLevel> vs, GameVersion gameSource = GameVersion.Any)
{
if (gameSource == GameVersion.Any)
@ -22,6 +23,7 @@ namespace PKHeX.Core
var encs = GetStaticEncounters(pkm, vs, gameSource);
return encs.Where(e => AllowGBCartEra || !GameVersion.GBCartEraOnly.Contains(e.Version));
}
public static IEnumerable<EncounterStatic> GetValidStaticEncounter(PKM pkm, GameVersion gameSource = GameVersion.Any)
{
var poss = GetPossible(pkm, gameSource: gameSource);
@ -33,6 +35,7 @@ namespace PKHeX.Core
// Back Check against pkm
return GetMatchingStaticEncounters(pkm, poss, lvl);
}
public static IEnumerable<EncounterStatic> GetValidStaticEncounter(PKM pkm, IReadOnlyList<DexLevel> vs, GameVersion gameSource)
{
var poss = GetPossible(pkm, vs, gameSource: gameSource);
@ -86,7 +89,7 @@ namespace PKHeX.Core
if (pkm.Format == 3 && pkm.IsEgg && e.EggLocation != pkm.Met_Location)
return false;
}
else if (pkm.VC || pkm.GenNumber <= 2 && e.EggLocation != 0) // Gen2 Egg
else if (pkm.VC || (pkm.GenNumber <= 2 && e.EggLocation != 0)) // Gen2 Egg
{
if (pkm.Format <= 2)
{
@ -164,7 +167,9 @@ namespace PKHeX.Core
}
}
else if (e.Level > lvl)
{
return false;
}
if (e.Gender != -1 && e.Gender != pkm.Gender)
return false;
@ -174,9 +179,13 @@ namespace PKHeX.Core
return false;
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 (pkm is IContestStats s && s.IsContestBelow(e))
return false;
@ -196,6 +205,7 @@ namespace PKHeX.Core
return false;
return true;
}
private static IEnumerable<EncounterStatic> GetStaticEncounters(PKM pkm, IReadOnlyList<DexLevel> dl, GameVersion gameSource = GameVersion.Any)
{
if (gameSource == GameVersion.Any)
@ -213,6 +223,7 @@ namespace PKHeX.Core
return GetGSStaticTransfer(pkm.Species, pkm.Met_Level);
return new EncounterInvalid(pkm);
}
private static EncounterStatic GetRBYStaticTransfer(int species, int pkmMetLevel)
{
var enc = new EncounterStatic
@ -230,6 +241,7 @@ namespace PKHeX.Core
enc.FlawlessIVCount = enc.Fateful ? 5 : 3;
return enc;
}
private static EncounterStatic GetGSStaticTransfer(int species, int pkmMetLevel)
{
var enc = new EncounterStatic
@ -247,6 +259,7 @@ namespace PKHeX.Core
enc.FlawlessIVCount = enc.Fateful ? 5 : 3;
return enc;
}
internal static EncounterStatic GetStaticLocation(PKM pkm, int species = -1)
{
switch (pkm.GenNumber)
@ -265,6 +278,7 @@ namespace PKHeX.Core
{
return pkm.Met_Location == e.Location && pkm.Egg_Location == e.EggLocation;
}
private static bool IsValidCatchRatePK1(EncounterStatic e, PK1 pk1)
{
var catch_rate = pk1.Catch_Rate;

View file

@ -145,6 +145,7 @@ namespace PKHeX.Core
return false;
return (MemoryFeelings[memory] & (1 << feeling)) != 0;
}
public static bool CanHaveIntensity(int memory, int intensity)
{
if (memory >= MemoryFeelings.Length)
@ -162,6 +163,7 @@ namespace PKHeX.Core
return feel;
}
}
public static int GetMinimumIntensity(int memory)
{
if (memory > MemoryMinIntensity.Length)

View file

@ -9,6 +9,7 @@ namespace PKHeX.Core
internal const int MaxMoveID_1 = 165;
internal const int MaxItemID_1 = 255;
internal const int MaxAbilityID_1 = 0;
/// <summary>
/// Generation 1 -> Generation 7 Transfer Location (Kanto)
/// </summary>
@ -73,23 +74,28 @@ namespace PKHeX.Core
// Crobat Espeon Umbreon Blissey
169,196,197,242
};
internal static readonly HashSet<int> SpecialMinMoveSlots = new HashSet<int>
{
25, 26, 29, 30, 31, 32, 33, 34, 36, 38, 40, 59, 91, 103, 114, 121,
};
internal static readonly HashSet<int> Types_Gen1 = new HashSet<int>
{
0, 1, 2, 3, 4, 5, 7, 8, 20, 21, 22, 23, 24, 25, 26
};
internal static readonly HashSet<int> Species_NotAvailable_CatchRate = new HashSet<int>
{
12, 18, 31, 34, 38, 45, 53, 59, 62, 65, 68, 71, 78, 91, 103, 121
};
internal static readonly int[] Stadium_CatchRate =
{
167, // Normal Box
168, // Gorgeous Box
};
internal static readonly HashSet<int> Stadium_GiftSpecies = new HashSet<int>
{
001, // Bulbasaur
@ -102,6 +108,7 @@ namespace PKHeX.Core
138, // Omanyte
140, // Kabuto
};
internal static readonly HashSet<int> Trade_Evolution1 = new HashSet<int>
{
064,

View file

@ -68,6 +68,7 @@ namespace PKHeX.Core
return CheckMatch(data.pkm, abilities, gen, AbilityState.CanMismatch);
}
private CheckResult VerifyAbility345(LegalityAnalysis data, IReadOnlyList<int> abilities, int abilnum)
{
var pkm = data.pkm;
@ -133,6 +134,7 @@ namespace PKHeX.Core
// Fall through when gen3 pkm transferred to gen4/5
return VerifyAbilityGen3Transfer(data, abilities, data.Info.EvoChainsAllGens[3][0].Species);
}
private AbilityState VerifyAbilityGen3Transfer(LegalityAnalysis data, IReadOnlyList<int> abilities, int maxGen3Species)
{
var pkm = data.pkm;
@ -193,6 +195,7 @@ namespace PKHeX.Core
return GetInvalid(pkm.Format < 6 ? V113 : V114);
}
private CheckResult VerifyAbilityPCD(LegalityAnalysis data, IReadOnlyList<int> abilities, PCD pcd)
{
var pkm = data.pkm;
@ -237,6 +240,7 @@ namespace PKHeX.Core
var state = pkm.Format == 5 ? AbilityState.MustMatch : AbilityState.CanMismatch;
return CheckMatch(data.pkm, abilities, 5, state);
}
private CheckResult VerifyAbility6(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -256,6 +260,7 @@ namespace PKHeX.Core
return VALID;
}
private CheckResult VerifyAbility7(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -304,6 +309,7 @@ namespace PKHeX.Core
return false; // Cannot alter from hidden ability.
return true;
}
private static int GetEncounterFixedAbilityNumber(IEncounterable enc)
{
switch (enc)

View file

@ -39,9 +39,8 @@ namespace PKHeX.Core
if (pkm.Species == 292 && Info.Generation > 3) // Shedinja. For gen3, copy the ball from Nincada
return VerifyBallEquals(data, 4); // Pokeball Only
if (pkm.Ball == 0x14 && Legal.AlolanCaptureNoHeavyBall.Contains(EncounterMatch.Species)
&& !EncounterMatch.EggEncounter && pkm.SM) // Heavy Ball, can inherit if from egg (USUM fixed catch rate calc)
return GetInvalid(V116);
if (pkm.Ball == 0x14 && Legal.AlolanCaptureNoHeavyBall.Contains(EncounterMatch.Species) && !EncounterMatch.EggEncounter && pkm.SM)
return GetInvalid(V116); // Heavy Ball, can inherit if from egg (USUM fixed catch rate calc)
if (EncounterMatch is EncounterStatic e)
return VerifyBallStatic(data, e);
@ -59,12 +58,14 @@ namespace PKHeX.Core
return VerifyBallEquals(data, 4); // Pokeball
return VerifyBallEquals(data, g.Ball);
}
private CheckResult VerifyBallStatic(LegalityAnalysis data, EncounterStatic s)
{
if (s.Location == 75 && s.Generation == 5) // Entree Forest (Dream World)
return VerifyBallEquals(data, Legal.DreamWorldBalls);
return VerifyBallEquals(data, Legal.GetWildBalls(data.pkm));
}
private CheckResult VerifyBallWild(LegalityAnalysis data, EncounterSlot w)
{
if (w.Location == 30016 && w.Generation == 7) // Poké Pelago
@ -81,6 +82,7 @@ namespace PKHeX.Core
return VerifyBallEquals(data, 0x18); // Sport Ball
return VerifyBallEquals(data, Legal.GetWildBalls(data.pkm));
}
private CheckResult VerifyBallEgg(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -95,6 +97,7 @@ namespace PKHeX.Core
default: return VerifyBallInherited(data);
}
}
private CheckResult VerifyBallInherited(LegalityAnalysis data)
{
switch (data.Info.Generation)
@ -162,7 +165,6 @@ namespace PKHeX.Core
if (pkm.AbilityNumber == 4 && Legal.Ban_Gen3BallHidden.Contains(pkm.SpecForm))
return GetInvalid(V122);
return GetValid(V123);
}
if (species > 650 && species != 700) // Sylveon
@ -174,6 +176,7 @@ namespace PKHeX.Core
return NONE;
}
private CheckResult VerifyBallEggGen7(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -230,7 +233,7 @@ namespace PKHeX.Core
{
if (species == 669 && pkm.AltForm == 3 && pkm.AbilityNumber == 4)
return GetInvalid(V122); // Can't obtain Flabébé-Blue with Hidden Ability in wild
if ((species > 731 && species <= 785) || Legal.PastGenAlolanNatives.Contains(species) && !Legal.PastGenAlolanNativesUncapturable.Contains(species))
if ((species > 731 && species <= 785) || (Legal.PastGenAlolanNatives.Contains(species) && !Legal.PastGenAlolanNativesUncapturable.Contains(species)))
return GetValid(V123);
if (Legal.PastGenAlolanScans.Contains(species))
return GetValid(V123);
@ -249,9 +252,6 @@ namespace PKHeX.Core
private CheckResult VerifyBallEquals(LegalityAnalysis data, int ball) => GetResult(ball == data.pkm.Ball);
private CheckResult VerifyBallEquals(LegalityAnalysis data, HashSet<int> balls) => GetResult(balls.Contains(data.pkm.Ball));
private CheckResult VerifyBallEquals(LegalityAnalysis data, ICollection<int> balls) => GetResult(balls.Contains(data.pkm.Ball));
private CheckResult GetResult(bool valid)
{
return valid ? GetValid(V119) : GetInvalid(V118);
}
private CheckResult GetResult(bool valid) => valid ? GetValid(V119) : GetInvalid(V118);
}
}

View file

@ -8,6 +8,7 @@ namespace PKHeX.Core
public sealed class CXDVerifier : Verifier
{
protected override CheckIdentifier Identifier => CheckIdentifier.Misc;
public override void Verify(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -19,6 +20,7 @@ namespace PKHeX.Core
if (pkm.OT_Gender == 1)
data.AddLine(GetInvalid(V407, CheckIdentifier.Trainer));
}
private static void VerifyCXDStarterCorrelation(LegalityAnalysis data)
{
var pidiv = data.Info.PIDIV;

View file

@ -8,11 +8,13 @@ namespace PKHeX.Core
public sealed class ConsoleRegionVerifier : Verifier
{
protected override CheckIdentifier Identifier => CheckIdentifier.Geography;
public override void Verify(LegalityAnalysis data)
{
var result = VerifyConsoleRegion(data.pkm);
data.AddLine(result);
}
private CheckResult VerifyConsoleRegion(PKM pkm)
{
int consoleRegion = pkm.ConsoleRegion;

View file

@ -9,6 +9,7 @@ namespace PKHeX.Core
public sealed class EffortValueVerifier : Verifier
{
protected override CheckIdentifier Identifier => CheckIdentifier.EVs;
public override void Verify(LegalityAnalysis data)
{
var pkm = data.pkm;

View file

@ -21,6 +21,7 @@ namespace PKHeX.Core
}
private CheckResult VALID => GetValid(V318);
private CheckResult VerifyForm(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -37,7 +38,9 @@ namespace PKHeX.Core
return GetInvalid(string.Format(V304, count - 1, pkm.AltForm));
if (EncounterMatch is EncounterSlot w && w.Type == SlotType.FriendSafari)
{
VerifyFormFriendSafari(data);
}
else if (EncounterMatch is EncounterEgg)
{
if (FormConverter.IsTotemForm(pkm.Species, pkm.AltForm))
@ -199,6 +202,9 @@ namespace PKHeX.Core
return 0;
}
private static readonly HashSet<int> BattleOnly;
private static readonly HashSet<int> SafariFloette = new HashSet<int> { 0, 1, 3 }; // 0/1/3 - RBY
static FormVerifier()
{
BattleOnly = new HashSet<int>();
@ -206,9 +212,7 @@ namespace PKHeX.Core
BattleOnly.UnionWith(Legal.BattleMegas);
BattleOnly.UnionWith(Legal.BattlePrimals);
}
private static readonly HashSet<int> BattleOnly;
private static readonly HashSet<int> SafariFloette = new HashSet<int> {0, 1, 3}; // 0/1/3 - RBY
private void VerifyFormFriendSafari(LegalityAnalysis data)
{
var pkm = data.pkm;

View file

@ -11,6 +11,7 @@ namespace PKHeX.Core
public sealed class IndividualValueVerifier : Verifier
{
protected override CheckIdentifier Identifier => CheckIdentifier.IVs;
public override void Verify(LegalityAnalysis data)
{
switch (data.EncounterMatch)
@ -28,7 +29,9 @@ namespace PKHeX.Core
var pkm = data.pkm;
if (pkm.IVTotal == 0)
{
data.AddLine(Get(V321, Severity.Fishy));
}
else
{
var hpiv = pkm.IV_HP;
@ -67,8 +70,10 @@ namespace PKHeX.Core
private static bool GetIsFixedIVSequenceValid(IReadOnlyList<int> IVs, IReadOnlyList<int> pkIVs)
{
for (int i = 0; i < 6; i++)
{
if (IVs[i] <= 31 && IVs[i] != pkIVs[i])
return false;
}
return true;
}

View file

@ -8,6 +8,7 @@ namespace PKHeX.Core
public sealed class ItemVerifier : Verifier
{
protected override CheckIdentifier Identifier => CheckIdentifier.HeldItem;
public override void Verify(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -20,6 +21,7 @@ namespace PKHeX.Core
if (pkm.IsEgg && pkm.HeldItem != 0)
data.AddLine(GetInvalid(V419));
}
private void VerifyEReaderBerry(LegalityAnalysis data)
{
if (Legal.EReaderBerryIsEnigma) // no E-Reader berry data provided, can't hold berry.

View file

@ -8,6 +8,7 @@ namespace PKHeX.Core
public sealed class LevelVerifier : Verifier
{
protected override CheckIdentifier Identifier => CheckIdentifier.Level;
public override void Verify(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -50,6 +51,7 @@ namespace PKHeX.Core
else
data.AddLine(GetValid(V88));
}
public void VerifyG1(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -73,6 +75,7 @@ namespace PKHeX.Core
if (pkm.Format <= 2 && !(EncounterMatch is EncounterTrade) && EncounterMatch.Species == pkm.Species && Legal.Trade_Evolution1.Contains(EncounterMatch.Species))
VerifyG1TradeEvo(data);
}
private void VerifyG1TradeEvo(LegalityAnalysis data)
{
var pkm = data.pkm;

View file

@ -15,6 +15,7 @@ namespace PKHeX.Core
VerifyMedalsRegular(data);
VerifyMedalsEvent(data);
}
private void VerifyMedalsRegular(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -25,24 +26,25 @@ namespace PKHeX.Core
int TrainCount = pkm.SuperTrainingMedalCount();
if (pkm.IsEgg && TrainCount > 0)
data.AddLine(GetInvalid(V89));
else if (TrainCount > 0 && Info.Generation > 6)
data.AddLine(GetInvalid(V90));
else
{
if (pkm.Format >= 7)
{
if (pkm.SecretSuperTrainingUnlocked)
data.AddLine(GetInvalid(V91));
if (pkm.SecretSuperTrainingComplete)
data.AddLine(GetInvalid(V92));
}
else
{
if (TrainCount == 30 ^ pkm.SecretSuperTrainingComplete)
data.AddLine(GetInvalid(V93));
}
data.AddLine(GetInvalid(V89));
return;
}
if (TrainCount > 0 && Info.Generation > 6)
{
data.AddLine(GetInvalid(V90));
return;
}
if (pkm.Format >= 7)
{
if (pkm.SecretSuperTrainingUnlocked)
data.AddLine(GetInvalid(V91));
if (pkm.SecretSuperTrainingComplete)
data.AddLine(GetInvalid(V92));
return;
}
if (TrainCount == 30 ^ pkm.SecretSuperTrainingComplete)
data.AddLine(GetInvalid(V93));
}
private void VerifyMedalsEvent(LegalityAnalysis data)

View file

@ -19,6 +19,7 @@ namespace PKHeX.Core
VerifyHTMemory(data);
data.AddLine(hist);
}
private CheckResult VerifyHistory(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -30,7 +31,7 @@ namespace PKHeX.Core
if (pkm.Format < 6)
return GetValid(V128);
if (pkm.OT_Affection != 0 && Info.Generation <= 2 || IsInvalidContestAffection(pkm))
if ((pkm.OT_Affection != 0 && Info.Generation <= 2) || IsInvalidContestAffection(pkm))
return GetInvalid(V129);
if (pkm.OT_Memory > 0 || pkm.OT_Feeling > 0 || pkm.OT_Intensity > 0 || pkm.OT_TextVar > 0)
return GetInvalid(V130);
@ -130,6 +131,7 @@ namespace PKHeX.Core
return GetValid(V145);
}
private CheckResult VerifyHistory7(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -156,6 +158,7 @@ namespace PKHeX.Core
return GetValid(V145);
}
private bool VerifyHistoryUntradedHandler(PKM pkm, out CheckResult result)
{
result = null;
@ -170,6 +173,7 @@ namespace PKHeX.Core
return true;
}
private bool VerifyHistoryUntradedEvolution(PKM pkm, IReadOnlyList<EvoCriteria>[] chain, out CheckResult result)
{
result = null;
@ -193,6 +197,7 @@ namespace PKHeX.Core
result = GetInvalid(V142);
return true;
}
private CheckResult VerifyCommonMemory(PKM pkm, int handler)
{
Memories.GetMemoryVariables(pkm, out int m, out int t, out int i, out int f, out string tr, handler);
@ -200,18 +205,23 @@ namespace PKHeX.Core
if (matchingMoveMemory != -1 && pkm.Species != 235 && !Legal.GetCanLearnMachineMove(pkm, Memories.MoveSpecificMemories[1][matchingMoveMemory], 6))
return GetInvalid(string.Format(V153, tr));
if (m == 6 && !Memories.LocationsWithPKCenter[0].Contains(t))
return GetInvalid(string.Format(V154, tr));
switch (m)
{
case 6 when !Memories.LocationsWithPKCenter[0].Contains(t):
return GetInvalid(string.Format(V154, tr));
if (m == 21) // {0} saw {2} carrying {1} on its back. {4} that {3}.
if (!Legal.GetCanLearnMachineMove(new PK6 { Species = t, EXP = PKX.GetEXP(100, t) }, 19, 6))
// {0} saw {2} carrying {1} on its back. {4} that {3}.
case 21 when !Legal.GetCanLearnMachineMove(new PK6 {Species = t, EXP = PKX.GetEXP(100, t)}, 19, 6):
return GetInvalid(string.Format(V153, tr));
if ((m == 16 || m == 48) && (t == 0 || !Legal.GetCanKnowMove(pkm, t, 6)))
return GetInvalid(string.Format(V153, tr));
case 16 when t == 0 || !Legal.GetCanKnowMove(pkm, t, 6):
case 48 when t == 0 || !Legal.GetCanKnowMove(pkm, t, 6):
return GetInvalid(string.Format(V153, tr));
if (m == 49 && (t == 0 || !Legal.GetCanRelearnMove(pkm, t, 6))) // {0} was able to remember {2} at {1}'s instruction. {4} that {3}.
return GetInvalid(string.Format(V153, tr));
// {0} was able to remember {2} at {1}'s instruction. {4} that {3}.
case 49 when t == 0 || !Legal.GetCanRelearnMove(pkm, t, 6):
return GetInvalid(string.Format(V153, tr));
}
if (!Memories.CanHaveIntensity(m, i))
return GetInvalid(string.Format(V254, tr, Memories.GetMinimumIntensity(m)));
@ -234,6 +244,7 @@ namespace PKHeX.Core
if (pkm.OT_Feeling != f)
data.AddLine(GetInvalid(string.Format(V200, V205, f)));
}
private void VerifyOTMemory(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -289,7 +300,7 @@ namespace PKHeX.Core
if (matchingOriginGame != -1)
{
int gameID = Memories.LocationsWithPKCenter[1][matchingOriginGame];
if (pkm.XY && gameID != 0 || pkm.AO && gameID != 1)
if ((pkm.XY && gameID != 0) || (pkm.AO && gameID != 1))
data.AddLine(Severity.Invalid, string.Format(V162, V205), CheckIdentifier.Memory);
}
data.AddLine(VerifyCommonMemory(pkm, 0));
@ -309,6 +320,7 @@ namespace PKHeX.Core
data.AddLine(VerifyCommonMemory(pkm, 0));
}
private void VerifyHTMemory(LegalityAnalysis data)
{
var pkm = data.pkm;

View file

@ -9,6 +9,7 @@ namespace PKHeX.Core
public sealed class MiscVerifier : Verifier
{
protected override CheckIdentifier Identifier => CheckIdentifier.Misc;
public override void Verify(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -18,21 +19,21 @@ namespace PKHeX.Core
if (pkm is IContestStats s && s.HasContestStats())
data.AddLine(GetInvalid(V320, CheckIdentifier.Egg));
if (pkm is PK4 pk4)
switch (pkm)
{
if (pk4.ShinyLeaf != 0)
case PK4 pk4 when pk4.ShinyLeaf != 0:
data.AddLine(GetInvalid(V414, CheckIdentifier.Egg));
if (pk4.PokéathlonStat != 0)
break;
case PK4 pk4 when pk4.PokéathlonStat != 0:
data.AddLine(GetInvalid(V415, CheckIdentifier.Egg));
}
if (pkm is PK3)
{
if (pkm.Language != 1) // All Eggs are Japanese and flagged specially for localized string
break;
case PK3 _ when pkm.Language != 1: // All Eggs are Japanese and flagged specially for localized string
data.AddLine(GetInvalid(string.Format(V5, LanguageID.Japanese, (LanguageID)pkm.Language), CheckIdentifier.Egg));
break;
}
}
VerifyMiscFatefulEncounter(data);
}
@ -52,6 +53,7 @@ namespace PKHeX.Core
VerifyMiscG1Types(data, pk1);
VerifyMiscG1CatchRate(data, pk1);
}
private void VerifyMiscG1Types(LegalityAnalysis data, PK1 pk1)
{
var Type_A = pk1.Type_A;
@ -60,9 +62,13 @@ namespace PKHeX.Core
{
// Can have any type combination of any species by using Conversion.
if (!Legal.Types_Gen1.Contains(Type_A))
{
data.AddLine(GetInvalid(V386));
}
else if (!Legal.Types_Gen1.Contains(Type_B))
{
data.AddLine(GetInvalid(V387));
}
else // Both match a type, ensure a gen1 species has this combo
{
var TypesAB_Match = PersonalTable.RB.IsValidTypeCombination(Type_A, Type_B);
@ -81,6 +87,7 @@ namespace PKHeX.Core
data.AddLine(second);
}
}
private void VerifyMiscG1CatchRate(LegalityAnalysis data, PK1 pk1)
{
var e = data.EncounterMatch;
@ -98,14 +105,23 @@ namespace PKHeX.Core
break;
case TradebackType.Gen1_NotTradeback:
if ((e as EncounterStatic)?.Version == GameVersion.Stadium || e is EncounterTradeCatchRate)
{
// Encounters detected by the catch rate, cant be invalid if match this encounters
data.AddLine(GetValid(V398));
else if (pk1.Species == 149 && catch_rate == PersonalTable.Y[149].CatchRate || Legal.Species_NotAvailable_CatchRate.Contains(pk1.Species) && catch_rate == PersonalTable.RB[pk1.Species].CatchRate)
}
else if ((pk1.Species == 149 && catch_rate == PersonalTable.Y[149].CatchRate) || (Legal.Species_NotAvailable_CatchRate.Contains(pk1.Species) && catch_rate == PersonalTable.RB[pk1.Species].CatchRate))
{
data.AddLine(GetInvalid(V396));
}
else if (!data.Info.EvoChainsAllGens[1].Any(c => RateMatchesEncounter(c.Species)))
{
data.AddLine(GetInvalid(pk1.Gen1_NotTradeback ? V397 : V399));
}
else
{
data.AddLine(GetValid(V398));
}
break;
}
@ -118,6 +134,7 @@ namespace PKHeX.Core
return false;
}
}
private static void VerifyMiscFatefulEncounter(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -154,13 +171,13 @@ namespace PKHeX.Core
if (pkm.FatefulEncounter)
data.AddLine(GetInvalid(V325, CheckIdentifier.Fateful));
}
private static void VerifyMiscEggCommon(LegalityAnalysis data)
{
var pkm = data.pkm;
if (pkm.Move1_PPUps > 0 || pkm.Move2_PPUps > 0 || pkm.Move3_PPUps > 0 || pkm.Move4_PPUps > 0)
data.AddLine(GetInvalid(V319, CheckIdentifier.Egg));
if (pkm.Move1_PP != pkm.GetMovePP(pkm.Move1, 0) || pkm.Move2_PP != pkm.GetMovePP(pkm.Move2, 0)
|| pkm.Move3_PP != pkm.GetMovePP(pkm.Move3, 0) || pkm.Move4_PP != pkm.GetMovePP(pkm.Move4, 0))
if (pkm.Move1_PP != pkm.GetMovePP(pkm.Move1, 0) || pkm.Move2_PP != pkm.GetMovePP(pkm.Move2, 0) || pkm.Move3_PP != pkm.GetMovePP(pkm.Move3, 0) || pkm.Move4_PP != pkm.GetMovePP(pkm.Move4, 0))
data.AddLine(GetInvalid(V420, CheckIdentifier.Egg));
var EncounterMatch = data.EncounterMatch;
@ -177,6 +194,7 @@ namespace PKHeX.Core
data.AddLine(GetInvalid(msg, CheckIdentifier.Egg));
}
}
private static void VerifyFatefulMysteryGift(LegalityAnalysis data, MysteryGift g)
{
var pkm = data.pkm;
@ -193,12 +211,14 @@ namespace PKHeX.Core
: GetInvalid(V322, CheckIdentifier.Fateful);
data.AddLine(result);
}
private static void VerifyWC3Shiny(LegalityAnalysis data, WC3 g3)
{
// check for shiny locked gifts
if (!g3.Shiny.IsValid(data.pkm))
data.AddLine(GetInvalid(V409, CheckIdentifier.Fateful));
}
private static void VerifyFatefulIngameActive(LegalityAnalysis data)
{
var pkm = data.pkm;

View file

@ -34,6 +34,7 @@ namespace PKHeX.Core
if (pkm.IsShiny)
data.AddLine(GetInvalid(V220, CheckIdentifier.Shiny));
}
private static bool VerifyNsPKMOTValid(PKM pkm)
{
if (pkm.TID != 00002 || pkm.SID != 00000)

View file

@ -106,7 +106,9 @@ namespace PKHeX.Core
data.AddLine(GetInvalid(V20));
}
else
{
data.AddLine(GetValid(V18));
}
}
return false;
}
@ -139,6 +141,7 @@ namespace PKHeX.Core
else
data.AddLine(GetValid(V14, CheckIdentifier.Egg));
}
private void VerifyNicknameTrade(LegalityAnalysis data)
{
switch (data.Info.Generation)
@ -177,7 +180,6 @@ namespace PKHeX.Core
}
}
private void VerifyTrade12(LegalityAnalysis data)
{
var et = (EncounterTrade)data.EncounterOriginal;
@ -187,6 +189,7 @@ namespace PKHeX.Core
if (!EncounterGenerator.IsEncounterTrade1Valid(data.pkm, et))
data.AddLine(GetInvalid(V10, CheckIdentifier.Trainer));
}
private void VerifyTrade3(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -199,8 +202,11 @@ namespace PKHeX.Core
VerifyTradeTable(data, Encounters3.TradeFRLG, Encounters3.TradeGift_FRLG, lang);
}
else
{
VerifyTradeTable(data, Encounters3.TradeRSE, Encounters3.TradeGift_RSE);
}
}
private void VerifyTrade4(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -241,6 +247,7 @@ namespace PKHeX.Core
VerifyTradeTable(data, Encounters4.TradeDPPt, Encounters4.TradeGift_DPPt, lang);
}
}
private static int DetectTradeLanguageG3DANTAEJynx(PKM pk, int lang)
{
if (lang != (int)LanguageID.Italian)
@ -250,6 +257,7 @@ namespace PKHeX.Core
lang = (int)LanguageID.English; // translation error; OT was not localized => same as English
return lang;
}
private static int DetectTradeLanguageG4MeisterMagikarp(PKM pkm, int lang)
{
if (lang == (int)LanguageID.English)
@ -273,6 +281,7 @@ namespace PKHeX.Core
return lang;
}
private static int DetectTradeLanguageG4SurgePikachu(PKM pkm, int lang)
{
if (lang == (int)LanguageID.French)
@ -296,6 +305,7 @@ namespace PKHeX.Core
return lang;
}
private void VerifyTrade5(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -318,6 +328,7 @@ namespace PKHeX.Core
VerifyTradeTable(data, Encounters5.TradeB2W2, Encounters5.TradeGift_B2W2);
}
}
private void VerifyTrade6(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -326,6 +337,7 @@ namespace PKHeX.Core
else if (pkm.AO)
VerifyTradeTable(data, Encounters6.TradeAO, Encounters6.TradeGift_AO, pkm.Language);
}
private void VerifyTrade7(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -334,28 +346,37 @@ namespace PKHeX.Core
else if (pkm.USUM)
VerifyTradeTable(data, Encounters7.TradeUSUM, Encounters7.TradeGift_USUM, pkm.Language);
}
private void VerifyTrade4Ranch(LegalityAnalysis data) => VerifyTradeOTOnly(data, Encounters4.RanchOTNames);
private void VerifyTradeTable(LegalityAnalysis data, string[][] ots, EncounterTrade[] table) => VerifyTradeTable(data, ots, table, data.pkm.Language);
private void VerifyTradeTable(LegalityAnalysis data, string[][] ots, EncounterTrade[] table, int language)
{
var validOT = language >= ots.Length ? ots[0] : ots[language];
var index = Array.IndexOf(table, data.EncounterMatch);
VerifyTradeOTNick(data, validOT, index);
}
private void VerifyTradeOTOnly(LegalityAnalysis data, string[] validOT)
{
var result = CheckTradeOTOnly(data, validOT);
data.AddLine(result);
}
private CheckResult CheckTradeOTOnly(LegalityAnalysis data, string[] validOT)
{
var pkm = data.pkm;
if (pkm.IsNicknamed)
data.AddLine(GetInvalid(V9, CheckIdentifier.Nickname));
return GetInvalid(V9, CheckIdentifier.Nickname);
int lang = pkm.Language;
if (validOT.Length <= lang)
data.AddLine(GetInvalid(V8, CheckIdentifier.Trainer));
else if (validOT[lang] != pkm.OT_Name)
data.AddLine(GetInvalid(V10, CheckIdentifier.Trainer));
else
data.AddLine(GetValid(V11, CheckIdentifier.Nickname));
return GetInvalid(V8, CheckIdentifier.Trainer);
if (validOT[lang] != pkm.OT_Name)
return GetInvalid(V10, CheckIdentifier.Trainer);
return GetValid(V11, CheckIdentifier.Nickname);
}
private void VerifyTradeOTNick(LegalityAnalysis data, string[] validOT, int index)
{
if (validOT.Length == 0)
@ -370,13 +391,11 @@ namespace PKHeX.Core
}
string nick = validOT[index];
string OT = validOT[validOT.Length / 2 + index];
string OT = validOT[(validOT.Length / 2) + index];
var pkm = data.pkm;
var EncounterMatch = data.EncounterMatch;
if (nick != pkm.Nickname
&& !(nick == "Quacklin" && pkm.Nickname == "Quacklin'") // apostrophe farfetch'd edge case
&& ((EncounterTrade)EncounterMatch).IsNicknamed) // trades that are not nicknamed (but are present in a table with others being named)
if (!IsNicknameMatch(nick, pkm, EncounterMatch)) // trades that are not nicknamed (but are present in a table with others being named)
data.AddLine(GetInvalid(V9, CheckIdentifier.Nickname));
else
data.AddLine(GetValid(V11, CheckIdentifier.Nickname));
@ -384,5 +403,14 @@ namespace PKHeX.Core
if (OT != pkm.OT_Name)
data.AddLine(GetInvalid(V10, CheckIdentifier.Trainer));
}
private static bool IsNicknameMatch(string nick, PKM pkm, IEncounterable EncounterMatch)
{
if (nick != pkm.Nickname)
return false;
if (nick == "Quacklin" && pkm.Nickname == "Quacklin'")
return true;
return ((EncounterTrade)EncounterMatch).IsNicknamed;
}
}
}

View file

@ -24,7 +24,7 @@ namespace PKHeX.Core
data.AddLine(Get(V207, Severity.Fishy));
var Info = data.Info;
if ((Info.Generation >= 6 || Info.Generation < 3 && pkm.Format >= 7) && pkm.PID == pkm.EncryptionConstant)
if ((Info.Generation >= 6 || (Info.Generation < 3 && pkm.Format >= 7)) && pkm.PID == pkm.EncryptionConstant)
data.AddLine(GetInvalid(V208)); // better to flag than 1:2^32 odds since RNG is not feasible to yield match
VerifyShiny(data);
@ -75,6 +75,7 @@ namespace PKHeX.Core
if (result != 0)
data.AddLine(GetInvalid(V411));
}
private void VerifyECPIDWurmple(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -91,6 +92,7 @@ namespace PKHeX.Core
data.AddLine(GetInvalid(V210, CheckIdentifier.EC));
}
}
private void VerifyEC(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -99,7 +101,9 @@ namespace PKHeX.Core
if (pkm.EncryptionConstant == 0)
data.AddLine(Get(V201, Severity.Fishy, CheckIdentifier.EC));
if (3 <= Info.Generation && Info.Generation <= 5)
{
VerifyTransferEC(data);
}
else
{
int xor = pkm.TSV ^ pkm.PSV;
@ -107,6 +111,7 @@ namespace PKHeX.Core
data.AddLine(Get(V211, Severity.Fishy, CheckIdentifier.EC));
}
}
private void VerifyTransferEC(LegalityAnalysis data)
{
var pkm = data.pkm;

View file

@ -11,6 +11,7 @@ namespace PKHeX.Core
public sealed class RibbonVerifier : Verifier
{
protected override CheckIdentifier Identifier => CheckIdentifier.Ribbon;
public override void Verify(LegalityAnalysis data)
{
var EncounterMatch = data.EncounterMatch;
@ -33,7 +34,9 @@ namespace PKHeX.Core
data.AddLine(GetInvalid(msg));
}
else
{
data.AddLine(GetValid(V602));
}
}
private static List<string> GetIncorrectRibbons(PKM pkm, object encounterContent, int gen)
@ -51,6 +54,7 @@ namespace PKHeX.Core
result.Add(string.Format(V601, string.Join(", ", invalidRibbons.Select(z => z.Replace("Ribbon", "")))));
return result;
}
private static bool GetIncorrectRibbonsEgg(PKM pkm, object encounterContent)
{
var RibbonNames = ReflectUtil.GetPropertiesStartWithPrefix(pkm.GetType(), "Ribbon");
@ -69,6 +73,7 @@ namespace PKHeX.Core
}
return false;
}
private static IEnumerable<RibbonResult> GetRibbonResults(PKM pkm, object encounterContent, int gen)
{
return GetInvalidRibbons(pkm, gen)
@ -96,8 +101,10 @@ namespace PKHeX.Core
if (pkm is IRibbonSetUnique4 u4)
{
if (!IsAllowedBattleFrontier(pkm.Species, pkm.AltForm, 4))
{
foreach (var z in GetInvalidRibbonsNone(u4.RibbonBitsAbility(), u4.RibbonNamesAbility()))
yield return z;
}
var c3 = u4.RibbonBitsContest3(); var c3n = u4.RibbonNamesContest3();
var c4 = u4.RibbonBitsContest4(); var c4n = u4.RibbonNamesContest4();
@ -115,10 +122,12 @@ namespace PKHeX.Core
{
bool required = false;
for (int j = i + 3; j >= i; j--)
{
if (bits[j])
required = true;
else if (required)
yield return new RibbonResult(names[j], false);
}
}
}
}
@ -170,25 +179,32 @@ namespace PKHeX.Core
yield return new RibbonResult(nameof(s3.RibbonEffort));
}
}
private static IEnumerable<RibbonResult> GetInvalidRibbons4Any(PKM pkm, IRibbonSetCommon4 s4, int gen)
{
if (s4.RibbonRecord)
yield return new RibbonResult(nameof(s4.RibbonRecord)); // Unobtainable
if (s4.RibbonFootprint && (pkm.Format < 6 && gen == 5 || gen >= 5 && pkm.CurrentLevel - pkm.Met_Level < 30))
if (s4.RibbonFootprint && ((pkm.Format < 6 && gen == 5) || (gen >= 5 && pkm.CurrentLevel - pkm.Met_Level < 30)))
yield return new RibbonResult(nameof(s4.RibbonFootprint));
bool gen34 = gen == 3 || gen == 4;
bool not6 = pkm.Format < 6 || gen > 6 || gen < 3;
bool noDaily = !gen34 && not6;
bool noCosmetic = !gen34 && (not6 || pkm.XY && pkm.IsUntraded);
bool noCosmetic = !gen34 && (not6 || (pkm.XY && pkm.IsUntraded));
if (noDaily)
{
foreach (var z in GetInvalidRibbonsNone(s4.RibbonBitsDaily(), s4.RibbonNamesDaily()))
yield return z;
}
if (noCosmetic)
{
foreach (var z in GetInvalidRibbonsNone(s4.RibbonBitsCosmetic(), s4.RibbonNamesCosmetic()))
yield return z;
}
}
private static IEnumerable<RibbonResult> GetInvalidRibbons6Any(PKM pkm, IRibbonSetCommon6 s6, int gen)
{
foreach (var p in GetInvalidRibbons6Memory(pkm, s6, gen))
@ -201,7 +217,7 @@ namespace PKHeX.Core
var contest = s6.RibbonBitsContest();
bool allContest = contest.All(z => z);
if (allContest ^ s6.RibbonContestStar && !(untraded && pkm.XY)) // if not already checked
if ((allContest ^ s6.RibbonContestStar) && !(untraded && pkm.XY)) // if not already checked
yield return new RibbonResult(nameof(s6.RibbonContestStar), s6.RibbonContestStar);
// Each contest victory requires a contest participation; each participation gives 20 OT affection (not current trainer).
@ -229,6 +245,7 @@ namespace PKHeX.Core
result.Combine(new RibbonResult(nameof(s6.RibbonBattlerExpert)));
yield return result;
}
private static IEnumerable<RibbonResult> GetInvalidRibbons6Memory(PKM pkm, IRibbonSetCommon6 s6, int gen)
{
int contest = 0;
@ -249,6 +266,7 @@ namespace PKHeX.Core
if (s6.RibbonCountMemoryBattle > battle)
yield return new RibbonResult(nameof(s6.RibbonCountMemoryBattle));
}
private static IEnumerable<RibbonResult> GetInvalidRibbons6Untraded(PKM pkm, IRibbonSetCommon6 s6)
{
if (pkm.XY)
@ -275,6 +293,7 @@ namespace PKHeX.Core
yield return new RibbonResult(nameof(s6.RibbonChampionKalos));
}
}
private static IEnumerable<RibbonResult> GetInvalidRibbons6Traded(PKM pkm, IRibbonSetCommon6 s6)
{
if (s6.RibbonTraining)
@ -294,6 +313,7 @@ namespace PKHeX.Core
result.Combine(new RibbonResult(nameof(s6.RibbonChampionG6Hoenn)));
yield return result;
}
private static IEnumerable<RibbonResult> GetInvalidRibbons7Any(PKM pkm, IRibbonSetCommon7 s7)
{
if (!IsAllowedBattleFrontier(pkm.Species))
@ -322,14 +342,17 @@ namespace PKHeX.Core
{
// only require national ribbon if no longer on origin game
bool xd = s.Version == GameVersion.XD;
eb[1] = !(xd && pkm is XK3 x && !x.RibbonNational || !xd && pkm is CK3 c && !c.RibbonNational);
eb[1] = !((xd && pkm is XK3 x && !x.RibbonNational) || (!xd && pkm is CK3 c && !c.RibbonNational));
}
}
for (int i = 0; i < sb.Length; i++)
{
if (sb[i] != eb[i])
yield return new RibbonResult(names[i], !eb[i]); // only flag if invalid
}
}
private static IEnumerable<RibbonResult> GetInvalidRibbonsEvent2(PKM pkm, object encounterContent)
{
if (!(pkm is IRibbonSetEvent4 set2))
@ -342,17 +365,23 @@ namespace PKHeX.Core
eb[1] = true; // require Wishing Ribbon
for (int i = 0; i < sb.Length; i++)
{
if (sb[i] != eb[i])
yield return new RibbonResult(names[i], !eb[i]); // only flag if invalid
}
}
private static IEnumerable<RibbonResult> GetInvalidRibbonsNone(IReadOnlyList<bool> bits, IReadOnlyList<string> names)
{
for (int i = 0; i < bits.Count; i++)
{
if (bits[i])
yield return new RibbonResult(names[i]);
}
}
private static bool IsAllowedInContest4(int species) => species != 201 && species != 132; // Disallow Unown and Ditto
private static bool IsAllowedBattleFrontier(int species, int form = 0, int gen = 0)
{
if (gen == 4 && species == 172 && form == 1) // spiky

View file

@ -1,4 +1,5 @@
using static PKHeX.Core.LegalityCheckStrings;
using System.Linq;
using static PKHeX.Core.LegalityCheckStrings;
namespace PKHeX.Core
{
@ -13,6 +14,7 @@ namespace PKHeX.Core
{
"PKHeX",
};
public override void Verify(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -29,20 +31,30 @@ namespace PKHeX.Core
data.AddLine(GetInvalid(V106));
if (pkm.TID == 0 && pkm.SID == 0)
{
data.AddLine(Get(V33, Severity.Fishy));
}
else if (pkm.VC)
{
if (pkm.SID != 0)
data.AddLine(GetInvalid(V34));
}
else if (pkm.TID == pkm.SID)
{
data.AddLine(Get(V35, Severity.Fishy));
}
else if (pkm.TID == 0)
{
data.AddLine(Get(V36, Severity.Fishy));
}
else if (pkm.SID == 0)
{
data.AddLine(Get(V37, Severity.Fishy));
else if (pkm.TID == 12345 && pkm.SID == 54321 || IsOTNameSuspicious(ot))
}
else if ((pkm.TID == 12345 && pkm.SID == 54321) || IsOTNameSuspicious(ot))
{
data.AddLine(Get(V417, Severity.Fishy));
}
if (pkm.VC)
VerifyOTG1(data);
@ -55,6 +67,7 @@ namespace PKHeX.Core
data.AddLine(GetInvalid($"Wordfilter: {bad}"));
}
}
public void VerifyOTG1(LegalityAnalysis data)
{
var pkm = data.pkm;
@ -72,9 +85,10 @@ namespace PKHeX.Core
data.AddLine(GetInvalid(V39));
}
if (pkm.OT_Gender == 1 && (pkm.Format == 2 && pkm.Met_Location == 0 || pkm.Format > 2 && pkm.VC1))
if (pkm.OT_Gender == 1 && ((pkm.Format == 2 && pkm.Met_Location == 0) || (pkm.Format > 2 && pkm.VC1)))
data.AddLine(GetInvalid(V408));
}
private void VerifyG1OTWithinBounds(LegalityAnalysis data, string str)
{
if (StringConverter.GetIsG1English(str))
@ -97,7 +111,8 @@ namespace PKHeX.Core
data.AddLine(GetInvalid(V421));
}
}
private CheckResult VerifyG1OTStadium(PKM pkm, string tr, EncounterStatic s)
private CheckResult VerifyG1OTStadium(PKM pkm, string tr, IVersion s)
{
bool jp = pkm.Japanese;
bool valid;
@ -110,10 +125,7 @@ namespace PKHeX.Core
private bool IsOTNameSuspicious(string name)
{
foreach (var ot in SuspiciousOTNames)
if (name.StartsWith(ot))
return true;
return false;
return SuspiciousOTNames.Any(name.StartsWith);
}
}
}

View file

@ -10,6 +10,7 @@ namespace PKHeX.Core
public sealed class TransferVerifier : Verifier
{
protected override CheckIdentifier Identifier => CheckIdentifier.Encounter;
public override void Verify(LegalityAnalysis data)
{
throw new NotImplementedException();
@ -73,9 +74,10 @@ namespace PKHeX.Core
if (encounter is EncounterStatic s && s.Version == GameVersion.C && s.EggLocation == 256) // Dizzy Punch Gifts
FlagIncompatibleTransferMove(pkm, Moves, 146, 2); // can't have Dizzy Punch at all
bool checkShiny = pkm.VC2 || pkm.TradebackStatus == TradebackType.WasTradeback && pkm.VC1;
bool checkShiny = pkm.VC2 || (pkm.TradebackStatus == TradebackType.WasTradeback && pkm.VC1);
if (!checkShiny)
yield break;
if (pkm.Gender == 1) // female
{
if (pkm.PersonalInfo.Gender == 31 && pkm.IsShiny) // impossible gender-shiny

View file

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace PKHeX.Core
@ -11,11 +12,13 @@ namespace PKHeX.Core
public byte mainform;
public FormSubregionTable[] otherforms;
}
private struct FormSubregionTable
{
public byte form;
public int[] region;
}
private static readonly int[][] VivillonCountryTable =
{
//missing ID 051,068,102,127,160,186
@ -38,6 +41,7 @@ namespace PKHeX.Core
/*16 Ocean */ new[] { 049, 077},
/*17 Jungle */ new[] { 016, 021, 022, 025, 027, 031, 040, 046, 052, 169, 153, 156},
};
private static readonly CountryTable[] RegionFormTable =
{
new CountryTable{
@ -272,13 +276,16 @@ namespace PKHeX.Core
/// <param name="region">Console Region ID</param>
public static int GetVivillonPattern(int country, int region)
{
CountryTable ct = Array.Find(RegionFormTable, t => t.countryID == country);
var ct = Array.Find(RegionFormTable, t => t.countryID == country);
if (ct.otherforms == null) // empty struct = no forms referenced
return ct.mainform; // No subregion table
foreach (var sub in ct.otherforms)
{
if (sub.region.Contains(region))
return sub.form;
}
return ct.mainform;
}
@ -295,9 +302,9 @@ namespace PKHeX.Core
case 0: // Japan
return country == 1;
case 1: // Americas
return 8 <= country && country <= 52 || new[] { 153, 156, 168, 174, 186 }.Contains(country);
return (8 <= country && country <= 52) || ExtendedAmericas.Contains(country);
case 2: // Europe
return 64 <= country && country <= 127 || new[] { 169, 184, 185 }.Contains(country);
return (64 <= country && country <= 127) || ExtendedEurope.Contains(country);
case 4: // China
return country == 144 || country == 160;
case 5: // Korea
@ -308,5 +315,8 @@ namespace PKHeX.Core
return false;
}
}
private static readonly HashSet<int> ExtendedAmericas = new HashSet<int> {153, 156, 168, 174, 186};
private static readonly HashSet<int> ExtendedEurope = new HashSet<int> { 153, 156, 168, 174, 186 };
}
}

View file

@ -92,10 +92,12 @@ namespace PKHeX.Core
byte[] data = (byte[])Data.Clone();
return GetMysteryGift(data);
}
/// <summary>
/// Gets a friendly name for the underlying <see cref="MysteryGift"/> type.
/// </summary>
public string Type => GetType().Name;
/// <summary>
/// Gets a friendly name for the underlying <see cref="MysteryGift"/> type for the <see cref="IEncounterable"/> interface.
/// </summary>
@ -126,7 +128,7 @@ namespace PKHeX.Core
{
int hash = 17;
foreach (var b in Data)
hash = hash*31 + b;
hash = (hash * 31) + b;
return hash;
}

View file

@ -71,6 +71,7 @@ namespace PKHeX.Core
}
}
}
private static void AddLinesPKM(MysteryGift gift, IBasicStrings strings, ICollection<string> result)
{
int TID7() => (int)((uint)(gift.TID | (gift.SID << 16)) % 1000000);

View file

@ -205,6 +205,7 @@ namespace PKHeX.Core
EncryptPK();
return true;
}
private void EncryptPK()
{
byte[] ekdata = new byte[PKX.SIZE_4PARTY];

View file

@ -8,4 +8,21 @@
int TID { get; set; }
int SID { get; set; }
}
public static partial class Extensions
{
public static int GetTrainerIDFormat(this ITrainerID tr)
{
if (tr is PKM p)
{
var format = p.GenNumber;
if ((format < 3 && p.Format >= 7) || format <= 0) // VC or bad gen
return 4; // use TID/SID 16bit style
return format;
}
if (tr is SaveFile s)
return s.Generation;
return -1;
}
}
}

View file

@ -245,6 +245,7 @@
r[i] = (data[start + (i >> 3)] >> (i & 7) & 0x1) == 1;
return r;
}
protected static byte[] SetBits(bool[] bits)
{
byte[] data = new byte[bits.Length>>3];
@ -313,6 +314,7 @@
/// Indicates that the entry is exclusively Female gendered.
/// </summary>
public bool OnlyFemale => Gender == 254;
/// <summary>
/// Indicates that the entry is exclusively Male gendered.
/// </summary>

View file

@ -6,6 +6,7 @@
public class PersonalInfoB2W2 : PersonalInfoBW
{
public new const int SIZE = 0x4C;
public PersonalInfoB2W2(byte[] data)
{
if (data.Length != SIZE)

View file

@ -7,6 +7,7 @@
{
protected PersonalInfoG1() { }
public const int SIZE = 0x1C;
public PersonalInfoG1(byte[] data)
{
if (data.Length != SIZE)
@ -15,6 +16,7 @@
Data = data;
TMHM = GetBits(Data, 0x14, 0x8);
}
public override byte[] Write()
{
SetBits(TMHM).CopyTo(Data, 0x14);
@ -58,6 +60,7 @@
public override int BaseFriendship { get => 0; set { } }
public override int EscapeRate { get => 0; set { } }
public override int Color { get => 0; set { } }
public int[] Moves
{
get => new[] { Move1, Move2, Move3, Move4 };

View file

@ -7,6 +7,7 @@
{
protected PersonalInfoG2() { }
public const int SIZE = 0x20;
public PersonalInfoG2(byte[] data)
{
if (data.Length != SIZE)
@ -15,6 +16,7 @@
Data = data;
TMHM = GetBits(Data, 0x18, 0x8);
}
public override byte[] Write()
{
SetBits(TMHM).CopyTo(Data, 0x18);
@ -37,8 +39,8 @@
public override int Gender { get => Data[0xD]; set => Data[0xD] = (byte)value; }
public override int HatchCycles { get => Data[0xF]; set => Data[0xF] = (byte)value; }
public override int EXPGrowth { get => Data[0x16]; set => Data[0x16] = (byte)value; }
public override int EggGroup1 { get => Data[0x17] & 0xF; set => Data[0x17] = (byte)(Data[0x17] & 0xF0 | value); }
public override int EggGroup2 { get => Data[0x17] >> 4; set => Data[0x17] = (byte)(Data[0x17] & 0x0F | value << 4); }
public override int EggGroup1 { get => Data[0x17] & 0xF; set => Data[0x17] = (byte)((Data[0x17] & 0xF0) | value); }
public override int EggGroup2 { get => Data[0x17] >> 4; set => Data[0x17] = (byte)((Data[0x17] & 0x0F) | value << 4); }
public override int[] Items
{

View file

@ -9,6 +9,7 @@ namespace PKHeX.Core
{
protected PersonalInfoG3() { }
public const int SIZE = 0x1C;
public PersonalInfoG3(byte[] data)
{
if (data.Length != SIZE)
@ -16,6 +17,7 @@ namespace PKHeX.Core
Data = data;
}
public override byte[] Write() => Data;
public override int HP { get => Data[0x00]; set => Data[0x00] = (byte)value; }
@ -46,7 +48,7 @@ namespace PKHeX.Core
public int Ability1 { get => Data[0x16]; set => Data[0x16] = (byte)value; }
public int Ability2 { get => Data[0x17]; set => Data[0x17] = (byte)value; }
public override int EscapeRate { get => Data[0x18]; set => Data[0x18] = (byte)value; }
public override int Color { get => Data[0x19] & 0x7F; set => Data[0x19] = (byte)(Data[0x19] & 0x80 | value); }
public override int Color { get => Data[0x19] & 0x7F; set => Data[0x19] = (byte)((Data[0x19] & 0x80) | value); }
public bool NoFlip { get => Data[0x19] >> 7 == 1; set => Data[0x19] = (byte)(Color | (value ? 0x80 : 0)); }
public override int[] Items
@ -59,6 +61,7 @@ namespace PKHeX.Core
Item2 = value[1];
}
}
public override int[] Abilities
{
get => new[] { Ability1, Ability2 };

View file

@ -8,6 +8,7 @@ namespace PKHeX.Core
public class PersonalInfoG4 : PersonalInfoG3
{
public new const int SIZE = 0x2C;
public PersonalInfoG4(byte[] data)
{
if (data.Length != SIZE)
@ -18,6 +19,7 @@ namespace PKHeX.Core
TMHM = GetBits(Data, 0x1C, 0x0D);
TypeTutors = new bool[0]; // not stored in personal
}
public override byte[] Write()
{
SetBits(TMHM).CopyTo(Data, 0x1C);

View file

@ -6,6 +6,7 @@
public class PersonalInfoORAS : PersonalInfoXY
{
public new const int SIZE = 0x50;
public PersonalInfoORAS(byte[] data)
{
if (data.Length != SIZE)
@ -24,6 +25,7 @@
GetBits(Data, 0x4C, 0x04),
};
}
public override byte[] Write()
{
SetBits(TMHM).CopyTo(Data, 0x28);

View file

@ -8,6 +8,7 @@ namespace PKHeX.Core
public class PersonalInfoSM : PersonalInfoXY
{
public new const int SIZE = 0x54;
public PersonalInfoSM(byte[] data)
{
if (data.Length != SIZE)
@ -22,6 +23,7 @@ namespace PKHeX.Core
GetBits(Data, 0x3C, 0x0A),
};
}
public override byte[] Write()
{
SetBits(TMHM).CopyTo(Data, 0x28);

View file

@ -7,6 +7,7 @@
{
protected PersonalInfoXY() { } // For ORAS
public new const int SIZE = 0x40;
public PersonalInfoXY(byte[] data)
{
if (data.Length != SIZE)
@ -18,6 +19,7 @@
TypeTutors = GetBits(Data, 0x38, 0x4);
// 0x3C-0x40 unknown
}
public override byte[] Write()
{
SetBits(TMHM).CopyTo(Data, 0x28);

View file

@ -16,70 +16,87 @@ namespace PKHeX.Core
/// Personal Table used in <see cref="GameVersion.USUM"/>.
/// </summary>
public static readonly PersonalTable USUM = GetTable("uu", GameVersion.USUM);
/// <summary>
/// Personal Table used in <see cref="GameVersion.SM"/>.
/// </summary>
public static readonly PersonalTable SM = GetTable("sm", GameVersion.SM);
/// <summary>
/// Personal Table used in <see cref="GameVersion.ORAS"/>.
/// </summary>
public static readonly PersonalTable AO = GetTable("ao", GameVersion.ORAS);
/// <summary>
/// Personal Table used in <see cref="GameVersion.XY"/>.
/// </summary>
public static readonly PersonalTable XY = GetTable("xy", GameVersion.XY);
/// <summary>
/// Personal Table used in <see cref="GameVersion.B2W2"/>.
/// </summary>
public static readonly PersonalTable B2W2 = GetTable("b2w2", GameVersion.B2W2);
/// <summary>
/// Personal Table used in <see cref="GameVersion.BW"/>.
/// </summary>
public static readonly PersonalTable BW = GetTable("bw", GameVersion.BW);
/// <summary>
/// Personal Table used in <see cref="GameVersion.HGSS"/>.
/// </summary>
public static readonly PersonalTable HGSS = GetTable("hgss", GameVersion.HGSS);
/// <summary>
/// Personal Table used in <see cref="GameVersion.Pt"/>.
/// </summary>
public static readonly PersonalTable Pt = GetTable("pt", GameVersion.Pt);
/// <summary>
/// Personal Table used in <see cref="GameVersion.DP"/>.
/// </summary>
public static readonly PersonalTable DP = GetTable("dp", GameVersion.DP);
/// <summary>
/// Personal Table used in <see cref="GameVersion.LG"/>.
/// </summary>
public static readonly PersonalTable LG = GetTable("lg", GameVersion.LG);
/// <summary>
/// Personal Table used in <see cref="GameVersion.FR"/>.
/// </summary>
public static readonly PersonalTable FR = GetTable("fr", GameVersion.FR);
/// <summary>
/// Personal Table used in <see cref="GameVersion.E"/>.
/// </summary>
public static readonly PersonalTable E = GetTable("e", GameVersion.E);
/// <summary>
/// Personal Table used in <see cref="GameVersion.RS"/>.
/// </summary>
public static readonly PersonalTable RS = GetTable("rs", GameVersion.RS);
/// <summary>
/// Personal Table used in <see cref="GameVersion.C"/>.
/// </summary>
public static readonly PersonalTable C = GetTable("c", GameVersion.C);
/// <summary>
/// Personal Table used in <see cref="GameVersion.GS"/>.
/// </summary>
public static readonly PersonalTable GS = GetTable("c", GameVersion.GS);
/// <summary>
/// Personal Table used in <see cref="GameVersion.RB"/>.
/// </summary>
public static readonly PersonalTable RB = GetTable("rb", GameVersion.RBY);
/// <summary>
/// Personal Table used in <see cref="GameVersion.YW"/>.
/// </summary>
public static readonly PersonalTable Y = GetTable("y", GameVersion.RBY);
private static PersonalTable GetTable(string game, GameVersion format)
{
return new PersonalTable(Util.GetBinaryResource($"personal_{game}"), format);
@ -95,6 +112,7 @@ namespace PKHeX.Core
}
return r;
}
private static Func<byte[], PersonalInfo> GetConstructor(GameVersion format)
{
switch (format)
@ -119,6 +137,7 @@ namespace PKHeX.Core
return z => new PersonalInfoSM(z);
}
}
private static int GetEntrySize(GameVersion format)
{
switch (format)
@ -143,12 +162,14 @@ namespace PKHeX.Core
default: return -1;
}
}
static PersonalTable() // Finish Setup
{
FixPersonalTableG1();
PopulateGen3Tutors();
PopulateGen4Tutors();
}
private static void FixPersonalTableG1()
{
// Update Yellow's catch rates; currently matches Red/Blue's values.
@ -159,6 +180,7 @@ namespace PKHeX.Core
for (int i = 0; i <= Legal.MaxSpeciesID_1; i++)
RB[i].Gender = Y[i].Gender = GS[i].Gender;
}
private static void PopulateGen3Tutors()
{
// Update Gen3 data with Emerald's data, FR/LG is a subset of Emerald's compatibility.
@ -170,6 +192,7 @@ namespace PKHeX.Core
E[i].AddTypeTutors(tutors[i]);
}
}
private static void PopulateGen4Tutors()
{
var tutors = Data.UnpackMini(Util.GetBinaryResource("tutors_g4.pkl"), "g4");
@ -179,7 +202,7 @@ namespace PKHeX.Core
public PersonalTable(byte[] data, GameVersion format)
{
Func<byte[], PersonalInfo> get = GetConstructor(format);
var get = GetConstructor(format);
int size = GetEntrySize(format);
byte[][] entries = SplitBytes(data, size);
Table = new PersonalInfo[data.Length / size];
@ -188,6 +211,7 @@ namespace PKHeX.Core
MaxSpeciesID = format.GetMaxSpeciesID();
}
private readonly PersonalInfo[] Table;
/// <summary>

View file

@ -14,6 +14,7 @@
{
nameof(IRibbonSetCommon3.RibbonChampionG3Hoenn), nameof(IRibbonSetCommon3.RibbonArtist), nameof(IRibbonSetCommon3.RibbonEffort)
};
internal static bool[] RibbonBits(this IRibbonSetCommon3 set)
{
if (set == null)
@ -25,6 +26,7 @@
set.RibbonEffort,
};
}
internal static string[] RibbonNames(this IRibbonSetCommon3 _) => RibbonSetNamesCommon3;
}
}

View file

@ -25,6 +25,7 @@
{
nameof(IRibbonSetCommon4.RibbonGorgeous), nameof(IRibbonSetCommon4.RibbonRoyal), nameof(IRibbonSetCommon4.RibbonGorgeousRoyal),
};
internal static bool[] RibbonBitsCosmetic(this IRibbonSetCommon4 set)
{
if (set == null)
@ -36,11 +37,14 @@
set.RibbonGorgeousRoyal,
};
}
internal static string[] RibbonNamesCosmetic(this IRibbonSetCommon4 _) => RibbonSetNamesCommon4;
private static readonly string[] RibbonSetNamesCommon4Only =
{
nameof(IRibbonSetCommon4.RibbonRecord), nameof(IRibbonSetCommon4.RibbonChampionSinnoh), nameof(IRibbonSetCommon4.RibbonLegend),
};
internal static bool[] RibbonBitsOnly(this IRibbonSetCommon4 set)
{
if (set == null)
@ -52,6 +56,7 @@
set.RibbonLegend,
};
}
internal static string[] RibbonNamesOnly(this IRibbonSetCommon4 _) => RibbonSetNamesCommon4Only;
private static readonly string[] RibbonSetNamesCommon4Daily =
@ -76,6 +81,7 @@
set.RibbonSmile,
};
}
internal static string[] RibbonNamesDaily(this IRibbonSetCommon4 _) => RibbonSetNamesCommon4Daily;
}
}

View file

@ -30,12 +30,14 @@
nameof(IRibbonSetCommon6.RibbonContestStar), nameof(IRibbonSetCommon6.RibbonMasterCoolness), nameof(IRibbonSetCommon6.RibbonMasterBeauty),
nameof(IRibbonSetCommon6.RibbonMasterCuteness), nameof(IRibbonSetCommon6.RibbonMasterCleverness), nameof(IRibbonSetCommon6.RibbonMasterToughness),
};
private static readonly string[] RibbonSetNamesCommon6Contest =
{
nameof(IRibbonSetCommon6.RibbonMasterCoolness), nameof(IRibbonSetCommon6.RibbonMasterBeauty),
nameof(IRibbonSetCommon6.RibbonMasterCuteness), nameof(IRibbonSetCommon6.RibbonMasterCleverness),
nameof(IRibbonSetCommon6.RibbonMasterToughness),
};
internal static bool[] RibbonBits(this IRibbonSetCommon6 set)
{
if (set == null)
@ -57,6 +59,7 @@
set.RibbonMasterToughness,
};
}
internal static bool[] RibbonBitsContest(this IRibbonSetCommon6 set)
{
if (set == null)
@ -70,6 +73,7 @@
set.RibbonMasterToughness,
};
}
internal static string[] RibbonNamesBool(this IRibbonSetCommon6 _) => RibbonSetNamesCommon6Bool;
internal static string[] RibbonNamesContest(this IRibbonSetCommon6 _) => RibbonSetNamesCommon6Contest;
}

View file

@ -16,6 +16,7 @@
nameof(IRibbonSetCommon7.RibbonChampionAlola), nameof(IRibbonSetCommon7.RibbonBattleRoyale),
nameof(IRibbonSetCommon7.RibbonBattleTreeGreat), nameof(IRibbonSetCommon7.RibbonBattleTreeMaster)
};
internal static bool[] RibbonBits(this IRibbonSetCommon7 set)
{
if (set == null)
@ -28,6 +29,7 @@
set.RibbonBattleTreeMaster,
};
}
internal static string[] RibbonNames(this IRibbonSetCommon7 _) => RibbonSetNamesCommon7;
}
}

View file

@ -18,6 +18,7 @@
nameof(IRibbonSetEvent3.RibbonEarth), nameof(IRibbonSetEvent3.RibbonNational), nameof(IRibbonSetEvent3.RibbonCountry),
nameof(IRibbonSetEvent3.RibbonChampionBattle), nameof(IRibbonSetEvent3.RibbonChampionRegional), nameof(IRibbonSetEvent3.RibbonChampionNational)
};
internal static bool[] RibbonBits(this IRibbonSetEvent3 set)
{
if (set == null)
@ -32,6 +33,7 @@
set.RibbonChampionNational,
};
}
internal static string[] RibbonNames(this IRibbonSetEvent3 _) => RibbonSetNamesEvent3;
}
}

View file

@ -27,6 +27,7 @@
nameof(IRibbonSetOnly3.Unused1), nameof(IRibbonSetOnly3.Unused2),
nameof(IRibbonSetOnly3.Unused3), nameof(IRibbonSetOnly3.Unused4),
};
internal static int[] RibbonCounts(this IRibbonSetOnly3 set)
{
if (set == null)
@ -40,6 +41,7 @@
set.RibbonCountG3Tough,
};
}
internal static string[] RibbonNames(this IRibbonSetOnly3 _) => RibbonSetNamesOnly3;
}
}

View file

@ -5,6 +5,7 @@
{
/// <summary> Ribbon awarded for clearing Hoenn's Battle Tower's Lv. 50 challenge. </summary>
bool RibbonWinning { get; set; }
/// <summary> Ribbon awarded for clearing Hoenn's Battle Tower's Lv. 100 challenge. </summary>
bool RibbonVictory { get; set; }
}
@ -15,6 +16,7 @@
{
nameof(IRibbonSetUnique3.RibbonWinning), nameof(IRibbonSetUnique3.RibbonVictory),
};
internal static bool[] RibbonBits(this IRibbonSetUnique3 set)
{
if (set == null)
@ -25,6 +27,7 @@
set.RibbonVictory,
};
}
internal static string[] RibbonNames(this IRibbonSetUnique3 _) => RibbonSetNamesUnique3;
}
}

View file

@ -64,6 +64,7 @@
nameof(IRibbonSetUnique4.RibbonAbilityPair),
nameof(IRibbonSetUnique4.RibbonAbilityWorld),
};
private static readonly string[] RibbonSetNamesUnique4Contest3 =
{
nameof(IRibbonSetUnique4.RibbonG3Cool),
@ -87,6 +88,7 @@
nameof(IRibbonSetUnique4.RibbonG3ToughHyper),
nameof(IRibbonSetUnique4.RibbonG3ToughMaster),
};
private static readonly string[] RibbonSetNamesUnique4Contest4 =
{
nameof(IRibbonSetUnique4.RibbonG4Cool),
@ -110,6 +112,7 @@
nameof(IRibbonSetUnique4.RibbonG4ToughUltra),
nameof(IRibbonSetUnique4.RibbonG4ToughMaster),
};
internal static bool[] RibbonBitsAbility(this IRibbonSetUnique4 set)
{
if (set == null)
@ -125,6 +128,7 @@
};
}
internal static bool[] RibbonBitsContest3(this IRibbonSetUnique4 set)
{
if (set == null)
@ -158,6 +162,7 @@
set.RibbonG3ToughMaster,
};
}
internal static bool[] RibbonBitsContest4(this IRibbonSetUnique4 set)
{
if (set == null)
@ -191,6 +196,7 @@
set.RibbonG4ToughMaster,
};
}
internal static string[] RibbonNamesAbility(this IRibbonSetUnique4 _) => RibbonSetNamesUnique4Ability;
internal static string[] RibbonNamesContest3(this IRibbonSetUnique4 _) => RibbonSetNamesUnique4Contest3;
internal static string[] RibbonNamesContest4(this IRibbonSetUnique4 _) => RibbonSetNamesUnique4Contest4;

View file

@ -22,6 +22,7 @@
nameof(IRibbonSetEvent4.RibbonEvent), nameof(IRibbonSetEvent4.RibbonBirthday), nameof(IRibbonSetEvent4.RibbonSpecial),
nameof(IRibbonSetEvent4.RibbonWorld), nameof(IRibbonSetEvent4.RibbonChampionWorld), nameof(IRibbonSetEvent4.RibbonSouvenir)
};
internal static bool[] RibbonBits(this IRibbonSetEvent4 set)
{
if (set == null)
@ -39,6 +40,7 @@
set.RibbonSouvenir,
};
}
internal static string[] RibbonNames(this IRibbonSetEvent4 _) => RibbonSetNamesEvent4;
}
}

View file

@ -42,7 +42,6 @@ namespace PKHeX.WinForms
ofs += SeenDispLen;
}
LanguageFlags = SetBits(Parent.Data, Parent.PokeDexLanguageFlags, LanguageLen);
}
public void Write()
@ -162,7 +161,6 @@ namespace PKHeX.WinForms
return Parent.Personal[spec].Gender;
}
public int GetBaseSpecies(int index)
{
if (index <= Parent.MaxSpeciesID)

View file

@ -16,31 +16,37 @@ namespace PKHeX.WinForms.Controls
get => Util.ToInt32(TB_Sheen.Text);
set => TB_Sheen.Text = value.ToString();
}
public int CNT_Cool
{
get => Util.ToInt32(TB_Cool.Text);
set => TB_Cool.Text = value.ToString();
}
public int CNT_Beauty
{
get => Util.ToInt32(TB_Beauty.Text);
set => TB_Beauty.Text = value.ToString();
}
public int CNT_Cute
{
get => Util.ToInt32(TB_Cute.Text);
set => TB_Cute.Text = value.ToString();
}
public int CNT_Smart
{
get => Util.ToInt32(TB_Smart.Text);
set => TB_Smart.Text = value.ToString();
}
public int CNT_Tough
{
get => Util.ToInt32(TB_Tough.Text);
set => TB_Tough.Text = value.ToString();
}
private void Update255_MTB(object sender, EventArgs e)
{
if (!(sender is MaskedTextBox tb)) return;

View file

@ -5,10 +5,7 @@ namespace PKHeX.WinForms.Controls
{
public partial class ContextMenuPKM : UserControl
{
public ContextMenuPKM()
{
InitializeComponent();
}
public ContextMenuPKM() => InitializeComponent();
public event EventHandler RequestEditorLegality;
public event EventHandler RequestEditorQR;

View file

@ -10,6 +10,7 @@ namespace PKHeX.WinForms.Controls
CHK_Nicknamed.Checked = pk.IsNicknamed;
TB_Nickname.Text = pk.Nickname;
}
private void SaveNickname(PKM pk)
{
pk.IsNicknamed = CHK_Nicknamed.Checked;
@ -27,6 +28,7 @@ namespace PKHeX.WinForms.Controls
TB_Level.Text = pk.Stat_Level.ToString();
TB_EXP.Text = pk.EXP.ToString();
}
private void SaveSpeciesLevelEXP(PKM pk)
{
pk.Species = WinFormsUtil.GetIndex(CB_Species);
@ -40,6 +42,7 @@ namespace PKHeX.WinForms.Controls
Label_OTGender.Text = gendersymbols[pk.OT_Gender];
Label_OTGender.ForeColor = GetGenderColor(pk.OT_Gender);
}
private void SaveOT(PKM pk)
{
pk.OT_Name = TB_OT.Text;
@ -54,6 +57,7 @@ namespace PKHeX.WinForms.Controls
CHK_Cured.Checked = pk.PKRS_Strain > 0 && pk.PKRS_Days == 0;
CB_PKRSDays.SelectedIndex = Math.Min(CB_PKRSDays.Items.Count - 1, pk.PKRS_Days); // to strip out bad hacked 'rus
}
private void SavePKRS(PKM pk)
{
pk.PKRS_Days = CB_PKRSDays.SelectedIndex;
@ -78,6 +82,7 @@ namespace PKHeX.WinForms.Controls
TB_PP3.Text = pk.Move3_PP.ToString();
TB_PP4.Text = pk.Move4_PP.ToString();
}
private void SaveMoves(PKM pk)
{
pk.Move1 = WinFormsUtil.GetIndex(CB_Move1);
@ -116,6 +121,7 @@ namespace PKHeX.WinForms.Controls
NUD_ShadowID.Value = 0;
}
}
private void SaveShadow3(IShadowPKM ck3)
{
ck3.ShadowID = (int)NUD_ShadowID.Value;
@ -130,6 +136,7 @@ namespace PKHeX.WinForms.Controls
CB_RelearnMove3.SelectedValue = pk.RelearnMove3;
CB_RelearnMove4.SelectedValue = pk.RelearnMove4;
}
private void SaveRelearnMoves(PKM pk7)
{
pk7.RelearnMove1 = WinFormsUtil.GetIndex(CB_RelearnMove1);
@ -147,6 +154,7 @@ namespace PKHeX.WinForms.Controls
LoadEVs(pk);
LoadMoves(pk);
}
private void SaveMisc1(PKM pk)
{
SaveSpeciesLevelEXP(pk);
@ -166,6 +174,7 @@ namespace PKHeX.WinForms.Controls
Label_HatchCounter.Visible = CHK_IsEgg.Checked && pkm.Format > 1;
Label_Friendship.Visible = !CHK_IsEgg.Checked && pkm.Format > 1;
}
private void SaveMisc2(PKM pk)
{
SavePKRS(pk);
@ -196,6 +205,7 @@ namespace PKHeX.WinForms.Controls
// Load Extrabyte Value
TB_ExtraByte.Text = pk.Data[Convert.ToInt32(CB_ExtraBytes.Text, 16)].ToString();
}
private void SaveMisc3(PKM pk)
{
pk.PID = Util.GetHexValue(TB_PID.Text);
@ -232,6 +242,7 @@ namespace PKHeX.WinForms.Controls
CAL_EggDate.Value = pk.EggMetDate ?? new DateTime(2000, 1, 1);
}
}
private void SaveMisc4(PKM pk)
{
pk.MetDate = CAL_MetDate.Value;
@ -267,6 +278,7 @@ namespace PKHeX.WinForms.Controls
LoadHandlingTrainer(pk);
LoadGeolocation(pk);
}
private void SaveMisc6(PKM pk)
{
pk.EncryptionConstant = Util.GetHexValue(TB_EC.Text);
@ -283,6 +295,7 @@ namespace PKHeX.WinForms.Controls
CB_SubRegion.SelectedValue = pk.Region;
CB_3DSReg.SelectedValue = pk.ConsoleRegion;
}
private void SaveGeolocation(PKM pk)
{
pk.Country = WinFormsUtil.GetIndex(CB_Country);
@ -310,6 +323,7 @@ namespace PKHeX.WinForms.Controls
GB_OT.BackgroundImage = null;
}
}
private void SaveHandlingTrainer(PKM pk)
{
pk.HT_Name = TB_OTt2.Text;
@ -337,10 +351,15 @@ namespace PKHeX.WinForms.Controls
TB_EC.Text = PID.ToString("X8");
}
else if ((XOR ^ 0x8000) >> 3 == 1 && PID != EC)
{
TB_EC.Text = (PID ^ 0x80000000).ToString("X8");
}
else // Not illegal, no fix.
{
TB_EC.Text = PID.ToString("X8");
}
}
private void LoadAbility4(PKM pk)
{
int[] abils = pk.PersonalInfo.Abilities;
@ -348,6 +367,7 @@ namespace PKHeX.WinForms.Controls
CB_Ability.SelectedIndex = Math.Min(CB_Ability.Items.Count - 1, index);
}
private static int GetAbilityIndex4(PKM pk, int[] abils)
{
int abilityIndex = Array.IndexOf(abils, pk.Ability);

View file

@ -54,6 +54,7 @@ namespace PKHeX.WinForms.Controls
private void UpdateStats() => Stats.UpdateStats();
private void LoadPartyStats(PKM pk) => Stats.LoadPartyStats(pk);
private void SavePartyStats(PKM pk)
{
Stats.SavePartyStats(pk);
@ -98,6 +99,7 @@ namespace PKHeX.WinForms.Controls
private readonly PictureBox[] Markings;
private bool forceValidation;
public PKM PreparePKM(bool click = true)
{
if (click)
@ -109,6 +111,7 @@ namespace PKHeX.WinForms.Controls
PKM pk = GetPKMfromFields();
return pk?.Clone();
}
public bool VerifiedPKM()
{
if (ModifierKeys == (Keys.Control | Keys.Shift | Keys.Alt))
@ -189,7 +192,9 @@ namespace PKHeX.WinForms.Controls
if (GB_ExtraBytes.Enabled)
CB_ExtraBytes.SelectedIndex = 0;
}
public void PopulateFields(PKM pk, bool focus = true, bool skipConversionCheck = false) => LoadFieldsFromPKM(pk, focus, skipConversionCheck);
private void LoadFieldsFromPKM(PKM pk, bool focus = true, bool skipConversionCheck = true)
{
if (pk == null) { WinFormsUtil.Error(MsgPKMLoadNull); return; }
@ -226,6 +231,7 @@ namespace PKHeX.WinForms.Controls
UpdateSprite();
LastData = PreparePKM()?.Data;
}
public void UpdateLegality(LegalityAnalysis la = null, bool skipMoveRepop = false)
{
if (!FieldsLoaded)
@ -245,8 +251,10 @@ namespace PKHeX.WinForms.Controls
movePB[i].Visible = !Legality.Info?.Moves[i].Valid ?? false;
if (pkm.Format >= 6)
{
for (int i = 0; i < 4; i++)
relearnPB[i].Visible = !Legality.Info?.Relearn[i].Valid ?? false;
}
if (skipMoveRepop)
return;
@ -266,6 +274,7 @@ namespace PKHeX.WinForms.Controls
FieldsLoaded |= tmp;
LegalityChanged?.Invoke(Legality.Valid, null);
}
public void UpdateUnicode(string[] symbols)
{
gendersymbols = symbols;
@ -287,6 +296,7 @@ namespace PKHeX.WinForms.Controls
if (PKX.GetGenderFromString(Label_CTGender.Text) < 2)
Label_CTGender.Text = gendersymbols[PKX.GetGenderFromString(Label_CTGender.Text)];
}
private void UpdateSprite()
{
if (FieldsLoaded && FieldsInitialized && !forceValidation)
@ -304,12 +314,14 @@ namespace PKHeX.WinForms.Controls
private Color GetGenderColor(int gender)
{
if (gender == 0) // male
return Color.Blue;
if (gender == 1) // female
return Color.Red;
switch (gender)
{
case 0: return Color.Blue;
case 1: return Color.Red;
}
return CB_Species.ForeColor;
}
private void SetDetailsOT(ITrainerInfo SAV)
{
if (!(SAV.OT?.Length > 0))
@ -338,6 +350,7 @@ namespace PKHeX.WinForms.Controls
UpdateNickname(null, null);
}
private void SetDetailsHT(ITrainerInfo SAV)
{
if (!(SAV.OT?.Length > 0))
@ -366,6 +379,7 @@ namespace PKHeX.WinForms.Controls
else
CB_Form.DataSource = ds;
}
private void SetAbilityList()
{
if (pkm.Format < 3) // no abilities
@ -383,6 +397,7 @@ namespace PKHeX.WinForms.Controls
CB_Ability.SelectedIndex = GetSafeIndex(CB_Ability, abil); // restore original index if available
FieldsLoaded = tmp;
}
private static int GetSafeIndex(ComboBox cb, int index) => Math.Max(0, Math.Min(cb.Items.Count - 1, index));
private void SetIsShiny(object sender)
@ -400,6 +415,7 @@ namespace PKHeX.WinForms.Controls
// Refresh Markings (for Shiny Star if applicable)
SetMarkings();
}
private void SetMarkings()
{
double getOpacity(bool b) => b ? 1 : 0.175;
@ -425,9 +441,12 @@ namespace PKHeX.WinForms.Controls
PB_MarkHorohoro.Image = changeOpacity(PB_MarkHorohoro, getOpacity(pkm.Horohoro));
for (int i = 0; i < pba.Length; i++)
{
if (GetMarkingColor(markings[i], out Color c))
pba[i].Image = ImageUtil.ChangeAllColorTo(pba[i].Image, c);
}
}
private bool GetMarkingColor(int markval, out Color c)
{
switch (markval)
@ -472,11 +491,13 @@ namespace PKHeX.WinForms.Controls
else
TB_Friendship.Text = TB_Friendship.Text == "255" ? pkm.PersonalInfo.BaseFriendship.ToString() : "255";
}
private void ClickLevel(object sender, EventArgs e)
{
if (ModifierKeys == Keys.Control)
((MaskedTextBox)sender).Text = "100";
}
private void ClickGender(object sender, EventArgs e)
{
// Get Gender Threshold
@ -509,6 +530,7 @@ namespace PKHeX.WinForms.Controls
UpdatePreviewSprite(Label_Gender, null);
}
private void ClickPPUps(object sender, EventArgs e)
{
bool min = ModifierKeys.HasFlag(Keys.Control);
@ -517,14 +539,17 @@ namespace PKHeX.WinForms.Controls
CB_PPu3.SelectedIndex = !min && WinFormsUtil.GetIndex(CB_Move3) > 0 ? 3 : 0;
CB_PPu4.SelectedIndex = !min && WinFormsUtil.GetIndex(CB_Move4) > 0 ? 3 : 0;
}
private void ClickMarking(object sender, EventArgs e)
{
int index = Array.IndexOf(Markings, sender);
pkm.ToggleMarking(index);
SetMarkings();
}
private void ClickOT(object sender, EventArgs e) => SetDetailsOT(SaveFileRequested?.Invoke(this, e));
private void ClickCT(object sender, EventArgs e) => SetDetailsHT(SaveFileRequested?.Invoke(this, e));
private void ClickTRGender(object sender, EventArgs e)
{
Label lbl = sender as Label;
@ -535,8 +560,10 @@ namespace PKHeX.WinForms.Controls
lbl.ForeColor = GetGenderColor(gender);
}
}
private void ClickBall(object sender, EventArgs e) => CB_Ball.SelectedIndex = 0;
private void ClickShinyLeaf(object sender, EventArgs e) => ShinyLeaf.CheckAll(ModifierKeys != Keys.Control);
private void ClickMetLocation(object sender, EventArgs e)
{
if (HaX)
@ -552,6 +579,7 @@ namespace PKHeX.WinForms.Controls
pkm = PreparePKM();
UpdateLegality();
}
private void ClickGT(object sender, EventArgs e)
{
if (!GB_nOT.Visible)
@ -570,6 +598,7 @@ namespace PKHeX.WinForms.Controls
}
TB_Friendship.Text = pkm.CurrentFriendship.ToString();
}
private void ClickMoves(object sender, EventArgs e)
{
UpdateLegality(skipMoveRepop: true);
@ -590,6 +619,7 @@ namespace PKHeX.WinForms.Controls
UpdateLegality();
}
private bool SetSuggestedMoves(bool random = false, bool silent = false)
{
int[] m = pkm.GetMoveSet(random);
@ -617,6 +647,7 @@ namespace PKHeX.WinForms.Controls
FieldsLoaded = true;
return true;
}
private bool SetSuggestedRelearnMoves(bool silent = false)
{
if (pkm.Format < 6)
@ -640,10 +671,11 @@ namespace PKHeX.WinForms.Controls
CB_RelearnMove4.SelectedValue = m[3];
return true;
}
private bool SetSuggestedMetLocation(bool silent = false)
{
var encounter = Legality.GetSuggestedMetInfo();
if (encounter == null || pkm.Format >= 3 && encounter.Location < 0)
if (encounter == null || (pkm.Format >= 3 && encounter.Location < 0))
{
if (!silent)
WinFormsUtil.Alert(MsgPKMSuggestionNone);
@ -699,10 +731,12 @@ namespace PKHeX.WinForms.Controls
SetIsShiny(null);
UpdateSprite();
}
private void UpdateBall(object sender, EventArgs e)
{
PB_Ball.Image = SpriteUtil.GetBallSprite(WinFormsUtil.GetIndex(CB_Ball));
}
private void UpdateEXPLevel(object sender, EventArgs e)
{
if (ChangingFields || !FieldsInitialized) return;
@ -728,7 +762,9 @@ namespace PKHeX.WinForms.Controls
// Change the XP
int Level = Util.ToInt32((HaX ? MT_Level : TB_Level).Text);
if (Level <= 0)
{
TB_Level.Text = "1";
}
else if (Level > 100)
{
TB_Level.Text = "100";
@ -749,6 +785,7 @@ namespace PKHeX.WinForms.Controls
Stats.UpdateStats();
UpdateLegality();
}
private void UpdateRandomPID(object sender, EventArgs e)
{
if (pkm.Format < 3)
@ -771,6 +808,7 @@ namespace PKHeX.WinForms.Controls
if (pkm.Format >= 6 && 3 <= pkm.GenNumber && pkm.GenNumber <= 5)
TB_EC.Text = TB_PID.Text;
}
private void UpdateRandomEC(object sender, EventArgs e)
{
if (pkm.Format < 6)
@ -781,12 +819,14 @@ namespace PKHeX.WinForms.Controls
TB_EC.Text = EC.ToString("X8");
UpdateLegality();
}
private void Update255_MTB(object sender, EventArgs e)
{
if (!(sender is MaskedTextBox tb)) return;
if (Util.ToInt32(tb.Text) > byte.MaxValue)
tb.Text = "255";
}
private void UpdateForm(object sender, EventArgs e)
{
if (CB_Form == sender && FieldsLoaded)
@ -824,7 +864,9 @@ namespace PKHeX.WinForms.Controls
}
}
else
{
UpdateGender();
}
if (ChangingFields)
return;
@ -834,6 +876,7 @@ namespace PKHeX.WinForms.Controls
UpdateSprite();
}
private void UpdateHaXForm(object sender, EventArgs e)
{
if (ChangingFields)
@ -845,6 +888,7 @@ namespace PKHeX.WinForms.Controls
UpdateSprite();
}
private void UpdatePP(object sender, EventArgs e)
{
if (!(sender is ComboBox cb))
@ -864,14 +908,20 @@ namespace PKHeX.WinForms.Controls
MovePP[index].Text = 0.ToString();
}
else
{
MovePP[index].Text = pkm.GetMovePP(move, ppups).ToString();
}
}
private void UpdatePKRSstrain(object sender, EventArgs e)
{
// Change the PKRS Days to the legal bounds.
int currentDuration = CB_PKRSDays.SelectedIndex;
CB_PKRSDays.Items.Clear();
foreach (int day in Enumerable.Range(0, CB_PKRSStrain.SelectedIndex % 4 + 2)) CB_PKRSDays.Items.Add(day);
int max = (CB_PKRSStrain.SelectedIndex % 4) + 2;
foreach (int day in Enumerable.Range(0, max))
CB_PKRSDays.Items.Add(day);
// Set the days back if they're legal, else set it to 1. (0 always passes).
CB_PKRSDays.SelectedIndex = currentDuration < CB_PKRSDays.Items.Count ? currentDuration : 1;
@ -883,6 +933,7 @@ namespace PKHeX.WinForms.Controls
CHK_Cured.Checked = false;
CHK_Infected.Checked = false;
}
private void UpdatePKRSdays(object sender, EventArgs e)
{
if (CB_PKRSDays.SelectedIndex != 0) return;
@ -892,6 +943,7 @@ namespace PKHeX.WinForms.Controls
CHK_Cured.Checked = CHK_Infected.Checked = false; // No Strain = Never Cured / Infected, triggers Strain update
else CHK_Cured.Checked = true; // Any Strain = Cured
}
private void UpdatePKRSCured(object sender, EventArgs e)
{
if (!FieldsInitialized) return;
@ -927,6 +979,7 @@ namespace PKHeX.WinForms.Controls
SetMarkings();
}
private void UpdatePKRSInfected(object sender, EventArgs e)
{
if (!FieldsInitialized) return;
@ -941,12 +994,14 @@ namespace PKHeX.WinForms.Controls
UpdatePKRSCured(sender, e);
}
}
private void UpdateCountry(object sender, EventArgs e)
{
int index;
if (sender is ComboBox c && (index = WinFormsUtil.GetIndex(c)) > 0)
SetCountrySubRegion(CB_SubRegion, $"sr_{index:000}");
}
private void UpdateSpecies(object sender, EventArgs e)
{
// Get Species dependent information
@ -972,6 +1027,7 @@ namespace PKHeX.WinForms.Controls
UpdateLegality();
}
private void UpdateOriginGame(object sender, EventArgs e)
{
GameVersion Version = (GameVersion)WinFormsUtil.GetIndex(CB_GameOrigin);
@ -1004,6 +1060,7 @@ namespace PKHeX.WinForms.Controls
TID_Trainer.LoadIDValues(pkm);
UpdateLegality();
}
private void ReloadMetLocations(GameVersion Version)
{
CB_MetLocation.InitializeBinding();
@ -1033,6 +1090,7 @@ namespace PKHeX.WinForms.Controls
CB_GameOrigin.Focus(); // hacky validation forcing
}
}
private void UpdateExtraByteValue(object sender, EventArgs e)
{
if (CB_ExtraBytes.Items.Count == 0 || !(sender is MaskedTextBox mtb))
@ -1045,6 +1103,7 @@ namespace PKHeX.WinForms.Controls
int offset = Convert.ToInt32(CB_ExtraBytes.Text, 16);
pkm.Data[offset] = (byte)value;
}
private void UpdateExtraByteIndex(object sender, EventArgs e)
{
if (CB_ExtraBytes.Items.Count == 0)
@ -1052,6 +1111,7 @@ namespace PKHeX.WinForms.Controls
// Byte changed, need to refresh the Text box for the byte's value.
TB_ExtraByte.Text = pkm.Data[Convert.ToInt32(CB_ExtraBytes.Text, 16)].ToString();
}
private void UpdateNatureModification(object sender, EventArgs e)
{
if (sender != CB_Nature) return;
@ -1079,6 +1139,7 @@ namespace PKHeX.WinForms.Controls
if (PKX.IsNicknamedAnyLanguage(species, TB_Nickname.Text, pkm.Format))
CHK_Nicknamed.Checked = true;
}
private void UpdateNickname(object sender, EventArgs e)
{
if (sender == Label_Species)
@ -1117,6 +1178,7 @@ namespace PKHeX.WinForms.Controls
if (pkm.Format == 2)
((PK2)pkm).SetNotNicknamed();
}
private void UpdateNicknameClick(object sender, MouseEventArgs e)
{
TextBox tb = sender as TextBox ?? TB_Nickname;
@ -1153,6 +1215,7 @@ namespace PKHeX.WinForms.Controls
pkm.HT_Trash = d.FinalBytes;
}
}
private void UpdateNotOT(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(TB_OTt2.Text))
@ -1162,8 +1225,11 @@ namespace PKHeX.WinForms.Controls
TB_Friendship.Text = pkm.CurrentFriendship.ToString();
}
else if (string.IsNullOrWhiteSpace(Label_CTGender.Text))
{
Label_CTGender.Text = gendersymbols[0];
}
}
private void UpdateIsEgg(object sender, EventArgs e)
{
// Display hatch counter if it is an egg, Display Friendship if it is not.
@ -1223,6 +1289,7 @@ namespace PKHeX.WinForms.Controls
UpdateNickname(null, null);
UpdateSprite();
}
private void UpdateMetAsEgg(object sender, EventArgs e)
{
GB_EggConditions.Enabled = CHK_AsEgg.Checked;
@ -1242,11 +1309,13 @@ namespace PKHeX.WinForms.Controls
UpdateLegality();
}
private void UpdateShinyPID(object sender, EventArgs e)
{
var ShinyPID = pkm.Format <= 2 || ModifierKeys != Keys.Control;
UpdateShiny(ShinyPID);
}
private void UpdateShiny(bool PID)
{
pkm.PID = Util.GetHexValue(TB_PID.Text);
@ -1282,6 +1351,7 @@ namespace PKHeX.WinForms.Controls
UpdatePreviewSprite?.Invoke(this, null);
UpdateLegality();
}
private void UpdateTSV(object sender, EventArgs e)
{
if (pkm.Format < 6)
@ -1292,6 +1362,7 @@ namespace PKHeX.WinForms.Controls
pkm.PID = Util.GetHexValue(TB_PID.Text);
Tip3.SetToolTip(TB_PID, $"PSV: {pkm.PSV:d4}");
}
private void Update_ID(object sender, EventArgs e)
{
// Trim out nonhex characters
@ -1311,12 +1382,14 @@ namespace PKHeX.WinForms.Controls
FieldsLoaded = true;
}
}
private void UpdateShadowID(object sender, EventArgs e)
{
if (!FieldsLoaded)
return;
FLP_Purification.Visible = NUD_ShadowID.Value > 0;
}
private void UpdatePurification(object sender, EventArgs e)
{
if (!FieldsLoaded)
@ -1325,6 +1398,7 @@ namespace PKHeX.WinForms.Controls
CHK_Shadow.Checked = NUD_Purification.Value > 0;
FieldsLoaded = true;
}
private void UpdateShadowCHK(object sender, EventArgs e)
{
if (!FieldsLoaded)
@ -1333,6 +1407,7 @@ namespace PKHeX.WinForms.Controls
NUD_Purification.Value = CHK_Shadow.Checked ? NUD_Purification.Maximum : 0;
FieldsLoaded = true;
}
private void ValidateComboBox(object sender)
{
if (!FieldsInitialized)
@ -1347,6 +1422,7 @@ namespace PKHeX.WinForms.Controls
else
cb.ResetBackColor();
}
private void ValidateComboBox(object sender, CancelEventArgs e)
{
if (!(sender is ComboBox))
@ -1355,6 +1431,7 @@ namespace PKHeX.WinForms.Controls
ValidateComboBox(sender);
UpdateSprite();
}
private void ValidateComboBox2(object sender, EventArgs e)
{
if (!FieldsInitialized || !FieldsLoaded)
@ -1383,6 +1460,7 @@ namespace PKHeX.WinForms.Controls
UpdateLegality();
}
}
private void ValidateMove(object sender, EventArgs e)
{
if (!FieldsInitialized || !FieldsLoaded)
@ -1397,6 +1475,7 @@ namespace PKHeX.WinForms.Controls
pkm.RelearnMoves = Relearn.Select(WinFormsUtil.GetIndex).ToArray();
UpdateLegality(skipMoveRepop: true);
}
private void ValidateMovePaint(object sender, DrawItemEventArgs e)
{
if (e.Index < 0) return;
@ -1412,6 +1491,7 @@ namespace PKHeX.WinForms.Controls
e.Graphics.FillRectangle(brush, e.Bounds);
e.Graphics.DrawString(i.Text, e.Font, tBrush, e.Bounds, StringFormat.GenericDefault);
}
private void ValidateLocation(object sender, EventArgs e)
{
ValidateComboBox(sender);
@ -1428,10 +1508,12 @@ namespace PKHeX.WinForms.Controls
{
new RibbonEditor(pkm).ShowDialog();
}
private void OpenMedals(object sender, EventArgs e)
{
new SuperTrainingEditor(pkm).ShowDialog();
}
private void OpenHistory(object sender, EventArgs e)
{
// Write back current values
@ -1454,11 +1536,13 @@ namespace PKHeX.WinForms.Controls
ToggleInterface(pkm);
return FinalizeInterface(sav);
}
private void ToggleInterface(PKM t)
{
FLP_Purification.Visible = FLP_ShadowID.Visible = t is IShadowPKM;
ToggleInterface(pkm.Format);
}
private void ToggleInterface(int gen)
{
FLP_Country.Visible = FLP_SubRegion.Visible = FLP_3DSRegion.Visible = gen >= 6;
@ -1505,6 +1589,7 @@ namespace PKHeX.WinForms.Controls
CenterSubEditors();
}
private bool FinalizeInterface(SaveFile sav)
{
bool init = FieldsInitialized;
@ -1522,7 +1607,9 @@ namespace PKHeX.WinForms.Controls
// Hide Unused Tabs
if (pkm.Format == 1 && tabMain.TabPages.Contains(Tab_Met))
{
tabMain.TabPages.Remove(Tab_Met);
}
else if (pkm.Format != 1 && !tabMain.TabPages.Contains(Tab_Met))
{
tabMain.TabPages.Insert(1, Tab_Met);
@ -1541,6 +1628,7 @@ namespace PKHeX.WinForms.Controls
UpdateOriginGame(null, null);
return TranslationRequired;
}
private void CenterSubEditors()
{
// Recenter PKM SubEditors
@ -1570,6 +1658,7 @@ namespace PKHeX.WinForms.Controls
CHK_Nicknamed.Checked = false;
LastData = null;
}
public void EnableDragDrop(DragEventHandler enter, DragEventHandler drop)
{
AllowDrop = true;
@ -1584,6 +1673,7 @@ namespace PKHeX.WinForms.Controls
// ReSharper disable once FieldCanBeMadeReadOnly.Global
public Action<ShowdownSet> LoadShowdownSet;
private void LoadShowdownSetDefault(ShowdownSet Set)
{
var pk = PreparePKM();
@ -1603,6 +1693,7 @@ namespace PKHeX.WinForms.Controls
PopulateFields(pk); // put data back in form
FieldsInitialized |= alreadyInit;
}
public void FlickerInterface()
{
tabMain.SelectedTab = Tab_Met; // parent tab of CB_GameOrigin
@ -1631,6 +1722,7 @@ namespace PKHeX.WinForms.Controls
PopulateFilteredDataSources(SAV);
}
private void PopulateFilteredDataSources(SaveFile SAV)
{
GameInfo.Strings.SetItemDataSource(SAV.Version, SAV.Generation, SAV.MaxItemID, SAV.HeldItems, HaX);
@ -1668,6 +1760,7 @@ namespace PKHeX.WinForms.Controls
suggestion.Add($"{MsgPKMSuggestionLevel} {minlvl}");
return suggestion;
}
private static IReadOnlyList<ComboItem> GetAbilityList(PKM pkm)
{
var abils = pkm.PersonalInfo.Abilities;
@ -1675,6 +1768,7 @@ namespace PKHeX.WinForms.Controls
abils = new[] { abils[0] };
return GameInfo.Strings.GetAbilityDataSource(abils);
}
private static PKM GetCompatiblePKM(SaveFile sav, PKM current)
{
if (current.Format < 3 || current.GetType() != sav.PKMType)

View file

@ -28,8 +28,11 @@ namespace PKHeX.WinForms.Controls
{
int value = 0;
for (int i = 0; i < Flags.Length; i++)
{
if (Flags[i].Checked)
value |= 1 << i;
}
return value;
}
set
@ -45,7 +48,9 @@ namespace PKHeX.WinForms.Controls
return;
if (CHK_C == c)
{
c.Image = c.Checked ? Resources.crown : greyCrown;
}
else
{
if (!c.Checked)

View file

@ -30,11 +30,13 @@ namespace PKHeX.WinForms.Controls
public Color StatHyperTrained { get; set; } = Color.LightGreen;
private IMainEditor MainEditor { get; set; }
public void SetMainEditor(IMainEditor editor)
{
MainEditor = editor;
CHK_HackedStats.Enabled = CHK_HackedStats.Visible = editor.HaX;
}
public bool Valid => pkm.Format < 3 || Convert.ToUInt32(TB_EVTotal.Text) <= 510 || CHK_HackedStats.Checked;
private readonly Label[] L_Stats;
@ -47,6 +49,7 @@ namespace PKHeX.WinForms.Controls
get => MainEditor.ChangingFields;
set => MainEditor.ChangingFields = value;
}
private bool FieldsInitialized => MainEditor.FieldsInitialized;
private void ClickIV(object sender, EventArgs e)
@ -55,7 +58,9 @@ namespace PKHeX.WinForms.Controls
return;
if (ModifierKeys.HasFlag(Keys.Alt)) // Min
{
t.Text = 0.ToString();
}
else if (ModifierKeys.HasFlag(Keys.Control))
{
var index = Array.IndexOf(MT_IVs, t);
@ -69,6 +74,7 @@ namespace PKHeX.WinForms.Controls
UpdateStats();
}
}
private void ClickEV(object sender, EventArgs e)
{
if (!(sender is MaskedTextBox t))
@ -85,6 +91,7 @@ namespace PKHeX.WinForms.Controls
int newEV = pkm.GetMaximumEV(index);
t.Text = newEV.ToString();
}
public void UpdateIVs(object sender, EventArgs e)
{
if (sender is MaskedTextBox m)
@ -153,6 +160,7 @@ namespace PKHeX.WinForms.Controls
UpdateStats();
}
private void UpdateRandomEVs(object sender, EventArgs e)
{
bool zero = ModifierKeys.HasFlag(Keys.Control);
@ -160,6 +168,7 @@ namespace PKHeX.WinForms.Controls
LoadEVs(evs);
UpdateEVs(null, null);
}
private void UpdateHackedStats(object sender, EventArgs e)
{
foreach (var s in MT_Stats)
@ -167,6 +176,7 @@ namespace PKHeX.WinForms.Controls
if (!CHK_HackedStats.Checked)
UpdateStats();
}
private void UpdateHackedStatText(object sender, EventArgs e)
{
if (!CHK_HackedStats.Checked || !(sender is TextBox tb))
@ -179,6 +189,7 @@ namespace PKHeX.WinForms.Controls
if (Convert.ToUInt32(text) > ushort.MaxValue)
tb.Text = "65535";
}
private void UpdateHyperTrainingFlag(int i, bool value)
{
if (value)
@ -186,6 +197,7 @@ namespace PKHeX.WinForms.Controls
else
MT_IVs[i].ResetBackColor();
}
private void UpdateHPType(object sender, EventArgs e)
{
if (ChangingFields || !FieldsInitialized)
@ -196,6 +208,7 @@ namespace PKHeX.WinForms.Controls
int[] newIVs = PKX.SetHPIVs(hpower, pkm.IVs, pkm.Format);
LoadIVs(newIVs);
}
private void ClickStatLabel(object sender, MouseEventArgs e)
{
if (sender == Label_SPC)
@ -217,10 +230,16 @@ namespace PKHeX.WinForms.Controls
private void LoadHyperTraining()
{
if (!(pkm is IHyperTrain h))
foreach (var iv in MT_IVs) iv.ResetBackColor();
else for (int i = 0; i < MT_IVs.Length; i++)
{
foreach (var iv in MT_IVs)
iv.ResetBackColor();
return;
}
for (int i = 0; i < MT_IVs.Length; i++)
UpdateHyperTrainingFlag(i, h.GetHT(i));
}
private void UpdateEVTotals()
{
int evtotal = pkm.EVTotal;
@ -236,6 +255,7 @@ namespace PKHeX.WinForms.Controls
TB_EVTotal.Text = evtotal.ToString();
EVTip.SetToolTip(TB_EVTotal, $"Remaining: {510 - evtotal}");
}
public void UpdateStats()
{
// Generate the stats.
@ -270,12 +290,14 @@ namespace PKHeX.WinForms.Controls
}
public void UpdateCharacteristic() => UpdateCharacteristic(pkm.Characteristic);
private void UpdateCharacteristic(int characteristic)
{
L_Characteristic.Visible = Label_CharacteristicPrefix.Visible = characteristic > -1;
if (characteristic > -1)
L_Characteristic.Text = GameInfo.Strings.characteristics[characteristic];
}
private void RecolorStatLabels(int nature)
{
// Reset Label Colors
@ -288,6 +310,7 @@ namespace PKHeX.WinForms.Controls
L_Stats[incr].ForeColor = StatIncreased;
L_Stats[decr].ForeColor = StatDecreased;
}
public string UpdateNatureModification(int nature)
{
// Reset Label Colors
@ -299,6 +322,7 @@ namespace PKHeX.WinForms.Controls
return "-/-";
return $"+{L_Stats[incr].Text} / -{L_Stats[decr].Text}".Replace(":", "");
}
public void SetATKIVGender(int gender)
{
pkm.SetATKIVGender(gender);
@ -318,6 +342,7 @@ namespace PKHeX.WinForms.Controls
Stat_SPD.Text = pk.Stat_SPD.ToString();
Stat_SPE.Text = pk.Stat_SPE.ToString();
}
public void SavePartyStats(PKM pk)
{
int size = pk.SIZE_PARTY;
@ -332,6 +357,7 @@ namespace PKHeX.WinForms.Controls
pk.Stat_SPA = Util.ToInt32(Stat_SPA.Text);
pk.Stat_SPD = Util.ToInt32(Stat_SPD.Text);
}
public void LoadEVs(int[] EVs)
{
ChangingFields = true;
@ -343,6 +369,7 @@ namespace PKHeX.WinForms.Controls
TB_SPDEV.Text = EVs[5].ToString();
ChangingFields = false;
}
public void LoadIVs(int[] IVs)
{
ChangingFields = true;
@ -399,6 +426,7 @@ namespace PKHeX.WinForms.Controls
}
}
}
public void InitializeDataSources()
{
CB_HPType.InitializeBinding();

View file

@ -19,17 +19,21 @@ namespace PKHeX.WinForms.Controls
var tsv = GetTSV();
if (tsv < 0)
return;
string IDstr = $"TSV: {tsv:d4}";
var repack = Trainer.SID * 1_000_000 + Trainer.TID;
var repack = (Trainer.SID * 1_000_000) + Trainer.TID;
string supplement = Format < 7
? $"G7ID: ({repack / 1_000_000:D4}){repack % 1_000_000:D6}"
: $"ID: {Trainer.TID:D5}/{Trainer.SID:D5}";
IDstr += Environment.NewLine + supplement;
TSVTooltip.SetToolTip(TB_TID, IDstr);
TSVTooltip.SetToolTip(TB_SID, IDstr);
TSVTooltip.SetToolTip(TB_TID7, IDstr);
TSVTooltip.SetToolTip(TB_SID7, IDstr);
}
private int GetTSV()
{
if (Format <= 2)
@ -39,22 +43,17 @@ namespace PKHeX.WinForms.Controls
return xor >> 3;
return xor >> 4;
}
public void LoadIDValues(ITrainerID tr)
{
Trainer = tr;
int format;
if (tr is PKM p)
{
format = p.GenNumber;
if (format < 3 && p.Format >= 7 || format <= 0) // VC or bad gen
format = 4; // use TID/SID 16bit style
}
else
format = tr is SaveFile s ? s.Generation : -1;
int format = tr.GetTrainerIDFormat();
SetFormat(format);
LoadValues();
}
public void UpdateSID() => LoadValues();
public void LoadInfo(ITrainerInfo info)
{
Trainer.TID = info.TID;
@ -71,11 +70,13 @@ namespace PKHeX.WinForms.Controls
else
LoadTID7(Trainer.TID, Trainer.SID);
}
private void LoadTID(int tid, int sid)
{
TB_TID.Text = tid.ToString("D5");
TB_SID.Text = sid.ToString("D5");
}
private void LoadTID7(int tid, int sid)
{
var repack = (uint)((sid << 16) | tid);
@ -85,6 +86,7 @@ namespace PKHeX.WinForms.Controls
TB_TID7.Text = tid.ToString("D6");
TB_SID7.Text = sid.ToString("D4");
}
private void SetFormat(int format)
{
if (format == Format)
@ -100,6 +102,7 @@ namespace PKHeX.WinForms.Controls
Format = format;
}
private IEnumerable<Control> GetControlsForFormat(int format)
{
if (format >= 7)
@ -108,7 +111,9 @@ namespace PKHeX.WinForms.Controls
return new Control[] { Label_TID, TB_TID, Label_SID, TB_SID };
return new Control[] { Label_TID, TB_TID };
}
private void UpdateTSV(object sender, EventArgs e) => UpdateTSV();
private void Update_ID(object sender, EventArgs e)
{
if (!(sender is MaskedTextBox mt))
@ -148,9 +153,10 @@ namespace PKHeX.WinForms.Controls
UpdatedID?.Invoke(sender, e);
}
private void SanityCheckSID7(int tid, int sid)
{
var repack = (long)sid * 1_000_000 + tid;
var repack = ((long)sid * 1_000_000) + tid;
if (repack > uint.MaxValue)
{
TB_SID7.Text = (sid - 1).ToString();

View file

@ -44,6 +44,7 @@ namespace PKHeX.WinForms.Controls
SE = se;
Reset();
}
public void Reset() { DragInfo = new SlotChangeInfo(SAV); ColorizedBox = ColorizedSlot = -1; }
public bool CanStartDrag => DragInfo.LeftMouseIsDown && !Cursor.Position.Equals(MouseDownPosition);
private Point MouseDownPosition { get; set; }
@ -53,6 +54,7 @@ namespace PKHeX.WinForms.Controls
if (SE != null)
DragInfo.Cursor = ((Control)sender).FindForm().Cursor = z;
}
public void MouseEnter(object sender, EventArgs e)
{
var pb = (PictureBox)sender;
@ -60,6 +62,7 @@ namespace PKHeX.WinForms.Controls
return;
BeginHoverSlot(pb);
}
private Bitmap GetGlowSprite(PKM pk)
{
var baseSprite = SpriteUtil.GetSprite(pk.Species, pk.AltForm, pk.Gender, 0, pk.IsEgg, false, pk.Format);
@ -68,6 +71,7 @@ namespace PKHeX.WinForms.Controls
ImageUtil.GlowEdges(pixels, new[] {GlowInitial.B, GlowInitial.G, GlowInitial.R}, baseSprite.Width);
return ImageUtil.GetBitmap(pixels, baseSprite.Width, baseSprite.Height);
}
private void BeginHoverSlot(PictureBox pb)
{
var view = WinFormsUtil.FindFirstControlOfType<ISlotViewer<PictureBox>>(pb);
@ -99,6 +103,7 @@ namespace PKHeX.WinForms.Controls
if (Settings.Default.HoverSlotPlayCry)
PlayCry(pk);
}
private void EndHoverSlot()
{
if (HoveredSlot != null)
@ -111,6 +116,7 @@ namespace PKHeX.WinForms.Controls
ShowSet.RemoveAll();
Sounds.Stop();
}
public void RefreshHoverSlot(ISlotViewer<PictureBox> parent)
{
if (HoveredSlot == null || !parent.SlotPictureBoxes.Contains(HoveredSlot))
@ -118,6 +124,7 @@ namespace PKHeX.WinForms.Controls
BeginHoverSlot(HoveredSlot);
}
public void MouseLeave(object sender, EventArgs e)
{
EndHoverSlot();
@ -126,11 +133,13 @@ namespace PKHeX.WinForms.Controls
return;
pb.BackgroundImage = OriginalBackground;
}
public void MouseClick(object sender, MouseEventArgs e)
{
if (!DragInfo.DragDropInProgress)
SE.ClickSlot(sender, e);
}
public void MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
@ -138,6 +147,7 @@ namespace PKHeX.WinForms.Controls
if (e.Button == MouseButtons.Right)
DragInfo.RightMouseIsDown = false;
}
public void MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
@ -148,6 +158,7 @@ namespace PKHeX.WinForms.Controls
if (e.Button == MouseButtons.Right)
DragInfo.RightMouseIsDown = true;
}
public void QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
{
if (e.Action != DragAction.Cancel && e.Action != DragAction.Drop)
@ -156,6 +167,7 @@ namespace PKHeX.WinForms.Controls
DragInfo.RightMouseIsDown = false;
DragInfo.DragDropInProgress = false;
}
public void DragEnter(object sender, DragEventArgs e)
{
if (e.AllowedEffect == (DragDropEffects.Copy | DragDropEffects.Link)) // external file
@ -166,6 +178,7 @@ namespace PKHeX.WinForms.Controls
if (DragInfo.DragDropInProgress)
SetCursor((Cursor)DragInfo.Cursor, sender);
}
public void MouseMove(object sender, MouseEventArgs e)
{
if (!CanStartDrag)
@ -182,6 +195,7 @@ namespace PKHeX.WinForms.Controls
bool encrypt = Control.ModifierKeys == Keys.Control;
HandleMovePKM(pb, encrypt);
}
public void DragDrop(object sender, DragEventArgs e)
{
PictureBox pb = (PictureBox)sender;
@ -204,15 +218,16 @@ namespace PKHeX.WinForms.Controls
private void ShowSimulatorSetTooltip(Control pb, PKM pk)
{
if (pk.Species == 0)
ShowSet.RemoveAll();
else
{
var set = new ShowdownSet(pk);
if (pk.Format <= 2) // Nature preview from IVs
set.Nature = (int)(pk.EXP % 25);
ShowSet.SetToolTip(pb, set.LocalizedText(Settings.Default.Language));
ShowSet.RemoveAll();
return;
}
var set = new ShowdownSet(pk);
if (pk.Format <= 2) // Nature preview from IVs
set.Nature = (int)(pk.EXP % 25);
ShowSet.SetToolTip(pb, set.LocalizedText(Settings.Default.Language));
}
private void PlayCry(PKM pk)
{
if (pk.Species == 0)
@ -256,12 +271,14 @@ namespace PKHeX.WinForms.Controls
if (DragInfo.Source.IsParty || DragInfo.Destination.IsParty)
SE.SetParty();
}
private async void DeleteAsync(string path, int delay)
{
await Task.Delay(delay).ConfigureAwait(true);
if (File.Exists(path) && DragInfo.CurrentPath == null)
File.Delete(path);
}
private string CreateDragDropPKM(PictureBox pb, bool encrypt, out bool external)
{
byte[] dragdata = SAV.DecryptPKM(DragInfo.Source.OriginalData);
@ -284,6 +301,7 @@ namespace PKHeX.WinForms.Controls
return newfile;
}
private bool TryMakeDragDropPKM(PictureBox pb, bool encrypt, PKM pkx, string newfile, out bool external)
{
File.WriteAllBytes(newfile, encrypt ? pkx.EncryptedBoxData : pkx.DecryptedBoxData);
@ -347,11 +365,13 @@ namespace PKHeX.WinForms.Controls
if (DragInfo.Source.Parent == null) // internal file
DragInfo.Reset();
}
private void AlertInvalidate(string msg)
{
DragInfo.Destination.Slot = -1; // Invalidate
WinFormsUtil.Alert(msg);
}
private bool TryLoadFiles(string[] files, DragEventArgs e, bool noEgg)
{
if (files.Length <= 0)
@ -407,6 +427,7 @@ namespace PKHeX.WinForms.Controls
Debug.WriteLine(c);
return true;
}
private bool TrySetPKMDestination(object sender, DragEventArgs e, bool overwrite, bool clone, bool noEgg)
{
PKM pkz = GetPKM(true);
@ -423,14 +444,16 @@ namespace PKHeX.WinForms.Controls
SetCursor(SE.GetDefaultCursor, sender);
return true;
}
private bool TrySetPKMSource(object sender, bool overwrite, bool clone)
{
if (overwrite && DragInfo.Destination.IsValid) // overwrite delete old slot
{
// Clear from slot
SetPKM(SAV.BlankPKM, true, null);
return true;
}
else if (!clone && DragInfo.Destination.IsValid)
if (!clone && DragInfo.Destination.IsValid)
{
// Load data from destination
PKM pk = ((PictureBox)sender).Image != null
@ -439,10 +462,9 @@ namespace PKHeX.WinForms.Controls
// Set destination pokemon data to source slot
SetPKM(pk, true, null);
return true;
}
else
return false;
return true;
return false;
}
public void SetColor(int box, int slot, Image img)
@ -471,6 +493,7 @@ namespace PKHeX.WinForms.Controls
// PKM Get Set
private PKM GetPKM(bool src) => GetPKM(src ? DragInfo.Source : DragInfo.Destination);
public PKM GetPKM(SlotChange slot)
{
int o = slot.Offset;
@ -485,7 +508,9 @@ namespace PKHeX.WinForms.Controls
pk.Box = slot.Box;
return pk;
}
private void SetPKM(PKM pk, bool src, Image img) => SetPKM(pk, src ? DragInfo.Source : DragInfo.Destination, src, img);
public void SetPKM(PKM pk, SlotChange slot, bool src, Image img)
{
if (slot.IsParty)
@ -511,6 +536,7 @@ namespace PKHeX.WinForms.Controls
}
SetColor(slot.Box, slot.Slot, img ?? Resources.slotSet);
}
private void SetPKMParty(PKM pk, bool src, SlotChange slot)
{
int o = slot.Offset;

View file

@ -45,7 +45,9 @@ namespace PKHeX.WinForms
WinFormsUtil.Alert(MsgProgramIllegalModeActive, MsgProgramIllegalModeBehave);
}
else if (showChangelog)
{
new About().ShowDialog();
}
if (BAKprompt && !Directory.Exists(BackupPath))
PromptBackup();
@ -57,7 +59,9 @@ namespace PKHeX.WinForms
get => GameInfo.CurrentLanguage;
private set => GameInfo.CurrentLanguage = value;
}
private static bool _unicode { get; set; }
public static bool Unicode
{
get => _unicode;
@ -71,6 +75,7 @@ namespace PKHeX.WinForms
public static string[] GenderSymbols { get; private set; } = { "♂", "♀", "-" };
public static bool HaX { get; private set; }
public static bool IsInitialized { get; private set; }
private readonly string[] main_langlist =
{
"日本語", // JPN
@ -82,6 +87,7 @@ namespace PKHeX.WinForms
"한국어", // KOR
"中文", // CHN
};
private static readonly List<IPlugin> Plugins = new List<IPlugin>();
#endregion
@ -139,6 +145,7 @@ namespace PKHeX.WinForms
DevUtil.AddControl(Menu_Tools);
#endif
}
private void FormLoadAddEvents()
{
C_SAV.PKME_Tabs = PKME_Tabs;
@ -163,6 +170,7 @@ namespace PKHeX.WinForms
dragout.ContextMenuStrip = mnu.mnuL;
C_SAV.menu.RequestEditorLegality += ShowLegality;
}
private void FormLoadInitialFiles(string[] args)
{
string pkmArg = null;
@ -185,7 +193,9 @@ namespace PKHeX.WinForms
WinFormsUtil.Error(path); // `path` contains the error message
if (path != null && File.Exists(path))
{
OpenQuick(path, force: true);
}
else
{
OpenSAV(C_SAV.SAV, null);
@ -202,6 +212,7 @@ namespace PKHeX.WinForms
else
GetPreview(dragout);
}
private void FormLoadCheckForUpdates()
{
L_UpdateAvailable.Click += (sender, e) => Process.Start(ThreadPath);
@ -220,6 +231,7 @@ namespace PKHeX.WinForms
}));
}).Start();
}
private void FormLoadConfig(out bool BAKprompt, out bool showChangelog)
{
BAKprompt = false;
@ -257,6 +269,7 @@ namespace PKHeX.WinForms
Settings.Version = Resources.ProgramVersion;
}
private void FormLoadPlugins()
{
#if !MERGED // merged should load dlls from within too, folder is no longer required
@ -267,6 +280,7 @@ namespace PKHeX.WinForms
foreach (var p in Plugins.OrderBy(z => z.Priority))
p.Initialize(C_SAV, PKME_Tabs, menuStrip1);
}
private static void DeleteConfig(string settingsFilename)
{
var dr = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MsgSettingsResetCorrupt, MsgSettingsResetPrompt);
@ -283,20 +297,25 @@ namespace PKHeX.WinForms
if (WinFormsUtil.OpenSAVPKMDialog(C_SAV.SAV.PKMExtensions, out string path))
OpenQuick(path);
}
private void MainMenuSave(object sender, EventArgs e)
{
if (!PKME_Tabs.VerifiedPKM()) return;
PKM pk = PreparePKM();
WinFormsUtil.SavePKMDialog(pk);
}
private void MainMenuExit(object sender, EventArgs e)
{
if (ModifierKeys == Keys.Control) // triggered via hotkey
{
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Quit PKHeX?"))
return;
}
Close();
}
private void MainMenuAbout(object sender, EventArgs e) => new About().ShowDialog();
// Sub Menu Options
@ -309,6 +328,7 @@ namespace PKHeX.WinForms
report.Show();
report.PopulateData(C_SAV.SAV.BoxData);
}
private void MainMenuDatabase(object sender, EventArgs e)
{
if (ModifierKeys == Keys.Shift)
@ -316,7 +336,10 @@ namespace PKHeX.WinForms
if (this.FirstFormOfType<KChart>() is KChart c)
{ c.CenterToForm(this); c.BringToFront(); }
else
{
new KChart(C_SAV.SAV).Show();
}
return;
}
@ -328,6 +351,7 @@ namespace PKHeX.WinForms
else
WinFormsUtil.Alert(MsgDatabase, string.Format(MsgDatabaseAdvice, DatabasePath));
}
private void MainMenuMysteryDB(object sender, EventArgs e)
{
if (this.FirstFormOfType<SAV_MysteryGiftDB>() is SAV_MysteryGiftDB z)
@ -335,6 +359,7 @@ namespace PKHeX.WinForms
new SAV_MysteryGiftDB(PKME_Tabs, C_SAV).Show();
}
private void MainMenuSettings(object sender, EventArgs e)
{
new SettingsEditor(Settings.Default, nameof(Settings.Default.BAKPrompt)).ShowDialog();
@ -353,6 +378,7 @@ namespace PKHeX.WinForms
if (C_SAV.SAV.HasBox)
C_SAV.ReloadSlots();
}
private void MainMenuBoxLoad(object sender, EventArgs e)
{
string path = null;
@ -365,6 +391,7 @@ namespace PKHeX.WinForms
if (C_SAV.LoadBoxes(out string result, path))
WinFormsUtil.Alert(result);
}
private void MainMenuBoxDump(object sender, EventArgs e)
{
// Dump all of box content to files.
@ -378,17 +405,20 @@ namespace PKHeX.WinForms
if (C_SAV.DumpBoxes(out string result, path))
WinFormsUtil.Alert(result);
}
private void MainMenuBoxDumpSingle(object sender, EventArgs e)
{
if (C_SAV.DumpBox(out string result))
WinFormsUtil.Alert(result);
}
private void MainMenuBatchEditor(object sender, EventArgs e)
{
new BatchEditor(PKME_Tabs.PreparePKM(), C_SAV.SAV).ShowDialog();
C_SAV.SetPKMBoxes(); // refresh
C_SAV.UpdateBoxViewers();
}
private void MainMenuFolder(object sender, EventArgs e)
{
var ofType = Application.OpenForms.OfType<SAV_FolderList>().FirstOrDefault();
@ -398,7 +428,9 @@ namespace PKHeX.WinForms
ofType.BringToFront();
}
else
{
new SAV_FolderList(s => OpenSAV(SaveUtil.GetVariantSAV(s.FilePath), s.FilePath)).Show();
}
}
// Misc Options
@ -425,6 +457,7 @@ namespace PKHeX.WinForms
// Set Species & Nickname
PKME_Tabs.LoadShowdownSet(Set);
}
private void ClickShowdownExportPKM(object sender, EventArgs e)
{
if (!PKME_Tabs.VerifiedPKM())
@ -442,6 +475,7 @@ namespace PKHeX.WinForms
else
WinFormsUtil.Alert(MsgSimulatorExportSuccess, text);
}
private void ClickShowdownExportParty(object sender, EventArgs e) => C_SAV.ClickShowdownExportParty(sender, e);
private void ClickShowdownExportBattleBox(object sender, EventArgs e) => C_SAV.ClickShowdownExportBattleBox(sender, e);
private void ClickShowdownExportCurrentBox(object sender, EventArgs e) => C_SAV.ClickShowdownExportCurrentBox(sender, e);
@ -461,27 +495,32 @@ namespace PKHeX.WinForms
if (Directory.Exists(path))
{ C_SAV.LoadBoxes(out string _, path); return; }
string ext = Path.GetExtension(path);
FileInfo fi = new FileInfo(path);
var fi = new FileInfo(path);
if (!fi.Exists)
return;
if (fi.Length > 0x10009C && fi.Length != SaveUtil.SIZE_G4BR && ! SAV3GCMemoryCard.IsMemoryCardSize(fi.Length)) // pbr/GC have size > 1MB
WinFormsUtil.Error(MsgFileSizeLarge + Environment.NewLine + string.Format(MsgFileSize, fi.Length), path);
else if (fi.Length < 32)
WinFormsUtil.Error(MsgFileSizeSmall + Environment.NewLine + string.Format(MsgFileSize, fi.Length), path);
else
{
byte[] input; try { input = File.ReadAllBytes(path); }
catch (Exception e) { WinFormsUtil.Error(MsgFileInUse + path, e); return; }
#if DEBUG
string ext = Path.GetExtension(path);
if (fi.Length > 0x10009C && fi.Length != SaveUtil.SIZE_G4BR && !SAV3GCMemoryCard.IsMemoryCardSize(fi.Length)) // pbr/GC have size > 1MB
{
WinFormsUtil.Error(MsgFileSizeLarge + Environment.NewLine + string.Format(MsgFileSize, fi.Length), path);
return;
}
if (fi.Length < 32)
{
WinFormsUtil.Error(MsgFileSizeSmall + Environment.NewLine + string.Format(MsgFileSize, fi.Length), path);
return;
}
byte[] input; try { input = File.ReadAllBytes(path); }
catch (Exception e) { WinFormsUtil.Error(MsgFileInUse + path, e); return; }
#if DEBUG
OpenFile(input, path, ext);
#else
#else
try { OpenFile(input, path, ext); }
catch (Exception e) { WinFormsUtil.Error(MsgFileLoadFail + "\nPath: " + path, e); }
#endif
}
#endif
}
private void OpenFile(byte[] input, string path, string ext)
{
if (TryLoadXorpadSAV(input, path))
@ -503,6 +542,7 @@ namespace PKHeX.WinForms
$"{MsgFileLoad}{Environment.NewLine}{path}",
$"{string.Format(MsgFileSize, input.Length)}{Environment.NewLine}{input.Length} bytes (0x{input.Length:X4})");
}
private bool TryLoadXorpadSAV(byte[] input, string path)
{
if (input.Length == 0x10009C) // Resize to 1MB
@ -533,6 +573,7 @@ namespace PKHeX.WinForms
WinFormsUtil.Error(MsgFileLoadSaveFail, path);
return true;
}
private bool TryLoadSAV(byte[] input, string path)
{
var sav = SaveUtil.GetVariantSAV(input);
@ -541,6 +582,7 @@ namespace PKHeX.WinForms
OpenSAV(sav, path);
return true;
}
private bool TryLoadMemoryCard(byte[] input, string path)
{
if (!SAV3GCMemoryCard.IsMemoryCardSize(input))
@ -554,6 +596,7 @@ namespace PKHeX.WinForms
OpenSAV(sav, path);
return true;
}
private bool TryLoadPKM(byte[] input, string ext)
{
if (ext == ".pgt") // size collision with pk6
@ -565,6 +608,7 @@ namespace PKHeX.WinForms
PKME_Tabs.PopulateFields(pk);
return true;
}
private bool TryLoadPCBoxBin(byte[] input)
{
if (!C_SAV.IsPCBoxBin(input.Length))
@ -578,6 +622,7 @@ namespace PKHeX.WinForms
WinFormsUtil.Alert(c);
return true;
}
private bool TryLoadBattleVideo(byte[] input)
{
if (!BattleVideo.IsValid(input))
@ -589,6 +634,7 @@ namespace PKHeX.WinForms
Debug.WriteLine(c);
return result;
}
private bool TryLoadMysteryGift(byte[] input, string path, string ext)
{
var tg = MysteryGift.GetMysteryGift(input, ext);
@ -634,6 +680,7 @@ namespace PKHeX.WinForms
OpenSAV(s, s.FileName);
return true;
}
private static GameVersion SelectMemoryCardSaveGame(SAV3GCMemoryCard MC)
{
if (MC.SaveGameCount == 1)
@ -649,10 +696,11 @@ namespace PKHeX.WinForms
dialog.ShowDialog();
return dialog.Result;
}
private static SAV3GCMemoryCard CheckGCMemoryCard(byte[] Data, string path)
{
SAV3GCMemoryCard MC = new SAV3GCMemoryCard();
GCMemoryCardState MCState = MC.LoadMemoryCardFile(Data);
var MC = new SAV3GCMemoryCard();
var MCState = MC.LoadMemoryCardFile(Data);
switch (MCState)
{
default: { WinFormsUtil.Error(MsgFileGameCubeBad, path); return null; }
@ -681,6 +729,7 @@ namespace PKHeX.WinForms
Legal.EReaderBerryName = sav.EBerryName;
Legal.ActiveTrainer = sav;
}
private static PKM LoadTemplate(SaveFile sav)
{
if (!Directory.Exists(TemplatePath))
@ -728,6 +777,7 @@ namespace PKHeX.WinForms
SystemSounds.Beep.Play();
}
private void ResetSAVPKMEditors(SaveFile sav)
{
bool WindowToggleRequired = C_SAV.SAV.Generation < 3 && sav.Generation >= 3; // version combobox refresh hack
@ -756,6 +806,7 @@ namespace PKHeX.WinForms
p.NotifySaveLoaded();
sav.Edited = false;
}
private static string GetProgramTitle()
{
#if DEBUG
@ -766,6 +817,7 @@ namespace PKHeX.WinForms
#endif
return $"PKH{(HaX ? "a" : "e")}X ({date})";
}
private static string GetProgramTitle(SaveFile sav)
{
string title = GetProgramTitle() + $" - {sav.GetType().Name}: ";
@ -773,6 +825,7 @@ namespace PKHeX.WinForms
return title + $"{sav.FileName} [{sav.OT} ({sav.Version})]";
return title + Path.GetFileNameWithoutExtension(Util.CleanFileName(sav.BAKName)); // more descriptive
}
private static bool TryBackupExportCheck(SaveFile sav, string path)
{
if (string.IsNullOrWhiteSpace(path)) // not actual save
@ -791,10 +844,10 @@ namespace PKHeX.WinForms
if (!locked)
return true;
WinFormsUtil.Alert(MsgFileWriteProtected + Environment.NewLine + path,
MsgFileWriteProtectedAdvice);
WinFormsUtil.Alert(MsgFileWriteProtected + Environment.NewLine + path, MsgFileWriteProtectedAdvice);
return false;
}
private static bool SanityCheckSAV(ref SaveFile sav)
{
// Finish setting up the save file.
@ -905,6 +958,7 @@ namespace PKHeX.WinForms
WinFormsUtil.TranslateInterface(this, CurrentLanguage); // Translate the UI to language.
Text = ProgramTitle;
}
private static void InitializeStrings()
{
string l = CurrentLanguage;
@ -926,6 +980,7 @@ namespace PKHeX.WinForms
#region //// PKX WINDOW FUNCTIONS ////
private bool QR6Notified;
private void ClickQR(object sender, EventArgs e)
{
if (ModifierKeys == Keys.Alt)
@ -957,6 +1012,7 @@ namespace PKHeX.WinForms
WinFormsUtil.Alert(MsgQRDecodeFail, string.Format(MsgQRDecodeSize, input.Length));
}
private void ExportQRFromTabs()
{
if (!PKME_Tabs.VerifiedPKM())
@ -1007,9 +1063,10 @@ namespace PKHeX.WinForms
ShowLegality(sender, e, pk);
}
private void ShowLegality(object sender, EventArgs e, PKM pk)
{
LegalityAnalysis la = new LegalityAnalysis(pk, C_SAV.SAV.Personal);
var la = new LegalityAnalysis(pk, C_SAV.SAV.Personal);
if (pk.Slot < 0)
PKME_Tabs.UpdateLegality(la);
bool verbose = ModifierKeys == Keys.Control;
@ -1021,14 +1078,18 @@ namespace PKHeX.WinForms
Clipboard.SetText(report);
}
else
{
WinFormsUtil.Alert(report);
}
}
private void ClickClone(object sender, EventArgs e)
{
if (!PKME_Tabs.VerifiedPKM()) return; // don't copy garbage to the box
PKM pk = PKME_Tabs.PreparePKM();
C_SAV.SetClonesToBox(pk);
}
private void GetPreview(PictureBox pb, PKM pk = null)
{
if (!IsInitialized)
@ -1041,7 +1102,9 @@ namespace PKHeX.WinForms
if (pb.BackColor == Color.Red)
pb.BackColor = Color.Transparent;
}
private void PKME_Tabs_UpdatePreviewSprite(object sender, EventArgs e) => GetPreview(dragout);
private void PKME_Tabs_LegalityChanged(object sender, EventArgs e)
{
if (sender == null || HaX)
@ -1053,10 +1116,10 @@ namespace PKHeX.WinForms
PB_Legal.Visible = true;
PB_Legal.Image = sender as bool? == false ? Resources.warn : Resources.valid;
}
private void PKME_Tabs_RequestShowdownExport(object sender, EventArgs e) => ClickShowdownExportPKM(sender, e);
private void PKME_Tabs_RequestShowdownImport(object sender, EventArgs e) => ClickShowdownImportPKM(sender, e);
private SaveFile PKME_Tabs_SaveFileRequested(object sender, EventArgs e) => C_SAV.SAV;
// Open/Save Array Manipulation //
private PKM PreparePKM(bool click = true) => PKME_Tabs.PreparePKM(click);
// Drag & Drop Events
@ -1067,6 +1130,7 @@ namespace PKHeX.WinForms
else if (e.Data != null) // within
e.Effect = DragDropEffects.Move;
}
private void Main_DragDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
@ -1108,19 +1172,22 @@ namespace PKHeX.WinForms
C_SAV.M.SetCursor(DefaultCursor, sender);
File.Delete(newfile);
}
private void Dragout_DragOver(object sender, DragEventArgs e) => e.Effect = DragDropEffects.Move;
// Dragout Display
private void DragoutEnter(object sender, EventArgs e)
{
dragout.BackgroundImage = WinFormsUtil.GetIndex(PKME_Tabs.CB_Species) > 0 ? Resources.slotSet : Resources.slotDel;
Cursor = Cursors.Hand;
}
private void DragoutLeave(object sender, EventArgs e)
{
dragout.BackgroundImage = Resources.slotTrans;
if (Cursor == Cursors.Hand)
Cursor = Cursors.Default;
}
private void DragoutDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
@ -1153,11 +1220,13 @@ namespace PKHeX.WinForms
if (C_SAV.ExportBackup() && !Directory.Exists(BackupPath))
PromptBackup();
}
private void ClickExportSAV(object sender, EventArgs e)
{
if (Menu_ExportSAV.Enabled)
C_SAV.ExportSaveFile();
}
private void ClickSaveFileName(object sender, EventArgs e)
{
if (!DetectSaveFile(out string path))
@ -1184,8 +1253,7 @@ namespace PKHeX.WinForms
private static void PromptBackup()
{
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo,
string.Format(MsgBackupCreateLocation, BackupPath), MsgBackupCreateQuestion))
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, string.Format(MsgBackupCreateLocation, BackupPath), MsgBackupCreateQuestion))
return;
try

View file

@ -4,7 +4,7 @@ using System.Windows.Forms;
namespace PKHeX.WinForms
{
public partial class ErrorWindow : Form
public sealed partial class ErrorWindow : Form
{
public static DialogResult ShowErrorDialog(string friendlyMessage, Exception ex, bool allowContinue)
{
@ -17,9 +17,7 @@ namespace PKHeX.WinForms
};
var dialogResult = dialog.ShowDialog();
if (dialogResult == DialogResult.Abort)
{
Environment.Exit(1);
}
return dialogResult;
}
@ -55,6 +53,8 @@ namespace PKHeX.WinForms
set => L_Message.Text = value;
}
private Exception _error;
public Exception Error
{
get => _error;
@ -64,7 +64,6 @@ namespace PKHeX.WinForms
UpdateExceptionDetailsMessage();
}
}
private Exception _error;
private void UpdateExceptionDetailsMessage()
{

View file

@ -180,6 +180,7 @@ namespace PKHeX.WinForms
byte[] data = QR7.GenerateQRData(pk7, box, slot, num_copies);
return GenerateQRCode(data, ppm: 4);
}
private static Image GenerateQRCode(byte[] data, int ppm = 4)
{
using (var generator = new QRCodeGenerator())

View file

@ -74,6 +74,7 @@ namespace PKHeX.WinForms
return releaseKey;
}
}
private static void Error(string msg) => MessageBox.Show(msg, "PKHeX Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
#if !DEBUG

View file

@ -1,13 +1,12 @@
namespace PKHeX.WinForms.Properties {
namespace PKHeX.WinForms.Properties
{
// This class allows you to handle specific events on the settings class:
// The SettingChanging event is raised before a setting's value is changed.
// The PropertyChanged event is raised after a setting's value is changed.
// The SettingsLoaded event is raised after the setting values are loaded.
// The SettingsSaving event is raised before the setting values are saved.
internal sealed partial class Settings {
internal sealed partial class Settings
{
public Settings() {
// // To add event handlers for saving and changing settings, uncomment the lines below:
//

View file

@ -5,14 +5,10 @@ namespace PKHeX.WinForms
{
public static class CyberGadgetUtil
{
public static string GetTempFolder()
{
return Path.Combine(Path.GetTempPath(), "3DSSE");
}
public static string GetCacheFolder()
{
return Path.Combine(GetBackupLocation(), "cache");
}
public static string GetTempFolder() => Path.Combine(Path.GetTempPath(), "3DSSE");
public static string GetCacheFolder() => Path.Combine(GetBackupLocation(), "cache");
private static string GetRegistryBase() => @"SOFTWARE\CYBER Gadget\3DSSaveEditor";
private static string GetRegistryValue(string key)
{
Microsoft.Win32.RegistryKey currentUser = Microsoft.Win32.Registry.CurrentUser;
@ -25,10 +21,7 @@ namespace PKHeX.WinForms
currentUser.Close();
return str;
}
private static string GetRegistryBase()
{
return @"SOFTWARE\CYBER Gadget\3DSSaveEditor";
}
private static string GetBackupLocation()
{
string registryValue = GetRegistryValue("Location");

View file

@ -15,6 +15,7 @@ namespace PKHeX.WinForms
#endif
private static readonly PrivateFontCollection s_FontCollection = new PrivateFontCollection();
private static FontFamily[] FontFamilies
{
get
@ -23,10 +24,9 @@ namespace PKHeX.WinForms
return s_FontCollection.Families;
}
}
public static Font GetPKXFont(float size)
{
return new Font(FontFamilies[0], size);
}
public static Font GetPKXFont(float size) => new Font(FontFamilies[0], size);
private static void SetPKXFont()
{
try

View file

@ -15,6 +15,7 @@ namespace PKHeX.WinForms
overLayer = ChangeOpacity(overLayer, transparency);
return LayerImage(baseLayer, overLayer, x, y);
}
public static Bitmap LayerImage(Image baseLayer, Image overLayer, int x, int y)
{
if (baseLayer == null)
@ -27,6 +28,7 @@ namespace PKHeX.WinForms
}
return img;
}
public static Bitmap ChangeOpacity(Image img, double trans)
{
if (img == null)
@ -44,6 +46,7 @@ namespace PKHeX.WinForms
return bmp;
}
public static Bitmap ChangeAllColorTo(Image img, Color c)
{
if (img == null)
@ -61,6 +64,7 @@ namespace PKHeX.WinForms
return bmp;
}
public static Bitmap ToGrayscale(Image img)
{
if (img == null)
@ -78,18 +82,21 @@ namespace PKHeX.WinForms
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, int stride = -1, PixelFormat format = PixelFormat.Format32bppArgb)
{
if (stride == -1 && format == PixelFormat.Format32bppArgb)
stride = 4 * width; // defaults
return new Bitmap(width, height, stride, format, Marshal.UnsafeAddrOfPinnedArrayElement(data, 0));
}
public static byte[] GetPixelData(Bitmap bitmap)
{
var argbData = new byte[bitmap.Width * bitmap.Height * 4];
@ -98,11 +105,13 @@ namespace PKHeX.WinForms
bitmap.UnlockBits(bd);
return argbData;
}
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);
}
private static void SetAllColorTo(byte[] data, Color c)
{
byte R = c.R;
@ -117,13 +126,14 @@ namespace PKHeX.WinForms
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);
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;
@ -152,10 +162,12 @@ namespace PKHeX.WinForms
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++)
{
var c = 4 * (i + (j * width));
data[c + 0] += (byte)(amount * (0xFF - data[c + 0]));
for (int j = top; j <= bottom; j++)
{
var c = 4 * (i + (j * width));
data[c + 0] += (byte)(amount * (0xFF - data[c + 0]));
}
}
}
for (int i = 0; i < data.Length; i += 4)
@ -179,16 +191,17 @@ namespace PKHeX.WinForms
float x = 100f * v / maxval;
if (x > 100)
x = 100;
double red = 255f * (x > 50 ? 1 - 2 * (x - 50) / 100.0 : 1.0);
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 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));
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);
}
}

View file

@ -23,6 +23,7 @@ namespace PKHeX.WinForms
return null;
}
}
public static Image GetImageFromURL(string webURL)
{
try

View file

@ -13,14 +13,17 @@ namespace PKHeX.WinForms
string str = PKX.GetResourceStringBall(ball);
return (Image)Resources.ResourceManager.GetObject(str) ?? Resources._ball4; // Poké Ball (default)
}
public static Image GetSprite(int species, int form, int gender, int item, bool isegg, bool shiny, int generation = -1, bool isBoxBGRed = false)
{
return Spriter.GetSprite(species, form, gender, item, isegg, shiny, generation, isBoxBGRed);
}
public static Image GetRibbonSprite(string name)
{
return Resources.ResourceManager.GetObject(name.Replace("CountG3", "G3").ToLower()) as Image;
}
public static Image GetTypeSprite(int type, int generation = PKX.Generation)
{
if (generation <= 2)
@ -33,29 +36,33 @@ namespace PKHeX.WinForms
if (gift.Empty)
return null;
Image img;
var img = GetBaseImage(gift);
if (gift.GiftUsed)
img = ImageUtil.ChangeOpacity(img, 0.3);
return img;
}
private static Image GetBaseImage(MysteryGift gift)
{
if (gift.IsEgg && gift.Species == 490) // Manaphy Egg
img = (Image)(Resources.ResourceManager.GetObject("_490_e") ?? Resources.unknown);
else if (gift.IsPokémon)
img = GetSprite(gift.Species, gift.Form, gift.Gender, gift.HeldItem, gift.IsEgg, gift.IsShiny, gift.Format);
else if (gift.IsItem)
return (Image)(Resources.ResourceManager.GetObject("_490_e") ?? Resources.unknown);
if (gift.IsPokémon)
return GetSprite(gift.Species, gift.Form, gift.Gender, gift.HeldItem, gift.IsEgg, gift.IsShiny, gift.Format);
if (gift.IsItem)
{
int item = gift.ItemID;
if (Legal.ZCrystalDictionary.TryGetValue(item, out int value))
item = value;
img = (Image)(Resources.ResourceManager.GetObject("item_" + item) ?? Resources.unknown);
return (Image)(Resources.ResourceManager.GetObject("item_" + item) ?? Resources.unknown);
}
else
img = Resources.unknown;
if (gift.GiftUsed)
img = ImageUtil.LayerImage(new Bitmap(img.Width, img.Height), img, 0, 0, 0.3);
return img;
return Resources.unknown;
}
private static Image GetSprite(PKM pkm, bool isBoxBGRed = false)
{
return GetSprite(pkm.Species, pkm.AltForm, pkm.Gender, pkm.SpriteItem, pkm.IsEgg, pkm.IsShiny, pkm.Format, isBoxBGRed);
}
private static Image GetSprite(SaveFile SAV)
{
string file = "tr_00";
@ -63,11 +70,13 @@ namespace PKHeX.WinForms
file = $"tr_{SAV.MultiplayerSpriteID:00}";
return Resources.ResourceManager.GetObject(file) as Image;
}
private static Image GetWallpaper(SaveFile SAV, int box)
{
string s = BoxWallpaper.GetWallpaper(SAV, box);
return (Bitmap)(Resources.ResourceManager.GetObject(s) ?? Resources.box_wp16xy);
}
private static Image GetSprite(PKM pkm, SaveFile SAV, int box, int slot, bool flagIllegal = false)
{
if (!pkm.Valid)
@ -103,6 +112,7 @@ namespace PKHeX.WinForms
public static Image Sprite(this MysteryGift gift) => GetSprite(gift);
public static Image Sprite(this SaveFile SAV) => GetSprite(SAV);
public static Image Sprite(this PKM pkm, bool isBoxBGRed = false) => GetSprite(pkm, isBoxBGRed);
public static Image Sprite(this PKM pkm, SaveFile SAV, int box, int slot, bool flagIllegal = false)
=> GetSprite(pkm, SAV, box, slot, flagIllegal);
}

View file

@ -14,6 +14,7 @@ namespace PKHeX.WinForms
private static string GetTranslationFileNameInternal(string lang) => $"lang_{lang}";
private static string GetTranslationFileNameExternal(string lang) => $"lang_{lang}.txt";
private static TranslationContext GetContext(string lang)
{
if (Context.TryGetValue(lang, out var context))
@ -81,8 +82,10 @@ namespace PKHeX.WinForms
break;
if (z.ContextMenuStrip != null) // control has attached menustrip
{
foreach (var obj in GetToolStripMenuItems(z.ContextMenuStrip))
yield return obj;
}
if (z is ComboBox || z is TextBox || z is MaskedTextBox || z is LinkLabel || z is NumericUpDown)
break; // undesirable to modify, ignore
@ -93,6 +96,7 @@ namespace PKHeX.WinForms
}
}
}
private static IEnumerable<T> GetChildrenOfType<T>(this Control control) where T : class
{
foreach (Control child in control.Controls)
@ -106,6 +110,7 @@ namespace PKHeX.WinForms
yield return descendant;
}
}
private static IEnumerable<object> GetToolStripMenuItems(ToolStrip menu)
{
foreach (var i in menu.Items.OfType<ToolStripMenuItem>())
@ -116,6 +121,7 @@ namespace PKHeX.WinForms
yield return sub;
}
}
private static IEnumerable<ToolStripMenuItem> GetToolsStripDropDownItems(ToolStripDropDownItem item)
{
foreach (var dropDownItem in item.DropDownItems.OfType<ToolStripMenuItem>())
@ -200,6 +206,7 @@ namespace PKHeX.WinForms
public bool RemoveUsedKeys { private get; set; }
public const char Separator = '=';
private readonly Dictionary<string, string> Translation = new Dictionary<string, string>();
public TranslationContext(IEnumerable<string> content, char separator = Separator)
{
var entries = content.Select(z => z.Split(separator)).Where(z => z.Length == 2);