mirror of
https://github.com/kwsch/pkNX.git
synced 2026-04-25 07:16:51 -05:00
Improved auto fill (#254)
* Rename fields Rename to `HatchedSpecies` `Species` here is actually `ModelID`. To get Species `DexIndexNational` should be used * Update interfaces Use DexIndexRegional Replace `RegionalFormIndex` with `Form` Add national dex index * Add debug assert * Add set functions for easy assignment of personal info * Update auto-fill * All missing SWSH data is now filled based on USUM data * Accounts for form data * Ignores all forms that are not carried over to next gen * Adds form number and national dex number * Update PLA filler to account for forms and other missing entries
This commit is contained in:
parent
7f051d06ed
commit
9346f482da
|
|
@ -81,13 +81,13 @@ public PersonalInfo8LA(PersonalInfoLAfb fb)
|
|||
public uint TR_D { get => FB.TR_D; set => FB.TR_D = value; }
|
||||
public uint TypeTutor { get => FB.TypeTutor; set => FB.TypeTutor = value; }
|
||||
|
||||
public ushort HatchedSpecies { get => FB.HatchSpecies; set => FB.HatchSpecies = (ushort)value; }
|
||||
public ushort HatchedSpecies { get => FB.HatchedSpecies; set => FB.HatchedSpecies = value; }
|
||||
public ushort LocalFormIndex { get => FB.LocalFormIndex; set => FB.LocalFormIndex = value; }
|
||||
public bool Field_45 { get => FB.Field_45; set => FB.Field_45 = value; }
|
||||
public ushort Field_46 { get => FB.Field_46; set => FB.Field_46 = value; }
|
||||
public byte Field_47 { get => FB.Field_47; set => FB.Field_47 = value; }
|
||||
|
||||
public ushort Species { get => FB.Species; set => FB.Species = value; }
|
||||
public ushort ModelID { get => FB.Species; set => FB.Species = value; }
|
||||
public ushort Form { get => FB.Form; set => FB.Form = value; }
|
||||
public ushort DexIndexNational { get => FB.DexIndexOther; set => FB.DexIndexOther = value; }
|
||||
public ushort DexIndexRegional { get => FB.DexIndexHisui; set => FB.DexIndexHisui = value; }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using pkNX.Containers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
|
||||
namespace pkNX.Structures.FlatBuffers;
|
||||
|
|
@ -101,4 +102,60 @@ public bool IsPresentInGame(ushort species, byte form)
|
|||
IPersonalInfo IPersonalTable.this[int index] => this[index];
|
||||
IPersonalInfo IPersonalTable.this[ushort species, byte form] => this[species, form];
|
||||
IPersonalInfo IPersonalTable.GetFormEntry(ushort species, byte form) => GetFormEntry(species, form);
|
||||
|
||||
public void FixMissingData()
|
||||
{
|
||||
// Fix all base forms
|
||||
int laFormCount = 0;
|
||||
for (ushort i = 1; i <= Legal.MaxSpeciesID_8; i++)
|
||||
{
|
||||
var l = Table[i];
|
||||
l.DexIndexNational = i;
|
||||
|
||||
var s = ResourcesUtil.SWSH.Table[i];
|
||||
|
||||
Debug.Assert(l.DexIndexNational == s.DexIndexNational);
|
||||
|
||||
if (l.HP == 0)
|
||||
{
|
||||
l.SetPersonalInfo(s);
|
||||
}
|
||||
|
||||
if (l.FormCount == 1)
|
||||
continue;
|
||||
|
||||
if (l.FormStatsIndex != 0)
|
||||
Debug.Assert(l.FormStatsIndex == (MaxSpeciesID + 1) + laFormCount);
|
||||
|
||||
l.FormStatsIndex = (MaxSpeciesID + 1) + laFormCount;
|
||||
laFormCount += l.FormCount - 1;
|
||||
|
||||
for (byte f = 1; f < l.FormCount; f++)
|
||||
{
|
||||
var formL = Table[l.FormStatsIndex + (f - 1)];
|
||||
|
||||
if (formL.HP == 0)
|
||||
{
|
||||
// Check if SWSH table has form data for this entry
|
||||
if (f < s.FormCount)
|
||||
{
|
||||
if (s.FormCount <= l.FormCount || (FormInfo.HasBattleOnlyForm(i) && !FormInfo.IsBattleOnlyForm(i, f, 8)))
|
||||
{
|
||||
var formS = ResourcesUtil.SWSH.GetFormEntry(i, f);
|
||||
|
||||
Debug.Assert(formL.DexIndexNational == formS.DexIndexNational);
|
||||
formL.SetPersonalInfo(formS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No form data was found, just write the base form data
|
||||
formL.SetPersonalInfo(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Debug.WriteLine("Auto fix for PLA data succeded");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ public class PersonalInfoLAfb
|
|||
[FlatBufferItem(40)] public ushort Item3 { get; set; } // Always Default (0)
|
||||
[FlatBufferItem(41)] public byte EggGroup1 { get; set; } // byte
|
||||
[FlatBufferItem(42)] public byte EggGroup2 { get; set; } // byte
|
||||
[FlatBufferItem(43)] public ushort HatchSpecies { get; set; } // ushort
|
||||
[FlatBufferItem(43)] public ushort HatchedSpecies { get; set; } // ushort
|
||||
[FlatBufferItem(44)] public ushort LocalFormIndex { get; set; } // ushort
|
||||
[FlatBufferItem(45)] public bool Field_45 { get; set; } // byte
|
||||
[FlatBufferItem(46)] public ushort Field_46 { get; set; } // ushort
|
||||
|
|
|
|||
|
|
@ -227,13 +227,13 @@ private void AddPersonalLines(List<string> lines, IPersonalInfo pi, int entry, s
|
|||
lines.Add("======");
|
||||
if (pi is IPersonalInfoSWSH s)
|
||||
{
|
||||
if (s.PokeDexIndex != 0)
|
||||
lines.Add($"Galar Dex: #{s.PokeDexIndex:000}");
|
||||
if (s.DexIndexRegional != 0)
|
||||
lines.Add($"Galar Dex: #{s.DexIndexRegional:000}");
|
||||
if (s.ArmorDexIndex != 0)
|
||||
lines.Add($"Armor Dex: #{s.ArmorDexIndex:000}");
|
||||
if (s.CrownDexIndex != 0)
|
||||
lines.Add($"Crown Dex: #{s.CrownDexIndex:000}");
|
||||
if (s.PokeDexIndex == 0 && s.ArmorDexIndex == 0 && s.CrownDexIndex == 0)
|
||||
if (s.DexIndexRegional == 0 && s.ArmorDexIndex == 0 && s.CrownDexIndex == 0)
|
||||
lines.Add("Galar Dex: Foreign");
|
||||
|
||||
if (s.CanNotDynamax)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using static pkNX.Structures.Species;
|
||||
|
||||
|
|
@ -8,6 +9,11 @@ namespace pkNX.Structures;
|
|||
/// </summary>
|
||||
public static class FormInfo
|
||||
{
|
||||
public static bool HasBattleOnlyForm(ushort species)
|
||||
{
|
||||
return BattleOnly.Contains(species);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the form cannot exist outside of a Battle.
|
||||
/// </summary>
|
||||
|
|
@ -17,7 +23,7 @@ public static class FormInfo
|
|||
/// <returns>True if it can only exist in a battle, false if it can exist outside of battle.</returns>
|
||||
public static bool IsBattleOnlyForm(ushort species, byte form, int format)
|
||||
{
|
||||
if (!BattleOnly.Contains(species))
|
||||
if (!HasBattleOnlyForm(species))
|
||||
return false;
|
||||
|
||||
// Some species have battle only forms as well as out-of-battle forms (other than base form).
|
||||
|
|
@ -29,13 +35,154 @@ public static bool IsBattleOnlyForm(ushort species, byte form, int format)
|
|||
case (int)Mimikyu when form == 2: // Totem disguise Mimikyu
|
||||
case (int)Necrozma when form < 3: // Only mark Ultra Necrozma as Battle Only
|
||||
return false;
|
||||
case (int)Minior: return form < 7; // Minior Shields-Down
|
||||
case (int)Minior:
|
||||
return form < 7; // Minior Shields-Down
|
||||
|
||||
default:
|
||||
return form != 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte RemoveBattleOnlyFormsFromCount(ushort species, byte formCount, int format)
|
||||
{
|
||||
if (!HasBattleOnlyForm(species))
|
||||
return formCount;
|
||||
|
||||
return Math.Min(formCount, GetOutOfBattleFormCount_Impl(species));
|
||||
}
|
||||
|
||||
public static byte RemoveTotemFormsFromCount(ushort species, byte formCount, int format)
|
||||
{
|
||||
if (!HasTotemForm(species))
|
||||
return formCount;
|
||||
|
||||
return Math.Min(formCount, GetOutOfBattleFormCount_Impl(species));
|
||||
}
|
||||
|
||||
public static byte GetOutOfBattleFormCount(ushort species, byte formCount, int format)
|
||||
{
|
||||
if (!HasTotemForm(species) && !HasBattleOnlyForm(species))
|
||||
return formCount;
|
||||
|
||||
return GetOutOfBattleFormCount_Impl(species);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Warning! Untested! Keep this private untill it's properly tested.
|
||||
/// Get the amount of forms that can be used out of battle and carried over to newer generations
|
||||
/// </summary>
|
||||
/// <remarks>This removes mega forms, totem forms, dynamax forms, etc.</remarks>
|
||||
/// <param name="species">The species to get the count for</param>
|
||||
/// <returns></returns>
|
||||
private static byte GetOutOfBattleFormCount_Impl(ushort species)
|
||||
{
|
||||
return species switch
|
||||
{
|
||||
(int)Rattata => 2,// Standard Form, Alolan Form
|
||||
(int)Raticate => 2,// Standard Form, Alolan Form
|
||||
(int)Pikachu => 10, // Pikachu with cap
|
||||
(int)Raichu => 2, // Standard Form, Alolan Form
|
||||
(int)Sandshrew => 2, // Standard Form, Alolan Form
|
||||
(int)Sandslash => 2, // Standard Form, Alolan Form
|
||||
(int)Vulpix => 2, // Standard Form, Alolan Form
|
||||
(int)Ninetales => 2, // Standard Form, Alolan Form
|
||||
(int)Diglett => 2, // Standard Form, Alolan Form
|
||||
(int)Dugtrio => 2, // Standard Form, Alolan Form
|
||||
(int)Meowth => 3, // Standard Form, Alolan Form, Galarian Form
|
||||
(int)Persian => 2, // Standard Form, Alolan Form
|
||||
(int)Growlithe => 2, // Standard Form, Hisuian Form
|
||||
(int)Arcanine => 2, // Standard Form, Hisuian Form
|
||||
(int)Geodude => 2, // Standard Form, Hisuian Form
|
||||
(int)Graveler => 2, // Standard Form, Hisuian Form
|
||||
(int)Golem => 2, // Standard Form, Hisuian Form
|
||||
(int)Ponyta => 2, // Standard Form, Galarian Form
|
||||
(int)Rapidash => 2, // Standard Form, Galarian Form
|
||||
(int)Slowpoke => 2, // Standard Form, Galarian Form
|
||||
(int)Slowbro => 2, // Standard Form, Galarian Form
|
||||
(int)Farfetchd => 2, // Standard Form, Galarian Form
|
||||
(int)Grimer => 2, // Standard Form, Alolan Form
|
||||
(int)Muk => 2, // Standard Form, Alolan Form
|
||||
(int)Voltorb => 2, // Standard Form, Hisuian Form
|
||||
(int)Electrode => 2, // Standard Form, Hisuian Form
|
||||
(int)Exeggutor => 2, // Standard Form, Alolan Form
|
||||
(int)Marowak => 2, // Standard Form, Alolan Form
|
||||
(int)Weezing => 2, // Standard Form, Galarian Form
|
||||
(int)MrMime => 2, // Standard Form, Galarian Form
|
||||
(int)Articuno => 2, // Standard Form, Galarian Form
|
||||
(int)Zapdos => 2, // Standard Form, Galarian Form
|
||||
(int)Moltres => 2, // Standard Form, Galarian Form
|
||||
|
||||
(int)Typhlosion => 2, // Standard Form, Hisuian Form
|
||||
(int)Slowking => 2, // Standard Form, Galarian Form
|
||||
(int)Unown => 28, // Unknown forms have no personal data
|
||||
(int)Sneasel => 2, // Standard Form, Hisuian Form
|
||||
(int)Corsola => 2, // Standard Form, Galarian Form
|
||||
|
||||
(int)Zigzagoon => 2, // Standard Form, Galarian Form
|
||||
(int)Linoone => 2, // Standard Form, Galarian Form
|
||||
//Spinda?
|
||||
(int)Castform => 4, // Normal Form, Sunny Form, Rainy Form, Snowy Form
|
||||
|
||||
(int)Burmy => 3, // Plant Cloak, Sandy Cloak, Trash Cloak
|
||||
(int)Wormadam => 3, // Plant Cloak, Sandy Cloak, Trash Cloak
|
||||
(int)Shellos => 2, // West Sea, East Sea
|
||||
(int)Gastrodon => 2, // West Sea, East Sea
|
||||
(int)Rotom => 6, // Standard Form, Heat Rotom, Wash Rotom, Frost Rotom, Fan Rotom, Mow Rotom
|
||||
(int)Dialga => 2, // Standard Form, Origin Form
|
||||
(int)Palkia => 2, // Standard Form, Origin Form
|
||||
(int)Giratina => 2, // Standard Form, Origin Form
|
||||
(int)Shaymin => 2, // Land Form, Sky Form
|
||||
|
||||
(int)Samurott => 2, // Standard Form, Hisuian Form
|
||||
(int)Lilligant => 2, // Standard Form, Hisuian Form
|
||||
(int)Basculin => 3, // Red-Striped Form, Blue-Striped Form, White-Striped Form
|
||||
(int)Darumaka => 2,// Standard Form, Galarian Form
|
||||
(int)Darmanitan => 2,// Standard Form, Galarian non-Zen Form
|
||||
(int)Yamask => 2,// Standard Form, Galarian Form
|
||||
(int)Zorua => 2,// Standard Form, Hisuian Form
|
||||
(int)Zoroark => 2,// Standard Form, Hisuian Form
|
||||
(int)Deerling => 4,
|
||||
(int)Sawsbuck => 4,
|
||||
(int)Braviary => 2,// Standard Form, Hisuian Form
|
||||
(int)Tornadus => 2, // Incarnate Form, Therian Form
|
||||
(int)Thundurus => 2, // Incarnate Form, Therian Form
|
||||
(int)Landorus => 2, // Incarnate Form, Therian Form
|
||||
|
||||
(int)Kyurem => 3, // Normal Form, Black Form, White Form
|
||||
(int)Keldeo => 2, // Ordinary Form, Resolute Form
|
||||
(int)Meloetta => 2, // Aria Form, Pirouette Form
|
||||
(int)Genesect => 5, // Normal, Electric, Fire, Ice, Water
|
||||
(int)Flabébé => 5, // Red Flower, Yellow Flower, Orange Flower, Blue Flower, White Flower
|
||||
(int)Floette => 6, // Red Flower, Yellow Flower, Orange Flower, Blue Flower, White Flower
|
||||
(int)Florges => 5, // Red Flower, Yellow Flower, Orange Flower, Blue Flower, White Flower
|
||||
|
||||
//(int)Aegislash => 2, // Sword Form, Shield Form
|
||||
(int)Sliggoo => 2,// Standard Form, Hisuian Form
|
||||
(int)Goodra => 2,// Standard Form, Hisuian Form
|
||||
(int)Avalugg => 2,// Standard Form, Hisuian Form
|
||||
(int)Zygarde => 4,// (0,1,2,3) can be out-of-battle, Zygarde Complete (4) is a battle form
|
||||
|
||||
(int)Decidueye => 2,// Standard Form, Hisuian Form
|
||||
(int)Oricorio => 4, // Baile Style, Pom-Pom Style, Pa'u Style, Sensu Style
|
||||
(int)Lycanroc => 3, // Midday Form, Midnight Form, Dusk Form
|
||||
|
||||
//(int)Wishiwashi => 2, // Solo Form, School Form
|
||||
(int)Silvally => 18, // Form for each type
|
||||
(int)Minior => 14, // (0-7) Meteor Forms, 7-14 are Core Forms
|
||||
(int)Mimikyu => 2, // Standard Form (0) && Totem disguise Mimikyu (2)
|
||||
(int)Necrozma => 3, // Standard Form, Dusk Mane Necrozma, Dawn Wings Necrozma
|
||||
|
||||
(int)Toxtricity => 2, // Amped Form, Low Key Form
|
||||
(int)Urshifu => 2, // Single Strike Style, Rapid Strike Style
|
||||
|
||||
(int)Calyrex => 3, // Standard Form, Ice Rider, Shadow Rider
|
||||
|
||||
(int)Enamorus => 2, // Incarnate Form, Therian Form
|
||||
|
||||
_ => 1,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverts the Battle Form to the form it would have outside of Battle.
|
||||
/// </summary>
|
||||
|
|
@ -225,6 +372,11 @@ public static bool IsTotemForm(ushort species, byte form)
|
|||
return form == 1;
|
||||
}
|
||||
|
||||
public static bool HasTotemForm(ushort species)
|
||||
{
|
||||
return Legal.Totem_USUM.Contains(species);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base <see cref="form"/> for the <see cref="species"/> when the Totem form is reverted (on transfer).
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ public sealed class PersonalInfo8SWSH : IPersonalInfoSWSH
|
|||
public PersonalInfo8SWSH(byte[] data)
|
||||
{
|
||||
Data = data;
|
||||
DexIndexNational = ModelID;
|
||||
|
||||
TMHM = new bool[200];
|
||||
for (var i = 0; i < CountTR; i++)
|
||||
{
|
||||
|
|
@ -97,24 +99,29 @@ public byte[] Write()
|
|||
public int Height { get => ReadUInt16LittleEndian(Data.AsSpan(0x24)); set => WriteUInt16LittleEndian(Data.AsSpan(0x24), (ushort)value); }
|
||||
public int Weight { get => ReadUInt16LittleEndian(Data.AsSpan(0x26)); set => WriteUInt16LittleEndian(Data.AsSpan(0x26), (ushort)value); }
|
||||
|
||||
public ushort Species { get => ReadUInt16LittleEndian(Data.AsSpan(0x4C)); set => WriteUInt16LittleEndian(Data.AsSpan(0x4C), value); }
|
||||
public ushort ModelID { get => (ushort)ReadUInt32LittleEndian(Data.AsSpan(0x4C)); set => WriteUInt32LittleEndian(Data.AsSpan(0x4C), value); } // Model ID
|
||||
public ushort HatchedSpecies { get => ReadUInt16LittleEndian(Data.AsSpan(0x56)); set => WriteUInt16LittleEndian(Data.AsSpan(0x56), value); }
|
||||
public ushort LocalFormIndex { get => ReadUInt16LittleEndian(Data.AsSpan(0x58)); set => WriteUInt16LittleEndian(Data.AsSpan(0x58), value); } // local region base form
|
||||
public ushort RegionalFlags { get => ReadUInt16LittleEndian(Data.AsSpan(0x5A)); set => WriteUInt16LittleEndian(Data.AsSpan(0x5A), value); }
|
||||
public bool IsRegionalForm { get => (RegionalFlags & 1) == 1; set => RegionalFlags = (ushort)((RegionalFlags & 0xFFFE) | (value ? 1 : 0)); }
|
||||
public bool CanNotDynamax { get => ((Data[0x5A] >> 2) & 1) == 1; set => Data[0x5A] = (byte)((Data[0x5A] & ~4) | (value ? 4 : 0)); }
|
||||
public ushort PokeDexIndex { get => ReadUInt16LittleEndian(Data.AsSpan(0x5C)); set => WriteUInt16LittleEndian(Data.AsSpan(0x5C), value); }
|
||||
public byte RegionalFormIndex { get => (byte)ReadUInt16LittleEndian(Data.AsSpan(0x5E)); set => WriteUInt16LittleEndian(Data.AsSpan(0x5E), value); } // form index of this entry
|
||||
public ushort DexIndexRegional { get => ReadUInt16LittleEndian(Data.AsSpan(0x5C)); set => WriteUInt16LittleEndian(Data.AsSpan(0x5C), value); }
|
||||
public ushort Form { get => (byte)ReadUInt16LittleEndian(Data.AsSpan(0x5E)); set => WriteUInt16LittleEndian(Data.AsSpan(0x5E), value); } // form index of this entry
|
||||
|
||||
// 0xA8-0xAB are armor type tutors, one bit for each type
|
||||
public ushort ArmorDexIndex { get => ReadUInt16LittleEndian(Data.AsSpan(0xAC)); set => WriteUInt16LittleEndian(Data.AsSpan(0xAC), value); }
|
||||
public ushort CrownDexIndex { get => ReadUInt16LittleEndian(Data.AsSpan(0xAE)); set => WriteUInt16LittleEndian(Data.AsSpan(0xAE), value); }
|
||||
|
||||
public ushort DexIndexNational { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Form that any offspring will hatch with, assuming it is holding an Everstone.
|
||||
/// </summary>
|
||||
public byte HatchFormIndexEverstone => IsRegionalForm ? RegionalFormIndex : (byte)LocalFormIndex;
|
||||
public byte HatchFormIndexEverstone => IsRegionalForm ? (byte)Form : (byte)LocalFormIndex;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the entry shows up in any of the built-in Pokédex.
|
||||
/// </summary>
|
||||
public bool IsInDex => PokeDexIndex != 0 || ArmorDexIndex != 0 || CrownDexIndex != 0;
|
||||
public bool IsInDex => DexIndexRegional != 0 || ArmorDexIndex != 0 || CrownDexIndex != 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,4 +97,10 @@ public static void GetSortedStatIndexes(this IBaseStat pi, Span<(int Index, int
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetIBaseStats(this IBaseStat self, IBaseStat other)
|
||||
{
|
||||
for (int j = 0; j < other.GetNumBaseStats(); ++j)
|
||||
self.SetBaseStatValue(j, other.GetBaseStatValue(j));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,4 +75,10 @@ public static void SetEVYieldValue(this IEffortValueYield stats, int index, int
|
|||
/// Gets the total number of base stats available.
|
||||
/// </summary>
|
||||
public static int GetNumEVs(this IEffortValueYield _) => 6;
|
||||
|
||||
public static void SetIEffortValueYield(this IEffortValueYield self, IEffortValueYield other)
|
||||
{
|
||||
for (int j = 0; j < other.GetNumEVs(); ++j)
|
||||
self.SetEVYieldValue(j, other.GetEVYieldValue(j));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,4 +66,10 @@ public static void SetAbilityAtIndex(this IPersonalAbility a, int index, int val
|
|||
/// </summary>
|
||||
/// <remarks>Duplicate abilities still count separately.</remarks>
|
||||
public static int GetNumAbilities(this IPersonalAbility _) => 3;
|
||||
|
||||
public static void SetIPersonalAbility(this IPersonalAbility self, IPersonalAbility other)
|
||||
{
|
||||
for (int j = 0; j < other.GetNumAbilities(); ++j)
|
||||
self.SetAbilityAtIndex(j, other.GetAbilityAtIndex(j));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,4 +57,26 @@ public static class PersonalEggExtensions
|
|||
/// <param name="group">Egg group</param>
|
||||
/// <returns>Egg is present in entry</returns>
|
||||
public static bool IsEggGroup(this IPersonalEgg pi, int group) => pi.EggGroup1 == group || pi.EggGroup2 == group;
|
||||
|
||||
public static void SetIPersonalEgg(this IPersonalEgg self, IPersonalEgg other)
|
||||
{
|
||||
self.EggGroup1 = other.EggGroup1;
|
||||
self.EggGroup2 = other.EggGroup2;
|
||||
|
||||
if (self is IPersonalEgg_1 self_1 && other is IPersonalEgg_1 other_1)
|
||||
{
|
||||
self_1.HatchCycles = other_1.HatchCycles;
|
||||
}
|
||||
|
||||
if (self is IPersonalEgg_2 self_2 && other is IPersonalEgg_2 other_2)
|
||||
{
|
||||
self_2.HatchCycles = other_2.HatchCycles;
|
||||
self_2.HatchedSpecies = other_2.HatchedSpecies;
|
||||
}
|
||||
|
||||
if (self is IPersonalEgg_3 self_3 && other is IPersonalEgg_3 other_3)
|
||||
{
|
||||
self_3.HatchedSpecies = other_3.HatchedSpecies;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,5 +68,4 @@ public static bool IsFormWithinRange(this IPersonalFormInfo info, byte form)
|
|||
return true;
|
||||
return form < info.FormCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,8 +63,6 @@ public interface IPersonalInfoSWSH : IPersonalInfoBin, IPersonalInfo, IPersonalE
|
|||
bool IsRegionalForm { get; set; }
|
||||
ushort RegionalFlags { get; set; }
|
||||
bool CanNotDynamax { get; set; }
|
||||
ushort PokeDexIndex { get; set; }
|
||||
byte RegionalFormIndex { get; set; }
|
||||
ushort ArmorDexIndex { get; set; }
|
||||
ushort CrownDexIndex { get; set; }
|
||||
}
|
||||
|
|
@ -75,4 +73,29 @@ public interface IPersonalInfoPLA : IPersonalInfo, IPersonalEgg_3, IMovesInfo_3,
|
|||
ushort Field_46 { get; set; } // ushort
|
||||
byte Field_47 { get; set; } // byte
|
||||
}
|
||||
|
||||
public static class IPersonalInfoExt
|
||||
{
|
||||
public static void SetPersonalInfo(this IPersonalInfo self, IPersonalInfo other)
|
||||
{
|
||||
self.SetIBaseStats(other);
|
||||
self.SetIEffortValueYield(other);
|
||||
self.SetIPersonalAbility(other);
|
||||
self.SetIPersonalItems(other);
|
||||
self.SetIPersonalType(other);
|
||||
self.SetIPersonalEgg(other);
|
||||
self.SetIPersonalTraits(other);
|
||||
self.SetIPersonalMisc(other);
|
||||
|
||||
if (self is IPersonalInfo_1 self_1 && other is IPersonalInfo_1 other_1)
|
||||
{
|
||||
self_1.SetIMovesInfo(other_1);
|
||||
}
|
||||
|
||||
if (self is IPersonalInfo_2 self_2 && other is IPersonalInfo_2 other_2)
|
||||
{
|
||||
self_2.SetIMovesInfo(other_2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,4 +62,10 @@ public static void SetItemAtIndex(this IPersonalItems a, int index, int value)
|
|||
/// </summary>
|
||||
/// <remarks>Duplicate items still count separately.</remarks>
|
||||
public static int GetNumItems(this IPersonalItems _) => 3;
|
||||
|
||||
public static void SetIPersonalItems(this IPersonalItems self, IPersonalItems other)
|
||||
{
|
||||
for (int j = 0; j < other.GetNumItems(); ++j)
|
||||
self.SetItemAtIndex(j, other.GetItemAtIndex(j));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,19 +16,34 @@ public interface IPersonalMisc
|
|||
/// </summary>
|
||||
public interface IPersonalMisc_1 : IPersonalMisc
|
||||
{
|
||||
ushort Species { get; set; }
|
||||
ushort ModelID { get; set; }
|
||||
ushort Form { get; set; }
|
||||
bool IsPresentInGame { get; set; }
|
||||
ushort LocalFormIndex { get; set; }
|
||||
|
||||
ushort DexIndexNational { get; set; } // ushort
|
||||
ushort DexIndexRegional { get; set; } // ushort
|
||||
}
|
||||
|
||||
public interface IPersonalMisc_2 : IPersonalMisc_1
|
||||
{
|
||||
ushort Form { get; set; }
|
||||
ushort DexIndexNational { get; set; } // ushort
|
||||
ushort DexIndexRegional { get; set; } // ushort
|
||||
ushort DexIndexLocal1 { get; set; } // uint
|
||||
ushort DexIndexLocal2 { get; set; } // uint
|
||||
ushort DexIndexLocal3 { get; set; } // uint
|
||||
ushort DexIndexLocal4 { get; set; } // uint
|
||||
ushort DexIndexLocal5 { get; set; } // uint
|
||||
}
|
||||
|
||||
public static class IPersonalMiscExtensions
|
||||
{
|
||||
public static void SetIPersonalMisc(this IPersonalMisc self, IPersonalMisc other)
|
||||
{
|
||||
self.EvoStage = other.EvoStage;
|
||||
|
||||
if (self is IPersonalMisc_1 self_1 && other is IPersonalMisc_1 other_1)
|
||||
{
|
||||
self_1.DexIndexNational = other_1.DexIndexNational;
|
||||
self_1.Form = other_1.Form;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -90,4 +90,18 @@ public static int RandomGender(this IPersonalTraits info)
|
|||
var fix = info.GetFixedGenderType();
|
||||
return fix >= 0 ? (int)fix : Util.Rand.Next(2);
|
||||
}
|
||||
|
||||
public static void SetIPersonalTraits(this IPersonalTraits self, IPersonalTraits other)
|
||||
{
|
||||
self.Gender = other.Gender;
|
||||
self.EXPGrowth = other.EXPGrowth;
|
||||
self.BaseEXP = other.BaseEXP;
|
||||
self.CatchRate = other.CatchRate;
|
||||
self.EscapeRate = other.EscapeRate;
|
||||
self.BaseFriendship = other.BaseFriendship;
|
||||
self.EscapeRate = other.EscapeRate;
|
||||
self.Color = other.Color;
|
||||
self.Height = other.Height;
|
||||
self.Weight = other.Weight;
|
||||
}
|
||||
}
|
||||
|
|
@ -51,4 +51,10 @@ public static bool IsType(this IPersonalType detail, Types type1, Types type2)
|
|||
/// <param name="type2">Second type</param>
|
||||
/// <returns>Typing is an exact match</returns>
|
||||
public static bool IsValidTypeCombination(this IPersonalType detail, Types type1, Types type2) => detail.Type1 == type1 && detail.Type2 == type2;
|
||||
|
||||
public static void SetIPersonalType(this IPersonalType self, IPersonalType other)
|
||||
{
|
||||
self.Type1 = other.Type1;
|
||||
self.Type2 = other.Type2;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace pkNX.Structures;
|
||||
|
||||
|
|
@ -77,4 +78,77 @@ public bool IsPresentInGame(ushort species, byte form)
|
|||
IPersonalInfo IPersonalTable.this[int index] => this[index];
|
||||
IPersonalInfo IPersonalTable.this[ushort species, byte form] => this[species, form];
|
||||
IPersonalInfo IPersonalTable.GetFormEntry(ushort species, byte form) => GetFormEntry(species, form);
|
||||
|
||||
public void FixMissingData()
|
||||
{
|
||||
// Fix all base forms
|
||||
int sFormCount = 0;
|
||||
for (ushort i = 1; i <= Legal.MaxSpeciesID_7_USUM; i++)
|
||||
{
|
||||
var s = Table[i];
|
||||
s.DexIndexNational = i;
|
||||
|
||||
var u = ResourcesUtil.USUM.Table[i];
|
||||
|
||||
if (s.FormCount == 0)
|
||||
{
|
||||
s.SetPersonalInfo(u);
|
||||
s.FormCount = Math.Max((byte)1, FormInfo.GetOutOfBattleFormCount(i, u.FormCount, 7));
|
||||
}
|
||||
|
||||
if (s.FormCount == 1)
|
||||
continue;
|
||||
|
||||
if (s.FormStatsIndex != 0)
|
||||
Debug.Assert(s.FormStatsIndex == (MaxSpeciesID + 1) + sFormCount);
|
||||
|
||||
s.FormStatsIndex = (MaxSpeciesID + 1) + sFormCount;
|
||||
sFormCount += s.FormCount - 1;
|
||||
|
||||
for (byte f = 1; f < s.FormCount; f++)
|
||||
{
|
||||
var formS = Table[s.FormStatsIndex + (f - 1)];
|
||||
|
||||
if (formS.FormCount == 0)
|
||||
{
|
||||
// Check if USUM table has form data for this entry
|
||||
if (f < u.FormCount)
|
||||
{
|
||||
if (u.FormCount <= s.FormCount || (FormInfo.HasTotemForm(i) && !FormInfo.IsTotemForm(i, f)))
|
||||
{
|
||||
var formU = ResourcesUtil.USUM.GetFormEntry(i, f);
|
||||
formS.SetPersonalInfo(formU);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No form data was found, just write the base form data
|
||||
formS.SetPersonalInfo(s);
|
||||
}
|
||||
|
||||
formS.FormCount = s.FormCount;
|
||||
formS.FormStatsIndex = s.FormStatsIndex;
|
||||
}
|
||||
|
||||
formS.DexIndexNational = i;
|
||||
formS.Form = f;
|
||||
}
|
||||
}
|
||||
|
||||
// Fix form number
|
||||
for (ushort i = Legal.MaxSpeciesID_7_USUM; i <= MaxSpeciesID; i++)
|
||||
{
|
||||
var s = Table[i];
|
||||
s.DexIndexNational = i;
|
||||
|
||||
for (byte f = 1; f < s.FormCount; f++)
|
||||
{
|
||||
var formS = Table[s.FormStatsIndex + (f - 1)];
|
||||
formS.DexIndexNational = i;
|
||||
formS.Form = f;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.WriteLine("Auto fix for SWSH data succeded");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,11 @@ public class ResourcesUtil
|
|||
/// </summary>
|
||||
public static readonly IReadOnlyList<EvolutionMethod[]> USUM_Evolutions = EvolutionSet7.GetArray(GetReader("uu"));
|
||||
|
||||
static ResourcesUtil()
|
||||
{
|
||||
SWSH.FixMissingData();
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> GetTableBinary(string game) => GetBinaryResource($"personal_{game}");
|
||||
private static ReadOnlySpan<byte> GetEvolutionBinary(string game) => GetBinaryResource($"evos_{game}.pkl");
|
||||
private static BinLinkerAccessor GetReader(string resource) => BinLinkerAccessor.Get(GetEvolutionBinary(resource), resource);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
|
@ -58,6 +59,8 @@ public static T[] GetArray<T>(this ReadOnlySpan<byte> entries, FromBytesConstruc
|
|||
if (entries.Length < size)
|
||||
return Array.Empty<T>();
|
||||
|
||||
Debug.Assert(entries.Length % size == 0, "This data can't be split into equally sized entries with the provided slice size");
|
||||
|
||||
var array = new T[entries.Length / size];
|
||||
for (int i = 0; i < entries.Length; i += size)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ private void DumpMoveUsers(IPersonalTable pt, Learnset8a lr)
|
|||
if (isShop)
|
||||
{
|
||||
var species = pt.Table.OfType<IPersonalInfoPLA>().Where(z => z.SpecialTutors[0][shopIndex] && z.IsPresentInGame);
|
||||
var names = species.Select(z => $"{spec[z.Species]}{(z.Form == 0 ? "" : $"-{z.Form}")}");
|
||||
var names = species.Select(z => $"{spec[z.ModelID]}{(z.Form == 0 ? "" : $"-{z.Form}")}");
|
||||
r.Add($"\tTutors: {string.Join(", ", names)}");
|
||||
}
|
||||
|
||||
|
|
@ -893,7 +893,7 @@ private void DumpDexSummarySpecies()
|
|||
{
|
||||
var p = (IPersonalInfoPLA)pt[i];
|
||||
bool any = false;
|
||||
var specForm = $"{p.Species:000}\t{p.Form}\t{s[p.Species]}{(p.Form == 0 ? "" : $"-{p.Form:00}")}";
|
||||
var specForm = $"{p.ModelID:000}\t{p.Form}\t{s[p.ModelID]}{(p.Form == 0 ? "" : $"-{p.Form:00}")}";
|
||||
if (p.DexIndexRegional != 0)
|
||||
{
|
||||
dex.Add($"{p.DexIndexRegional:000}\t{specForm}");
|
||||
|
|
|
|||
|
|
@ -464,9 +464,9 @@ public void DumpGalarDex()
|
|||
{
|
||||
var p = (IPersonalInfoSWSH)pt[i];
|
||||
bool any = false;
|
||||
if (p.PokeDexIndex != 0)
|
||||
if (p.DexIndexRegional != 0)
|
||||
{
|
||||
galar.Add($"{p.PokeDexIndex:000} - [{i:000]} - {s[i]}");
|
||||
galar.Add($"{p.DexIndexRegional:000} - [{i:000]} - {s[i]}");
|
||||
any = true;
|
||||
}
|
||||
if (p.ArmorDexIndex != 0)
|
||||
|
|
|
|||
|
|
@ -276,12 +276,12 @@ public int[] GetSpeciesBanlist()
|
|||
{
|
||||
if (pi.IsPresentInGame)
|
||||
{
|
||||
banned.Remove(pi.Species);
|
||||
hasForm.Add(pi.Species);
|
||||
banned.Remove(pi.ModelID);
|
||||
hasForm.Add(pi.ModelID);
|
||||
}
|
||||
else if (!hasForm.Contains(pi.Species))
|
||||
else if (!hasForm.Contains(pi.ModelID))
|
||||
{
|
||||
banned.Add(pi.Species);
|
||||
banned.Add(pi.ModelID);
|
||||
}
|
||||
}
|
||||
return banned.ToArray();
|
||||
|
|
@ -291,8 +291,8 @@ public int GetRandomForm(int spec)
|
|||
{
|
||||
var pt = Data.PersonalData;
|
||||
var formRand = pt.Table.Cast<IPersonalMisc_1>()
|
||||
.Where(z => z.IsPresentInGame && !(Legal.BattleExclusiveForms.Contains(z.Species) || Legal.BattleFusions.Contains(z.Species)))
|
||||
.GroupBy(z => z.Species)
|
||||
.Where(z => z.IsPresentInGame && !(Legal.BattleExclusiveForms.Contains(z.ModelID) || Legal.BattleFusions.Contains(z.ModelID)))
|
||||
.GroupBy(z => z.ModelID)
|
||||
.ToDictionary(z => z.Key, z => z.ToList());
|
||||
|
||||
if (!formRand.TryGetValue((ushort)spec, out var entries))
|
||||
|
|
|
|||
|
|
@ -85,12 +85,12 @@ private void RandomizeArea(ResidentArea8a area, SpeciesSettings settings)
|
|||
{
|
||||
if (pi.IsPresentInGame)
|
||||
{
|
||||
banned.Remove(pi.Species);
|
||||
hasForm.Add(pi.Species);
|
||||
banned.Remove(pi.ModelID);
|
||||
hasForm.Add(pi.ModelID);
|
||||
}
|
||||
else if (!hasForm.Contains(pi.Species))
|
||||
else if (!hasForm.Contains(pi.ModelID))
|
||||
{
|
||||
banned.Add(pi.Species);
|
||||
banned.Add(pi.ModelID);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -98,8 +98,8 @@ private void RandomizeArea(ResidentArea8a area, SpeciesSettings settings)
|
|||
rand.Initialize(settings, banned.ToArray());
|
||||
|
||||
var formRand = pt.Table.Cast<IPersonalMisc_1>()
|
||||
.Where(z => z.IsPresentInGame && !(Legal.BattleExclusiveForms.Contains(z.Species) || Legal.BattleFusions.Contains(z.Species)))
|
||||
.GroupBy(z => z.Species)
|
||||
.Where(z => z.IsPresentInGame && !(Legal.BattleExclusiveForms.Contains(z.ModelID) || Legal.BattleFusions.Contains(z.ModelID)))
|
||||
.GroupBy(z => z.ModelID)
|
||||
.ToDictionary(z => z.Key, z => z.ToList());
|
||||
|
||||
var encounters = area.Encounters;
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ public MapViewer8a(GameManagerPLA rom, GFPack resident)
|
|||
if (!e.IsPresentInGame)
|
||||
continue;
|
||||
|
||||
var species = e.Species;
|
||||
var species = e.ModelID;
|
||||
if (nameList.All(z => z.Value != species))
|
||||
nameList.Add(new(speciesNames[species], species));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -315,8 +315,8 @@ public void LoadPersonal(IPersonalInfo pkm)
|
|||
if (pkm is IPersonalInfoSWSH swsh)
|
||||
{
|
||||
L_TM.Text = "TMs/TRs:";
|
||||
MT_GoID.Text = swsh.Species.ToString("000");
|
||||
TB_RegionalDex.Text = swsh.PokeDexIndex.ToString("000");
|
||||
MT_GoID.Text = swsh.ModelID.ToString("000");
|
||||
TB_RegionalDex.Text = swsh.DexIndexRegional.ToString("000");
|
||||
TB_ArmorDex.Text = swsh.ArmorDexIndex.ToString("000");
|
||||
TB_CrownDex.Text = swsh.CrownDexIndex.ToString("000");
|
||||
CHK_IsPresentInGame.Checked = swsh.IsPresentInGame;
|
||||
|
|
@ -404,7 +404,7 @@ public void SavePersonal()
|
|||
}
|
||||
if (pkm is IPersonalInfoSWSH swsh)
|
||||
{
|
||||
swsh.PokeDexIndex = Convert.ToUInt16(TB_RegionalDex.Text);
|
||||
swsh.DexIndexRegional = Convert.ToUInt16(TB_RegionalDex.Text);
|
||||
swsh.ArmorDexIndex = Convert.ToUInt16(TB_ArmorDex.Text);
|
||||
swsh.CrownDexIndex = Convert.ToUInt16(TB_CrownDex.Text);
|
||||
swsh.IsPresentInGame = CHK_IsPresentInGame.Checked;
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ public void LoadPersonal(IPersonalInfoPLA pkm)
|
|||
TB_SPDEVs.Text = pkm.EV_SPD.ToString(TB_SPDEVs.Mask);
|
||||
TB_BST.Text = pkm.GetBaseStatTotal().ToString(TB_BST.Mask);
|
||||
|
||||
TB_Classification.Text = classifications[pkm.Species];
|
||||
TB_Classification.Text = classifications[pkm.ModelID];
|
||||
|
||||
CB_Type1.SelectedIndex = (int)pkm.Type1;
|
||||
CB_Type2.SelectedIndex = (int)pkm.Type2;
|
||||
|
|
@ -310,10 +310,10 @@ public void UpdateGenderDetailLabel()
|
|||
|
||||
public void UpdateButtonStates()
|
||||
{
|
||||
B_PreviousPokemon.Enabled = cPersonal.Species > 0;
|
||||
B_PreviousPokemon.Enabled = cPersonal.ModelID > 0;
|
||||
B_PreviousForm.Enabled = cPersonal.Form > 0;
|
||||
B_NextForm.Enabled = (cPersonal.Form + 1) < cPersonal.FormCount;
|
||||
B_NextPokemon.Enabled = (cPersonal.Species + 1) < Data.PersonalData.MaxSpeciesID;
|
||||
B_NextPokemon.Enabled = (cPersonal.ModelID + 1) < Data.PersonalData.MaxSpeciesID;
|
||||
}
|
||||
|
||||
public void SavePersonal()
|
||||
|
|
@ -471,6 +471,93 @@ public void SaveEvolutions()
|
|||
row.SaveEvolution();
|
||||
}
|
||||
|
||||
public void AutoFillPersonal()
|
||||
{
|
||||
Debug.Assert(Data.PersonalData is PersonalTable8LA, "This function is build for PLA data. It needs to be updated if more data is added.");
|
||||
|
||||
var la = (PersonalTable8LA)Data.PersonalData;
|
||||
la.FixMissingData();
|
||||
}
|
||||
|
||||
public void AutoFillEvolutions()
|
||||
{
|
||||
var usum = ResourcesUtil.USUM_Evolutions;
|
||||
var usumPersonal = ResourcesUtil.SWSH;
|
||||
|
||||
var swsh = ResourcesUtil.SWSH_Evolutions;
|
||||
var swshPersonal = ResourcesUtil.SWSH;
|
||||
|
||||
for (int i = 0; i < usum.Count; i++)
|
||||
{
|
||||
EvolutionMethod[] evoSet = swsh[i];
|
||||
EvolutionMethod[] usumEvos = usum[i];
|
||||
|
||||
if (evoSet[0].Method == EvolutionType.None && usumEvos[0].Method != EvolutionType.None)
|
||||
{
|
||||
for (int j = 0; j < usumEvos.Length; j++)
|
||||
{
|
||||
if (usumEvos[j].Method == EvolutionType.None)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var usumEntry = usumEvos[j];
|
||||
var evoEntry = evoSet[j];
|
||||
evoEntry.Species = usumEntry.Species;
|
||||
evoEntry.Form = usumEntry.Form;
|
||||
evoEntry.Argument = usumEntry.Argument;
|
||||
evoEntry.Method = usumEntry.Method;
|
||||
evoEntry.Level = usumEntry.Level;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var la = Data.EvolutionData;
|
||||
for (int i = 0; i < la.Length; i++)
|
||||
{
|
||||
EvolutionSet8a evoSet = la[i];
|
||||
if (evoSet.Table == null || evoSet.Table.Length == 0)
|
||||
{
|
||||
var species = evoSet.Species;
|
||||
var form = evoSet.Form;
|
||||
|
||||
if (species > Legal.MaxSpeciesID_8)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int index = swshPersonal.GetFormIndex(species, (byte)form);
|
||||
if (index == 0)
|
||||
{
|
||||
// Assume the form doesn't exsist in the game
|
||||
continue;
|
||||
}
|
||||
|
||||
var swshEvos = swsh[index];
|
||||
|
||||
List<EvolutionEntry8a> entries = new();
|
||||
for (int j = 0; j < swshEvos.Length; j++)
|
||||
{
|
||||
var swhsEntry = swshEvos[j];
|
||||
if (swhsEntry.Method == EvolutionType.None)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
entries.Add(new EvolutionEntry8a
|
||||
{
|
||||
Species = swhsEntry.Species,
|
||||
Form = swhsEntry.Form,
|
||||
Argument = swhsEntry.Argument,
|
||||
Method = (ushort)swhsEntry.Method,
|
||||
Level = swhsEntry.Level
|
||||
});
|
||||
}
|
||||
evoSet.Table = entries.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void B_PDumpTable_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
|
@ -604,75 +691,11 @@ private void B_LearnMetronome_Click(object sender, EventArgs e)
|
|||
|
||||
private void B_AufoFill_Click(object sender, EventArgs e)
|
||||
{
|
||||
Debug.Assert(Data.PersonalData is PersonalTable8LA, "This function is build for PLA data. It needs to be updated if more data is added.");
|
||||
// Make sure any modifications are saved before forcing to reload everything
|
||||
SaveCurrent();
|
||||
|
||||
var swsh = ResourcesUtil.SWSH;
|
||||
var usum = ResourcesUtil.USUM;
|
||||
|
||||
// Fix gender for ss data
|
||||
for (ushort i = 1; i <= usum.MaxSpeciesID; i++)
|
||||
{
|
||||
var ss = swsh.Table[i];
|
||||
if (ss.HP == 0)
|
||||
ss.Gender = usum.Table[i].Gender;
|
||||
}
|
||||
|
||||
// Fill all data for la
|
||||
var la = (PersonalTable8LA)Data.PersonalData;
|
||||
for (ushort i = 1; i <= swsh.MaxSpeciesID; i++)
|
||||
{
|
||||
var fc = la.Table[i].FormCount;
|
||||
for (byte f = 0; f < fc; f++)
|
||||
{
|
||||
var l = la.GetFormEntry(i, f);
|
||||
if (l == null || l.HP != 0)
|
||||
continue;
|
||||
|
||||
var s = swsh.GetFormEntry(i, f);
|
||||
|
||||
//IBaseStat
|
||||
for (int j = 0; j < s.GetNumBaseStats(); ++j)
|
||||
l.SetBaseStatValue(j, s.GetBaseStatValue(j));
|
||||
|
||||
//IEffortValueYield
|
||||
for (int j = 0; j < s.GetNumEVs(); ++j)
|
||||
l.SetEVYieldValue(j, s.GetEVYieldValue(j));
|
||||
|
||||
//IPersonalAbility
|
||||
for (int j = 0; j < s.GetNumAbilities(); ++j)
|
||||
l.SetAbilityAtIndex(j, s.GetAbilityAtIndex(j));
|
||||
|
||||
//IPersonalItems
|
||||
for (int j = 0; j < s.GetNumItems(); ++j)
|
||||
l.SetItemAtIndex(j, s.GetItemAtIndex(j));
|
||||
|
||||
//IPersonalType
|
||||
l.Type1 = s.Type1;
|
||||
l.Type2 = s.Type2;
|
||||
|
||||
//IPersonalEgg_2
|
||||
l.EggGroup1 = s.EggGroup1;
|
||||
l.EggGroup2 = s.EggGroup2;
|
||||
//l.HatchCycles = s.HatchCycles;
|
||||
l.HatchedSpecies = s.HatchedSpecies;
|
||||
|
||||
//IPersonalTraits
|
||||
l.Gender = s.Gender;
|
||||
l.EXPGrowth = s.EXPGrowth;
|
||||
l.BaseEXP = s.BaseEXP;
|
||||
l.CatchRate = s.CatchRate;
|
||||
l.BaseFriendship = s.BaseFriendship;
|
||||
l.EscapeRate = s.EscapeRate;
|
||||
l.Color = s.Color;
|
||||
l.Height = s.Height;
|
||||
l.Weight = s.Weight;
|
||||
|
||||
//IPersonalMisc_1
|
||||
//l.Species = i;
|
||||
l.DexIndexNational = i;
|
||||
l.EvoStage = s.EvoStage;
|
||||
}
|
||||
}
|
||||
AutoFillPersonal();
|
||||
AutoFillEvolutions();
|
||||
|
||||
// Reload selected
|
||||
LoadIndex(CB_Species.SelectedIndex);
|
||||
|
|
@ -681,8 +704,8 @@ private void B_AufoFill_Click(object sender, EventArgs e)
|
|||
|
||||
private void B_NextPokemon_Click(object sender, EventArgs e)
|
||||
{
|
||||
Debug.Assert(cPersonal.Species < Data.PersonalData.MaxSpeciesID);
|
||||
CB_Species.SelectedIndex = cPersonal.Species + 1;
|
||||
Debug.Assert(cPersonal.ModelID < Data.PersonalData.MaxSpeciesID);
|
||||
CB_Species.SelectedIndex = cPersonal.ModelID + 1;
|
||||
}
|
||||
|
||||
private void B_NextForm_Click(object sender, EventArgs e)
|
||||
|
|
@ -690,7 +713,7 @@ private void B_NextForm_Click(object sender, EventArgs e)
|
|||
Debug.Assert(cPersonal.Form < cPersonal.FormCount);
|
||||
|
||||
var pt = Data.PersonalData;
|
||||
CB_Species.SelectedIndex = pt.GetFormIndex(cPersonal.Species, (byte)(cPersonal.Form + 1));
|
||||
CB_Species.SelectedIndex = pt.GetFormIndex(cPersonal.ModelID, (byte)(cPersonal.Form + 1));
|
||||
}
|
||||
|
||||
private void B_PreviousForm_Click(object sender, EventArgs e)
|
||||
|
|
@ -698,13 +721,13 @@ private void B_PreviousForm_Click(object sender, EventArgs e)
|
|||
Debug.Assert(cPersonal.Form > 0);
|
||||
|
||||
var pt = Data.PersonalData;
|
||||
CB_Species.SelectedIndex = pt.GetFormIndex(cPersonal.Species, (byte)(cPersonal.Form - 1));
|
||||
CB_Species.SelectedIndex = pt.GetFormIndex(cPersonal.ModelID, (byte)(cPersonal.Form - 1));
|
||||
}
|
||||
|
||||
private void B_PreviousPokemon_Click(object sender, EventArgs e)
|
||||
{
|
||||
Debug.Assert(cPersonal.Species > 0);
|
||||
CB_Species.SelectedIndex = cPersonal.Species - 1;
|
||||
Debug.Assert(cPersonal.ModelID > 0);
|
||||
CB_Species.SelectedIndex = cPersonal.ModelID - 1;
|
||||
}
|
||||
|
||||
private void B_Save_Click(object sender, EventArgs e)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user