Sword/Shield Update

This commit is contained in:
Kurt 2019-11-15 17:34:18 -08:00
parent d59764f25f
commit cefb56a749
1328 changed files with 31304 additions and 4801 deletions

View file

@ -87,8 +87,8 @@ namespace PKHeX.Core
private static IEnumerable<Ball> GetBallListFromColor(PKM pkm)
{
// Fetch with latest-gen personal info; Gen1/2 don't store color
var pi = PKX.Personal.GetFormeEntry(pkm.Species, pkm.AltForm);
// Gen1/2 don't store color in personal info
var pi = pkm.Format >= 3 ? pkm.PersonalInfo : PersonalTable.USUM.GetFormeEntry(pkm.Species, 0);
var color = (PersonalColor)pi.Color;
var balls = BallColors[color];
var currentBall = (Ball)pkm.Ball;

View file

@ -168,7 +168,9 @@ namespace PKHeX.Core
public static void SetNature(this PKM pk, int nature)
{
var value = Math.Min((int)Nature.Quirky, Math.Max((int)Nature.Hardy, nature));
if (pk.Format <= 4)
if (pk.Format >= 8)
pk.StatNature = value;
else if (pk.Format <= 4)
pk.SetPIDNature(value);
else
pk.Nature = value;
@ -302,8 +304,8 @@ namespace PKHeX.Core
return m;
var encounter = legal.GetSuggestedMetInfo();
if (encounter?.Relearn?.Length > 0)
m = encounter.Relearn;
if (encounter is IRelearn r && r.Relearn.Length > 0)
m = r.Relearn;
return m;
}
@ -671,6 +673,7 @@ namespace PKHeX.Core
pk.Markings = markings;
break;
case 7: // 0 (none) | 1 (blue) | 2 (pink)
case 8:
markings[index] = (markings[index] + 1) % 3; // cycle 0->1->2->0...
pk.Markings = markings;
break;

View file

@ -16,7 +16,7 @@ namespace PKHeX.Core
public string? Position => pkm.Identifier;
public string Nickname => pkm.Nickname;
public string Species => Get(Strings.specieslist, pkm.Species);
public string Nature => Get(Strings.natures, pkm.Nature);
public string Nature => Get(Strings.natures, pkm.StatNature);
public string Gender => Get(GenderSymbols, pkm.Gender);
public string ESV => pkm.PSV.ToString("0000");
public string HP_Type => Get(Strings.types, pkm.HPType + 1);

View file

@ -0,0 +1,211 @@
using System.Collections.Generic;
using System.Linq;
namespace PKHeX.Core
{
/// <summary>
/// Logic for applying ribbons.
/// </summary>
public static class RibbonApplicator
{
private static List<string> GetAllRibbonNames(PKM pkm) => RibbonInfo.GetRibbonInfo(pkm).Select(z => z.Name).ToList();
/// <summary>
/// Gets a list of valid ribbons for the <see cref="pkm"/>.
/// </summary>
/// <param name="pkm">Entity to fetch the list for.</param>
/// <param name="allRibbons">All ribbon names.</param>
/// <returns>List of all valid ribbon names.</returns>
public static IReadOnlyList<string> GetValidRibbons(PKM pkm, IList<string> allRibbons)
{
var pk = pkm.Clone();
return SetAllValidRibbons(allRibbons, pk);
}
/// <summary>
/// Gets a list of valid ribbons for the <see cref="pkm"/>.
/// </summary>
/// <param name="pkm">Entity to fetch the list for.</param>
/// <returns>List of all valid ribbon names.</returns>
public static IReadOnlyList<string> GetValidRibbons(PKM pkm)
{
var names = GetAllRibbonNames(pkm);
return GetValidRibbons(pkm, names);
}
/// <summary>
/// Gets a list of valid ribbons for the <see cref="pkm"/> that can be removed.
/// </summary>
/// <param name="pkm">Entity to fetch the list for.</param>
/// <param name="allRibbons">All ribbon names.</param>
/// <returns>List of all removable ribbon names.</returns>
public static IReadOnlyList<string> GetRemovableRibbons(PKM pkm, IList<string> allRibbons)
{
var pk = pkm.Clone();
return RemoveAllValidRibbons(allRibbons, pk);
}
/// <summary>
/// Gets a list of valid ribbons for the <see cref="pkm"/> that can be removed.
/// </summary>
/// <param name="pkm">Entity to fetch the list for.</param>
/// <returns>List of all removable ribbon names.</returns>
public static IReadOnlyList<string> GetRemovableRibbons(PKM pkm)
{
var names = GetAllRibbonNames(pkm);
return GetRemovableRibbons(pkm, names);
}
/// <summary>
/// Sets all valid ribbons to the <see cref="pkm"/>.
/// </summary>
/// <param name="pkm">Entity to set ribbons for.</param>
/// <returns>True if any ribbons were applied.</returns>
public static bool SetAllValidRibbons(PKM pkm)
{
var ribNames = GetAllRibbonNames(pkm);
return SetAllValidRibbons(pkm, ribNames);
}
/// <summary>
/// Sets all valid ribbons to the <see cref="pkm"/>.
/// </summary>
/// <param name="pkm">Entity to set ribbons for.</param>
/// <param name="ribNames">Ribbon names to try setting.</param>
/// <returns>True if any ribbons were applied.</returns>
public static bool SetAllValidRibbons(PKM pkm, List<string> ribNames)
{
var list = SetAllValidRibbons(ribNames, pkm);
return list.Count != 0;
}
private static IReadOnlyList<string> SetAllValidRibbons(IList<string> allRibbons, PKM pk)
{
var la = new LegalityAnalysis(pk);
var valid = new List<string>();
while (TryApplyAllRibbons(pk, la, allRibbons, valid) != 0)
{
// Repeat the operation until no more ribbons are set.
}
return valid;
}
/// <summary>
/// Sets all valid ribbons to the <see cref="pkm"/>.
/// </summary>
/// <param name="pkm">Entity to set ribbons for.</param>
/// <returns>True if any ribbons were removed.</returns>
public static bool RemoveAllValidRibbons(PKM pkm)
{
var ribNames = GetAllRibbonNames(pkm);
return RemoveAllValidRibbons(pkm, ribNames);
}
/// <summary>
/// Sets all valid ribbons to the <see cref="pkm"/>.
/// </summary>
/// <param name="pkm">Entity to set ribbons for.</param>
/// <param name="ribNames">Ribbon names to try setting.</param>
/// <returns>True if any ribbons were removed.</returns>
public static bool RemoveAllValidRibbons(PKM pkm, List<string> ribNames)
{
var list = RemoveAllValidRibbons(ribNames, pkm);
return list.Count != 0;
}
private static IReadOnlyList<string> RemoveAllValidRibbons(IList<string> allRibbons, PKM pk)
{
var la = new LegalityAnalysis(pk);
var valid = new List<string>();
while (TryRemoveAllRibbons(pk, la, allRibbons, valid) != 0)
{
// Repeat the operation until no more ribbons are set.
}
return valid;
}
private static int TryApplyAllRibbons(PKM pk, LegalityAnalysis la, IList<string> allRibbons, ICollection<string> valid)
{
int applied = 0;
for (int i = 0; i < allRibbons.Count;)
{
la.ResetParse();
var rib = allRibbons[i];
var success = TryApplyRibbon(pk, la, rib);
if (success)
{
++applied;
allRibbons.RemoveAt(i);
valid.Add(rib);
}
else
{
RemoveRibbon(pk, rib);
++i;
}
}
return applied;
}
private static int TryRemoveAllRibbons(PKM pk, LegalityAnalysis la, IList<string> allRibbons, ICollection<string> valid)
{
int removed = 0;
for (int i = 0; i < allRibbons.Count;)
{
la.ResetParse();
var rib = allRibbons[i];
var success = TryRemoveRibbon(pk, la, rib);
if (success)
{
++removed;
allRibbons.RemoveAt(i);
valid.Add(rib);
}
else
{
SetRibbonValue(pk, rib, 1);
++i;
}
}
return removed;
}
private static void RemoveRibbon(PKM pk, string rib) => SetRibbonValue(pk, rib, 0);
private static bool TryRemoveRibbon(PKM pk, LegalityAnalysis la, string rib)
{
RemoveRibbon(pk, rib);
LegalityAnalysis.Ribbon.Verify(la);
return la.Results.All(z => z.Valid);
}
private static bool TryApplyRibbon(PKM pk, LegalityAnalysis la, string rib)
{
SetRibbonValue(pk, rib, 1);
LegalityAnalysis.Ribbon.Verify(la);
return la.Results.All(z => z.Valid);
}
private static void SetRibbonValue(PKM pk, string rib, int value)
{
switch (rib)
{
case nameof(PK7.RibbonCountMemoryBattle):
ReflectUtil.SetValue(pk, rib, value * (pk.Gen4 ? 6 : 8));
break;
case nameof(PK7.RibbonCountMemoryContest):
ReflectUtil.SetValue(pk, rib, value * (pk.Gen4 ? 20 : 40));
break;
default:
ReflectUtil.SetValue(pk, rib, value != 0);
break;
}
}
}
}

View file

@ -56,12 +56,12 @@ namespace PKHeX.Core
public override string Extension => string.Empty;
public override bool ChecksumsValid => true;
public override string ChecksumInfo => string.Empty;
public override int Generation => PKX.Generation;
public override int Generation => 3;
public override string GetString(byte[] data, int offset, int length) => string.Empty;
public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0) => Array.Empty<byte>();
public override PersonalTable Personal => PKX.Personal;
public override PersonalTable Personal => PersonalTable.RS;
public override int MaxEV => 0;
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_GG;
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_RS;
public override int GetBoxOffset(int box) => -1;
public override string GetBoxName(int box) => $"Box {box:00}";
public override void SetBoxName(int box, string value) { }
@ -77,10 +77,10 @@ namespace PKHeX.Core
public override int GetPartyOffset(int slot) => -1;
protected override void SetChecksums() { }
public override Type PKMType => typeof(PKM);
public override Type PKMType => typeof(PK3);
protected override PKM GetPKM(byte[] data) => BlankPKM;
protected override byte[] DecryptPKM(byte[] data) => data;
public override PKM BlankPKM => new PK7();
public override PKM BlankPKM => new PK3();
public override int SIZE_STORED => 0;
protected override int SIZE_PARTY => 0;
}

View file

@ -11,8 +11,6 @@ namespace PKHeX.Core
pkms.AddRange(sav.BoxData);
if (sav.HasParty)
pkms.AddRange(sav.PartyData);
if (sav.HasBattleBox)
pkms.AddRange(sav.BattleBoxData);
var extra = sav.GetExtraPKM();
pkms.AddRange(extra);
@ -57,6 +55,7 @@ namespace PKHeX.Core
SAV6XY xy => GetExtraSlots6XY(xy),
SAV6AO xy => GetExtraSlots6AO(xy),
SAV7 sav7 => GetExtraSlots7(sav7, all),
SAV8SWSH ss => GetExtraSlots8(ss),
_ => None
};
}
@ -65,7 +64,7 @@ namespace PKHeX.Core
{
return new List<SlotInfoMisc>
{
new SlotInfoMisc(0, sav.GetDaycareSlotOffset(0, 2)) {Type = StorageSlotType.Daycare } // egg
new SlotInfoMisc(sav.Data, 0, sav.GetDaycareSlotOffset(0, 2)) {Type = StorageSlotType.Daycare } // egg
};
}
@ -75,7 +74,7 @@ namespace PKHeX.Core
return None;
return new List<SlotInfoMisc>
{
new SlotInfoMisc(0, sav.GetBlockOffset(4) + 0xE18) {Type = StorageSlotType.Daycare }
new SlotInfoMisc(sav.Data, 0, sav.GetBlockOffset(4) + 0xE18) {Type = StorageSlotType.Daycare }
};
}
@ -83,7 +82,7 @@ namespace PKHeX.Core
{
return new List<SlotInfoMisc>
{
new SlotInfoMisc(0, sav.GTS) {Type = StorageSlotType.GTS },
new SlotInfoMisc(sav.Data, 0, sav.GTS) {Type = StorageSlotType.GTS },
};
}
@ -91,8 +90,15 @@ namespace PKHeX.Core
{
return new List<SlotInfoMisc>
{
new SlotInfoMisc(0, sav.GTS) {Type = StorageSlotType.GTS},
new SlotInfoMisc(0, sav.Fused) {Type = StorageSlotType.Fused}
new SlotInfoMisc(sav.Data, 0, sav.GTS) {Type = StorageSlotType.GTS},
new SlotInfoMisc(sav.Data, 0, sav.Fused) {Type = StorageSlotType.Fused},
new SlotInfoMisc(sav.Data, 0, sav.GetBattleBoxSlot(0)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 1, sav.GetBattleBoxSlot(1)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 2, sav.GetBattleBoxSlot(2)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 3, sav.GetBattleBoxSlot(3)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 4, sav.GetBattleBoxSlot(4)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 5, sav.GetBattleBoxSlot(5)) {Type = StorageSlotType.BattleBox},
};
}
@ -100,9 +106,16 @@ namespace PKHeX.Core
{
return new List<SlotInfoMisc>
{
new SlotInfoMisc(0, sav.GTS) {Type = StorageSlotType.GTS},
new SlotInfoMisc(0, sav.Fused) {Type = StorageSlotType.Fused},
new SlotInfoMisc(0, sav.SUBE) {Type = StorageSlotType.Misc},
new SlotInfoMisc(sav.Data, 0, sav.GTS) {Type = StorageSlotType.GTS},
new SlotInfoMisc(sav.Data, 0, sav.Fused) {Type = StorageSlotType.Fused},
new SlotInfoMisc(sav.Data, 0, sav.SUBE) {Type = StorageSlotType.Misc},
new SlotInfoMisc(sav.Data, 0, sav.GetBattleBoxSlot(0)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 1, sav.GetBattleBoxSlot(1)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 2, sav.GetBattleBoxSlot(2)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 3, sav.GetBattleBoxSlot(3)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 4, sav.GetBattleBoxSlot(4)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 5, sav.GetBattleBoxSlot(5)) {Type = StorageSlotType.BattleBox},
};
}
@ -110,8 +123,15 @@ namespace PKHeX.Core
{
return new List<SlotInfoMisc>
{
new SlotInfoMisc(0, sav.GTS) {Type = StorageSlotType.GTS},
new SlotInfoMisc(0, sav.Fused) {Type = StorageSlotType.Fused}
new SlotInfoMisc(sav.Data, 0, sav.GTS) {Type = StorageSlotType.GTS},
new SlotInfoMisc(sav.Data, 0, sav.Fused) {Type = StorageSlotType.Fused},
new SlotInfoMisc(sav.Data, 0, sav.GetBattleBoxSlot(0)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 1, sav.GetBattleBoxSlot(1)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 2, sav.GetBattleBoxSlot(2)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 3, sav.GetBattleBoxSlot(3)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 4, sav.GetBattleBoxSlot(4)) {Type = StorageSlotType.BattleBox},
new SlotInfoMisc(sav.Data, 5, sav.GetBattleBoxSlot(5)) {Type = StorageSlotType.BattleBox},
};
}
@ -119,15 +139,15 @@ namespace PKHeX.Core
{
var list = new List<SlotInfoMisc>
{
new SlotInfoMisc(0, sav.AllBlocks[07].Offset) {Type = StorageSlotType.GTS},
new SlotInfoMisc(0, sav.GetFusedSlotOffset(0)) {Type = StorageSlotType.Fused}
new SlotInfoMisc(sav.Data, 0, sav.AllBlocks[07].Offset) {Type = StorageSlotType.GTS},
new SlotInfoMisc(sav.Data, 0, sav.GetFusedSlotOffset(0)) {Type = StorageSlotType.Fused}
};
if (sav is SAV7USUM)
{
list.AddRange(new[]
{
new SlotInfoMisc(1, sav.GetFusedSlotOffset(1)) {Type = StorageSlotType.Fused},
new SlotInfoMisc(2, sav.GetFusedSlotOffset(2)) {Type = StorageSlotType.Fused},
new SlotInfoMisc(sav.Data, 1, sav.GetFusedSlotOffset(1)) {Type = StorageSlotType.Fused},
new SlotInfoMisc(sav.Data, 2, sav.GetFusedSlotOffset(2)) {Type = StorageSlotType.Fused},
});
}
@ -135,8 +155,25 @@ namespace PKHeX.Core
return list;
for (int i = 0; i < ResortSave7.ResortCount; i++)
list.Add(new SlotInfoMisc(i, sav.ResortSave.GetResortSlotOffset(i)) { Type = StorageSlotType.Resort });
list.Add(new SlotInfoMisc(sav.Data, i, sav.ResortSave.GetResortSlotOffset(i)) { Type = StorageSlotType.Resort });
return list;
}
private static List<SlotInfoMisc> GetExtraSlots8(ISaveBlock8Main sav)
{
var fused = sav.Fused;
var dc = sav.Daycare;
return new List<SlotInfoMisc>
{
new SlotInfoMisc(fused.Data, 0, Fused8.GetFusedSlotOffset(0), true),
new SlotInfoMisc(fused.Data, 0, Fused8.GetFusedSlotOffset(0), true),
new SlotInfoMisc(fused.Data, 0, Fused8.GetFusedSlotOffset(0), true),
new SlotInfoMisc(dc.Data, 0, Daycare8.GetDaycareSlotOffset(0, 0)),
new SlotInfoMisc(dc.Data, 0, Daycare8.GetDaycareSlotOffset(0, 1)),
new SlotInfoMisc(dc.Data, 0, Daycare8.GetDaycareSlotOffset(1, 0)),
new SlotInfoMisc(dc.Data, 0, Daycare8.GetDaycareSlotOffset(1, 1)),
};
}
}
}

View file

@ -12,25 +12,36 @@ namespace PKHeX.Core
public WriteBlockedMessage CanWriteTo(SaveFile sav, PKM pkm) => WriteBlockedMessage.InvalidDestination;
public StorageSlotType Type { get; set; }
public SlotInfoMisc(int slot, int offset, bool party = false)
private readonly byte[] Data; // buffer to r/w
public SlotInfoMisc(SaveFile sav, int slot, int offset, bool party = false)
{
Slot = slot;
Offset = offset;
PartyFormat = party;
Data = sav.Data;
}
public SlotInfoMisc(byte[] data, int slot, int offset, bool party = false)
{
Slot = slot;
Offset = offset;
PartyFormat = party;
Data = data;
}
public bool WriteTo(SaveFile sav, PKM pkm, PKMImportSetting setting = PKMImportSetting.UseDefault)
{
if (PartyFormat)
sav.SetPartySlot(pkm, Offset, setting, setting);
sav.SetSlotFormatParty(pkm, Data, Offset, setting, setting);
else
sav.SetStoredSlot(pkm, Offset, setting, setting);
sav.SetSlotFormatStored(pkm, Data, Offset, setting, setting);
return true;
}
public PKM Read(SaveFile sav)
{
return PartyFormat ? sav.GetPartySlot(Offset) : sav.GetStoredSlot(Offset);
return PartyFormat ? sav.GetPartySlot(Data, Offset) : sav.GetStoredSlot(Data, Offset);
}
private bool Equals(SlotInfoMisc other) => Offset == other.Offset;

View file

@ -69,7 +69,7 @@ namespace PKHeX.Core
public int Friendship { get; private set; } = 255;
/// <summary>
/// <see cref="PKM.Nature"/> of the Set entity.
/// <see cref="PKM.StatNature"/> of the Set entity.
/// </summary>
public int Nature { get; set; } = -1;
@ -393,7 +393,7 @@ namespace PKHeX.Core
Nature = pkm.Nature;
Gender = genders[pkm.Gender < 2 ? pkm.Gender : 2];
Friendship = pkm.CurrentFriendship;
Level = Experience.GetLevel(pkm.EXP, pkm.Species, pkm.AltForm);
Level = Experience.GetLevel(pkm.EXP, pkm.PersonalInfo.EXPGrowth);
Shiny = pkm.IsShiny;
SetFormString(pkm.AltForm);

View file

@ -239,6 +239,31 @@
ShadowShield,
PrismArmor,
Neuroforce,
IntrepidSword,
DauntlessShield,
Libero,
BallFetch,
CottonDown,
PropellerTail,
MirrorArmor,
GulpMissile,
Stalwart,
SteamEngine,
PunkRock,
SandSpit,
IceScales,
Ripen,
IceFace,
PowerSpot,
Mimicry,
ScreenCleaner,
SteelySpirit,
PerishBody,
WanderingSpirit,
GorillaTactics,
NeutralizingGas,
PastelVeil,
HungerSwitch,
MAX_COUNT,
}
}

View file

@ -42,6 +42,8 @@ namespace PKHeX.Core
MetGen8 = CreateGen8(s);
Memories = new MemoryStrings(s);
Empty = new ComboItem(s.Species[0], 0);
}
public readonly GameStrings Source;
@ -66,6 +68,8 @@ namespace PKHeX.Core
private readonly IReadOnlyList<ComboItem> MetGen7GG;
private readonly IReadOnlyList<ComboItem> MetGen8;
public readonly ComboItem Empty;
private static IReadOnlyList<ComboItem> GetVersionList(GameStrings s)
{
var list = s.gamelist;

View file

@ -125,11 +125,10 @@ namespace PKHeX.Core
metGG_40000 = Get("gg_40000");
metGG_60000 = metSM_60000;
// todo
metSWSH_00000 = Enumerable.Range(1, 500).Select(z => $"a{z}").ToArray();
metSWSH_30000 = Enumerable.Range(1, 500).Select(z => $"b{z}").ToArray();
metSWSH_40000 = Enumerable.Range(1, 500).Select(z => $"c{z}").ToArray();
metSWSH_60000 = Enumerable.Range(1, 500).Select(z => $"d{z}").ToArray();
metSWSH_00000 = Get("swsh_00000");
metSWSH_30000 = Get("swsh_30000");
metSWSH_40000 = Get("swsh_40000");
metSWSH_60000 = Get("swsh_60000");
Sanitize();
@ -206,6 +205,14 @@ namespace PKHeX.Core
foreach (var i in Legal.Pouch_ZCrystal_USUM)
itemlist[i] += " [Z]";
itemlist[0121] += " (1)"; // Pokémon Box Link
itemlist[1075] += " (2)"; // Pokémon Box Link
itemlist[1080] += " (SW/SH)"; // Fishing Rod
itemlist[1081] += " (1)"; // Rotom Bike
itemlist[1266] += " (2)"; // Rotom Bike
for (int i = 12; i <= 29; i++) // Differentiate DNA Samples
g3coloitems[500 + i] += $" ({i - 11:00})";
// differentiate G3 Card Key from Colo
@ -219,6 +226,7 @@ namespace PKHeX.Core
SanitizeMetG5BW();
SanitizeMetG6XY();
SanitizeMetG7SM();
SanitizeMetG8SWSH();
if (lang == "es" || lang == "it")
{
@ -322,6 +330,34 @@ namespace PKHeX.Core
metGG_40000[i] += " (-)";
}
private void SanitizeMetG8SWSH()
{
// SWSH duplicates -- elaborate!
var metSWSH_00000_good = (string[])metSWSH_00000.Clone();
for (int i = 2; i < metSWSH_00000_good.Length; i += 2)
{
var nextLoc = metSWSH_00000[i + 1];
if (!string.IsNullOrWhiteSpace(nextLoc) && nextLoc[0] != '[')
metSWSH_00000_good[i] += $" ({nextLoc})";
}
for (int i = 121; i <= 155; i+=2)
metSWSH_00000_good[i] = string.Empty; // clear Wild Area sub-zone strings (trips duplicate Test)
metSWSH_00000_good.CopyTo(metSWSH_00000, 0);
metSWSH_30000[0] += $" ({NPC})"; // Anything from an NPC
metSWSH_30000[1] += $" ({EggName})"; // Egg From Link Trade
for (int i = 2; i <= 5; i++) // distinguish first set of regions (unused) from second (used)
metSWSH_30000[i] += " (-)";
metSWSH_30000[18] += " (?)"; // Kanto for the third time
for (int i = 54; i < 60; i++) // distinguish Event year duplicates
metSWSH_40000[i] += " (-)";
metSWSH_40000[29] += " (-)"; // a Video game Event (in spanish etc) -- duplicate with line 39
metSWSH_40000[52] += " (-)"; // a Pokémon event -- duplicate with line 37
}
public IReadOnlyList<string> GetItemStrings(int generation, GameVersion game = GameVersion.Any)
{
return generation switch

View file

@ -13,10 +13,10 @@ namespace PKHeX.Core
s = strings;
memories = new Lazy<List<ComboItem>>(GetMemories);
none = new Lazy<List<ComboItem>>(() => Util.GetCBList(new[] {string.Empty}));
species = new Lazy<List<ComboItem>>(() => Util.GetCBList(s.specieslist.Take(Legal.MaxSpeciesID_6 + 1).ToArray()));
species = new Lazy<List<ComboItem>>(() => Util.GetCBList(s.specieslist.ToArray()));
item = new Lazy<List<ComboItem>>(() => Util.GetCBList(s.itemlist, Memories.MemoryItems));
genloc = new Lazy<List<ComboItem>>(() => Util.GetCBList(s.genloc));
moves = new Lazy<List<ComboItem>>(() => Util.GetCBList(s.movelist.Take(622).ToArray())); // Hyperspace Fury
moves = new Lazy<List<ComboItem>>(() => Util.GetCBList(s.movelist.ToArray())); // Hyperspace Fury
specific = new Lazy<List<ComboItem>>(() => Util.GetCBList(s.metXY_00000, Legal.Met_XY_0));
}
@ -48,21 +48,8 @@ namespace PKHeX.Core
return memory_list1;
}
public string[] GetMemoryQualities()
{
var list = new string[7];
for (int i = 0; i < list.Length; i++)
list[i] = s.memories[2 + i];
return list;
}
public string[] GetMemoryFeelings()
{
var list = new string[24];
for (int i = 0; i < 24; i++)
list[i] = s.memories[10 + i];
return list;
}
public string[] GetMemoryQualities() => s.memories.Slice(2, 7);
public string[] GetMemoryFeelings() => s.memories.Slice(10, 24);
public List<ComboItem> GetArgumentStrings(MemoryArgType memIndex)
{

View file

@ -237,9 +237,10 @@ namespace PKHeX.Core
case Gen7:
return SM.Contains(g2) || USUM.Contains(g2) || GG.Contains(g2);
case Gen8:
case SWSH:
return g2 == SW || g2 == SH;
case Gen8:
return SWSH.Contains(g2);
default: return false;
}

View file

@ -5,31 +5,31 @@
/// </summary>
public enum Nature : byte
{
Hardy,
Lonely,
Brave,
Adamant,
Naughty,
Bold,
Docile,
Relaxed,
Impish,
Lax,
Timid,
Hasty,
Serious,
Jolly,
Naive,
Modest,
Mild,
Quiet,
Bashful,
Rash,
Calm,
Gentle,
Sassy,
Careful,
Quirky,
Hardy = 0,
Lonely = 1,
Brave = 2,
Adamant = 3,
Naughty = 4,
Bold = 5,
Docile = 6,
Relaxed = 7,
Impish = 8,
Lax = 9,
Timid = 10,
Hasty = 11,
Serious = 12,
Jolly = 13,
Naive = 14,
Modest = 15,
Mild = 16,
Quiet = 17,
Bashful = 18,
Rash = 19,
Calm = 20,
Gentle = 21,
Sassy = 22,
Careful = 23,
Quirky = 24,
Random = 25,
}

View file

@ -815,6 +815,87 @@
Zeraora,
Meltan,
Melmetal,
Grookey,
Thwackey,
Rillaboom,
Scorbunny,
Raboot,
Cinderace,
Sobble,
Drizzile,
Inteleon,
Skwovet,
Greedent,
Rookidee,
Corvisquire,
Corviknight,
Blipbug,
Dottler,
Orbeetle,
Nickit,
Thievul,
Gossifleur,
Eldegoss,
Wooloo,
Dubwool,
Chewtle,
Drednaw,
Yamper,
Boltund,
Rolycoly,
Carkol,
Coalossal,
Applin,
Flapple,
Appletun,
Silicobra,
Sandaconda,
Cramorant,
Arrokuda,
Barraskewda,
Toxel,
Toxtricity,
Sizzlipede,
Centiskorch,
Clobbopus,
Grapploct,
Sinistea,
Polteageist,
Hatenna,
Hattrem,
Hatterene,
Impidimp,
Morgrem,
Grimmsnarl,
Obstagoon,
Perrserker,
Cursola,
Sirfetchd,
MrRime,
Runerigus,
Milcery,
Alcremie,
Falinks,
Pincurchin,
Snom,
Frosmoth,
Stonjourner,
Eiscue,
Indeedee,
Morpeko,
Cufant,
Copperajah,
Dracozolt,
Arctozolt,
Dracovish,
Arctovish,
Duraludon,
Dreepy,
Drakloak,
Dragapult,
Zacian,
Zamazenta,
Eternatus,
MAX_COUNT,
}
}

View file

@ -22,6 +22,11 @@ namespace PKHeX.Core
/// </summary>
public IReadOnlyList<CheckResult> Results => Parse;
/// <summary>
/// Only use this when trying to mutate the legality. Not for use when checking legality.
/// </summary>
public void ResetParse() => Parse.Clear();
private IEncounterable? EncounterOriginalGB;
/// <summary>

View file

@ -51,7 +51,7 @@ namespace PKHeX.Core
/// <param name="vs">Evolution lineage</param>
/// <param name="minLevel">Minimum level of the encounter</param>
/// <returns>Enumerable list of encounters</returns>
public virtual IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<DexLevel> vs, int minLevel = 0)
public virtual IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> vs, int minLevel = 0)
{
if (minLevel == 0) // any
return Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species));
@ -60,7 +60,7 @@ namespace PKHeX.Core
return GetFilteredSlots(pkm, slots, minLevel);
}
protected virtual IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<DexLevel> vs, int minLevel)
protected virtual IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<EvoCriteria> vs, int minLevel)
{
var slots = Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && evo.Level >= slot.LevelMin));
// Get slots where pokemon can exist with respect to level constraints

View file

@ -125,7 +125,7 @@ namespace PKHeX.Core
return entries.Select(GetArea3).Where(Area => Area.Slots.Length != 0).ToArray();
}
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<DexLevel> vs, int minLevel)
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<EvoCriteria> vs, int minLevel)
{
var slots = Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && evo.Level >= slot.LevelMin));

View file

@ -59,7 +59,7 @@ namespace PKHeX.Core
EncounterUtil.MarkEncountersStaticMagnetPullPermutation(grp, PersonalTable.HGSS, trackPermute);
}
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<DexLevel> vs, int minLevel)
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<EvoCriteria> vs, int minLevel)
{
var slots = Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && evo.Level >= slot.LevelMin));

View file

@ -13,7 +13,7 @@ namespace PKHeX.Core
private const int FluteBoostMax = 3; // Black Flute increases levels.
private const int DexNavBoost = 30; // Maximum DexNav chain
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<DexLevel> vs, int minLevel)
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<EvoCriteria> vs, int minLevel)
{
var slots = Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && evo.Level >= (slot.LevelMin - FluteBoostMax)));

View file

@ -11,7 +11,7 @@ namespace PKHeX.Core
{
private const int CatchComboBonus = 1;
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<DexLevel> vs, int minLevel)
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<EvoCriteria> vs, int minLevel)
{
var slots = Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && evo.Level >= (slot.LevelMin - CatchComboBonus)));

View file

@ -9,35 +9,24 @@ namespace PKHeX.Core
/// </summary>
public sealed class EncounterArea8 : EncounterArea32
{
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<DexLevel> vs, int minLevel)
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<EvoCriteria> vs, int minLevel)
{
var loc = Location;
if (120 <= loc && loc <= 154) // wild area gets boosted up to level 60 postgame
{
const int boostTo = 60;
if (pkm.Met_Level == boostTo)
{
var boost = Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && evo.Form == slot.Form && evo.Level >= boostTo));
return boost.Where(s => s.LevelMax < 60 || s.IsLevelWithinRange(minLevel));
}
}
var slots = Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && evo.Level >= (slot.LevelMin)));
// Get slots where pokemon can exist with respect to level constraints
return slots.Where(s => s.IsLevelWithinRange(minLevel));
}
protected override IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots, int minLevel)
{
int species = pkm.Species;
int form = pkm.AltForm;
if (Legal.GalarVariantFormEvolutions.Contains(species)) // match form if same species, else form 0.
{
foreach (var slot in slots)
{
if (species == slot.Species ? slot.Form == form : slot.Form == 0)
yield return slot;
}
}
else if (form == 0)
{
// enforce no form
foreach (var slot in slots)
{
yield return slot;
}
}
}
protected override IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots, int minLevel) => slots;
}
}

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core
/// </summary>
public sealed class EncounterAreaFake : EncounterArea
{
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<DexLevel> vs, int minLevel)
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<EvoCriteria> vs, int minLevel)
=> Enumerable.Empty<EncounterSlot>();
protected override IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots, int minLevel)

View file

@ -39,7 +39,7 @@ namespace PKHeX.Core
return slots;
}
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<DexLevel> vs, int minLevel = 0)
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> vs, int minLevel = 0)
{
if (minLevel == 0) // any
return Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species));
@ -54,7 +54,7 @@ namespace PKHeX.Core
return GetFilteredSlots(pkm, encounterSlots, Gen1Version, RBDragonair).OrderBy(slot => slot.LevelMin); // prefer lowest levels
}
private static bool FilterGBSlotsCatchRate(PKM pkm, ref IReadOnlyList<DexLevel> vs, ref GameVersion Gen1Version, ref bool RBDragonair)
private static bool FilterGBSlotsCatchRate(PKM pkm, ref IReadOnlyList<EvoCriteria> vs, ref GameVersion Gen1Version, ref bool RBDragonair)
{
if (!(pkm is PK1 pk1) || !pkm.Gen1_NotTradeback)
return true;
@ -129,7 +129,7 @@ namespace PKHeX.Core
}
}
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<DexLevel> vs, int minLevel)
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IEnumerable<EvoCriteria> vs, int minLevel)
{
var slots = Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && evo.Level >= slot.LevelMin));

View file

@ -15,7 +15,7 @@ namespace PKHeX.Core
private static readonly Verifier ConsoleRegion = new ConsoleRegionVerifier();
private static readonly Verifier Ability = new AbilityVerifier();
private static readonly Verifier Medal = new MedalVerifier();
private static readonly Verifier Ribbon = new RibbonVerifier();
public static readonly Verifier Ribbon = new RibbonVerifier();
private static readonly Verifier Item = new ItemVerifier();
private static readonly Verifier EncounterType = new EncounterTypeVerifier();
private static readonly Verifier HyperTraining = new HyperTrainingVerifier();

View file

@ -58,8 +58,8 @@ namespace PKHeX.Core
internal static readonly Learnset[] LevelUpGG = LearnsetReader.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_gg.pkl"), "gg"));
// Gen 8
internal static readonly EggMoves7[] EggMovesSWSH = EggMoves7.GetArray(Data.UnpackMini(Util.GetBinaryResource("eggmove_sm.pkl"), "sm"));
internal static readonly Learnset[] LevelUpSWSH = LearnsetReader.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_sm.pkl"), "sm"));
internal static readonly EggMoves7[] EggMovesSWSH = EggMoves7.GetArray(Data.UnpackMini(Util.GetBinaryResource("eggmove_swsh.pkl"), "ss"));
internal static readonly Learnset[] LevelUpSWSH = LearnsetReader.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_swsh.pkl"), "ss"));
// Setup Help
static Legal()
@ -513,6 +513,13 @@ namespace PKHeX.Core
if (pkm.Format >= 7 && AlolanVariantEvolutions12.Contains(pkm.Species))
return pkm.AltForm == 1;
if (pkm.Format >= 8)
{
if (GalarVariantFormEvolutions.Contains(pkm.Species))
return pkm.AltForm == 1;
if (GalarForm0Evolutions.TryGetValue(pkm.Species, out var orig))
return pkm.AltForm != orig; // bad compare?
}
if (pkm.Species == 678 && pkm.Gender == 1)
return pkm.AltForm == 1;
return pkm.Species == 773;

View file

@ -27,8 +27,8 @@ namespace PKHeX.Core
/// <summary>Event Database for Generation 7 <see cref="GameVersion.GG"/></summary>
public static WB7[] MGDB_G7GG { get; private set; } = Array.Empty<WB7>();
/// <summary>Event Database for Generation 7</summary>
public static WC7[] MGDB_G8 { get; private set; } = Array.Empty<WC7>(); // todo
/// <summary>Event Database for Generation 8</summary>
public static WC8[] MGDB_G8 { get; private set; } = Array.Empty<WC8>();
/// <summary>Indicates if the databases are initialized.</summary>
public static bool Initialized => MGDB_G3.Length != 0;
@ -47,6 +47,9 @@ namespace PKHeX.Core
private static HashSet<WB7> GetWB7DB(byte[] wc7full) => new HashSet<WB7>(ArrayUtil.EnumerateSplit(wc7full, WB7.SizeFull).Select(d => new WB7(d)));
private static HashSet<WC8> GetWC8DB(byte[] wc8bin) =>
new HashSet<WC8>(ArrayUtil.EnumerateSplit(wc8bin, WC8.Size).Select(d => new WC8(d)));
public static void RefreshMGDB(params string[] paths)
{
var g4 = GetPCDDB(Util.GetBinaryResource("wc4.pkl"));
@ -54,6 +57,7 @@ namespace PKHeX.Core
var g6 = GetWC6DB(Util.GetBinaryResource("wc6.pkl"), Util.GetBinaryResource("wc6full.pkl"));
var g7 = GetWC7DB(Util.GetBinaryResource("wc7.pkl"), Util.GetBinaryResource("wc7full.pkl"));
var b7 = GetWB7DB(Util.GetBinaryResource("wb7full.pkl"));
var g8 = GetWC8DB(Util.GetBinaryResource("wc8.pkl"));
foreach (var gift in paths.Where(Directory.Exists).SelectMany(MysteryUtil.GetGiftsFromFolder))
{
@ -64,6 +68,7 @@ namespace PKHeX.Core
case WC6 wc6: g6.Add(wc6); continue;
case WC7 wc7: g7.Add(wc7); continue;
case WB7 wb7: b7.Add(wb7); continue;
case WC8 wc8: g8.Add(wc8); continue;
}
}
@ -73,6 +78,7 @@ namespace PKHeX.Core
MGDB_G6 = g6.ToArray();
MGDB_G7 = g7.ToArray();
MGDB_G7GG = b7.ToArray();
MGDB_G8 = g8.ToArray();
}
public static IEnumerable<MysteryGift> GetAllEvents(bool sorted = true)

File diff suppressed because it is too large Load diff

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core
/// <remarks>
/// Static Encounters are fixed position encounters with properties that are not subject to Wild Encounter conditions.
/// </remarks>
public class EncounterStatic : IEncounterable, IMoveset, IGeneration, ILocation, IContestStats, IVersion
public class EncounterStatic : IEncounterable, IMoveset, IGeneration, ILocation, IContestStats, IVersion, IRelearn
{
public int Species { get; set; }
public int[] Moves { get; set; } = Array.Empty<int>();
@ -80,7 +80,7 @@ namespace PKHeX.Core
pk.AltForm = Form;
int lang = (int)Language.GetSafeLanguage(Generation, (LanguageID)SAV.Language);
int level = LevelMin;
int level = GetMinimalLevel();
var version = this.GetCompatibleVersion((GameVersion)SAV.Game);
SanityCheckVersion(ref version);
@ -126,25 +126,41 @@ namespace PKHeX.Core
if (pk.Format < 6)
return pk;
if (Relearn.Length > 0)
pk.RelearnMoves = Relearn;
pk.SetRelearnMoves(Relearn);
SAV.ApplyHandlingTrainerInfo(pk);
pk.SetRandomEC();
if (this is IGigantamax g && pk is IGigantamax pg)
pg.CanGigantamax = g.CanGigantamax;
if (this is IDynamaxLevel d && pk is IDynamaxLevel pd)
pd.DynamaxLevel = d.DynamaxLevel;
return pk;
}
protected virtual int GetMinimalLevel() => LevelMin;
protected virtual void SetPINGA(PKM pk, EncounterCriteria criteria)
{
int gender = criteria.GetGender(Gender, pk.PersonalInfo);
int nature = (int)criteria.GetNature(Nature);
int ability = Ability;
int ability = GetRandomAbility(); // use criteria?
var pidtype = GetPIDType();
PIDGenerator.SetRandomWildPID(pk, pk.Format, nature, ability >> 1, gender, pidtype);
PIDGenerator.SetRandomWildPID(pk, pk.Format, nature, ability, gender, pidtype);
SetIVs(pk);
}
private int GetRandomAbility()
{
return Ability switch
{
0 => Util.Rand.Next(2),
-1 => Util.Rand.Next(3),
_ => (Ability >> 1)
};
}
private void SetEggMetData(PKM pk, ITrainerInfo tr, DateTime today)
{
pk.Met_Location = Math.Max(0, EncounterSuggestion.GetSuggestedEggMetLocation(pk));
@ -240,16 +256,65 @@ namespace PKHeX.Core
}
}
public bool IsMatch(PKM pkm, int lvl)
public virtual bool IsMatch(PKM pkm, int lvl)
{
if (Nature != Nature.Random && pkm.Nature != (int)Nature)
if (Nature != Nature.Random && pkm.Nature != (int) Nature)
return false;
if (Generation > 3 && pkm.Format > 3 && pkm.WasEgg != EggEncounter && pkm.Egg_Location == 0 && !pkm.IsEgg)
return false;
if (this is EncounterStaticPID p && p.PID != pkm.PID)
if (!IsMatchEggLocation(pkm, ref lvl))
return false;
if (!IsMatchLevel(pkm, lvl))
return false;
if (!IsMatchGender(pkm))
return false;
if (!IsMatchForm(pkm))
return false;
if (EggLocation == Locations.Daycare5 && Relearn.Length == 0 && pkm.RelearnMoves.Any(z => z != 0)) // gen7 eevee edge case
return false;
if (!IsMatchIVs(pkm))
return false;
if (pkm is IContestStats s && s.IsContestBelow(this))
return false;
// Defer to EC/PID check
// if (e.Shiny != null && e.Shiny != pkm.IsShiny)
// continue;
// Defer ball check to later
// if (e.Gift && pkm.Ball != 4) // PokéBall
// continue;
return true;
}
private bool IsMatchIVs(PKM pkm)
{
if (IVs.Length == 0)
return true; // nothing to check, IVs are random
if (Generation <= 2 && pkm.Format > 2)
return true; // IVs are regenerated on VC transfer upward
return Legal.GetIsFixedIVSequenceValidSkipRand(IVs, pkm);
}
private bool IsMatchForm(PKM pkm)
{
if (SkipFormCheck)
return true;
if (Form != pkm.AltForm && !Legal.IsFormChangeable(pkm, Species))
return false;
return true;
}
private bool IsMatchEggLocation(PKM pkm, ref int lvl)
{
if (Generation == 3 && EggLocation != 0) // Gen3 Egg
{
if (pkm.Format == 3 && pkm.IsEgg && EggLocation != pkm.Met_Location)
@ -257,30 +322,31 @@ namespace PKHeX.Core
}
else if (Generation <= 2 && EggLocation != 0) // Gen2 Egg
{
if (pkm.Format <= 2)
if (pkm.Format > 2)
return true;
if (pkm.IsEgg)
{
if (pkm.IsEgg)
{
if (pkm.Met_Location != 0 && pkm.Met_Level != 0)
return false;
}
else
{
switch (pkm.Met_Level)
{
case 0 when pkm.Met_Location != 0:
return false;
case 1 when pkm.Met_Location == 0:
return false;
default:
if (pkm.Met_Location == 0 && pkm.Met_Level != 0)
return false;
break;
}
}
if (pkm.Met_Level == 1) // Gen2 Eggs are met at 1, and hatch at level 5.
lvl = 5;
if (pkm.Met_Location != 0 && pkm.Met_Level != 0)
return false;
}
else
{
switch (pkm.Met_Level)
{
case 0 when pkm.Met_Location != 0:
return false;
case 1 when pkm.Met_Location == 0:
return false;
default:
if (pkm.Met_Location == 0 && pkm.Met_Level != 0)
return false;
break;
}
}
if (pkm.Met_Level == 1) // Gen2 Eggs are met at 1, and hatch at level 5.
lvl = 5;
}
else if (EggLocation != pkm.Egg_Location)
{
@ -297,7 +363,7 @@ namespace PKHeX.Core
{
// check Pt/HGSS data
if (pkm.Format <= 4)
return false; // must match
return false;
if (!Locations.IsPtHGSSLocationEgg(EggLocation)) // non-Pt/HGSS egg gift
return false;
// transferring 4->5 clears pt/hgss location value and keeps Faraway Place
@ -317,59 +383,37 @@ namespace PKHeX.Core
if (Locations.IsPtHGSSLocationEgg(EggLocation)) // egg gift
{
if (pkm.Format > 4)
return false; // locations match when it shouldn't
}
}
if (pkm.HasOriginalMetLocation)
{
if (!EggEncounter && Location != 0 && Location != pkm.Met_Location)
return false;
if (Level != lvl)
{
if (!(pkm.Format == 3 && EggEncounter && lvl == 0))
return false;
}
}
else if (Level > lvl)
{
return false;
}
if (Gender != -1 && Gender != pkm.Gender)
{
if (Species == (int)Core.Species.Azurill && Generation == 4 && Location == 233 && pkm.Gender == 0)
{
if (PKX.GetGenderFromPIDAndRatio(pkm.PID, 0xBF) != 1)
return false;
}
else
{
return false;
}
}
if (Form != pkm.AltForm && !SkipFormCheck && !Legal.IsFormChangeable(pkm, Species))
return false;
if (EggLocation == Locations.Daycare5 && Relearn.Length == 0 && pkm.RelearnMoves.Any(z => z != 0)) // gen7 eevee edge case
return true;
}
private bool IsMatchGender(PKM pkm)
{
if (Gender == -1 || Gender == pkm.Gender)
return true;
if (Species == (int) Core.Species.Azurill && Generation == 4 && Location == 233 && pkm.Gender == 0)
return PKX.GetGenderFromPIDAndRatio(pkm.PID, 0xBF) == 1;
return false;
}
protected virtual bool IsMatchLevel(PKM pkm, int lvl)
{
if (!pkm.HasOriginalMetLocation)
return lvl >= Level;
if (!EggEncounter && Location != 0 && Location != pkm.Met_Location)
return false;
if (IVs.Length != 0 && (Generation > 2 || pkm.Format <= 2)) // 1,2->7 regenerates IVs, only check if original IVs still exist
{
if (!Legal.GetIsFixedIVSequenceValidSkipRand(IVs, pkm))
return false;
}
if (pkm is IContestStats s && s.IsContestBelow(this))
if (lvl == Level)
return true;
if (!(pkm.Format == 3 && EggEncounter && lvl == 0))
return false;
// Defer to EC/PID check
// if (e.Shiny != null && e.Shiny != pkm.IsShiny)
// continue;
// Defer ball check to later
// if (e.Gift && pkm.Ball != 4) // PokéBall
// continue;
return true;
}
}

View file

@ -19,6 +19,13 @@
pk.Nature = nature;
pk.RefreshAbility(ability >> 1);
}
public override bool IsMatch(PKM pkm, int lvl)
{
if (PID != pkm.PID)
return false;
return base.IsMatch(pkm, lvl);
}
}
internal sealed class EncounterStaticN : EncounterStaticPID

View file

@ -74,6 +74,7 @@ namespace PKHeX.Core
Locations.LinkTrade5NPC,
Locations.LinkTrade6NPC,
Locations.LinkTrade6NPC, // 7 is same as 6
Locations.LinkTrade6NPC, // 8 is same as 6
};
public PKM ConvertToPKM(ITrainerInfo SAV) => ConvertToPKM(SAV, EncounterCriteria.Unrestricted);
@ -83,6 +84,12 @@ namespace PKHeX.Core
var pk = PKMConverter.GetBlank(Generation, Version);
SAV.ApplyToPKM(pk);
ApplyDetails(SAV, criteria, pk);
return pk;
}
protected virtual void ApplyDetails(ITrainerInfo SAV, EncounterCriteria criteria, PKM pk)
{
var version = this.GetCompatibleVersion((GameVersion)SAV.Game);
int lang = (int)Language.GetSafeLanguage(Generation, (LanguageID)SAV.Language);
int level = CurrentLevel > 0 ? CurrentLevel : LevelMin;
@ -102,7 +109,7 @@ namespace PKHeX.Core
pk.SetNickname(GetNickname(lang));
pk.CurrentLevel = level;
pk.Version = (int)version;
pk.Version = (int) version;
pk.TID = TID;
pk.SID = SID;
pk.Ball = Ball;
@ -117,11 +124,12 @@ namespace PKHeX.Core
var location = Location > 0 ? Location : DefaultMetLocation[Generation - 1];
SetMetData(pk, level, location, time);
}
if (EggLocation != 0)
SetEggMetData(pk, time);
if (pk is PK1 pk1 && this is EncounterTradeCatchRate c)
pk1.Catch_Rate = (int)c.Catch_Rate;
pk1.Catch_Rate = (int) c.Catch_Rate;
if (pk is IContestStats s)
this.CopyContestStatsTo(s);
@ -132,7 +140,7 @@ namespace PKHeX.Core
UpdateEdgeCase(pk);
if (pk.Format < 6)
return pk;
return;
SAV.ApplyHandlingTrainerInfo(pk, force: true);
pk.SetRandomEC();
@ -141,8 +149,6 @@ namespace PKHeX.Core
pk.SetRandomMemory6();
else if (pk.Format == 7)
SetSMOTMemory(pk);
return pk;
}
protected virtual void SetPINGA(PKM pk, EncounterCriteria criteria)
@ -229,7 +235,7 @@ namespace PKHeX.Core
pk.OT_Feeling = 5;
}
public bool IsMatch(PKM pkm, int lvl)
public virtual bool IsMatch(PKM pkm, int lvl)
{
if (IVs.Length != 0)
{
@ -237,27 +243,38 @@ namespace PKHeX.Core
return false;
}
if (this is EncounterTradePID p)
{
if (p.PID != pkm.EncryptionConstant)
return false;
if (Nature != Nature.Random && (int)Nature != pkm.Nature) // gen5 BW only
return false;
}
else
{
if (!Shiny.IsValid(pkm))
return false;
if (Nature != Nature.Random && (int)Nature != pkm.Nature)
return false;
if (Gender != -1 && Gender != pkm.Gender)
return false;
}
if (!IsMatchNatureGenderShiny(pkm))
return false;
if (TID != pkm.TID)
return false;
if (SID != pkm.SID)
return false;
if (!IsMatchLevel(pkm, lvl))
return false;
if (CurrentLevel != -1 && CurrentLevel > pkm.CurrentLevel)
return false;
if (Form != pkm.AltForm && !Legal.IsFormChangeable(pkm, pkm.Species))
return false;
if (OTGender != -1 && OTGender != pkm.OT_Gender)
return false;
if (EggLocation != pkm.Egg_Location)
return false;
// if (z.Ability == 4 ^ pkm.AbilityNumber == 4) // defer to Ability
// countinue;
if (!Version.Contains((GameVersion)pkm.Version))
return false;
if (pkm is IContestStats s && s.IsContestBelow(this))
return false;
return true;
}
private bool IsMatchLevel(PKM pkm, int lvl)
{
if (pkm.HasOriginalMetLocation)
{
var loc = Location > 0 ? Location : DefaultMetLocation[Generation - 1];
@ -279,21 +296,17 @@ namespace PKHeX.Core
return false;
}
if (CurrentLevel != -1 && CurrentLevel > pkm.CurrentLevel)
return true;
}
protected virtual bool IsMatchNatureGenderShiny(PKM pkm)
{
if (!Shiny.IsValid(pkm))
return false;
if (Gender != -1 && Gender != pkm.Gender)
return false;
if (Form != pkm.AltForm && !Legal.IsFormChangeable(pkm, pkm.Species))
return false;
if (OTGender != -1 && OTGender != pkm.OT_Gender)
return false;
if (EggLocation != pkm.Egg_Location)
return false;
// if (z.Ability == 4 ^ pkm.AbilityNumber == 4) // defer to Ability
// countinue;
if (!Version.Contains((GameVersion)pkm.Version))
return false;
if (pkm is IContestStats s && s.IsContestBelow(this))
if (Nature != Nature.Random && pkm.Nature != (int)Nature)
return false;
return true;

View file

@ -25,5 +25,14 @@
SetIVs(pk);
}
protected override bool IsMatchNatureGenderShiny(PKM pkm)
{
if (pkm.PID != pkm.EncryptionConstant)
return false;
if (Nature != Nature.Random && (int)Nature != pkm.Nature) // gen5 BW only
return false;
return true;
}
}
}

View file

@ -131,7 +131,7 @@ namespace PKHeX.Core
private static bool IsDeferredSport(this EncounterSlot slot, bool IsSportBall) => IsSportBall != ((slot.Type & SlotType.BugContest) != 0);
private static bool IsDeferredHiddenAbility(this EncounterSlot slot, bool IsHidden) => IsHidden != slot.IsHiddenAbilitySlot();
private static IEnumerable<EncounterSlot> GetValidEncounterSlots(PKM pkm, EncounterArea loc, IReadOnlyList<DexLevel> vs, int lvl)
private static IEnumerable<EncounterSlot> GetValidEncounterSlots(PKM pkm, EncounterArea loc, IReadOnlyList<EvoCriteria> vs, int lvl)
{
if (pkm.Egg_Location != 0)
return Enumerable.Empty<EncounterSlot>();

View file

@ -0,0 +1,7 @@
namespace PKHeX.Core
{
public interface IRelearn
{
int[] Relearn { get; }
}
}

View file

@ -48,5 +48,21 @@ namespace PKHeX.Core
return true;
}
public static bool IsEvolvedChangedFormValid(int species, int currentForm, int originalForm)
{
switch (currentForm)
{
case 0 when Legal.GalarForm0Evolutions.TryGetValue(species, out var val):
return originalForm == val;
case 1 when Legal.AlolanVariantEvolutions12.Contains(species):
case 1 when Legal.GalarVariantFormEvolutions.Contains(species):
return originalForm == 0;
case 2 when species == (int)Species.Darmanitan:
return originalForm == 1;
default:
return false;
}
}
}
}

View file

@ -21,7 +21,7 @@ namespace PKHeX.Core
return info.EncounterMatch switch
{
MysteryGift g => VerifyRelearnSpecifiedMoveset(pkm, info, g.RelearnMoves),
EncounterStatic s when s.Relearn.Length > 0 => VerifyRelearnSpecifiedMoveset(pkm, info, s.Relearn),
IRelearn s when s.Relearn.Length > 0 => VerifyRelearnSpecifiedMoveset(pkm, info, s.Relearn),
EncounterEgg e => VerifyRelearnEggBase(pkm, info, e),
EncounterSlot z when pkm.RelearnMove1 != 0 && z.Permissions.DexNav && EncounterSlotGenerator.IsDexNavValid(pkm) => VerifyRelearnDexNav(pkm, info),
_ => VerifyRelearnNone(pkm, info)

View file

@ -106,6 +106,7 @@ namespace PKHeX.Core
case 5: // Bank keeps current level
case 6:
case 7:
case 8:
return lvl >= Level && (!pkm.IsNative || pkm.Met_Level < lvl);
default: return false;

View file

@ -35,7 +35,7 @@ namespace PKHeX.Core
Evolves6 = new EvolutionTree(unpack("ao"), GameVersion.Gen6, PersonalTable.AO, Legal.MaxSpeciesID_6);
Evolves7 = new EvolutionTree(unpack("uu"), GameVersion.Gen7, PersonalTable.USUM, Legal.MaxSpeciesID_7_USUM);
Evolves7b = new EvolutionTree(unpack("gg"), GameVersion.Gen7, PersonalTable.GG, Legal.MaxSpeciesID_7b);
Evolves8 = new EvolutionTree(unpack("gg"), GameVersion.Gen8, PersonalTable.SWSH, Legal.MaxSpeciesID_8);
Evolves8 = new EvolutionTree(unpack("ss"), GameVersion.Gen8, PersonalTable.SWSH, Legal.MaxSpeciesID_8);
// There's always oddballs.
Evolves7.FixEvoTreeSM();

View file

@ -184,6 +184,8 @@ namespace PKHeX.Core
public static string LFatefulMystery { get; set; } = "Mystery Gift Fateful Encounter.";
public static string LFatefulMysteryMissing { get; set; } = "Mystery Gift Fateful Encounter flag missing.";
public static string LFavoriteMarkingUnavailable { get; set; } = "Favorite Marking is not available.";
public static string LFormBattle { get; set; } = "Form cannot exist outside of a battle.";
public static string LFormEternal { get; set; } = "Valid Eternal Flower encounter.";
public static string LFormEternalInvalid { get; set; } = "Invalid Eternal Flower encounter.";
@ -297,6 +299,7 @@ namespace PKHeX.Core
public static string LMemoryHTEvent { get; set; } = "Current handler should not be Event OT.";
public static string LMemoryHTFlagInvalid { get; set; } = "Untraded: Current handler should not be the Handling Trainer.";
public static string LMemoryHTGender { get; set; } = "HT Gender invalid: {0}";
public static string LMemoryHTLanguage { get; set; } = "HT Language is missing.";
public static string LMemoryIndexArgHT { get; set; } = "Should have a HT Memory TextVar value (somewhere).";
public static string LMemoryIndexFeel { get; set; } = "{0} Memory: Feeling should be index {1}.";
@ -370,6 +373,7 @@ namespace PKHeX.Core
public static string LMoveSourceSpecial { get; set; } = "Special Non-Relearn Move.";
public static string LMoveSourceTMHM { get; set; } = "Learned by TM/HM.";
public static string LMoveSourceTutor { get; set; } = "Learned by Move Tutor.";
public static string LMoveSourceTR { get; set; } = "Unexpected Technical Record Learned flag: {0}";
public static string LNickFlagEggNo { get; set; } = "Egg must be not nicknamed.";
public static string LNickFlagEggYes { get; set; } = "Egg must be nicknamed.";
@ -410,9 +414,11 @@ namespace PKHeX.Core
public static string LRibbonFInvalid_0 { get; set; } = "Invalid Ribbons: {0}";
public static string LRibbonFMissing_0 { get; set; } = "Missing Ribbons: {0}";
public static string LStatDynamaxInvalid { get; set; } = "Dynamax Level is not within the expected range.";
public static string LStatIncorrectHeight { get; set; } = "Calculated Height does not match stored value.";
public static string LStatIncorrectWeight { get; set; } = "Calculated Weight does not match stored value.";
public static string LStatIncorrectCP { get; set; } = "Calculated CP does not match stored value.";
public static string LStatGigantamaxInvalid { get; set; } = "Gigantamax Flag mismatch.";
public static string LSuperComplete { get; set; } = "Super Training complete flag mismatch.";
public static string LSuperDistro { get; set; } = "Distribution Super Training missions are not released.";

View file

@ -150,10 +150,10 @@ namespace PKHeX.Core
#endregion
private static readonly HashSet<int> MemoryGeneral = new HashSet<int> { 1, 2, 3, 4, 19, 24, 31, 32, 33, 35, 36, 37, 38, 39, 42, 52, 59 };
private static readonly HashSet<int> MemoryGeneral = new HashSet<int> { 1, 2, 3, 4, 19, 24, 31, 32, 33, 35, 36, 37, 38, 39, 42, 52, 59, 70, 86 };
private static readonly HashSet<int> MemorySpecific = new HashSet<int> { 6 };
private static readonly HashSet<int> MemoryMove = new HashSet<int> { 12, 16, 48, 49 };
private static readonly HashSet<int> MemoryItem = new HashSet<int> { 5, 15, 26, 34, 40, 51 };
private static readonly HashSet<int> MemoryMove = new HashSet<int> { 12, 16, 48, 49, 80, 81, 89 };
private static readonly HashSet<int> MemoryItem = new HashSet<int> { 5, 15, 26, 34, 40, 51, 84, 88 };
private static readonly HashSet<int> MemorySpecies = new HashSet<int> { 7, 9, 13, 14, 17, 21, 18, 25, 29, 44, 45, 50, 60 };
public static MemoryArgType GetMemoryArgType(int memory)

View file

@ -35,14 +35,15 @@ namespace PKHeX.Core
switch (generation)
{
case 1: return GetIsLevelUp1(species, move, lvl, form, minlvlG1, version);
case 2: if (move > MaxMoveID_1 && pkm.LearnMovesNew2Disallowed()) return LearnNONE;
return GetIsLevelUp2(species, move, lvl, form, minlvlG2, pkm.Korean, version);
case 2 when move > MaxMoveID_1 && pkm.LearnMovesNew2Disallowed(): return LearnNONE;
case 2: return GetIsLevelUp2(species, move, lvl, form, minlvlG2, pkm.Korean, version);
case 3: return GetIsLevelUp3(species, move, lvl, form, version);
case 4: return GetIsLevelUp4(species, move, lvl, form, version);
case 5: return GetIsLevelUp5(species, move, lvl, form, version);
case 6: return GetIsLevelUp6(species, move, lvl, form, version);
case 7: return GetIsLevelUp7(species, move, form, version);
case 8: return GetIsLevelUp8(species, move, form, version);
case 7: return GetIsLevelUp7(species, move, form, version); // move reminder can give any move 1-100
case 8: return GetIsLevelUp8(species, move, lvl, form, version);
}
return LearnNONE;
}
@ -203,7 +204,7 @@ namespace PKHeX.Core
return LearnNONE;
}
private static LearnVersion GetIsLevelUp8(int species, int move, int form, GameVersion ver = Any)
private static LearnVersion GetIsLevelUp8(int species, int move, int lvl, int form, GameVersion ver = Any)
{
switch (ver)
{
@ -211,7 +212,7 @@ namespace PKHeX.Core
case SW: case SH:
if (species > MaxSpeciesID_8)
return LearnNONE;
return LearnSWSH.GetIsLevelUp(species, form, move);
return LearnSWSH.GetIsLevelUp(species, form, move, lvl);
}
return LearnNONE;
}
@ -273,7 +274,7 @@ namespace PKHeX.Core
5 => GetMovesLevelUp5(species, form, lvl, version),
6 => GetMovesLevelUp6(species, form, lvl, version),
7 => GetMovesLevelUp7(species, form, lvl, MoveReminder, version),
8 => GetMovesLevelUp8(species, form, lvl, MoveReminder, version),
8 => GetMovesLevelUp8(species, form, lvl, version),
_ => (IEnumerable<int>)Array.Empty<int>()
};
}
@ -318,9 +319,9 @@ namespace PKHeX.Core
return AddMovesLevelUp7(new List<int>(), ver, species, max, form, MoveReminder);
}
private static List<int> GetMovesLevelUp8(int species, int form, int max, bool MoveReminder, GameVersion ver = Any)
private static List<int> GetMovesLevelUp8(int species, int form, int max, GameVersion ver = Any)
{
return AddMovesLevelUp8(new List<int>(), ver, species, max, form, MoveReminder);
return AddMovesLevelUp8(new List<int>(), ver, species, max, form);
}
private static List<int> AddMovesLevelUp1(List<int> moves, GameVersion ver, int species, int form, int max, int min)
@ -467,10 +468,9 @@ namespace PKHeX.Core
return moves;
}
private static List<int> AddMovesLevelUp8(List<int> moves, GameVersion ver, int species, int max, int form, bool MoveReminder)
private static List<int> AddMovesLevelUp8(List<int> moves, GameVersion ver, int species, int max, int form)
{
if (MoveReminder)
max = 100; // Move reminder can teach any level in movepool now!
// Move reminder can NOT teach any level like Gen7
switch (ver)
{
case Any:

View file

@ -5,7 +5,7 @@ namespace PKHeX.Core
{
internal static class MoveTechnicalMachine
{
internal static GameVersion GetIsMachineMove(PKM pkm, int species, int form, int generation, int move, GameVersion ver = GameVersion.Any, bool RemoveTransfer = false)
internal static GameVersion GetIsMachineMove(PKM pkm, int species, int form, int generation, int move, GameVersion ver = GameVersion.Any, bool RemoveTransfer = false, bool allowBit = false)
{
if (pkm.IsMovesetRestricted())
ver = (GameVersion) pkm.Version;
@ -21,7 +21,7 @@ namespace PKHeX.Core
case 5: return GetIsMachine5(species, move, form);
case 6: return GetIsMachine6(species, move, form, ver);
case 7: return GetIsMachine7(species, move, form, ver);
case 8: return GetIsMachine8(species, move, form, ver);
case 8: return GetIsMachine8(pkm, species, move, form, ver, allowBit);
default:
return Legal.NONE;
}
@ -219,11 +219,11 @@ namespace PKHeX.Core
return Legal.NONE;
}
private static GameVersion GetIsMachine8(int species, int move, int form, GameVersion ver)
private static GameVersion GetIsMachine8(PKM pkm, int species, int move, int form, GameVersion ver, bool allowBit)
{
if (GameVersion.SWSH.Contains(ver))
{
for (int i = 0; i < Legal.TMHM_SWSH.Length; i++)
for (int i = 0; i < 100; i++)
{
if (Legal.TMHM_SWSH[i] != move)
continue;
@ -231,6 +231,18 @@ namespace PKHeX.Core
return GameVersion.SWSH;
break;
}
for (int i = 0; i < 100; i++)
{
if (Legal.TMHM_SWSH[i + 100] != move)
continue;
if (!PersonalTable.SWSH.GetFormeEntry(species, form).TMHM[i + 100])
break;
if (allowBit)
return GameVersion.SWSH;
if (((PK8) pkm).GetMoveRecordFlag(i))
return GameVersion.SWSH;
break;
}
}
return Legal.NONE;
@ -254,7 +266,7 @@ namespace PKHeX.Core
case 5: AddMachine5(r, species, form); break;
case 6: AddMachine6(r, species, form, ver); break;
case 7: AddMachine7(r, species, form, ver); break;
case 8: AddMachine8(r, species, form, ver); break;
case 8: AddMachine8(r, species, form, pkm, ver); break;
}
return r.Distinct();
}
@ -368,7 +380,7 @@ namespace PKHeX.Core
}
}
private static void AddMachine8(List<int> r, int species, int form, GameVersion ver = GameVersion.Any)
private static void AddMachine8(List<int> r, int species, int form, PKM pkm, GameVersion ver = GameVersion.Any)
{
switch (ver)
{
@ -376,7 +388,7 @@ namespace PKHeX.Core
case GameVersion.SW:
case GameVersion.SH:
case GameVersion.SWSH:
AddMachineSWSH(r, species, form);
AddMachineSWSH(r, species, form, pkm);
return;
}
}
@ -415,12 +427,28 @@ namespace PKHeX.Core
r.AddRange(Legal.TMHM_GG.Where((_, m) => pi.TMHM[m]));
}
private static void AddMachineSWSH(List<int> r, int species, int form)
private static void AddMachineSWSH(List<int> r, int species, int form, PKM pkm)
{
if (species > Legal.MaxSpeciesID_8)
return;
var pi = PersonalTable.SWSH.GetFormeEntry(species, form);
r.AddRange(Legal.TMHM_SWSH.Where((_, m) => pi.TMHM[m]));
var tmhm = pi.TMHM;
for (int i = 0; i < 100; i++)
{
if (!tmhm[i])
continue;
r.Add(Legal.TMHM_SWSH[i]);
}
var pk8 = (PK8)pkm;
for (int i = 0; i < 100; i++)
{
if (!tmhm[i + 100])
continue;
if (!pk8.GetMoveRecordFlag(i))
continue;
r.Add(Legal.TMHM_SWSH[i + 100]);
}
}
}
}

View file

@ -50,8 +50,8 @@
/// <summary> Route 4 in <see cref="GameVersion.Gen7"/> </summary>
public const int HatchLocation7 = 50;
/// <summary> ??? in <see cref="GameVersion.SWSH"/> </summary>
public const int HatchLocation8 = 50; // todo
/// <summary> Route 5 in <see cref="GameVersion.SWSH"/> </summary>
public const int HatchLocation8 = 40;
/// <summary> Generation 3 -> Generation 4 Transfer Location (Pal Park) </summary>
public const int Transfer3 = 0x37;

View file

@ -168,6 +168,12 @@ namespace PKHeX.Core
808, // Meltan
809, // Melmetal
(int)Species.Zacian,
(int)Species.Zamazenta,
(int)Species.Eternatus,
// 891, // mythical1?
// 892, // mythical2?
};
public static readonly HashSet<int> BattleFrontierBanlist = new HashSet<int>
@ -231,6 +237,10 @@ namespace PKHeX.Core
716, // Xerneas
746, // Wishiwashi
778, // Mimikyu
(int)Species.Zacian,
(int)Species.Zamazenta,
(int)Species.Eternatus,
};
public static readonly HashSet<int> BattleMegas = new HashSet<int>

View file

@ -1,65 +1,187 @@
using System.Collections.Generic;
using System.Linq;
// ReSharper disable RedundantEmptyObjectOrCollectionInitializer todo
namespace PKHeX.Core
{
public static partial class Legal
{
internal const int MaxSpeciesID_8 = 809;
internal const int MaxMoveID_8 = 719;
internal const int MaxItemID_8 = 920;
internal const int MaxAbilityID_8 = 232;
internal const int MaxBallID_8 = 0x1A; // 26
internal const int MaxSpeciesID_8 = 890; // Eternatus
internal const int MaxMoveID_8 = 796; // Steel Beam (jet fuel)
internal const int MaxItemID_8 = 1278; // Rotom Catalog, or 1578 for all catalog parts?
internal const int MaxAbilityID_8 = 258;
internal const int MaxBallID_8 = 0x1A; // 26 Beast
internal const int MaxGameID_8 = 45;
#region Met Locations
internal static readonly int[] Met_SWSH_0 =
{
002, 004, 006, 008,
012, 014, 016, 018,
020, 022, 024, 028,
030, 032, 034, 036,
040, 044, 046, 048,
052, 054, 056, 058,
060, 064, 066, 068,
070, 072, 076, 078,
080, 084, 086, 088,
090, 092, 094, 096, 098,
102, 104, 106, 108,
110, 112, 114, 116, 118,
120, 122, 124, 126, 128,
130, 132, 134, 136, 138,
140, 142, 144, 146, 148,
150, 152, 154, 156, 158,
160, 162,
};
internal static readonly int[] Met_SWSH_3 =
{
30001, 30003, 30004, 30005, 30006, 30007, 30008, 30009, 30010, 30011, 30012, 30013, 30014, 30015, 30016, 30017, 30018
};
internal static readonly int[] Met_SWSH_4 =
{
40001, 40002, 40003, 40005, 40006, 40007, 40008, 40009, 40010,
40011, 40012, 40013, 40014, 40016, 40017, 40018, 40019, 40020,
40021, 40022, 40024, 40025, 40026, 40027, 40028, 40029, 40030,
40032, 40033, 40034, 40035, 40036, 40037, 40038, 40039, 40040,
40041, 40042, 40043, 40044, 40045, 40047, 40048, 40049, 40050,
40051, 40052, 40053, 40055, 40056, 40057, 40058, 40059, 40060,
40061, 40063, 40064, 40065, 40066, 40067, 40068, 40069, 40070,
40071, 40072, 40074, 40075, 40076, 40077, 40078, 40079, 40080,
40081, 40082, 40083, 40084, 40085, 40086,
};
internal static readonly int[] Met_SWSH_6 =
{
};
public const int StandardHatchLocation8 = 50; // todo
internal static readonly int[] Met_SWSH_6 = {/* XY */ 60001, 60003, /* ORAS */ 60004, };
#endregion
internal static readonly ushort[] Pouch_Regular_SWSH = // 00
internal static readonly ushort[] Pouch_Regular_SWSH =
{
045, 046, 047, 048, 049, 050, 051, 052, 053, 076, 077, 079, 080, 081, 082, 083, 084, 085, 107, 108, 109,
116, 117, 118, 119, 213, 214, 215, 217, 218, 219, 220, 221, 222, 223, 224, 228, 229, 230, 231, 232, 233,
234, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 253, 254, 255, 257,
259, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305,
306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 325, 326, 537, 538, 539,
540, 541, 542, 543, 544, 545, 546, 547, 564, 565, 566, 567, 568, 569, 570, 639, 640, 644, 645, 646, 647,
648, 649, 650, 846, 849, 879, 880, 881, 882, 883, 884, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913,
914, 915, 916, 917, 918, 919, 920, 1103, 1104, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118,
1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1231, 1232, 1233, 1234, 1235, 1236, 1237,
1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254,
1279,
1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297,
1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315,
1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1333,
1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351,
1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1369,
1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387,
1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405,
1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1415, 1416, 1417, 1418, 1419, 1420, 1421, 1422, 1423,
1424, 1425, 1426, 1427, 1428, 1429, 1430, 1431, 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, 1440, 1441,
1442, 1443, 1444, 1445, 1446, 1447, 1448, 1449, 1450, 1451, 1452, 1453, 1454, 1455, 1456, 1457, 1458, 1459,
1460, 1461, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1474, 1475, 1476, 1477,
1478, 1479, 1480, 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495,
1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1512, 1513,
1514, 1515, 1516, 1517, 1518, 1519, 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, 1529, 1530, 1531,
1532, 1533, 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, 1548, 1549,
1550, 1551, 1552, 1553, 1554, 1555, 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1567,
1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575, 1576, 1577, 1578,
};
internal static readonly ushort[] Pouch_Ball_SWSH = { // 08
internal static readonly ushort[] Pouch_Ball_SWSH =
{
001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012, 013, 014, 015, 016,
492, 493, 494, 495, 496, 497, 498, 499, 500,
576,
851,
};
internal static readonly ushort[] Pouch_Battle_SWSH = { // 16
internal static readonly ushort[] Pouch_Battle_SWSH =
{
055, 056, 057, 058, 059, 060, 061, 062, 063,
};
internal static readonly ushort[] Pouch_Items_SWSH = Pouch_Regular_SWSH.Concat(Pouch_Ball_SWSH).Concat(Pouch_Battle_SWSH).ToArray();
internal static readonly ushort[] Pouch_Key_SWSH = {
internal static readonly ushort[] Pouch_Key_SWSH =
{
078,
628, 629, 631, 632,
703,
943, 944, 945, 946,
1074, 1075, 1076, 1077, 1080, 1081, 1100,
1255, 1266, 1267, 1269, 1270, 1271, 1278,
};
internal static readonly ushort[] Pouch_TMHM_SWSH = { // 02
internal static readonly ushort[] TM_SWSH =
{
328, 329, 330, 331, 332, 333, 334, 335, 336, 337,
338, 339, 340, 341, 342, 343, 344, 345, 346, 347,
348, 349, 350, 351, 352, 353, 354, 355, 356, 357,
358, 359, 360, 361, 362, 363, 364, 365, 366, 367,
368, 369, 370, 371, 372, 373, 374, 375, 376, 377,
378, 379, 380, 381, 382, 383, 384, 385, 386, 387,
388, 389, 390, 391, 392, 393, 394, 395, 396, 397,
398, 399, 400, 401, 402, 403, 404, 405, 406, 407,
408, 409, 410, 411, 412, 413, 414, 415, 416, 417,
418, 419, 618, 619, 620, 690, 691, 692, 693, // TM99
1230, // TM00
};
internal static readonly ushort[] Pouch_Medicine_SWSH = { // 32
internal static readonly ushort[] TR_SWSH =
{
1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139,
1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149,
1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159,
1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169,
1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179,
1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189,
1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199,
1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209,
1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219,
1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229,
};
internal static readonly ushort[] Pouch_Berries_SWSH = {
internal static readonly ushort[] Pouch_TMHM_SWSH = TM_SWSH.Concat(TR_SWSH).ToArray();
internal static readonly ushort[] Pouch_Medicine_SWSH =
{
017, 018, 019, 020, 021, 022, 023, 024, 025, 026,
027, 028, 029, 030, 031, 032, 033, 034, 035, 036,
037, 038, 039, 040, 041, 042, 043, 054,
134,
504, 591,
708, 709,
852, 903,
};
internal static readonly ushort[] HeldItems_SWSH = new ushort[1].Concat(Pouch_Items_SWSH).Concat(Pouch_Berries_SWSH).Concat(Pouch_Medicine_SWSH).ToArray();
internal static readonly ushort[] Pouch_Berries_SWSH =
{
149, 150, 151, 152, 153, 154, 155, 156, 157, 158,
159, 160, 161, 162, 163, 169, 170, 171, 172, 173,
174, 184, 185, 186, 187, 188, 189, 190, 191, 192,
193, 194, 195, 196, 197, 198, 199, 200, 201, 202,
203, 204, 205, 206, 207, 208, 209, 210, 211, 212,
686, 687, 688,
};
internal static readonly ushort[] Pouch_Ingredients_SWSH =
{
1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093,
1094, 1095, 1096, 1097, 1098, 1099, 1256, 1257, 1258, 1259,
1260, 1261, 1262, 1263, 1264,
};
internal static readonly ushort[] Pouch_Treasure_SWSH =
{
086, 087, 088, 089, 090, 091, 092, 094, 106,
571, 580, 581, 582, 583,
795, 796,
1105, 1106, 1107, 1108,
};
internal static readonly ushort[] HeldItems_SWSH = new ushort[1].Concat(Pouch_Items_SWSH).Concat(Pouch_Berries_SWSH).Concat(Pouch_Medicine_SWSH).Concat(TR_SWSH).ToArray();
internal static readonly HashSet<int> WildPokeballs8 = new HashSet<int> {
(int)Ball.Poke,
@ -76,14 +198,45 @@ namespace PKHeX.Core
(int)Ball.Dusk,
(int)Ball.Heal,
(int)Ball.Quick,
// Ball Guy
(int)Ball.Friend,
(int)Ball.Lure,
(int)Ball.Level,
(int)Ball.Heavy,
(int)Ball.Love,
(int)Ball.Moon,
(int)Ball.Dream,
};
internal static readonly HashSet<int> GalarOriginForms = new HashSet<int>
{
(int)Species.Meowth,
(int)Species.Ponyta,
(int)Species.Rapidash,
(int)Species.Farfetchd,
(int)Species.MrMime,
(int)Species.Corsola,
(int)Species.Zigzagoon,
(int)Species.Linoone,
(int)Species.Yamask,
(int)Species.Darmanitan,
(int)Species.Stunfisk,
};
internal static readonly HashSet<int> GalarVariantFormEvolutions = new HashSet<int>
{
(int)Species.Weezing,
};
internal static readonly IReadOnlyDictionary<int, int> GalarForm0Evolutions = new Dictionary<int, int>
{
{(int)Species.Perrserker, 2},
{(int)Species.Obstagoon, 1},
{(int)Species.MrMime, 1},
{(int)Species.Sirfetchd, 2},
{(int)Species.Runerigus, 1},
{(int)Species.Cursola, 1},
};
internal static readonly HashSet<int> EvolveToGalarForms = new HashSet<int>(GalarVariantFormEvolutions.Concat(GalarOriginForms));
@ -92,29 +245,163 @@ namespace PKHeX.Core
internal static readonly HashSet<int> ValidMet_SWSH = new HashSet<int>
{
006, 008,
012, 014, 016, 018,
020, 022, 024, 028,
030, 032, 034, 036,
040, 044, 046, 048,
052, 054, 056, 058,
060, 064, 066, 068,
070, 072, 076, 078,
080, 084, 086, 088,
090, 092, 094, 096, 098,
102, 104, 106, 108,
110, 112, 114, 116, 118,
120, 122, 124, 126, 128,
130, 132, 134, 136, 138,
140, 142, 144, 146, 148,
150, 152, 154, 156, 158,
160, 162,
};
internal static readonly int[] TMHM_SWSH =
{
// TM
005, 025, 006, 007, 008, 009, 019, 042, 063, 416,
345, 076, 669, 083, 086, 091, 103, 113, 115, 219,
120, 156, 157, 168, 173, 182, 184, 196, 202, 204,
211, 213, 201, 240, 241, 258, 250, 251, 261, 263,
129, 270, 279, 280, 286, 291, 311, 313, 317, 328,
331, 333, 340, 341, 350, 362, 369, 371, 372, 374,
384, 385, 683, 409, 419, 421, 422, 423, 424, 427,
433, 472, 478, 440, 474, 490, 496, 506, 512, 514,
521, 523, 527, 534, 541, 555, 566, 577, 580, 581,
604, 678, 595, 598, 206, 403, 684, 693, 707, 784,
// TR
014, 034, 053, 056, 057, 058, 059, 067, 085, 087,
089, 094, 097, 116, 118, 126, 127, 133, 141, 161,
164, 179, 188, 191, 200, 473, 203, 214, 224, 226,
227, 231, 242, 247, 248, 253, 257, 269, 271, 276,
285, 299, 304, 315, 322, 330, 334, 337, 339, 347,
348, 349, 360, 370, 390, 394, 396, 398, 399, 402,
404, 405, 406, 408, 411, 412, 413, 414, 417, 428,
430, 437, 438, 441, 442, 444, 446, 447, 482, 484,
486, 492, 500, 502, 503, 526, 528, 529, 535, 542,
583, 599, 605, 663, 667, 675, 676, 706, 710, 776,
};
internal static readonly byte[] MovePP_SWSH =
{
00,
35, 25, 10, 15, 20, 20, 15, 15, 15, 35, 30, 05, 10, 20, 30, 35, 35, 20, 15, 20, 20, 25, 20, 30, 05, 10, 15, 15, 15, 25, 20, 05, 35, 15, 20, 20, 10, 15, 30, 35, 20, 20, 30, 25, 40, 20, 15, 20, 20, 20,
30, 25, 15, 30, 25, 05, 15, 10, 05, 20, 20, 20, 05, 35, 20, 20, 20, 20, 20, 15, 25, 15, 10, 20, 25, 10, 35, 30, 15, 10, 40, 10, 15, 30, 15, 20, 10, 15, 10, 05, 10, 10, 25, 10, 20, 40, 30, 30, 20, 20,
15, 10, 40, 15, 10, 30, 10, 20, 10, 40, 40, 20, 30, 30, 20, 30, 10, 10, 20, 05, 10, 30, 20, 20, 20, 05, 15, 15, 20, 10, 15, 35, 20, 15, 10, 10, 30, 15, 40, 20, 10, 10, 05, 10, 30, 10, 15, 20, 15, 40,
20, 10, 05, 15, 10, 10, 10, 15, 30, 30, 10, 10, 20, 10, 01, 01, 10, 25, 10, 05, 15, 25, 15, 10, 15, 30, 05, 40, 15, 10, 25, 10, 30, 10, 20, 10, 10, 10, 10, 10, 20, 05, 40, 05, 05, 15, 05, 10, 05, 10,
10, 10, 10, 20, 20, 40, 15, 10, 20, 20, 25, 05, 15, 10, 05, 20, 15, 20, 25, 20, 05, 30, 05, 10, 20, 40, 05, 20, 40, 20, 15, 35, 10, 05, 05, 05, 15, 05, 20, 05, 05, 15, 20, 10, 05, 05, 15, 10, 15, 15,
10, 10, 10, 20, 10, 10, 10, 10, 15, 15, 15, 10, 20, 20, 10, 20, 20, 20, 20, 20, 10, 10, 10, 20, 20, 05, 15, 10, 10, 15, 10, 20, 05, 05, 10, 10, 20, 05, 10, 20, 10, 20, 20, 20, 05, 05, 15, 20, 10, 15,
20, 15, 10, 10, 15, 10, 05, 05, 10, 15, 10, 05, 20, 25, 05, 40, 15, 05, 40, 15, 20, 20, 05, 15, 20, 20, 15, 15, 05, 10, 30, 20, 30, 15, 05, 40, 15, 05, 20, 05, 15, 25, 25, 15, 20, 15, 20, 15, 20, 10,
20, 20, 05, 05, 10, 05, 40, 10, 10, 05, 10, 10, 15, 10, 20, 15, 30, 10, 20, 05, 10, 10, 15, 10, 10, 05, 15, 05, 10, 10, 30, 20, 20, 10, 10, 05, 05, 10, 05, 20, 10, 20, 10, 15, 10, 20, 20, 20, 15, 15,
10, 15, 15, 15, 10, 10, 10, 20, 10, 30, 05, 10, 15, 10, 10, 05, 20, 30, 10, 30, 15, 15, 15, 15, 30, 10, 20, 15, 10, 10, 20, 15, 05, 05, 15, 15, 05, 10, 05, 20, 05, 15, 20, 05, 20, 20, 20, 20, 10, 20,
10, 15, 20, 15, 10, 10, 05, 10, 05, 05, 10, 05, 05, 10, 05, 05, 05, 15, 10, 10, 10, 10, 10, 10, 15, 20, 15, 10, 15, 10, 15, 10, 20, 10, 10, 10, 20, 20, 20, 20, 20, 15, 15, 15, 15, 15, 15, 20, 15, 10,
15, 15, 15, 15, 10, 10, 10, 10, 10, 15, 15, 15, 15, 05, 05, 15, 05, 10, 10, 10, 20, 20, 20, 10, 10, 30, 15, 15, 10, 15, 25, 10, 15, 10, 10, 10, 20, 10, 10, 10, 10, 10, 15, 15, 05, 05, 10, 10, 10, 05,
05, 10, 05, 05, 15, 10, 05, 05, 05, 10, 10, 10, 10, 20, 25, 10, 20, 30, 25, 20, 20, 15, 20, 15, 20, 20, 10, 10, 10, 10, 10, 20, 10, 30, 15, 10, 10, 10, 20, 20, 05, 05, 05, 20, 10, 10, 20, 15, 20, 20,
10, 20, 30, 10, 10, 40, 40, 30, 20, 40, 20, 20, 10, 10, 10, 10, 05, 10, 10, 05, 05, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01,
01, 01, 01, 01, 01, 01, 01, 01, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 40, 15, 20, 30, 20, 15, 15, 20, 10, 15, 15, 10, 05, 10, 10, 20, 15, 10, 15, 15, 15, 05, 15, 20, 20, 01, 01, 01, 01, 01, 01,
01, 01, 01, 05, 05, 10, 10, 10, 20, 10, 10, 10, 05, 05, 20, 10, 10, 10, 01, 05, 15, 05, 01, 01, 01, 01, 01, 01, 10, 15, 15, 20, 20, 20, 20, 15, 15, 10, 10, 05, 20, 05, 10, 05, 15, 10, 10, 05, 15, 20,
10, 10, 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 05, 10, 15, 10, 15, 05, 05, 05, 10, 15, 40, 10, 10, 10, 15, 10, 10, 10, 10, 05, 05, 05,
};
internal static readonly HashSet<int> Ban_NoHidden8 = new HashSet<int>
{
};
// No wild encounter with Hidden, so can't breed a hidden yet.
(int)Species.Grookey,
(int)Species.Thwackey,
(int)Species.Rillaboom,
(int)Species.Scorbunny,
(int)Species.Raboot,
(int)Species.Cinderace,
(int)Species.Sobble,
(int)Species.Drizzile,
(int)Species.Inteleon,
internal static readonly HashSet<int> TransferrableGalar = new HashSet<int>()
{
(int)Species.Dracozolt,
(int)Species.Arctozolt,
(int)Species.Dracovish,
(int)Species.Arctovish,
(int)Species.Toxel,
(int)Species.Toxtricity,
};
#region Unreleased Items
internal static readonly HashSet<int> UnreleasedHeldItems_8 = new HashSet<int>
{
// todo
504, // Rage Candy Bar
708, // Lumiose Galette
709, // Shalour Sable
715, // Fairy Gem
};
#endregion
internal static readonly bool[] ReleasedHeldItems_8 = Enumerable.Range(0, MaxItemID_8+1).Select(i => HeldItems_SWSH.Contains((ushort)i) && !UnreleasedHeldItems_8.Contains(i)).ToArray();
/// <summary>
/// Moves that aren't kill
/// </summary>
internal static readonly HashSet<int> ValidMoves_SWSH = new HashSet<int>
{
001, 005, 006, 007, 008, 009, 010, 011, 012, 014,
015, 016, 017, 018, 019, 020, 021, 022, 023, 024,
025, 028, 029, 030, 031, 032, 033, 034, 035, 036,
037, 038, 039, 040, 042, 043, 044, 045, 046, 047,
048, 050, 051, 052, 053, 054, 055, 056, 057, 058,
059, 060, 061, 062, 063, 064, 065, 066, 067, 069,
070, 071, 072, 073, 074, 075, 076, 077, 078, 079,
080, 081, 083, 084, 085, 086, 087, 088, 089, 090,
091, 092, 093, 094, 095, 097, 098, 100, 101, 103,
104, 105, 106, 107, 108, 109, 110, 111, 113, 114,
115, 116, 120, 122, 123, 124, 126, 127, 129, 130,
133, 135, 136, 137, 138, 139, 141, 143, 147, 150,
151, 152, 153, 154, 156, 157, 161, 162, 163, 164,
167, 170, 172, 174, 175, 178, 179, 180, 181, 183,
184, 186, 187, 188, 189, 190, 191, 192, 195, 196,
198, 199, 200, 201, 202, 204, 205, 206, 207, 209,
210, 211, 212, 213, 215, 217, 219, 220, 223, 224,
225, 226, 227, 229, 230, 231, 232, 233, 234, 235,
236, 238, 239, 240, 241, 242, 244, 245, 246, 247,
248, 249, 250, 251, 252, 253, 254, 255, 256, 257,
258, 259, 260, 261, 262, 263, 268, 269, 272, 273,
275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
285, 286, 288, 291, 292, 297, 298, 299, 303, 304,
305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
315, 317, 319, 321, 322, 323, 325, 326, 328, 329,
330, 331, 332, 333, 334, 335, 336, 337, 338, 339,
340, 341, 342, 344, 345, 347, 348, 349, 350, 351,
352, 353, 355, 356, 359, 360, 361, 362, 365, 366,
367, 368, 369, 370, 371, 372, 374, 375, 379, 380,
384, 385, 387, 388, 389, 390, 392, 393, 394, 395,
396, 397, 398, 399, 400, 401, 402, 403, 404, 405,
406, 407, 408, 409, 410, 411, 412, 413, 414, 416,
417, 418, 419, 420, 421, 422, 423, 424, 425, 427,
428, 430, 432, 433, 434, 435, 436, 437, 438, 439,
440, 441, 442, 444, 446, 447, 450, 451, 452, 453,
454, 455, 457, 458, 468, 470, 471, 472, 473, 474,
475, 478, 479, 480, 482, 483, 484, 486, 487, 488,
489, 490, 491, 492, 493, 494, 496, 497, 499, 500,
502, 503, 504, 505, 506, 508, 509, 510, 512, 513,
514, 515, 517, 518, 519, 520, 521, 522, 523, 524,
525, 526, 527, 528, 529, 530, 532, 533, 534, 535,
536, 538, 539, 540, 541, 542, 544, 549, 550, 551,
556, 558, 559, 560, 564, 565, 566, 567, 568, 570,
571, 572, 573, 574, 575, 576, 577, 579, 580, 581,
582, 583, 584, 585, 586, 587, 589, 590, 594, 595,
597, 598, 599, 602, 603, 604, 605, 608, 609, 610,
611, 612, 660, 662, 663, 664, 667, 668, 669, 670,
673, 674, 675, 676, 677, 678, 679, 680, 681, 682,
683, 684, 685, 688, 691, 693, 694, 706, 707, 709,
710, 711, 715, 716, 718, 745, 746, 747, 748, 749,
750, 751, 752, 753, 754, 755, 756,
};
}
}

View file

@ -175,7 +175,10 @@ namespace PKHeX.Core
}
if (pkm.AltForm != 0 && BattleOnly.Contains(pkm.Species))
return GetInvalid(LFormBattle);
{
if (pkm.Species == (int)Species.Darmanitan && pkm.Species == 2) { } // this one is OK, Galarian non-Zen
else return GetInvalid(LFormBattle);
}
return VALID;
}

View file

@ -46,7 +46,7 @@ namespace PKHeX.Core
var reqEXP = EncounterMatch is EncounterStatic s && s.Version == GameVersion.C
? 125 // Gen2 Dizzy Punch gifts always have 125 EXP, even if it's more than the Lv5 exp required.
: Experience.GetEXP(elvl, pkm.Species, pkm.AltForm);
: Experience.GetEXP(elvl, pkm.PersonalInfo.EXPGrowth);
if (reqEXP != pkm.EXP)
data.AddLine(GetInvalid(LEggEXP));
return;
@ -55,7 +55,7 @@ namespace PKHeX.Core
int lvl = pkm.CurrentLevel;
if (lvl < pkm.Met_Level)
data.AddLine(GetInvalid(LLevelMetBelow));
else if (!EncounterMatch.IsWithinRange(pkm) && lvl != 100 && pkm.EXP == Experience.GetEXP(lvl, pkm.Species, pkm.AltForm))
else if (!EncounterMatch.IsWithinRange(pkm) && lvl != 100 && pkm.EXP == Experience.GetEXP(lvl, pkm.PersonalInfo.EXPGrowth))
data.AddLine(Get(LLevelEXPThreshold, Severity.Fishy));
else
data.AddLine(GetValid(LLevelMetSane));

View file

@ -213,7 +213,7 @@ namespace PKHeX.Core
return GetInvalid(string.Format(LMemoryArgBadPokecenter, memory.Handler));
// {0} saw {2} carrying {1} on its back. {4} that {3}.
case 21 when !Legal.GetCanLearnMachineMove(new PK6 {Species = memory.Variable, EXP = Experience.GetEXP(100, memory.Variable, 0)}, 19, 6):
case 21 when !Legal.GetCanLearnMachineMove(new PK6 {Species = memory.Variable, EXP = Experience.GetEXP(100, PersonalTable.XY.GetFormeIndex(memory.Variable, 0))}, 19, 6):
return GetInvalid(string.Format(LMemoryArgBadMove, memory.Handler));
case 16 when memory.Variable == 0 || !Legal.GetCanKnowMove(pkm, memory.Variable, 6):

View file

@ -43,6 +43,8 @@ namespace PKHeX.Core
data.AddLine(GetInvalid(LTransferBad));
if (pkm is PB7 pb7)
VerifyBelugaStats(data, pb7);
if (pkm is PK8 pk8)
VerifySWSHStats(data, pk8);
VerifyMiscFatefulEncounter(data);
}
@ -223,6 +225,7 @@ namespace PKHeX.Core
{
case WC6 wc6 when !wc6.CanBeReceivedByVersion(pkm.Version) && !pkm.WasTradedEgg:
case WC7 wc7 when !wc7.CanBeReceivedByVersion(pkm.Version) && !pkm.WasTradedEgg:
case WC8 wc8 when !wc8.CanBeReceivedByVersion(pkm.Version) && !pkm.WasTradedEgg:
data.AddLine(GetInvalid(LEncGiftVersionNotDistributed, GameOrigin));
return;
case WC6 wc6 when wc6.RestrictLanguage != 0 && wc6.Language != wc6.RestrictLanguage:
@ -259,11 +262,11 @@ namespace PKHeX.Core
// No point using the evolution tree. Just handle certain species.
switch (pkm.Species)
{
case 745 when (pkm.AltForm == 0 && Moon()) || (pkm.AltForm == 1 && Sun()): // Lycanroc
case 791 when Moon(): // Solgaleo
case 792 when Sun(): // Lunala
bool Sun() => pkm.Version == (int)GameVersion.SN || pkm.Version == (int)GameVersion.US;
bool Moon() => pkm.Version == (int)GameVersion.MN || pkm.Version == (int)GameVersion.UM;
case (int)Species.Lycanroc when (pkm.AltForm == 0 && Moon()) || (pkm.AltForm == 1 && Sun()):
case (int)Species.Solgaleo when Moon():
case (int)Species.Lunala when Sun():
bool Sun() => (pkm.Version & 1) == 0;
bool Moon() => (pkm.Version & 1) == 1;
if (pkm.IsUntraded)
data.AddLine(GetInvalid(LEvoTradeRequired, Evolution));
break;
@ -315,5 +318,35 @@ namespace PKHeX.Core
private static readonly int[] tradeEvo7b = { 064, 067, 075, 093 };
private static bool IsStarter(PKM pb7) => (pb7.Species == 25 && pb7.AltForm == 8) || (pb7.Species == 133 && pb7.AltForm == 1);
private void VerifySWSHStats(LegalityAnalysis data, PK8 pk8)
{
if (pk8.Favorite)
data.AddLine(GetInvalid(LFavoriteMarkingUnavailable, Encounter));
var gflag = data.EncounterMatch is IGigantamax g && g.CanGigantamax;
if (gflag != pk8.CanGigantamax)
data.AddLine(GetInvalid(LStatGigantamaxInvalid));
if (pk8.DynamaxLevel != 0)
{
if (pk8.IsEgg || pk8.DynamaxLevel > 10)
data.AddLine(GetInvalid(LStatDynamaxInvalid));
}
PersonalInfo? pi = null;
for (int i = 0; i < 100; i++)
{
if (!pk8.GetMoveRecordFlag(i))
continue;
if (!(pi ??= pk8.PersonalInfo).TMHM[i + 100])
data.AddLine(GetInvalid(string.Format(LMoveSourceTR, LegalityAnalysis.MoveStrings[Legal.TMHM_SWSH[i + 100]])));
}
if (!string.IsNullOrWhiteSpace(pk8.HT_Name) && pk8.HT_Language == 0)
data.AddLine(GetInvalid(LMemoryHTLanguage));
// weight/height scalars can be legally 0 (1:65536) so don't bother checking
}
}
}

View file

@ -28,14 +28,17 @@ namespace PKHeX.Core
return;
}
if (pkm.VC && pkm.IsNicknamed)
if (pkm.Format <= 7) // can nickname afterwards
{
VerifyG1NicknameWithinBounds(data, pkm.Nickname);
}
else if (EncounterMatch is MysteryGift m)
{
if (pkm.IsNicknamed && !m.IsEgg)
data.AddLine(Get(LEncGiftNicknamed, ParseSettings.NicknamedMysteryGift));
if (pkm.VC && pkm.IsNicknamed)
{
VerifyG1NicknameWithinBounds(data, pkm.Nickname);
}
else if (EncounterMatch is MysteryGift m)
{
if (pkm.IsNicknamed && !m.IsEgg)
data.AddLine(Get(LEncGiftNicknamed, ParseSettings.NicknamedMysteryGift));
}
}
if (EncounterMatch is EncounterTrade t)
@ -83,7 +86,7 @@ namespace PKHeX.Core
}
if (nickname.Length > Legal.GetMaxLengthNickname(data.Info.Generation, (LanguageID)pkm.Language))
{
var severe = data.EncounterOriginal.EggEncounter && pkm.WasTradedEgg && nickname.Length <= Legal.GetMaxLengthNickname(data.Info.Generation, English)
var severe = pkm.Format >= 8 || (data.EncounterOriginal.EggEncounter && pkm.WasTradedEgg && nickname.Length <= Legal.GetMaxLengthNickname(data.Info.Generation, English))
? Severity.Fishy
: Severity.Invalid;
data.AddLine(Get(LNickLengthLong, severe));
@ -345,7 +348,7 @@ namespace PKHeX.Core
private static CheckResult CheckTradeOTOnly(LegalityAnalysis data, string[] validOT)
{
var pkm = data.pkm;
if (pkm.IsNicknamed)
if (pkm.IsNicknamed && pkm.Format < 8)
return GetInvalid(LEncTradeChangedNickname, CheckIdentifier.Nickname);
int lang = pkm.Language;
if (validOT.Length <= lang)

View file

@ -104,10 +104,9 @@ namespace PKHeX.Core
{
var pkm = data.pkm;
int species = pkm.Species;
if (!Legal.TransferrableGalar.Contains(species))
var pi = (PersonalInfoSWSH)PersonalTable.SWSH.GetFormeEntry(species, pkm.AltForm);
if (!pi.IsPresentInGame)
data.AddLine(GetInvalid(LTransferBad));
// todo: alternate forms disallowed?
}
public IEnumerable<CheckResult> VerifyVCEncounter(PKM pkm, IEncounterable encounter, ILocation transfer, IList<CheckMoveResult> Moves)

View file

@ -45,7 +45,7 @@ namespace PKHeX.Core
/// <returns>A boolean indicating whether or not the given length is valid for a mystery gift.</returns>
public static bool IsMysteryGift(long len) => MGSizes.Contains((int)len);
private static readonly HashSet<int> MGSizes = new HashSet<int>{ WC6Full.Size, WC6.Size, PGF.Size, PGT.Size, PCD.Size };
private static readonly HashSet<int> MGSizes = new HashSet<int>{ WC8.Size, WC6Full.Size, WC6.Size, PGF.Size, PGT.Size, PCD.Size };
/// <summary>
/// Converts the given data to a <see cref="MysteryGift"/>.
@ -61,6 +61,8 @@ namespace PKHeX.Core
switch (data.Length)
{
case WC8.Size when ext == ".wc8":
return new WC8(data);
case WB7.SizeFull when ext == ".wb7full":
case WB7.Size when ext == ".wb7":
return new WB7(data);
@ -106,6 +108,7 @@ namespace PKHeX.Core
return new WC7(data);
return new WC6(data);
case WR7.Size: return new WR7(data);
case WC8.Size: return new WC8(data);
case PGF.Size: return new PGF(data);
case PGT.Size: return new PGT(data);

View file

@ -8,7 +8,7 @@ namespace PKHeX.Core
/// <summary>
/// Generation 5 Mystery Gift Template File
/// </summary>
public sealed class PGF : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, ILangNick, IContestStats
public sealed class PGF : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, ILangNick, IContestStats, INature
{
public const int Size = 0xCC;
public override int Format => 5;
@ -201,7 +201,7 @@ namespace PKHeX.Core
CNT_Tough = CNT_Tough,
CNT_Sheen = CNT_Sheen,
EXP = Experience.GetEXP(currentLevel, Species, 0),
EXP = Experience.GetEXP(currentLevel, pi.EXPGrowth),
// Ribbons
RibbonCountry = RibbonCountry,
@ -370,7 +370,8 @@ namespace PKHeX.Core
if (Level != pkm.Met_Level) return false;
if (Ball != pkm.Ball) return false;
if (Nature != -1 && Nature != pkm.Nature) return false;
if (Nature != -1 && pkm.Nature != Nature)
return false;
if (Gender != 2 && Gender != pkm.Gender) return false;
if (pkm is IContestStats s && s.IsContestBelow(this))

View file

@ -8,7 +8,7 @@ namespace PKHeX.Core
/// <summary>
/// Generation 7 Mystery Gift Template File
/// </summary>
public sealed class WB7 : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, ILangNick, IAwakened
public sealed class WB7 : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, ILangNick, IAwakened, INature
{
public const int Size = 0x108;
public const int SizeFull = 0x310;
@ -360,7 +360,7 @@ namespace PKHeX.Core
HT_Gender = OT_Name.Length > 0 ? SAV.Gender : 0,
CurrentHandler = OT_Name.Length > 0 ? 1 : 0,
EXP = Experience.GetEXP(currentLevel, Species, 0),
EXP = Experience.GetEXP(currentLevel, pi.EXPGrowth),
OT_Friendship = pi.BaseFriendship,
FatefulEncounter = true,
@ -518,7 +518,7 @@ namespace PKHeX.Core
if (MetLevel != pkm.Met_Level) return false;
if (Ball != pkm.Ball) return false;
if (OTGender < 3 && OTGender != pkm.OT_Gender) return false;
if (Nature != -1 && Nature != pkm.Nature) return false;
if (Nature != -1 && pkm.Nature != Nature) return false;
if (Gender != 3 && Gender != pkm.Gender) return false;
if (pkm is IAwakened s && s.IsAwakeningBelow(this))

View file

@ -77,9 +77,7 @@ namespace PKHeX.Core
Met_Level = Met_Level,
Met_Location = Location,
Ball = 4,
EXP = Experience.GetEXP(Level, Species, 0),
// Ribbons
RibbonCountry = RibbonCountry,
RibbonNational = RibbonNational,
@ -91,6 +89,7 @@ namespace PKHeX.Core
FatefulEncounter = Fateful,
Version = GetVersion(SAV),
};
pk.EXP = Experience.GetEXP(Level, pk.PersonalInfo.EXPGrowth);
SetMoves(pk);
bool hatchedEgg = IsEgg && SAV.Generation != 3;

View file

@ -8,7 +8,7 @@ namespace PKHeX.Core
/// <summary>
/// Generation 6 Mystery Gift Template File
/// </summary>
public sealed class WC6 : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, ILangNick, IContestStats
public sealed class WC6 : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, ILangNick, IContestStats, INature
{
public const int Size = 0x108;
public const uint EonTicketConst = 0x225D73C2;
@ -305,7 +305,7 @@ namespace PKHeX.Core
HT_Gender = OT_Name.Length > 0 ? SAV.Gender : 0,
CurrentHandler = OT_Name.Length > 0 ? 1 : 0,
EXP = Experience.GetEXP(Level, Species, 0),
EXP = Experience.GetEXP(Level, pi.EXPGrowth),
// Ribbons
RibbonCountry = RibbonCountry,
@ -501,7 +501,7 @@ namespace PKHeX.Core
if (Level != pkm.Met_Level) return false;
if (Ball != pkm.Ball) return false;
if (OTGender < 3 && OTGender != pkm.OT_Gender) return false;
if (Nature != -1 && Nature != pkm.Nature) return false;
if (Nature != -1 && pkm.Nature != Nature) return false;
if (Gender != 3 && Gender != pkm.Gender) return false;
if (pkm is IContestStats s && s.IsContestBelow(this))

View file

@ -8,7 +8,7 @@ namespace PKHeX.Core
/// <summary>
/// Generation 7 Mystery Gift Template File
/// </summary>
public sealed class WC7 : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, ILangNick, IContestStats
public sealed class WC7 : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4, ILangNick, IContestStats, INature
{
public const int Size = 0x108;
public override int Format => 7;
@ -349,7 +349,7 @@ namespace PKHeX.Core
HT_Gender = OT_Name.Length > 0 ? SAV.Gender : 0,
CurrentHandler = OT_Name.Length > 0 ? 1 : 0,
EXP = Experience.GetEXP(currentLevel, Species, 0),
EXP = Experience.GetEXP(currentLevel, pi.EXPGrowth),
// Ribbons
RibbonCountry = RibbonCountry,
@ -543,7 +543,7 @@ namespace PKHeX.Core
if (MetLevel != pkm.Met_Level) return false;
if (Ball != pkm.Ball) return false;
if (OTGender < 3 && OTGender != pkm.OT_Gender) return false;
if (Nature != -1 && Nature != pkm.Nature) return false;
if (Nature != -1 && pkm.Nature != Nature) return false;
if (Gender != 3 && Gender != pkm.Gender) return false;
if (pkm is IContestStats s && s.IsContestBelow(this))

View file

@ -0,0 +1,544 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PKHeX.Core
{
/// <summary>
/// Generation 8 Mystery Gift Template File
/// </summary>
public sealed class WC8 : DataMysteryGift, ILangNick, INature, IGigantamax, IDynamaxLevel
{
public const int Size = 0x2D0;
public const int CardStart = 0x0;
public override int Format => 8;
public enum GiftType : byte
{
None = 0,
Pokemon = 1,
Item = 2,
BP = 3,
Clothing = 4,
}
public WC8() : this(new byte[Size]) { }
public WC8(byte[] data) : base(data) { }
// TODO: public byte RestrictVersion?
public bool CanBeReceivedByVersion(int v)
{
if (v < (int)GameVersion.SW || v > (int)GameVersion.SH)
return false;
return true;
}
// General Card Properties
public override int CardID
{
get => BitConverter.ToUInt16(Data, CardStart + 0x8);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x8);
}
public byte CardFlags { get => Data[CardStart + 0x10]; set => Data[CardStart + 0x10] = value; }
public GiftType CardType { get => (GiftType)Data[CardStart + 0x11]; set => Data[CardStart + 0x11] = (byte)value; }
public bool GiftRepeatable { get => (CardFlags & 1) == 0; set => CardFlags = (byte)((CardFlags & ~1) | (value ? 0 : 1)); }
public override bool GiftUsed { get => false; set => throw new Exception(); }
public int CardTitleIndex
{
get => Data[CardStart + 0x15];
set => Data[CardStart + 0x15] = (byte) value;
}
public override string CardTitle
{
get => "Mystery Gift"; // TODO: Use text string from CardTitleIndex
set => throw new Exception();
}
// Item Properties
public override bool IsItem { get => CardType == GiftType.Item; set { if (value) CardType = GiftType.Item; } }
public override int ItemID
{
get => GetItem(0);
set => SetItem(0, (ushort)value);
}
public override int Quantity
{
get => GetQuantity(0);
set => SetQuantity(0, (ushort)value);
}
public int GetItem(int index) => BitConverter.ToUInt16(Data, CardStart + 0x20 + (0x4 * index));
public void SetItem(int index, ushort item) => BitConverter.GetBytes(item).CopyTo(Data, CardStart + 0x20 + (4 * index));
public int GetQuantity(int index) => BitConverter.ToUInt16(Data, CardStart + 0x22 + (0x4 * index));
public void SetQuantity(int index, ushort quantity) => BitConverter.GetBytes(quantity).CopyTo(Data, CardStart + 0x22 + (4 * index));
// Pokémon Properties
public override bool IsPokémon { get => CardType == GiftType.Pokemon; set { if (value) CardType = GiftType.Pokemon; } }
public override bool IsShiny => PIDType == Shiny.Always;
public override int TID
{
get => BitConverter.ToUInt16(Data, CardStart + 0x20);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x20);
}
public override int SID {
get => BitConverter.ToUInt16(Data, CardStart + 0x22);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x22);
}
public int OriginGame
{
get => BitConverter.ToInt32(Data, CardStart + 0x24);
set => BitConverter.GetBytes(value).CopyTo(Data, CardStart + 0x24);
}
public uint EncryptionConstant
{
get => BitConverter.ToUInt32(Data, CardStart + 0x28);
set => BitConverter.GetBytes(value).CopyTo(Data, CardStart + 0x28);
}
public uint PID
{
get => BitConverter.ToUInt32(Data, CardStart + 0x2C);
set => BitConverter.GetBytes(value).CopyTo(Data, CardStart + 0x2C);
}
// Nicknames, OT Names 0x30 - 0x228
public override int EggLocation { get => BitConverter.ToUInt16(Data, CardStart + 0x228); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x228); }
public int MetLocation { get => BitConverter.ToUInt16(Data, CardStart + 0x22A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x22A); }
public override int Ball
{
get => BitConverter.ToUInt16(Data, CardStart + 0x22C);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x22C);
}
public override int HeldItem
{
get => BitConverter.ToUInt16(Data, CardStart + 0x22E);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x22E);
}
public int Move1 { get => BitConverter.ToUInt16(Data, CardStart + 0x230); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x230); }
public int Move2 { get => BitConverter.ToUInt16(Data, CardStart + 0x232); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x232); }
public int Move3 { get => BitConverter.ToUInt16(Data, CardStart + 0x234); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x234); }
public int Move4 { get => BitConverter.ToUInt16(Data, CardStart + 0x236); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x236); }
public int RelearnMove1 { get => BitConverter.ToUInt16(Data, CardStart + 0x238); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x238); }
public int RelearnMove2 { get => BitConverter.ToUInt16(Data, CardStart + 0x23A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x23A); }
public int RelearnMove3 { get => BitConverter.ToUInt16(Data, CardStart + 0x23C); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x23C); }
public int RelearnMove4 { get => BitConverter.ToUInt16(Data, CardStart + 0x23E); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x23E); }
public override int Species { get => BitConverter.ToUInt16(Data, CardStart + 0x240); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x240); }
public override int Form { get => Data[CardStart + 0x242]; set => Data[CardStart + 0x242] = (byte)value; }
public override int Gender { get => Data[CardStart + 0x243]; set => Data[CardStart + 0x243] = (byte)value; }
public override int Level { get => Data[CardStart + 0x244]; set => Data[CardStart + 0x244] = (byte)value; }
public override bool IsEgg { get => Data[CardStart + 0x245] == 1; set => Data[CardStart + 0x245] = (byte)(value ? 1 : 0); }
public int Nature { get => (sbyte)Data[CardStart + 0x246]; set => Data[CardStart + 0x246] = (byte)value; }
public override int AbilityType { get => Data[CardStart + 0x247]; set => Data[CardStart + 0x247] = (byte)value; }
public Shiny PIDType
{
get
{
switch (Data[CardStart + 0x248])
{
case 0:
return Shiny.Never;
case 1:
return Shiny.Random;
case 2: // Fixed never shiny
case 3: // Fixed always shiny
case 4:
return Shiny.FixedValue;
default:
throw new ArgumentException();
}
}
}
public int MetLevel { get => Data[CardStart + 0x249]; set => Data[CardStart + 0x249] = (byte)value; }
public byte DynamaxLevel { get => Data[CardStart + 0x24A]; set => Data[CardStart + 0x24A] = value; }
public bool CanGigantamax { get => Data[CardStart + 0x24B] != 0; set => Data[CardStart + 0x24B] = (byte)(value ? 1 : 0); }
// Ribbons 0x24C-0x26C
public byte GetRibbon(int index)
{
if (index >= 0x20) throw new IndexOutOfRangeException();
return Data[0x24C + index];
}
public void SetRibbon(int index, byte value)
{
if (index >= 0x20) throw new IndexOutOfRangeException();
Data[0x24C + index] = value;
}
public int IV_HP { get => Data[CardStart + 0x26C]; set => Data[CardStart + 0x26C] = (byte)value; }
public int IV_ATK { get => Data[CardStart + 0x26D]; set => Data[CardStart + 0x26D] = (byte)value; }
public int IV_DEF { get => Data[CardStart + 0x26E]; set => Data[CardStart + 0x26E] = (byte)value; }
public int IV_SPE { get => Data[CardStart + 0x26F]; set => Data[CardStart + 0x26F] = (byte)value; }
public int IV_SPA { get => Data[CardStart + 0x270]; set => Data[CardStart + 0x270] = (byte)value; }
public int IV_SPD { get => Data[CardStart + 0x271]; set => Data[CardStart + 0x271] = (byte)value; }
public int OTGender { get => Data[CardStart + 0x272]; set => Data[CardStart + 0x272] = (byte)value; }
public int EV_HP { get => Data[CardStart + 0x273]; set => Data[CardStart + 0x273] = (byte)value; }
public int EV_ATK { get => Data[CardStart + 0x274]; set => Data[CardStart + 0x274] = (byte)value; }
public int EV_DEF { get => Data[CardStart + 0x275]; set => Data[CardStart + 0x275] = (byte)value; }
public int EV_SPE { get => Data[CardStart + 0x276]; set => Data[CardStart + 0x276] = (byte)value; }
public int EV_SPA { get => Data[CardStart + 0x277]; set => Data[CardStart + 0x277] = (byte)value; }
public int EV_SPD { get => Data[CardStart + 0x278]; set => Data[CardStart + 0x278] = (byte)value; }
public int OT_Intensity { get => Data[CardStart + 0x279]; set => Data[CardStart + 0x279] = (byte)value; }
public int OT_Memory { get => Data[CardStart + 0x27A]; set => Data[CardStart + 0x27A] = (byte)value; }
public int OT_Feeling { get => Data[CardStart + 0x27B]; set => Data[CardStart + 0x27B] = (byte)value; }
public int OT_TextVar { get => BitConverter.ToUInt16(Data, CardStart + 0x27C); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x27C); }
// Meta Accessible Properties
public override int[] IVs
{
get => new[] { IV_HP, IV_ATK, IV_DEF, IV_SPE, IV_SPA, IV_SPD };
set
{
if (value.Length != 6) return;
IV_HP = value[0]; IV_ATK = value[1]; IV_DEF = value[2];
IV_SPE = value[3]; IV_SPA = value[4]; IV_SPD = value[5];
}
}
public int[] EVs
{
get => new[] { EV_HP, EV_ATK, EV_DEF, EV_SPE, EV_SPA, EV_SPD };
set
{
if (value.Length != 6) return;
EV_HP = value[0]; EV_ATK = value[1]; EV_DEF = value[2];
EV_SPE = value[3]; EV_SPA = value[4]; EV_SPD = value[5];
}
}
public bool GetIsNicknamed(int language) => BitConverter.ToUInt16(Data, GetNicknameOffset(language)) != 0;
public int GetNicknameLanguage(int language) => Data[GetNicknameOffset(language) + 0x1A];
public bool GetHasOT(int language) => BitConverter.ToUInt16(Data, GetOTOffset(language)) != 0;
private int GetLanguageIndex(int language)
{
var lang = (LanguageID) language;
if (lang < LanguageID.Japanese || lang == LanguageID.UNUSED_6)
return (int) LanguageID.English; // fallback
return lang < LanguageID.UNUSED_6 ? language - 1 : language - 2;
}
public override int Location { get => MetLocation; set => MetLocation = (ushort)value; }
public override int[] Moves
{
get => new[] { Move1, Move2, Move3, Move4 };
set
{
if (value.Length > 0) Move1 = value[0];
if (value.Length > 1) Move2 = value[1];
if (value.Length > 2) Move3 = value[2];
if (value.Length > 3) Move4 = value[3];
}
}
public override int[] RelearnMoves
{
get => new[] { RelearnMove1, RelearnMove2, RelearnMove3, RelearnMove4 };
set
{
if (value.Length > 0) RelearnMove1 = value[0];
if (value.Length > 1) RelearnMove2 = value[1];
if (value.Length > 2) RelearnMove3 = value[2];
if (value.Length > 3) RelearnMove4 = value[3];
}
}
public override string OT_Name { get; set; } = string.Empty;
public string Nickname => string.Empty;
public bool IsNicknamed => false;
public int Language => 2;
public string GetNickname(int language) => Util.TrimFromZero(Encoding.Unicode.GetString(Data, GetNicknameOffset(language), 0x1A));
public void SetNickname(int language, string value) => Encoding.Unicode.GetBytes(value.PadRight(0x1A / 2, '\0')).CopyTo(Data, GetNicknameOffset(language));
public string GetOT(int language) => Util.TrimFromZero(Encoding.Unicode.GetString(Data, GetOTOffset(language), 0x1A));
public void SetOT(int language, string value) => Encoding.Unicode.GetBytes(value.PadRight(0x1A / 2, '\0')).CopyTo(Data, GetOTOffset(language));
private int GetNicknameOffset(int language)
{
int index = GetLanguageIndex(language);
return 0x30 + (index * 0x1C);
}
private int GetOTOffset(int language)
{
int index = GetLanguageIndex(language);
return 0x12C + (index * 0x1C);
}
public override PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria)
{
if (!IsPokémon)
throw new ArgumentException(nameof(IsPokémon));
int currentLevel = Level > 0 ? Level : Util.Rand.Next(100) + 1;
int metLevel = MetLevel > 0 ? MetLevel : currentLevel;
var pi = PersonalTable.SWSH.GetFormeEntry(Species, Form);
var OT = GetOT(SAV.Language);
var pk = new PK8
{
EncryptionConstant = EncryptionConstant != 0 ? EncryptionConstant : Util.Rand32(),
TID = TID,
SID = SID,
Species = Species,
AltForm = Form,
CurrentLevel = currentLevel,
Ball = Ball != 0 ? Ball : 4, // Default is Pokeball
Met_Level = metLevel,
HeldItem = HeldItem,
EXP = Experience.GetEXP(currentLevel, pi.EXPGrowth),
Move1 = Move1,
Move2 = Move2,
Move3 = Move3,
Move4 = Move4,
RelearnMove1 = RelearnMove1,
RelearnMove2 = RelearnMove2,
RelearnMove3 = RelearnMove3,
RelearnMove4 = RelearnMove4,
Version = OriginGame != 0 ? OriginGame : SAV.Game,
OT_Name = OT.Length > 0 ? OT : SAV.OT,
OT_Gender = OTGender < 2 ? OTGender : SAV.Gender,
HT_Name = GetHasOT(Language) ? SAV.OT : string.Empty,
HT_Gender = GetHasOT(Language) ? SAV.Gender : 0,
HT_Language = GetHasOT(Language) ? SAV.Language : 0,
CurrentHandler = GetHasOT(Language) ? 1 : 0,
OT_Friendship = pi.BaseFriendship,
OT_Intensity = OT_Intensity,
OT_Memory = OT_Memory,
OT_TextVar = OT_TextVar,
OT_Feeling = OT_Feeling,
FatefulEncounter = true,
EVs = EVs,
CanGigantamax = CanGigantamax,
DynamaxLevel = DynamaxLevel,
Met_Location = MetLocation,
Egg_Location = EggLocation,
};
pk.SetMaximumPPCurrent();
if ((SAV.Generation > Format && OriginGame == 0) || !CanBeReceivedByVersion(pk.Version))
{
// give random valid game
do { pk.Version = (int)GameVersion.SW + Util.Rand.Next(2); }
while (!CanBeReceivedByVersion(pk.Version));
}
if (OTGender >= 2)
{
pk.TID = SAV.TID;
pk.SID = SAV.SID;
}
// Official code explicitly corrects for meowstic
if (pk.Species == 678)
pk.AltForm = pk.Gender;
pk.MetDate = DateTime.Now;
var nickname_language = GetNicknameLanguage(SAV.Language);
pk.Language = nickname_language != 0 ? nickname_language : SAV.Language;
pk.IsNicknamed = GetIsNicknamed(SAV.Language);
pk.Nickname = pk.IsNicknamed ? Nickname : SpeciesName.GetSpeciesNameGeneration(Species, pk.Language, Format);
for (var i = 0; i < 0x20; i++)
{
var ribbon = GetRibbon(i);
if (ribbon != 0xFF)
pk.SetRibbon(ribbon);
}
SetPINGA(pk, SAV, criteria);
if (IsEgg)
SetEggMetData(pk);
pk.CurrentFriendship = pk.IsEgg ? pi.HatchCycles : pi.BaseFriendship;
pk.HeightScalar = PokeSizeExtensions.GetRandomPokeSize();
pk.WeightScalar = PokeSizeExtensions.GetRandomPokeSize();
pk.RefreshChecksum();
return pk;
}
private void SetEggMetData(PKM pk)
{
pk.IsEgg = true;
pk.EggMetDate = DateTime.Now;
pk.Nickname = SpeciesName.GetSpeciesNameGeneration(0, pk.Language, Format);
pk.IsNicknamed = true;
}
private void SetPINGA(PKM pk, ITrainerInfo SAV, EncounterCriteria criteria)
{
var pi = PersonalTable.USUM.GetFormeEntry(Species, Form);
pk.Nature = (int)criteria.GetNature(Nature == -1 ? Core.Nature.Random : (Nature)Nature);
pk.StatNature = pk.Nature;
pk.Gender = criteria.GetGender(Gender, pi);
var av = GetAbilityIndex(criteria, pi);
pk.RefreshAbility(av);
SetPID(pk, SAV);
SetIVs(pk);
}
private int GetAbilityIndex(EncounterCriteria criteria, PersonalInfo pi)
{
switch (AbilityType)
{
case 00: // 0 - 0
case 01: // 1 - 1
case 02: // 2 - H
return AbilityType;
case 03: // 0/1
case 04: // 0/1/H
return criteria.GetAbility(AbilityType, pi); // 3 or 2
default:
throw new ArgumentException(nameof(AbilityType));
}
}
private uint GetFixedPID(ITrainerInfo SAV)
{
uint pid = PID;
var val = Data[CardStart + 0x248];
if (val == 4)
return pid;
return (uint)((pid & 0xFFFF) | ((SAV.SID ^ SAV.TID ^ (pid & 0xFFFF) ^ (val == 2 ? 1 : 0)) << 16));
}
private void SetPID(PKM pk, ITrainerInfo SAV)
{
switch (PIDType)
{
case Shiny.FixedValue: // Specified
pk.PID = GetFixedPID(SAV);
break;
case Shiny.Random: // Random
pk.PID = Util.Rand32();
break;
case Shiny.Always: // Random Shiny
pk.PID = Util.Rand32();
pk.PID = (uint)(((pk.TID ^ pk.SID ^ (pk.PID & 0xFFFF)) << 16) | (pk.PID & 0xFFFF));
break;
case Shiny.Never: // Random Nonshiny
pk.PID = Util.Rand32();
if (pk.IsShiny) pk.PID ^= 0x10000000;
break;
}
}
private void SetIVs(PKM pk)
{
int[] finalIVs = new int[6];
var ivflag = Array.Find(IVs, iv => (byte)(iv - 0xFC) < 3);
if (ivflag == 0) // Random IVs
{
for (int i = 0; i < 6; i++)
finalIVs[i] = IVs[i] > 31 ? Util.Rand.Next(pk.MaxIV + 1) : IVs[i];
}
else // 1/2/3 perfect IVs
{
int IVCount = ivflag - 0xFB;
do { finalIVs[Util.Rand.Next(6)] = 31; }
while (finalIVs.Count(iv => iv == 31) < IVCount);
for (int i = 0; i < 6; i++)
finalIVs[i] = finalIVs[i] == 31 ? pk.MaxIV : Util.Rand.Next(pk.MaxIV + 1);
}
pk.IVs = finalIVs;
}
protected override bool IsMatchExact(PKM pkm, IEnumerable<DexLevel> vs)
{
if (pkm.Egg_Location == 0) // Not Egg
{
if (OTGender < 2)
{
if (SID != pkm.SID) return false;
if (TID != pkm.TID) return false;
if (OTGender != pkm.OT_Gender) return false;
}
var OT = GetOT(pkm.Language); // May not be guaranteed to work.
if (!string.IsNullOrEmpty(OT) && OT != pkm.OT_Name) return false;
if (OriginGame != 0 && OriginGame != pkm.Version) return false;
if (EncryptionConstant != 0 && EncryptionConstant != pkm.EncryptionConstant) return false;
}
if (Form != pkm.AltForm && vs.All(z => !Legal.IsFormChangeable(pkm, z.Species)))
return false;
if (IsEgg)
{
if (EggLocation != pkm.Egg_Location) // traded
{
if (pkm.Egg_Location != Locations.LinkTrade6)
return false;
}
else if (PIDType == 0 && pkm.IsShiny)
{
return false; // can't be traded away for unshiny
}
if (pkm.IsEgg && !pkm.IsNative)
return false;
}
else
{
if (!PIDType.IsValid(pkm)) return false;
if (EggLocation != pkm.Egg_Location) return false;
if (MetLocation != pkm.Met_Location) return false;
}
if (MetLevel != 0 && MetLevel != pkm.Met_Level) return false;
if (Ball != 0 && Ball != pkm.Ball) return false;
if (Ball == 0 && pkm.Ball != 4) return false;
if (OTGender < 2 && OTGender != pkm.OT_Gender) return false;
if (Nature != -1 && pkm.Nature != Nature) return false;
if (Gender != 3 && Gender != pkm.Gender) return false;
if (!(pkm is IGigantamax g && g.CanGigantamax == CanGigantamax))
return false;
if (!(pkm is IDynamaxLevel dl && dl.DynamaxLevel >= DynamaxLevel))
return false;
return PIDType != 0 || pkm.PID == PID;
}
protected override bool IsMatchDeferred(PKM pkm)
{
return pkm.Species == Species;
}
}
}

View file

@ -78,7 +78,7 @@
<None Remove="Resources\byte\evos_rby.pkl" />
<None Remove="Resources\byte\evos_uu.pkl" />
<None Remove="Resources\byte\evos_gg.pkl" />
<None Remove="Resources\byte\evos_swsh.pkl" />
<None Remove="Resources\byte\evos_ss.pkl" />
<None Remove="Resources\byte\hmtm_g3.pkl" />
<None Remove="Resources\byte\lvlmove_ao.pkl" />
<None Remove="Resources\byte\lvlmove_b2w2.pkl" />
@ -128,6 +128,7 @@
<None Remove="Resources\byte\wc7.pkl" />
<None Remove="Resources\byte\wc7full.pkl" />
<None Remove="Resources\byte\wb7full.pkl" />
<None Remove="Resources\byte\wc8.pkl" />
<None Remove="Resources\text\de\lang_de.txt" />
<None Remove="Resources\text\de\LegalityCheckStrings_de.txt" />
<None Remove="Resources\text\de\MessageStrings_en.txt" />
@ -173,6 +174,7 @@
<None Remove="Resources\text\de\text_tradehgss_de.txt" />
<None Remove="Resources\text\de\text_traderse_de.txt" />
<None Remove="Resources\text\de\text_tradesm_de.txt" />
<None Remove="Resources\text\de\text_tradeswsh_de.txt" />
<None Remove="Resources\text\de\text_tradeusum_de.txt" />
<None Remove="Resources\text\de\text_tradexy_de.txt" />
<None Remove="Resources\text\de\text_TrainingBag_de.txt" />
@ -227,6 +229,7 @@
<None Remove="Resources\text\en\text_tradehgss_en.txt" />
<None Remove="Resources\text\en\text_traderse_en.txt" />
<None Remove="Resources\text\en\text_tradesm_en.txt" />
<None Remove="Resources\text\en\text_tradeswsh_en.txt" />
<None Remove="Resources\text\en\text_tradeusum_en.txt" />
<None Remove="Resources\text\en\text_tradexy_en.txt" />
<None Remove="Resources\text\en\text_TrainingBag_en.txt" />
@ -281,6 +284,7 @@
<None Remove="Resources\text\es\text_tradehgss_es.txt" />
<None Remove="Resources\text\es\text_traderse_es.txt" />
<None Remove="Resources\text\es\text_tradesm_es.txt" />
<None Remove="Resources\text\es\text_tradeswsh_es.txt" />
<None Remove="Resources\text\es\text_tradeusum_es.txt" />
<None Remove="Resources\text\es\text_tradexy_es.txt" />
<None Remove="Resources\text\es\text_TrainingBag_es.txt" />
@ -335,6 +339,7 @@
<None Remove="Resources\text\fr\text_tradehgss_fr.txt" />
<None Remove="Resources\text\fr\text_traderse_fr.txt" />
<None Remove="Resources\text\fr\text_tradesm_fr.txt" />
<None Remove="Resources\text\fr\text_tradeswsh_fr.txt" />
<None Remove="Resources\text\fr\text_tradeusum_fr.txt" />
<None Remove="Resources\text\fr\text_tradexy_fr.txt" />
<None Remove="Resources\text\fr\text_TrainingBag_fr.txt" />
@ -413,6 +418,7 @@
<None Remove="Resources\text\it\text_tradehgss_it.txt" />
<None Remove="Resources\text\it\text_traderse_it.txt" />
<None Remove="Resources\text\it\text_tradesm_it.txt" />
<None Remove="Resources\text\it\text_tradeswsh_it.txt" />
<None Remove="Resources\text\it\text_tradeusum_it.txt" />
<None Remove="Resources\text\it\text_tradexy_it.txt" />
<None Remove="Resources\text\it\text_TrainingBag_it.txt" />
@ -467,6 +473,7 @@
<None Remove="Resources\text\ja\text_tradehgss_ja.txt" />
<None Remove="Resources\text\ja\text_traderse_ja.txt" />
<None Remove="Resources\text\ja\text_tradesm_ja.txt" />
<None Remove="Resources\text\ja\text_tradeswsh_ja.txt" />
<None Remove="Resources\text\ja\text_tradeusum_ja.txt" />
<None Remove="Resources\text\ja\text_tradexy_ja.txt" />
<None Remove="Resources\text\ja\text_TrainingBag_ja.txt" />
@ -519,6 +526,7 @@
<None Remove="Resources\text\ko\text_tradegsc_ko.txt" />
<None Remove="Resources\text\ko\text_tradehgss_ko.txt" />
<None Remove="Resources\text\ko\text_tradesm_ko.txt" />
<None Remove="Resources\text\ko\text_tradeswsh_ko.txt" />
<None Remove="Resources\text\ko\text_tradeusum_ko.txt" />
<None Remove="Resources\text\ko\text_tradexy_ko.txt" />
<None Remove="Resources\text\ko\text_TrainingBag_ko.txt" />
@ -781,6 +789,7 @@
<None Remove="Resources\text\zh\text_swsh_60000_zh.txt" />
<None Remove="Resources\text\zh\text_tradeao_zh.txt" />
<None Remove="Resources\text\zh\text_tradesm_zh.txt" />
<None Remove="Resources\text\zh\text_tradeswsh_zh.txt" />
<None Remove="Resources\text\zh\text_tradeusum_zh.txt" />
<None Remove="Resources\text\zh\text_tradexy_zh.txt" />
<None Remove="Resources\text\zh\text_TrainingBag_zh.txt" />
@ -856,7 +865,7 @@
<EmbeddedResource Include="Resources\byte\evos_rby.pkl" />
<EmbeddedResource Include="Resources\byte\evos_uu.pkl" />
<EmbeddedResource Include="Resources\byte\evos_gg.pkl" />
<EmbeddedResource Include="Resources\byte\evos_swsh.pkl" />
<EmbeddedResource Include="Resources\byte\evos_ss.pkl" />
<EmbeddedResource Include="Resources\byte\hmtm_g3.pkl" />
<EmbeddedResource Include="Resources\byte\lvlmove_ao.pkl" />
<EmbeddedResource Include="Resources\byte\lvlmove_b2w2.pkl" />
@ -906,6 +915,7 @@
<EmbeddedResource Include="Resources\byte\wc7.pkl" />
<EmbeddedResource Include="Resources\byte\wc7full.pkl" />
<EmbeddedResource Include="Resources\byte\wb7full.pkl" />
<EmbeddedResource Include="Resources\byte\wc8.pkl" />
<EmbeddedResource Include="Resources\text\de\lang_de.txt" />
<EmbeddedResource Include="Resources\text\de\LegalityCheckStrings_de.txt" />
<EmbeddedResource Include="Resources\text\de\MessageStrings_de.txt" />
@ -951,6 +961,7 @@
<EmbeddedResource Include="Resources\text\de\text_tradehgss_de.txt" />
<EmbeddedResource Include="Resources\text\de\text_traderse_de.txt" />
<EmbeddedResource Include="Resources\text\de\text_tradesm_de.txt" />
<EmbeddedResource Include="Resources\text\de\text_tradeswsh_de.txt" />
<EmbeddedResource Include="Resources\text\de\text_tradeusum_de.txt" />
<EmbeddedResource Include="Resources\text\de\text_tradexy_de.txt" />
<EmbeddedResource Include="Resources\text\de\text_TrainingBag_de.txt" />
@ -1005,6 +1016,7 @@
<EmbeddedResource Include="Resources\text\en\text_tradehgss_en.txt" />
<EmbeddedResource Include="Resources\text\en\text_traderse_en.txt" />
<EmbeddedResource Include="Resources\text\en\text_tradesm_en.txt" />
<EmbeddedResource Include="Resources\text\en\text_tradeswsh_en.txt" />
<EmbeddedResource Include="Resources\text\en\text_tradeusum_en.txt" />
<EmbeddedResource Include="Resources\text\en\text_tradexy_en.txt" />
<EmbeddedResource Include="Resources\text\en\text_TrainingBag_en.txt" />
@ -1059,6 +1071,7 @@
<EmbeddedResource Include="Resources\text\es\text_tradehgss_es.txt" />
<EmbeddedResource Include="Resources\text\es\text_traderse_es.txt" />
<EmbeddedResource Include="Resources\text\es\text_tradesm_es.txt" />
<EmbeddedResource Include="Resources\text\es\text_tradeswsh_es.txt" />
<EmbeddedResource Include="Resources\text\es\text_tradeusum_es.txt" />
<EmbeddedResource Include="Resources\text\es\text_tradexy_es.txt" />
<EmbeddedResource Include="Resources\text\es\text_TrainingBag_es.txt" />
@ -1113,6 +1126,7 @@
<EmbeddedResource Include="Resources\text\fr\text_tradehgss_fr.txt" />
<EmbeddedResource Include="Resources\text\fr\text_traderse_fr.txt" />
<EmbeddedResource Include="Resources\text\fr\text_tradesm_fr.txt" />
<EmbeddedResource Include="Resources\text\fr\text_tradeswsh_fr.txt" />
<EmbeddedResource Include="Resources\text\fr\text_tradeusum_fr.txt" />
<EmbeddedResource Include="Resources\text\fr\text_tradexy_fr.txt" />
<EmbeddedResource Include="Resources\text\fr\text_TrainingBag_fr.txt" />
@ -1191,6 +1205,7 @@
<EmbeddedResource Include="Resources\text\it\text_tradehgss_it.txt" />
<EmbeddedResource Include="Resources\text\it\text_traderse_it.txt" />
<EmbeddedResource Include="Resources\text\it\text_tradesm_it.txt" />
<EmbeddedResource Include="Resources\text\it\text_tradeswsh_it.txt" />
<EmbeddedResource Include="Resources\text\it\text_tradeusum_it.txt" />
<EmbeddedResource Include="Resources\text\it\text_tradexy_it.txt" />
<EmbeddedResource Include="Resources\text\it\text_TrainingBag_it.txt" />
@ -1245,6 +1260,7 @@
<EmbeddedResource Include="Resources\text\ja\text_tradehgss_ja.txt" />
<EmbeddedResource Include="Resources\text\ja\text_traderse_ja.txt" />
<EmbeddedResource Include="Resources\text\ja\text_tradesm_ja.txt" />
<EmbeddedResource Include="Resources\text\ja\text_tradeswsh_ja.txt" />
<EmbeddedResource Include="Resources\text\ja\text_tradeusum_ja.txt" />
<EmbeddedResource Include="Resources\text\ja\text_tradexy_ja.txt" />
<EmbeddedResource Include="Resources\text\ja\text_TrainingBag_ja.txt" />
@ -1297,6 +1313,7 @@
<EmbeddedResource Include="Resources\text\ko\text_tradegsc_ko.txt" />
<EmbeddedResource Include="Resources\text\ko\text_tradehgss_ko.txt" />
<EmbeddedResource Include="Resources\text\ko\text_tradesm_ko.txt" />
<EmbeddedResource Include="Resources\text\ko\text_tradeswsh_ko.txt" />
<EmbeddedResource Include="Resources\text\ko\text_tradeusum_ko.txt" />
<EmbeddedResource Include="Resources\text\ko\text_tradexy_ko.txt" />
<EmbeddedResource Include="Resources\text\ko\text_TrainingBag_ko.txt" />
@ -1559,6 +1576,7 @@
<EmbeddedResource Include="Resources\text\zh\text_swsh_60000_zh.txt" />
<EmbeddedResource Include="Resources\text\zh\text_tradeao_zh.txt" />
<EmbeddedResource Include="Resources\text\zh\text_tradesm_zh.txt" />
<EmbeddedResource Include="Resources\text\zh\text_tradeswsh_zh.txt" />
<EmbeddedResource Include="Resources\text\zh\text_tradeusum_zh.txt" />
<EmbeddedResource Include="Resources\text\zh\text_tradexy_zh.txt" />
<EmbeddedResource Include="Resources\text\zh\text_TrainingBag_zh.txt" />

View file

@ -7,12 +7,12 @@ namespace PKHeX.Core
/// <remarks> Values are stored in Big Endian format rather than Little Endian. Beware. </remarks>
public sealed class BK4 : G4PKM
{
private static readonly byte[] Unused =
private static readonly ushort[] Unused =
{
0x42, 0x43, 0x5E, 0x63, 0x64, 0x65, 0x66, 0x67, 0x87
};
public override IReadOnlyList<byte> ExtraBytes => Unused;
public override IReadOnlyList<ushort> ExtraBytes => Unused;
public override int SIZE_PARTY => PKX.SIZE_4STORED;
public override int SIZE_STORED => PKX.SIZE_4STORED;

View file

@ -6,7 +6,7 @@ namespace PKHeX.Core
/// <summary> Generation 3 <see cref="PKM"/> format, exclusively for Pokémon Colosseum. </summary>
public sealed class CK3 : G3PKM, IShadowPKM
{
private static readonly byte[] Unused =
private static readonly ushort[] Unused =
{
0x11, 0x12, 0x13,
0x61, 0x62, 0x63, 0x64,
@ -15,7 +15,7 @@ namespace PKHeX.Core
// 0xFC onwards unused?
};
public override IReadOnlyList<byte> ExtraBytes => Unused;
public override IReadOnlyList<ushort> ExtraBytes => Unused;
public override int SIZE_PARTY => PKX.SIZE_3CSTORED;
public override int SIZE_STORED => PKX.SIZE_3CSTORED;

View file

@ -5,9 +5,9 @@ using System.Runtime.CompilerServices;
namespace PKHeX.Core
{
/// <summary> Generation 7 <see cref="PKM"/> format used for <see cref="GameVersion.GG"/>. </summary>
public sealed class PB7 : G6PKM, IHyperTrain, IAwakened
public sealed class PB7 : G6PKM, IHyperTrain, IAwakened, IScaledSize, IFavorite
{
public static readonly byte[] Unused =
public static readonly ushort[] Unused =
{
0x2A, // Old Marking Value (PelagoEventStatus)
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, // Unused Ribbons
@ -20,7 +20,7 @@ namespace PKHeX.Core
0xC8, 0xC9, // OT Terminator
};
public override IReadOnlyList<byte> ExtraBytes => Unused;
public override IReadOnlyList<ushort> ExtraBytes => Unused;
public override int SIZE_PARTY => SIZE;
public override int SIZE_STORED => SIZE;
@ -533,19 +533,6 @@ namespace PKHeX.Core
WeightAbsolute = updated;
}
public static int GetSizeRating(int scalar)
{
if (scalar < 0x10)
return 0; // 1/16 = XS
if (scalar < 0x30u)
return 1; // 2/16 = S
if (scalar < 0xD0u)
return 2; // average (10/16)
if (scalar < 0xF0u)
return 3; // 2/16 = L
return 4; // 1/16 = XL
}
[MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
private static float GetHeightRatio(int heightScalar)
{

View file

@ -6,7 +6,7 @@ namespace PKHeX.Core
/// <summary> Generation 3 <see cref="PKM"/> format. </summary>
public sealed class PK3 : G3PKM
{
private static readonly byte[] Unused =
private static readonly ushort[] Unused =
{
0x2A, 0x2B
};
@ -16,7 +16,7 @@ namespace PKHeX.Core
public override int Format => 3;
public override PersonalInfo PersonalInfo => PersonalTable.RS[Species];
public override IReadOnlyList<byte> ExtraBytes => Unused;
public override IReadOnlyList<ushort> ExtraBytes => Unused;
public override byte[] Data { get; }
public PK3() => Data = new byte[PKX.SIZE_3PARTY];
@ -213,7 +213,7 @@ namespace PKHeX.Core
Species = Species,
TID = TID,
SID = SID,
EXP = IsEgg ? Experience.GetEXP(5, Species, 0) : EXP,
EXP = IsEgg ? Experience.GetEXP(5, PersonalInfo.EXPGrowth) : EXP,
Gender = PKX.GetGenderFromPID(Species, PID),
AltForm = AltForm,
// IsEgg = false, -- already false

View file

@ -7,12 +7,12 @@ namespace PKHeX.Core
/// <summary> Generation 4 <see cref="PKM"/> format. </summary>
public sealed class PK4 : G4PKM
{
private static readonly byte[] Unused =
private static readonly ushort[] Unused =
{
0x42, 0x43, 0x5E, 0x63, 0x64, 0x65, 0x66, 0x67, 0x87
};
public override IReadOnlyList<byte> ExtraBytes => Unused;
public override IReadOnlyList<ushort> ExtraBytes => Unused;
public override int SIZE_PARTY => PKX.SIZE_4PARTY;
public override int SIZE_STORED => PKX.SIZE_4STORED;

View file

@ -7,7 +7,7 @@ namespace PKHeX.Core
/// <summary> Generation 5 <see cref="PKM"/> format. </summary>
public sealed class PK5 : PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetUnique3, IRibbonSetUnique4, IRibbonSetCommon3, IRibbonSetCommon4, IContestStats
{
private static readonly byte[] Unused =
private static readonly ushort[] Unused =
{
0x87, // PokeStar Fame -- this is first to prevent 0x42 from being the first ExtraByte as this byte has GUI functionality
0x42, // Hidden Ability/NPokemon
@ -18,7 +18,7 @@ namespace PKHeX.Core
0x86, // unused
};
public override IReadOnlyList<byte> ExtraBytes => Unused;
public override IReadOnlyList<ushort> ExtraBytes => Unused;
public override int SIZE_PARTY => PKX.SIZE_5PARTY;
public override int SIZE_STORED => PKX.SIZE_5STORED;

View file

@ -6,13 +6,13 @@ namespace PKHeX.Core
/// <summary> Generation 6 <see cref="PKM"/> format. </summary>
public sealed class PK6 : G6PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IContestStats, IGeoTrack, ISuperTrain
{
private static readonly byte[] Unused =
private static readonly ushort[] Unused =
{
0x36, 0x37, // Unused Ribbons
0x58, 0x59, 0x73, 0x90, 0x91, 0x9E, 0x9F, 0xA0, 0xA1, 0xA7, 0xAA, 0xAB, 0xAC, 0xAD, 0xC8, 0xC9, 0xD7, 0xE4, 0xE5, 0xE6, 0xE7
};
public override IReadOnlyList<byte> ExtraBytes => Unused;
public override IReadOnlyList<ushort> ExtraBytes => Unused;
public override int Format => 6;
public override PersonalInfo PersonalInfo => PersonalTable.AO.GetFormeEntry(Species, AltForm);
@ -194,8 +194,8 @@ namespace PKHeX.Core
public bool RibbonChampionRegional { get => (RIB4 & (1 << 2)) == 1 << 2; set => RIB4 = (byte)((RIB4 & ~(1 << 2)) | (value ? 1 << 2 : 0)); }
public bool RibbonChampionNational { get => (RIB4 & (1 << 3)) == 1 << 3; set => RIB4 = (byte)((RIB4 & ~(1 << 3)) | (value ? 1 << 3 : 0)); }
public bool RibbonChampionWorld { get => (RIB4 & (1 << 4)) == 1 << 4; set => RIB4 = (byte)((RIB4 & ~(1 << 4)) | (value ? 1 << 4 : 0)); }
public bool RIB4_5 { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)((RIB4 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused
public bool RIB4_6 { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)((RIB4 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused
public bool HasContestMemoryRibbon { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)((RIB4 & ~(1 << 5)) | (value ? 1 << 5 : 0)); }
public bool HasBattleMemoryRibbon { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)((RIB4 & ~(1 << 6)) | (value ? 1 << 6 : 0)); }
public bool RibbonChampionG6Hoenn { get => (RIB4 & (1 << 7)) == 1 << 7; set => RIB4 = (byte)((RIB4 & ~(1 << 7)) | (value ? 1 << 7 : 0)); }
public bool RibbonContestStar { get => (RIB5 & (1 << 0)) == 1 << 0; set => RIB5 = (byte)((RIB5 & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool RibbonMasterCoolness { get => (RIB5 & (1 << 1)) == 1 << 1; set => RIB5 = (byte)((RIB5 & ~(1 << 1)) | (value ? 1 << 1 : 0)); }
@ -205,8 +205,8 @@ namespace PKHeX.Core
public bool RibbonMasterToughness { get => (RIB5 & (1 << 5)) == 1 << 5; set => RIB5 = (byte)((RIB5 & ~(1 << 5)) | (value ? 1 << 5 : 0)); }
public bool RIB5_6 { get => (RIB5 & (1 << 6)) == 1 << 6; set => RIB5 = (byte)((RIB5 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused
public bool RIB5_7 { get => (RIB5 & (1 << 7)) == 1 << 7; set => RIB5 = (byte)((RIB5 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } // Unused
public int RibbonCountMemoryContest { get => Data[0x38]; set => Data[0x38] = (byte)value; }
public int RibbonCountMemoryBattle { get => Data[0x39]; set => Data[0x39] = (byte)value; }
public int RibbonCountMemoryContest { get => Data[0x38]; set => HasContestMemoryRibbon = (Data[0x38] = (byte)value) != 0; }
public int RibbonCountMemoryBattle { get => Data[0x39]; set => HasBattleMemoryRibbon = (Data[0x39] = (byte)value) != 0; }
private ushort DistByte { get => BitConverter.ToUInt16(Data, 0x3A); set => BitConverter.GetBytes(value).CopyTo(Data, 0x3A); }
public bool DistSuperTrain1 { get => (DistByte & (1 << 0)) == 1 << 0; set => DistByte = (byte)((DistByte & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool DistSuperTrain2 { get => (DistByte & (1 << 1)) == 1 << 1; set => DistByte = (byte)((DistByte & ~(1 << 1)) | (value ? 1 << 1 : 0)); }

View file

@ -6,14 +6,14 @@ namespace PKHeX.Core
/// <summary> Generation 7 <see cref="PKM"/> format. </summary>
public sealed class PK7 : G6PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetCommon7, IContestStats, IHyperTrain, IGeoTrack, ISuperTrain
{
private static readonly byte[] Unused =
private static readonly ushort[] Unused =
{
0x2A, // Old Marking Value (PelagoEventStatus)
// 0x36, 0x37, // Unused Ribbons
0x58, 0x59, 0x73, 0x90, 0x91, 0x9E, 0x9F, 0xA0, 0xA1, 0xA7, 0xAA, 0xAB, 0xAC, 0xAD, 0xC8, 0xC9, 0xD7, 0xE4, 0xE5, 0xE6, 0xE7
};
public override IReadOnlyList<byte> ExtraBytes => Unused;
public override IReadOnlyList<ushort> ExtraBytes => Unused;
public override int Format => 7;
public override PersonalInfo PersonalInfo => PersonalTable.USUM.GetFormeEntry(Species, AltForm);
@ -196,8 +196,8 @@ namespace PKHeX.Core
public bool RibbonChampionRegional { get => (RIB4 & (1 << 2)) == 1 << 2; set => RIB4 = (byte)((RIB4 & ~(1 << 2)) | (value ? 1 << 2 : 0)); }
public bool RibbonChampionNational { get => (RIB4 & (1 << 3)) == 1 << 3; set => RIB4 = (byte)((RIB4 & ~(1 << 3)) | (value ? 1 << 3 : 0)); }
public bool RibbonChampionWorld { get => (RIB4 & (1 << 4)) == 1 << 4; set => RIB4 = (byte)((RIB4 & ~(1 << 4)) | (value ? 1 << 4 : 0)); }
public bool RIB4_5 { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)((RIB4 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused
public bool RIB4_6 { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)((RIB4 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused
public bool HasContestMemoryRibbon { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)((RIB4 & ~(1 << 5)) | (value ? 1 << 5 : 0)); }
public bool HasBattleMemoryRibbon { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)((RIB4 & ~(1 << 6)) | (value ? 1 << 6 : 0)); }
public bool RibbonChampionG6Hoenn { get => (RIB4 & (1 << 7)) == 1 << 7; set => RIB4 = (byte)((RIB4 & ~(1 << 7)) | (value ? 1 << 7 : 0)); }
public bool RibbonContestStar { get => (RIB5 & (1 << 0)) == 1 << 0; set => RIB5 = (byte)((RIB5 & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool RibbonMasterCoolness { get => (RIB5 & (1 << 1)) == 1 << 1; set => RIB5 = (byte)((RIB5 & ~(1 << 1)) | (value ? 1 << 1 : 0)); }
@ -215,8 +215,8 @@ namespace PKHeX.Core
public bool RIB6_5 { get => (RIB6 & (1 << 5)) == 1 << 5; set => RIB6 = (byte)((RIB6 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused
public bool RIB6_6 { get => (RIB6 & (1 << 6)) == 1 << 6; set => RIB6 = (byte)((RIB6 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused
public bool RIB6_7 { get => (RIB6 & (1 << 7)) == 1 << 7; set => RIB6 = (byte)((RIB6 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } // Unused
public int RibbonCountMemoryContest { get => Data[0x38]; set => Data[0x38] = (byte)value; }
public int RibbonCountMemoryBattle { get => Data[0x39]; set => Data[0x39] = (byte)value; }
public int RibbonCountMemoryContest { get => Data[0x38]; set => HasContestMemoryRibbon = (Data[0x38] = (byte)value) != 0; }
public int RibbonCountMemoryBattle { get => Data[0x39]; set => HasBattleMemoryRibbon = (Data[0x39] = (byte)value) != 0; }
private ushort DistByte { get => BitConverter.ToUInt16(Data, 0x3A); set => BitConverter.GetBytes(value).CopyTo(Data, 0x3A); }
public bool DistSuperTrain1 { get => (DistByte & (1 << 0)) == 1 << 0; set => DistByte = (byte)((DistByte & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool DistSuperTrain2 { get => (DistByte & (1 << 1)) == 1 << 1; set => DistByte = (byte)((DistByte & ~(1 << 1)) | (value ? 1 << 1 : 0)); }

View file

@ -4,18 +4,49 @@ using System.Collections.Generic;
namespace PKHeX.Core
{
/// <summary> Generation 8 <see cref="PKM"/> format. </summary>
public sealed class PK8 : G6PKM, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetCommon7, IContestStats, IHyperTrain, IGeoTrack
public sealed class PK8 : PKM,
IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetCommon7, IRibbonSetCommon8,
IContestStats, IHyperTrain, IScaledSize, IGigantamax, IFavorite, IDynamaxLevel, IRibbonIndex, IHandlerLanguage
{
private static readonly byte[] Unused =
private static readonly ushort[] Unused =
{
// Alignment bytes
0x17, 0x1A, 0x1B, 0x23, 0x33, 0x3E, 0x3F,
0xC5, 0x115, 0x11F,
};
public override IReadOnlyList<byte> ExtraBytes => Unused;
public override IReadOnlyList<ushort> ExtraBytes => Unused;
public override int Format => 8;
public override PersonalInfo PersonalInfo => PersonalTable.USUM.GetFormeEntry(Species, AltForm);
public override PersonalInfo PersonalInfo => PersonalTable.SWSH.GetFormeEntry(Species, AltForm);
public override byte[] Data { get; }
public PK8() => Data = new byte[PKX.SIZE_8PARTY];
public PK8()
{
Data = new byte[PKX.SIZE_8PARTY];
AffixedRibbon = -1; // 00 would make it show Kalos Champion :)
}
protected override ushort CalculateChecksum()
{
ushort chk = 0;
for (int i = 8; i < PKX.SIZE_8STORED; i += 2) // don't use SIZE_STORED property; pb7 overrides stored size
chk += BitConverter.ToUInt16(Data, i);
return chk;
}
// Simple Generated Attributes
public override int CurrentFriendship
{
get => CurrentHandler == 0 ? OT_Friendship : HT_Friendship;
set { if (CurrentHandler == 0) OT_Friendship = value; else HT_Friendship = value; }
}
public int OppositeFriendship
{
get => CurrentHandler == 1 ? OT_Friendship : HT_Friendship;
set { if (CurrentHandler == 1) OT_Friendship = value; else HT_Friendship = value; }
}
public PK8(byte[] data)
{
@ -30,280 +61,354 @@ namespace PKHeX.Core
private string GetString(int Offset, int Count) => StringConverter.GetString7(Data, Offset, Count);
private byte[] SetString(string value, int maxLength, bool chinese = false) => StringConverter.SetString7(value, maxLength, Language, chinese: chinese);
public override int SIZE_PARTY => PKX.SIZE_8PARTY;
public override int SIZE_STORED => PKX.SIZE_8STORED;
// Trash Bytes
public override byte[] Nickname_Trash { get => GetData(0x58, 24); set { if (value?.Length == 24) value.CopyTo(Data, 0x58); } }
public override byte[] HT_Trash { get => GetData(0xA8, 24); set { if (value?.Length == 24) value.CopyTo(Data, 0xA8); } }
public override byte[] OT_Trash { get => GetData(0xF8, 24); set { if (value?.Length == 24) value.CopyTo(Data, 0xF8); } }
public override bool WasLink => Met_Location == Locations.LinkGift6;
public override bool WasEvent => Locations.IsEventLocation5(Met_Location) || FatefulEncounter;
public override bool WasEventEgg => GenNumber < 5 ? base.WasEventEgg : (Locations.IsEventLocation5(Egg_Location) || (FatefulEncounter && Egg_Location == Locations.LinkTrade6)) && Met_Level == 1;
// Maximums
public override int MaxIV => 31;
public override int MaxEV => 252;
public override int OTLength => 12;
public override int NickLength => 12;
public override int PSV => (int)((PID >> 16 ^ (PID & 0xFFFF)) >> 4);
public override int TSV => (TID ^ SID) >> 4;
public override bool IsUntraded => Data[0x78] == 0 && Data[0x78 + 1] == 0 && Format == GenNumber; // immediately terminated HT_Name data (\0)
// Complex Generated Attributes
public override int Characteristic
{
get
{
int pm6 = (int)(EncryptionConstant % 6);
int maxIV = MaximumIV;
int pm6stat = 0;
for (int i = 0; i < 6; i++)
{
pm6stat = (pm6 + i) % 6;
if (GetIV(pm6stat) == maxIV)
break;
}
return (pm6stat * 5) + (maxIV % 5);
}
}
// Methods
protected override byte[] Encrypt()
{
RefreshChecksum();
return PKX.EncryptArray8(Data);
}
public void FixRelearn()
{
while (true)
{
if (RelearnMove4 != 0 && RelearnMove3 == 0)
{
RelearnMove3 = RelearnMove4;
RelearnMove4 = 0;
}
if (RelearnMove3 != 0 && RelearnMove2 == 0)
{
RelearnMove2 = RelearnMove3;
RelearnMove3 = 0;
continue;
}
if (RelearnMove2 != 0 && RelearnMove1 == 0)
{
RelearnMove1 = RelearnMove2;
RelearnMove2 = 0;
continue;
}
break;
}
}
public void Trade(ITrainerInfo tr, int Day = 1, int Month = 1, int Year = 2015)
{
if (IsEgg)
{
// Eggs do not have any modifications done if they are traded
// Apply link trade data, only if it left the OT (ignore if dumped & imported, or cloned, etc)
if ((tr.OT != OT_Name) || (tr.TID != TID) || (tr.SID != SID) || (tr.Gender != OT_Gender))
SetLinkTradeEgg(Day, Month, Year, Locations.LinkTrade6);
return;
}
// Process to the HT if the OT of the Pokémon does not match the SAV's OT info.
if (!TradeOT(tr))
TradeHT(tr);
}
public override uint EncryptionConstant { get => BitConverter.ToUInt32(Data, 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, 0x00); }
public override ushort Sanity { get => BitConverter.ToUInt16(Data, 0x04); set => BitConverter.GetBytes(value).CopyTo(Data, 0x04); }
public override ushort Checksum { get => BitConverter.ToUInt16(Data, 0x06); set => BitConverter.GetBytes(value).CopyTo(Data, 0x06); }
// Structure
#region Block A
public override uint EncryptionConstant
{
get => BitConverter.ToUInt32(Data, 0x00);
set => BitConverter.GetBytes(value).CopyTo(Data, 0x00);
}
public override int Species { get => BitConverter.ToUInt16(Data, 0x08); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x08); }
public override int HeldItem { get => BitConverter.ToUInt16(Data, 0x0A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0A); }
public override int TID { get => BitConverter.ToUInt16(Data, 0x0C); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0C); }
public override int SID { get => BitConverter.ToUInt16(Data, 0x0E); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0E); }
public override uint EXP { get => BitConverter.ToUInt32(Data, 0x10); set => BitConverter.GetBytes(value).CopyTo(Data, 0x10); }
public override int Ability { get => BitConverter.ToUInt16(Data, 0x14); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x14); }
public override int AbilityNumber { get => Data[0x16] & 7; set => Data[0x16] = (byte)((Data[0x16] & ~7) | (value & 7)); }
public bool Favorite { get => (Data[0x16] & 8) != 0; set => Data[0x16] = (byte)((Data[0x16] & ~8) | ((value ? 1 : 0) << 3)); } // unused, was in LGPE but not in SWSH
public bool CanGigantamax { get => (Data[0x16] & 16) != 0; set => Data[0x16] = (byte)((Data[0x16] & ~16) | (value ? 16 : 0)); }
// 0x17 alignment unused
public override int MarkValue { get => BitConverter.ToUInt16(Data, 0x18); protected set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x18); }
// 0x1A alignment unused
// 0x1B alignment unused
public override uint PID { get => BitConverter.ToUInt32(Data, 0x1C); set => BitConverter.GetBytes(value).CopyTo(Data, 0x1C); }
public override int Nature { get => Data[0x20]; set => Data[0x20] = (byte)value; }
public override int StatNature { get => Data[0x21]; set => Data[0x21] = (byte)value; }
public override bool FatefulEncounter { get => (Data[0x22] & 1) == 1; set => Data[0x22] = (byte)((Data[0x22] & ~0x01) | (value ? 1 : 0)); }
public bool Flag2 { get => (Data[0x22] & 2) == 2; set => Data[0x22] = (byte)((Data[0x22] & ~0x02) | (value ? 2 : 0)); }
public override int Gender { get => (Data[0x22] >> 2) & 0x3; set => Data[0x22] = (byte)((Data[0x22] & 0xF3) | (value << 2)); }
// 0x23 alignment unused
public override ushort Sanity
{
get => BitConverter.ToUInt16(Data, 0x04);
set => BitConverter.GetBytes(value).CopyTo(Data, 0x04);
}
public override ushort Checksum
{
get => BitConverter.ToUInt16(Data, 0x06);
set => BitConverter.GetBytes(value).CopyTo(Data, 0x06);
}
public override int Species
{
get => BitConverter.ToUInt16(Data, 0x08);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x08);
}
public override int HeldItem
{
get => BitConverter.ToUInt16(Data, 0x0A);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0A);
}
public override int TID
{
get => BitConverter.ToUInt16(Data, 0x0C);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0C);
}
public override int SID
{
get => BitConverter.ToUInt16(Data, 0x0E);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0E);
}
public override uint EXP
{
get => BitConverter.ToUInt32(Data, 0x10);
set => BitConverter.GetBytes(value).CopyTo(Data, 0x10);
}
public override int Ability { get => Data[0x14]; set => Data[0x14] = (byte)value; }
public override int AbilityNumber { get => Data[0x15] & 7; set => Data[0x15] = (byte)((Data[0x15] & ~7) | (value & 7)); }
public override int MarkValue { get => BitConverter.ToUInt16(Data, 0x16); protected set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x16); }
public override uint PID
{
get => BitConverter.ToUInt32(Data, 0x18);
set => BitConverter.GetBytes(value).CopyTo(Data, 0x18);
}
public override int Nature { get => Data[0x1C]; set => Data[0x1C] = (byte)value; }
public override bool FatefulEncounter { get => (Data[0x1D] & 1) == 1; set => Data[0x1D] = (byte)((Data[0x1D] & ~0x01) | (value ? 1 : 0)); }
public override int Gender { get => (Data[0x1D] >> 1) & 0x3; set => Data[0x1D] = (byte)((Data[0x1D] & ~0x06) | (value << 1)); }
public override int AltForm { get => Data[0x1D] >> 3; set => Data[0x1D] = (byte)((Data[0x1D] & 0x07) | (value << 3)); }
public override int EV_HP { get => Data[0x1E]; set => Data[0x1E] = (byte)value; }
public override int EV_ATK { get => Data[0x1F]; set => Data[0x1F] = (byte)value; }
public override int EV_DEF { get => Data[0x20]; set => Data[0x20] = (byte)value; }
public override int EV_SPE { get => Data[0x21]; set => Data[0x21] = (byte)value; }
public override int EV_SPA { get => Data[0x22]; set => Data[0x22] = (byte)value; }
public override int EV_SPD { get => Data[0x23]; set => Data[0x23] = (byte)value; }
public int CNT_Cool { get => Data[0x24]; set => Data[0x24] = (byte)value; }
public int CNT_Beauty { get => Data[0x25]; set => Data[0x25] = (byte)value; }
public int CNT_Cute { get => Data[0x26]; set => Data[0x26] = (byte)value; }
public int CNT_Smart { get => Data[0x27]; set => Data[0x27] = (byte)value; }
public int CNT_Tough { get => Data[0x28]; set => Data[0x28] = (byte)value; }
public int CNT_Sheen { get => Data[0x29]; set => Data[0x29] = (byte)value; }
public byte ResortEventStatus { get => Data[0x2A]; set => Data[0x2A] = value; }
private byte PKRS { get => Data[0x2B]; set => Data[0x2B] = value; }
public override int AltForm { get => BitConverter.ToUInt16(Data, 0x24); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x24); }
public override int EV_HP { get => Data[0x26]; set => Data[0x26] = (byte)value; }
public override int EV_ATK { get => Data[0x27]; set => Data[0x27] = (byte)value; }
public override int EV_DEF { get => Data[0x28]; set => Data[0x28] = (byte)value; }
public override int EV_SPE { get => Data[0x29]; set => Data[0x29] = (byte)value; }
public override int EV_SPA { get => Data[0x2A]; set => Data[0x2A] = (byte)value; }
public override int EV_SPD { get => Data[0x2B]; set => Data[0x2B] = (byte)value; }
public int CNT_Cool { get => Data[0x2C]; set => Data[0x2C] = (byte)value; }
public int CNT_Beauty { get => Data[0x2D]; set => Data[0x2D] = (byte)value; }
public int CNT_Cute { get => Data[0x2E]; set => Data[0x2E] = (byte)value; }
public int CNT_Smart { get => Data[0x2F]; set => Data[0x2F] = (byte)value; }
public int CNT_Tough { get => Data[0x30]; set => Data[0x30] = (byte)value; }
public int CNT_Sheen { get => Data[0x31]; set => Data[0x31] = (byte)value; }
private byte PKRS { get => Data[0x32]; set => Data[0x32] = value; }
public override int PKRS_Days { get => PKRS & 0xF; set => PKRS = (byte)((PKRS & ~0xF) | value); }
public override int PKRS_Strain { get => PKRS >> 4; set => PKRS = (byte)((PKRS & 0xF) | value << 4); }
private byte ST1 { get => Data[0x2C]; set => Data[0x2C] = value; }
public bool Unused0 { get => (ST1 & (1 << 0)) == 1 << 0; set => ST1 = (byte)((ST1 & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool Unused1 { get => (ST1 & (1 << 1)) == 1 << 1; set => ST1 = (byte)((ST1 & ~(1 << 1)) | (value ? 1 << 1 : 0)); }
public bool SuperTrain1_SPA { get => (ST1 & (1 << 2)) == 1 << 2; set => ST1 = (byte)((ST1 & ~(1 << 2)) | (value ? 1 << 2 : 0)); }
public bool SuperTrain1_HP { get => (ST1 & (1 << 3)) == 1 << 3; set => ST1 = (byte)((ST1 & ~(1 << 3)) | (value ? 1 << 3 : 0)); }
public bool SuperTrain1_ATK { get => (ST1 & (1 << 4)) == 1 << 4; set => ST1 = (byte)((ST1 & ~(1 << 4)) | (value ? 1 << 4 : 0)); }
public bool SuperTrain1_SPD { get => (ST1 & (1 << 5)) == 1 << 5; set => ST1 = (byte)((ST1 & ~(1 << 5)) | (value ? 1 << 5 : 0)); }
public bool SuperTrain1_SPE { get => (ST1 & (1 << 6)) == 1 << 6; set => ST1 = (byte)((ST1 & ~(1 << 6)) | (value ? 1 << 6 : 0)); }
public bool SuperTrain1_DEF { get => (ST1 & (1 << 7)) == 1 << 7; set => ST1 = (byte)((ST1 & ~(1 << 7)) | (value ? 1 << 7 : 0)); }
private byte ST2 { get => Data[0x2D]; set => Data[0x2D] = value; }
public bool SuperTrain2_SPA { get => (ST2 & (1 << 0)) == 1 << 0; set => ST2 = (byte)((ST2 & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool SuperTrain2_HP { get => (ST2 & (1 << 1)) == 1 << 1; set => ST2 = (byte)((ST2 & ~(1 << 1)) | (value ? 1 << 1 : 0)); }
public bool SuperTrain2_ATK { get => (ST2 & (1 << 2)) == 1 << 2; set => ST2 = (byte)((ST2 & ~(1 << 2)) | (value ? 1 << 2 : 0)); }
public bool SuperTrain2_SPD { get => (ST2 & (1 << 3)) == 1 << 3; set => ST2 = (byte)((ST2 & ~(1 << 3)) | (value ? 1 << 3 : 0)); }
public bool SuperTrain2_SPE { get => (ST2 & (1 << 4)) == 1 << 4; set => ST2 = (byte)((ST2 & ~(1 << 4)) | (value ? 1 << 4 : 0)); }
public bool SuperTrain2_DEF { get => (ST2 & (1 << 5)) == 1 << 5; set => ST2 = (byte)((ST2 & ~(1 << 5)) | (value ? 1 << 5 : 0)); }
public bool SuperTrain3_SPA { get => (ST2 & (1 << 6)) == 1 << 6; set => ST2 = (byte)((ST2 & ~(1 << 6)) | (value ? 1 << 6 : 0)); }
public bool SuperTrain3_HP { get => (ST2 & (1 << 7)) == 1 << 7; set => ST2 = (byte)((ST2 & ~(1 << 7)) | (value ? 1 << 7 : 0)); }
private byte ST3 { get => Data[0x2E]; set => Data[0x2E] = value; }
public bool SuperTrain3_ATK { get => (ST3 & (1 << 0)) == 1 << 0; set => ST3 = (byte)((ST3 & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool SuperTrain3_SPD { get => (ST3 & (1 << 1)) == 1 << 1; set => ST3 = (byte)((ST3 & ~(1 << 1)) | (value ? 1 << 1 : 0)); }
public bool SuperTrain3_SPE { get => (ST3 & (1 << 2)) == 1 << 2; set => ST3 = (byte)((ST3 & ~(1 << 2)) | (value ? 1 << 2 : 0)); }
public bool SuperTrain3_DEF { get => (ST3 & (1 << 3)) == 1 << 3; set => ST3 = (byte)((ST3 & ~(1 << 3)) | (value ? 1 << 3 : 0)); }
public bool SuperTrain4_1 { get => (ST3 & (1 << 4)) == 1 << 4; set => ST3 = (byte)((ST3 & ~(1 << 4)) | (value ? 1 << 4 : 0)); }
public bool SuperTrain5_1 { get => (ST3 & (1 << 5)) == 1 << 5; set => ST3 = (byte)((ST3 & ~(1 << 5)) | (value ? 1 << 5 : 0)); }
public bool SuperTrain5_2 { get => (ST3 & (1 << 6)) == 1 << 6; set => ST3 = (byte)((ST3 & ~(1 << 6)) | (value ? 1 << 6 : 0)); }
public bool SuperTrain5_3 { get => (ST3 & (1 << 7)) == 1 << 7; set => ST3 = (byte)((ST3 & ~(1 << 7)) | (value ? 1 << 7 : 0)); }
private byte ST4 { get => Data[0x2F]; set => Data[0x2F] = value; }
public bool SuperTrain5_4 { get => (ST4 & (1 << 0)) == 1 << 0; set => ST4 = (byte)((ST4 & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool SuperTrain6_1 { get => (ST4 & (1 << 1)) == 1 << 1; set => ST4 = (byte)((ST4 & ~(1 << 1)) | (value ? 1 << 1 : 0)); }
public bool SuperTrain6_2 { get => (ST4 & (1 << 2)) == 1 << 2; set => ST4 = (byte)((ST4 & ~(1 << 2)) | (value ? 1 << 2 : 0)); }
public bool SuperTrain6_3 { get => (ST4 & (1 << 3)) == 1 << 3; set => ST4 = (byte)((ST4 & ~(1 << 3)) | (value ? 1 << 3 : 0)); }
public bool SuperTrain7_1 { get => (ST4 & (1 << 4)) == 1 << 4; set => ST4 = (byte)((ST4 & ~(1 << 4)) | (value ? 1 << 4 : 0)); }
public bool SuperTrain7_2 { get => (ST4 & (1 << 5)) == 1 << 5; set => ST4 = (byte)((ST4 & ~(1 << 5)) | (value ? 1 << 5 : 0)); }
public bool SuperTrain7_3 { get => (ST4 & (1 << 6)) == 1 << 6; set => ST4 = (byte)((ST4 & ~(1 << 6)) | (value ? 1 << 6 : 0)); }
public bool SuperTrain8_1 { get => (ST4 & (1 << 7)) == 1 << 7; set => ST4 = (byte)((ST4 & ~(1 << 7)) | (value ? 1 << 7 : 0)); }
public uint SuperTrainBitFlags { get => BitConverter.ToUInt32(Data, 0x2C); set => BitConverter.GetBytes(value).CopyTo(Data); }
private byte RIB0 { get => Data[0x30]; set => Data[0x30] = value; } // Ribbons are read as uints, but let's keep them per byte.
private byte RIB1 { get => Data[0x31]; set => Data[0x31] = value; }
private byte RIB2 { get => Data[0x32]; set => Data[0x32] = value; }
private byte RIB3 { get => Data[0x33]; set => Data[0x33] = value; }
private byte RIB4 { get => Data[0x34]; set => Data[0x34] = value; }
private byte RIB5 { get => Data[0x35]; set => Data[0x35] = value; }
private byte RIB6 { get => Data[0x36]; set => Data[0x36] = value; }
//private byte RIB7 { get => Data[0x37]; set => Data[0x37] = value; } // Unused
public bool RibbonChampionKalos { get => (RIB0 & (1 << 0)) == 1 << 0; set => RIB0 = (byte)((RIB0 & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool RibbonChampionG3Hoenn { get => (RIB0 & (1 << 1)) == 1 << 1; set => RIB0 = (byte)((RIB0 & ~(1 << 1)) | (value ? 1 << 1 : 0)); }
public bool RibbonChampionSinnoh { get => (RIB0 & (1 << 2)) == 1 << 2; set => RIB0 = (byte)((RIB0 & ~(1 << 2)) | (value ? 1 << 2 : 0)); }
public bool RibbonBestFriends { get => (RIB0 & (1 << 3)) == 1 << 3; set => RIB0 = (byte)((RIB0 & ~(1 << 3)) | (value ? 1 << 3 : 0)); }
public bool RibbonTraining { get => (RIB0 & (1 << 4)) == 1 << 4; set => RIB0 = (byte)((RIB0 & ~(1 << 4)) | (value ? 1 << 4 : 0)); }
public bool RibbonBattlerSkillful { get => (RIB0 & (1 << 5)) == 1 << 5; set => RIB0 = (byte)((RIB0 & ~(1 << 5)) | (value ? 1 << 5 : 0)); }
public bool RibbonBattlerExpert { get => (RIB0 & (1 << 6)) == 1 << 6; set => RIB0 = (byte)((RIB0 & ~(1 << 6)) | (value ? 1 << 6 : 0)); }
public bool RibbonEffort { get => (RIB0 & (1 << 7)) == 1 << 7; set => RIB0 = (byte)((RIB0 & ~(1 << 7)) | (value ? 1 << 7 : 0)); }
public bool RibbonAlert { get => (RIB1 & (1 << 0)) == 1 << 0; set => RIB1 = (byte)((RIB1 & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool RibbonShock { get => (RIB1 & (1 << 1)) == 1 << 1; set => RIB1 = (byte)((RIB1 & ~(1 << 1)) | (value ? 1 << 1 : 0)); }
public bool RibbonDowncast { get => (RIB1 & (1 << 2)) == 1 << 2; set => RIB1 = (byte)((RIB1 & ~(1 << 2)) | (value ? 1 << 2 : 0)); }
public bool RibbonCareless { get => (RIB1 & (1 << 3)) == 1 << 3; set => RIB1 = (byte)((RIB1 & ~(1 << 3)) | (value ? 1 << 3 : 0)); }
public bool RibbonRelax { get => (RIB1 & (1 << 4)) == 1 << 4; set => RIB1 = (byte)((RIB1 & ~(1 << 4)) | (value ? 1 << 4 : 0)); }
public bool RibbonSnooze { get => (RIB1 & (1 << 5)) == 1 << 5; set => RIB1 = (byte)((RIB1 & ~(1 << 5)) | (value ? 1 << 5 : 0)); }
public bool RibbonSmile { get => (RIB1 & (1 << 6)) == 1 << 6; set => RIB1 = (byte)((RIB1 & ~(1 << 6)) | (value ? 1 << 6 : 0)); }
public bool RibbonGorgeous { get => (RIB1 & (1 << 7)) == 1 << 7; set => RIB1 = (byte)((RIB1 & ~(1 << 7)) | (value ? 1 << 7 : 0)); }
public bool RibbonRoyal { get => (RIB2 & (1 << 0)) == 1 << 0; set => RIB2 = (byte)((RIB2 & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool RibbonGorgeousRoyal { get => (RIB2 & (1 << 1)) == 1 << 1; set => RIB2 = (byte)((RIB2 & ~(1 << 1)) | (value ? 1 << 1 : 0)); }
public bool RibbonArtist { get => (RIB2 & (1 << 2)) == 1 << 2; set => RIB2 = (byte)((RIB2 & ~(1 << 2)) | (value ? 1 << 2 : 0)); }
public bool RibbonFootprint { get => (RIB2 & (1 << 3)) == 1 << 3; set => RIB2 = (byte)((RIB2 & ~(1 << 3)) | (value ? 1 << 3 : 0)); }
public bool RibbonRecord { get => (RIB2 & (1 << 4)) == 1 << 4; set => RIB2 = (byte)((RIB2 & ~(1 << 4)) | (value ? 1 << 4 : 0)); }
public bool RibbonLegend { get => (RIB2 & (1 << 5)) == 1 << 5; set => RIB2 = (byte)((RIB2 & ~(1 << 5)) | (value ? 1 << 5 : 0)); }
public bool RibbonCountry { get => (RIB2 & (1 << 6)) == 1 << 6; set => RIB2 = (byte)((RIB2 & ~(1 << 6)) | (value ? 1 << 6 : 0)); }
public bool RibbonNational { get => (RIB2 & (1 << 7)) == 1 << 7; set => RIB2 = (byte)((RIB2 & ~(1 << 7)) | (value ? 1 << 7 : 0)); }
public bool RibbonEarth { get => (RIB3 & (1 << 0)) == 1 << 0; set => RIB3 = (byte)((RIB3 & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool RibbonWorld { get => (RIB3 & (1 << 1)) == 1 << 1; set => RIB3 = (byte)((RIB3 & ~(1 << 1)) | (value ? 1 << 1 : 0)); }
public bool RibbonClassic { get => (RIB3 & (1 << 2)) == 1 << 2; set => RIB3 = (byte)((RIB3 & ~(1 << 2)) | (value ? 1 << 2 : 0)); }
public bool RibbonPremier { get => (RIB3 & (1 << 3)) == 1 << 3; set => RIB3 = (byte)((RIB3 & ~(1 << 3)) | (value ? 1 << 3 : 0)); }
public bool RibbonEvent { get => (RIB3 & (1 << 4)) == 1 << 4; set => RIB3 = (byte)((RIB3 & ~(1 << 4)) | (value ? 1 << 4 : 0)); }
public bool RibbonBirthday { get => (RIB3 & (1 << 5)) == 1 << 5; set => RIB3 = (byte)((RIB3 & ~(1 << 5)) | (value ? 1 << 5 : 0)); }
public bool RibbonSpecial { get => (RIB3 & (1 << 6)) == 1 << 6; set => RIB3 = (byte)((RIB3 & ~(1 << 6)) | (value ? 1 << 6 : 0)); }
public bool RibbonSouvenir { get => (RIB3 & (1 << 7)) == 1 << 7; set => RIB3 = (byte)((RIB3 & ~(1 << 7)) | (value ? 1 << 7 : 0)); }
public bool RibbonWishing { get => (RIB4 & (1 << 0)) == 1 << 0; set => RIB4 = (byte)((RIB4 & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool RibbonChampionBattle { get => (RIB4 & (1 << 1)) == 1 << 1; set => RIB4 = (byte)((RIB4 & ~(1 << 1)) | (value ? 1 << 1 : 0)); }
public bool RibbonChampionRegional { get => (RIB4 & (1 << 2)) == 1 << 2; set => RIB4 = (byte)((RIB4 & ~(1 << 2)) | (value ? 1 << 2 : 0)); }
public bool RibbonChampionNational { get => (RIB4 & (1 << 3)) == 1 << 3; set => RIB4 = (byte)((RIB4 & ~(1 << 3)) | (value ? 1 << 3 : 0)); }
public bool RibbonChampionWorld { get => (RIB4 & (1 << 4)) == 1 << 4; set => RIB4 = (byte)((RIB4 & ~(1 << 4)) | (value ? 1 << 4 : 0)); }
public bool RIB4_5 { get => (RIB4 & (1 << 5)) == 1 << 5; set => RIB4 = (byte)((RIB4 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused
public bool RIB4_6 { get => (RIB4 & (1 << 6)) == 1 << 6; set => RIB4 = (byte)((RIB4 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused
public bool RibbonChampionG6Hoenn { get => (RIB4 & (1 << 7)) == 1 << 7; set => RIB4 = (byte)((RIB4 & ~(1 << 7)) | (value ? 1 << 7 : 0)); }
public bool RibbonContestStar { get => (RIB5 & (1 << 0)) == 1 << 0; set => RIB5 = (byte)((RIB5 & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool RibbonMasterCoolness { get => (RIB5 & (1 << 1)) == 1 << 1; set => RIB5 = (byte)((RIB5 & ~(1 << 1)) | (value ? 1 << 1 : 0)); }
public bool RibbonMasterBeauty { get => (RIB5 & (1 << 2)) == 1 << 2; set => RIB5 = (byte)((RIB5 & ~(1 << 2)) | (value ? 1 << 2 : 0)); }
public bool RibbonMasterCuteness { get => (RIB5 & (1 << 3)) == 1 << 3; set => RIB5 = (byte)((RIB5 & ~(1 << 3)) | (value ? 1 << 3 : 0)); }
public bool RibbonMasterCleverness { get => (RIB5 & (1 << 4)) == 1 << 4; set => RIB5 = (byte)((RIB5 & ~(1 << 4)) | (value ? 1 << 4 : 0)); }
public bool RibbonMasterToughness { get => (RIB5 & (1 << 5)) == 1 << 5; set => RIB5 = (byte)((RIB5 & ~(1 << 5)) | (value ? 1 << 5 : 0)); }
public bool RibbonChampionAlola { get => (RIB5 & (1 << 6)) == 1 << 6; set => RIB5 = (byte)((RIB5 & ~(1 << 6)) | (value ? 1 << 6 : 0)); }
public bool RibbonBattleRoyale { get => (RIB5 & (1 << 7)) == 1 << 7; set => RIB5 = (byte)((RIB5 & ~(1 << 7)) | (value ? 1 << 7 : 0)); }
public bool RibbonBattleTreeGreat { get => (RIB6 & (1 << 0)) == 1 << 0; set => RIB6 = (byte)((RIB6 & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool RibbonBattleTreeMaster { get => (RIB6 & (1 << 1)) == 1 << 1; set => RIB6 = (byte)((RIB6 & ~(1 << 1)) | (value ? 1 << 1 : 0)); }
public bool RIB6_2 { get => (RIB6 & (1 << 2)) == 1 << 2; set => RIB6 = (byte)((RIB6 & ~(1 << 2)) | (value ? 1 << 2 : 0)); } // Unused
public bool RIB6_3 { get => (RIB6 & (1 << 3)) == 1 << 3; set => RIB6 = (byte)((RIB6 & ~(1 << 3)) | (value ? 1 << 3 : 0)); } // Unused
public bool RIB6_4 { get => (RIB6 & (1 << 4)) == 1 << 4; set => RIB6 = (byte)((RIB6 & ~(1 << 4)) | (value ? 1 << 4 : 0)); } // Unused
public bool RIB6_5 { get => (RIB6 & (1 << 5)) == 1 << 5; set => RIB6 = (byte)((RIB6 & ~(1 << 5)) | (value ? 1 << 5 : 0)); } // Unused
public bool RIB6_6 { get => (RIB6 & (1 << 6)) == 1 << 6; set => RIB6 = (byte)((RIB6 & ~(1 << 6)) | (value ? 1 << 6 : 0)); } // Unused
public bool RIB6_7 { get => (RIB6 & (1 << 7)) == 1 << 7; set => RIB6 = (byte)((RIB6 & ~(1 << 7)) | (value ? 1 << 7 : 0)); } // Unused
public int RibbonCountMemoryContest { get => Data[0x38]; set => Data[0x38] = (byte)value; }
public int RibbonCountMemoryBattle { get => Data[0x39]; set => Data[0x39] = (byte)value; }
private ushort DistByte { get => BitConverter.ToUInt16(Data, 0x3A); set => BitConverter.GetBytes(value).CopyTo(Data, 0x3A); }
public bool DistSuperTrain1 { get => (DistByte & (1 << 0)) == 1 << 0; set => DistByte = (byte)((DistByte & ~(1 << 0)) | (value ? 1 << 0 : 0)); }
public bool DistSuperTrain2 { get => (DistByte & (1 << 1)) == 1 << 1; set => DistByte = (byte)((DistByte & ~(1 << 1)) | (value ? 1 << 1 : 0)); }
public bool DistSuperTrain3 { get => (DistByte & (1 << 2)) == 1 << 2; set => DistByte = (byte)((DistByte & ~(1 << 2)) | (value ? 1 << 2 : 0)); }
public bool DistSuperTrain4 { get => (DistByte & (1 << 3)) == 1 << 3; set => DistByte = (byte)((DistByte & ~(1 << 3)) | (value ? 1 << 3 : 0)); }
public bool DistSuperTrain5 { get => (DistByte & (1 << 4)) == 1 << 4; set => DistByte = (byte)((DistByte & ~(1 << 4)) | (value ? 1 << 4 : 0)); }
public bool DistSuperTrain6 { get => (DistByte & (1 << 5)) == 1 << 5; set => DistByte = (byte)((DistByte & ~(1 << 5)) | (value ? 1 << 5 : 0)); }
public bool Dist7 { get => (DistByte & (1 << 6)) == 1 << 6; set => DistByte = (byte)((DistByte & ~(1 << 6)) | (value ? 1 << 6 : 0)); }
public bool Dist8 { get => (DistByte & (1 << 7)) == 1 << 7; set => DistByte = (byte)((DistByte & ~(1 << 7)) | (value ? 1 << 7 : 0)); }
public uint FormDuration { get => BitConverter.ToUInt32(Data, 0x3C); set => BitConverter.GetBytes(value).CopyTo(Data, 0x3C); }
// 0x33 unused padding
// ribbon u32
public bool RibbonChampionKalos { get => FlagUtil.GetFlag(Data, 0x34, 0); set => FlagUtil.SetFlag(Data, 0x34, 0, value); }
public bool RibbonChampionG3Hoenn { get => FlagUtil.GetFlag(Data, 0x34, 1); set => FlagUtil.SetFlag(Data, 0x34, 1, value); }
public bool RibbonChampionSinnoh { get => FlagUtil.GetFlag(Data, 0x34, 2); set => FlagUtil.SetFlag(Data, 0x34, 2, value); }
public bool RibbonBestFriends { get => FlagUtil.GetFlag(Data, 0x34, 3); set => FlagUtil.SetFlag(Data, 0x34, 3, value); }
public bool RibbonTraining { get => FlagUtil.GetFlag(Data, 0x34, 4); set => FlagUtil.SetFlag(Data, 0x34, 4, value); }
public bool RibbonBattlerSkillful { get => FlagUtil.GetFlag(Data, 0x34, 5); set => FlagUtil.SetFlag(Data, 0x34, 5, value); }
public bool RibbonBattlerExpert { get => FlagUtil.GetFlag(Data, 0x34, 6); set => FlagUtil.SetFlag(Data, 0x34, 6, value); }
public bool RibbonEffort { get => FlagUtil.GetFlag(Data, 0x34, 7); set => FlagUtil.SetFlag(Data, 0x34, 7, value); }
public bool RibbonAlert { get => FlagUtil.GetFlag(Data, 0x35, 0); set => FlagUtil.SetFlag(Data, 0x35, 0, value); }
public bool RibbonShock { get => FlagUtil.GetFlag(Data, 0x35, 1); set => FlagUtil.SetFlag(Data, 0x35, 1, value); }
public bool RibbonDowncast { get => FlagUtil.GetFlag(Data, 0x35, 2); set => FlagUtil.SetFlag(Data, 0x35, 2, value); }
public bool RibbonCareless { get => FlagUtil.GetFlag(Data, 0x35, 3); set => FlagUtil.SetFlag(Data, 0x35, 3, value); }
public bool RibbonRelax { get => FlagUtil.GetFlag(Data, 0x35, 4); set => FlagUtil.SetFlag(Data, 0x35, 4, value); }
public bool RibbonSnooze { get => FlagUtil.GetFlag(Data, 0x35, 5); set => FlagUtil.SetFlag(Data, 0x35, 5, value); }
public bool RibbonSmile { get => FlagUtil.GetFlag(Data, 0x35, 6); set => FlagUtil.SetFlag(Data, 0x35, 6, value); }
public bool RibbonGorgeous { get => FlagUtil.GetFlag(Data, 0x35, 7); set => FlagUtil.SetFlag(Data, 0x35, 7, value); }
public bool RibbonRoyal { get => FlagUtil.GetFlag(Data, 0x36, 0); set => FlagUtil.SetFlag(Data, 0x36, 0, value); }
public bool RibbonGorgeousRoyal { get => FlagUtil.GetFlag(Data, 0x36, 1); set => FlagUtil.SetFlag(Data, 0x36, 1, value); }
public bool RibbonArtist { get => FlagUtil.GetFlag(Data, 0x36, 2); set => FlagUtil.SetFlag(Data, 0x36, 2, value); }
public bool RibbonFootprint { get => FlagUtil.GetFlag(Data, 0x36, 3); set => FlagUtil.SetFlag(Data, 0x36, 3, value); }
public bool RibbonRecord { get => FlagUtil.GetFlag(Data, 0x36, 4); set => FlagUtil.SetFlag(Data, 0x36, 4, value); }
public bool RibbonLegend { get => FlagUtil.GetFlag(Data, 0x36, 5); set => FlagUtil.SetFlag(Data, 0x36, 5, value); }
public bool RibbonCountry { get => FlagUtil.GetFlag(Data, 0x36, 6); set => FlagUtil.SetFlag(Data, 0x36, 6, value); }
public bool RibbonNational { get => FlagUtil.GetFlag(Data, 0x36, 7); set => FlagUtil.SetFlag(Data, 0x36, 7, value); }
public bool RibbonEarth { get => FlagUtil.GetFlag(Data, 0x37, 0); set => FlagUtil.SetFlag(Data, 0x37, 0, value); }
public bool RibbonWorld { get => FlagUtil.GetFlag(Data, 0x37, 1); set => FlagUtil.SetFlag(Data, 0x37, 1, value); }
public bool RibbonClassic { get => FlagUtil.GetFlag(Data, 0x37, 2); set => FlagUtil.SetFlag(Data, 0x37, 2, value); }
public bool RibbonPremier { get => FlagUtil.GetFlag(Data, 0x37, 3); set => FlagUtil.SetFlag(Data, 0x37, 3, value); }
public bool RibbonEvent { get => FlagUtil.GetFlag(Data, 0x37, 4); set => FlagUtil.SetFlag(Data, 0x37, 4, value); }
public bool RibbonBirthday { get => FlagUtil.GetFlag(Data, 0x37, 5); set => FlagUtil.SetFlag(Data, 0x37, 5, value); }
public bool RibbonSpecial { get => FlagUtil.GetFlag(Data, 0x37, 6); set => FlagUtil.SetFlag(Data, 0x37, 6, value); }
public bool RibbonSouvenir { get => FlagUtil.GetFlag(Data, 0x37, 7); set => FlagUtil.SetFlag(Data, 0x37, 7, value); }
// ribbon u32
public bool RibbonWishing { get => FlagUtil.GetFlag(Data, 0x38, 0); set => FlagUtil.SetFlag(Data, 0x38, 0, value); }
public bool RibbonChampionBattle { get => FlagUtil.GetFlag(Data, 0x38, 1); set => FlagUtil.SetFlag(Data, 0x38, 1, value); }
public bool RibbonChampionRegional { get => FlagUtil.GetFlag(Data, 0x38, 2); set => FlagUtil.SetFlag(Data, 0x38, 2, value); }
public bool RibbonChampionNational { get => FlagUtil.GetFlag(Data, 0x38, 3); set => FlagUtil.SetFlag(Data, 0x38, 3, value); }
public bool RibbonChampionWorld { get => FlagUtil.GetFlag(Data, 0x38, 4); set => FlagUtil.SetFlag(Data, 0x38, 4, value); }
public bool HasContestMemoryRibbon { get => FlagUtil.GetFlag(Data, 0x38, 5); set => FlagUtil.SetFlag(Data, 0x38, 5, value); }
public bool HasBattleMemoryRibbon { get => FlagUtil.GetFlag(Data, 0x38, 6); set => FlagUtil.SetFlag(Data, 0x38, 6, value); }
public bool RibbonChampionG6Hoenn { get => FlagUtil.GetFlag(Data, 0x38, 7); set => FlagUtil.SetFlag(Data, 0x38, 7, value); }
public bool RibbonContestStar { get => FlagUtil.GetFlag(Data, 0x39, 0); set => FlagUtil.SetFlag(Data, 0x39, 0, value); }
public bool RibbonMasterCoolness { get => FlagUtil.GetFlag(Data, 0x39, 1); set => FlagUtil.SetFlag(Data, 0x39, 1, value); }
public bool RibbonMasterBeauty { get => FlagUtil.GetFlag(Data, 0x39, 2); set => FlagUtil.SetFlag(Data, 0x39, 2, value); }
public bool RibbonMasterCuteness { get => FlagUtil.GetFlag(Data, 0x39, 3); set => FlagUtil.SetFlag(Data, 0x39, 3, value); }
public bool RibbonMasterCleverness { get => FlagUtil.GetFlag(Data, 0x39, 4); set => FlagUtil.SetFlag(Data, 0x39, 4, value); }
public bool RibbonMasterToughness { get => FlagUtil.GetFlag(Data, 0x39, 5); set => FlagUtil.SetFlag(Data, 0x39, 5, value); }
public bool RibbonChampionAlola { get => FlagUtil.GetFlag(Data, 0x39, 6); set => FlagUtil.SetFlag(Data, 0x39, 6, value); }
public bool RibbonBattleRoyale { get => FlagUtil.GetFlag(Data, 0x39, 7); set => FlagUtil.SetFlag(Data, 0x39, 7, value); }
public bool RibbonBattleTreeGreat { get => FlagUtil.GetFlag(Data, 0x3A, 0); set => FlagUtil.SetFlag(Data, 0x3A, 0, value); }
public bool RibbonBattleTreeMaster { get => FlagUtil.GetFlag(Data, 0x3A, 1); set => FlagUtil.SetFlag(Data, 0x3A, 1, value); }
public bool RibbonChampionGalar { get => FlagUtil.GetFlag(Data, 0x3A, 2); set => FlagUtil.SetFlag(Data, 0x3A, 2, value); }
public bool RibbonTowerMaster { get => FlagUtil.GetFlag(Data, 0x3A, 3); set => FlagUtil.SetFlag(Data, 0x3A, 3, value); }
public bool RibbonMasterRank { get => FlagUtil.GetFlag(Data, 0x3A, 4); set => FlagUtil.SetFlag(Data, 0x3A, 4, value); }
public bool RibbonMarkLunchtime { get => FlagUtil.GetFlag(Data, 0x3A, 5); set => FlagUtil.SetFlag(Data, 0x3A, 5, value); }
public bool RibbonMarkSleepyTime { get => FlagUtil.GetFlag(Data, 0x3A, 6); set => FlagUtil.SetFlag(Data, 0x3A, 6, value); }
public bool RibbonMarkDusk { get => FlagUtil.GetFlag(Data, 0x3A, 7); set => FlagUtil.SetFlag(Data, 0x3A, 7, value); }
public bool RibbonMarkDawn { get => FlagUtil.GetFlag(Data, 0x3B, 0); set => FlagUtil.SetFlag(Data, 0x3B, 0, value); }
public bool RibbonMarkCloudy { get => FlagUtil.GetFlag(Data, 0x3B, 1); set => FlagUtil.SetFlag(Data, 0x3B, 1, value); }
public bool RibbonMarkRainy { get => FlagUtil.GetFlag(Data, 0x3B, 2); set => FlagUtil.SetFlag(Data, 0x3B, 2, value); }
public bool RibbonMarkStormy { get => FlagUtil.GetFlag(Data, 0x3B, 3); set => FlagUtil.SetFlag(Data, 0x3B, 3, value); }
public bool RibbonMarkSnowy { get => FlagUtil.GetFlag(Data, 0x3B, 4); set => FlagUtil.SetFlag(Data, 0x3B, 4, value); }
public bool RibbonMarkBlizzard { get => FlagUtil.GetFlag(Data, 0x3B, 5); set => FlagUtil.SetFlag(Data, 0x3B, 5, value); }
public bool RibbonMarkDry { get => FlagUtil.GetFlag(Data, 0x3B, 6); set => FlagUtil.SetFlag(Data, 0x3B, 6, value); }
public bool RibbonMarkSandstorm { get => FlagUtil.GetFlag(Data, 0x3B, 7); set => FlagUtil.SetFlag(Data, 0x3B, 7, value); }
public int RibbonCountMemoryContest { get => Data[0x3C]; set => HasContestMemoryRibbon = (Data[0x3C] = (byte)value) != 0; }
public int RibbonCountMemoryBattle { get => Data[0x3D]; set => HasBattleMemoryRibbon = (Data[0x3D] = (byte)value) != 0; }
// 0x3E padding
// 0x3F padding
// 0x40 Ribbon 1
public bool RibbonMarkMisty { get => FlagUtil.GetFlag(Data, 0x40, 0); set => FlagUtil.SetFlag(Data, 0x40, 0, value); }
public bool RibbonMarkDestiny { get => FlagUtil.GetFlag(Data, 0x40, 1); set => FlagUtil.SetFlag(Data, 0x40, 1, value); }
public bool RibbonMarkFishing { get => FlagUtil.GetFlag(Data, 0x40, 2); set => FlagUtil.SetFlag(Data, 0x40, 2, value); }
public bool RibbonMarkCurry { get => FlagUtil.GetFlag(Data, 0x40, 3); set => FlagUtil.SetFlag(Data, 0x40, 3, value); }
public bool RibbonMarkUncommon { get => FlagUtil.GetFlag(Data, 0x40, 4); set => FlagUtil.SetFlag(Data, 0x40, 4, value); }
public bool RibbonMarkRare { get => FlagUtil.GetFlag(Data, 0x40, 5); set => FlagUtil.SetFlag(Data, 0x40, 5, value); }
public bool RibbonMarkRowdy { get => FlagUtil.GetFlag(Data, 0x40, 6); set => FlagUtil.SetFlag(Data, 0x40, 6, value); }
public bool RibbonMarkAbsentMinded { get => FlagUtil.GetFlag(Data, 0x40, 7); set => FlagUtil.SetFlag(Data, 0x40, 7, value); }
public bool RibbonMarkJittery { get => FlagUtil.GetFlag(Data, 0x41, 0); set => FlagUtil.SetFlag(Data, 0x41, 0, value); }
public bool RibbonMarkExcited { get => FlagUtil.GetFlag(Data, 0x41, 1); set => FlagUtil.SetFlag(Data, 0x41, 1, value); }
public bool RibbonMarkCharismatic { get => FlagUtil.GetFlag(Data, 0x41, 2); set => FlagUtil.SetFlag(Data, 0x41, 2, value); }
public bool RibbonMarkCalmness { get => FlagUtil.GetFlag(Data, 0x41, 3); set => FlagUtil.SetFlag(Data, 0x41, 3, value); }
public bool RibbonMarkIntense { get => FlagUtil.GetFlag(Data, 0x41, 4); set => FlagUtil.SetFlag(Data, 0x41, 4, value); }
public bool RibbonMarkZonedOut { get => FlagUtil.GetFlag(Data, 0x41, 5); set => FlagUtil.SetFlag(Data, 0x41, 5, value); }
public bool RibbonMarkJoyful { get => FlagUtil.GetFlag(Data, 0x41, 6); set => FlagUtil.SetFlag(Data, 0x41, 6, value); }
public bool RibbonMarkAngry { get => FlagUtil.GetFlag(Data, 0x41, 7); set => FlagUtil.SetFlag(Data, 0x41, 7, value); }
public bool RibbonMarkSmiley { get => FlagUtil.GetFlag(Data, 0x41, 0); set => FlagUtil.SetFlag(Data, 0x41, 0, value); }
public bool RibbonMarkTeary { get => FlagUtil.GetFlag(Data, 0x42, 1); set => FlagUtil.SetFlag(Data, 0x42, 1, value); }
public bool RibbonMarkUpbeat { get => FlagUtil.GetFlag(Data, 0x42, 2); set => FlagUtil.SetFlag(Data, 0x42, 2, value); }
public bool RibbonMarkPeeved { get => FlagUtil.GetFlag(Data, 0x42, 3); set => FlagUtil.SetFlag(Data, 0x42, 3, value); }
public bool RibbonMarkIntellectual { get => FlagUtil.GetFlag(Data, 0x42, 4); set => FlagUtil.SetFlag(Data, 0x42, 4, value); }
public bool RibbonMarkFerocious { get => FlagUtil.GetFlag(Data, 0x42, 5); set => FlagUtil.SetFlag(Data, 0x42, 5, value); }
public bool RibbonMarkCrafty { get => FlagUtil.GetFlag(Data, 0x42, 6); set => FlagUtil.SetFlag(Data, 0x42, 6, value); }
public bool RibbonMarkScowling { get => FlagUtil.GetFlag(Data, 0x42, 7); set => FlagUtil.SetFlag(Data, 0x42, 7, value); }
public bool RibbonMarkKindly { get => FlagUtil.GetFlag(Data, 0x43, 0); set => FlagUtil.SetFlag(Data, 0x43, 0, value); }
public bool RibbonMarkFlustered { get => FlagUtil.GetFlag(Data, 0x43, 1); set => FlagUtil.SetFlag(Data, 0x43, 1, value); }
public bool RibbonMarkPumpedUp { get => FlagUtil.GetFlag(Data, 0x43, 2); set => FlagUtil.SetFlag(Data, 0x43, 2, value); }
public bool RibbonMarkZeroEnergy { get => FlagUtil.GetFlag(Data, 0x43, 3); set => FlagUtil.SetFlag(Data, 0x43, 3, value); }
public bool RibbonMarkPrideful { get => FlagUtil.GetFlag(Data, 0x43, 4); set => FlagUtil.SetFlag(Data, 0x43, 4, value); }
public bool RibbonMarkUnsure { get => FlagUtil.GetFlag(Data, 0x43, 5); set => FlagUtil.SetFlag(Data, 0x43, 5, value); }
public bool RibbonMarkHumble { get => FlagUtil.GetFlag(Data, 0x43, 6); set => FlagUtil.SetFlag(Data, 0x43, 6, value); }
public bool RibbonMarkThorny { get => FlagUtil.GetFlag(Data, 0x43, 7); set => FlagUtil.SetFlag(Data, 0x43, 7, value); }
// 0x44 Ribbon 2
public bool RibbonMarkVigor { get => FlagUtil.GetFlag(Data, 0x44, 0); set => FlagUtil.SetFlag(Data, 0x44, 0, value); }
public bool RibbonMarkSlump { get => FlagUtil.GetFlag(Data, 0x44, 1); set => FlagUtil.SetFlag(Data, 0x44, 1, value); }
public bool RIB44_2 { get => FlagUtil.GetFlag(Data, 0x44, 2); set => FlagUtil.SetFlag(Data, 0x44, 2, value); }
public bool RIB44_3 { get => FlagUtil.GetFlag(Data, 0x44, 3); set => FlagUtil.SetFlag(Data, 0x44, 3, value); }
public bool RIB44_4 { get => FlagUtil.GetFlag(Data, 0x44, 4); set => FlagUtil.SetFlag(Data, 0x44, 4, value); }
public bool RIB44_5 { get => FlagUtil.GetFlag(Data, 0x44, 5); set => FlagUtil.SetFlag(Data, 0x44, 5, value); }
public bool RIB44_6 { get => FlagUtil.GetFlag(Data, 0x44, 6); set => FlagUtil.SetFlag(Data, 0x44, 6, value); }
public bool RIB44_7 { get => FlagUtil.GetFlag(Data, 0x44, 7); set => FlagUtil.SetFlag(Data, 0x44, 7, value); }
public bool RIB45_0 { get => FlagUtil.GetFlag(Data, 0x45, 0); set => FlagUtil.SetFlag(Data, 0x45, 0, value); }
public bool RIB45_1 { get => FlagUtil.GetFlag(Data, 0x45, 1); set => FlagUtil.SetFlag(Data, 0x45, 1, value); }
public bool RIB45_2 { get => FlagUtil.GetFlag(Data, 0x45, 2); set => FlagUtil.SetFlag(Data, 0x45, 2, value); }
public bool RIB45_3 { get => FlagUtil.GetFlag(Data, 0x45, 3); set => FlagUtil.SetFlag(Data, 0x45, 3, value); }
public bool RIB45_4 { get => FlagUtil.GetFlag(Data, 0x45, 4); set => FlagUtil.SetFlag(Data, 0x45, 4, value); }
public bool RIB45_5 { get => FlagUtil.GetFlag(Data, 0x45, 5); set => FlagUtil.SetFlag(Data, 0x45, 5, value); }
public bool RIB45_6 { get => FlagUtil.GetFlag(Data, 0x45, 6); set => FlagUtil.SetFlag(Data, 0x45, 6, value); }
public bool RIB45_7 { get => FlagUtil.GetFlag(Data, 0x45, 7); set => FlagUtil.SetFlag(Data, 0x45, 7, value); }
public bool RIB46_0 { get => FlagUtil.GetFlag(Data, 0x41, 0); set => FlagUtil.SetFlag(Data, 0x41, 0, value); }
public bool RIB46_1 { get => FlagUtil.GetFlag(Data, 0x46, 1); set => FlagUtil.SetFlag(Data, 0x46, 1, value); }
public bool RIB46_2 { get => FlagUtil.GetFlag(Data, 0x46, 2); set => FlagUtil.SetFlag(Data, 0x46, 2, value); }
public bool RIB46_3 { get => FlagUtil.GetFlag(Data, 0x46, 3); set => FlagUtil.SetFlag(Data, 0x46, 3, value); }
public bool RIB46_4 { get => FlagUtil.GetFlag(Data, 0x46, 4); set => FlagUtil.SetFlag(Data, 0x46, 4, value); }
public bool RIB46_5 { get => FlagUtil.GetFlag(Data, 0x46, 5); set => FlagUtil.SetFlag(Data, 0x46, 5, value); }
public bool RIB46_6 { get => FlagUtil.GetFlag(Data, 0x46, 6); set => FlagUtil.SetFlag(Data, 0x46, 6, value); }
public bool RIB46_7 { get => FlagUtil.GetFlag(Data, 0x46, 7); set => FlagUtil.SetFlag(Data, 0x46, 7, value); }
public bool RIB47_0 { get => FlagUtil.GetFlag(Data, 0x47, 0); set => FlagUtil.SetFlag(Data, 0x47, 0, value); }
public bool RIB47_1 { get => FlagUtil.GetFlag(Data, 0x47, 1); set => FlagUtil.SetFlag(Data, 0x47, 1, value); }
public bool RIB47_2 { get => FlagUtil.GetFlag(Data, 0x47, 2); set => FlagUtil.SetFlag(Data, 0x47, 2, value); }
public bool RIB47_3 { get => FlagUtil.GetFlag(Data, 0x47, 3); set => FlagUtil.SetFlag(Data, 0x47, 3, value); }
public bool RIB47_4 { get => FlagUtil.GetFlag(Data, 0x47, 4); set => FlagUtil.SetFlag(Data, 0x47, 4, value); }
public bool RIB47_5 { get => FlagUtil.GetFlag(Data, 0x47, 5); set => FlagUtil.SetFlag(Data, 0x47, 5, value); }
public bool RIB47_6 { get => FlagUtil.GetFlag(Data, 0x47, 6); set => FlagUtil.SetFlag(Data, 0x47, 6, value); }
public bool RIB47_7 { get => FlagUtil.GetFlag(Data, 0x47, 7); set => FlagUtil.SetFlag(Data, 0x47, 7, value); }
public uint U48 { get => BitConverter.ToUInt32(Data, 0x48); set => BitConverter.GetBytes(value).CopyTo(Data, 0x48); }
public byte GetFromArrayA1(int index)
{
if ((uint)index >= 4)
throw new ArgumentException(nameof(index));
return Data[0x4C + index];
}
public void SetFromArrayA1(int index, byte value)
{
if ((uint)index >= 4)
throw new ArgumentException(nameof(index));
Data[0x4C + index] = value;
}
public int HeightScalar { get => Data[0x50]; set => Data[0x50] = (byte)value; }
public int WeightScalar { get => Data[0x51]; set => Data[0x51] = (byte)value; }
public byte GetFromArrayA2(int index)
{
if ((uint)index >= 6)
throw new ArgumentException(nameof(index));
return Data[0x52 + index];
}
public void SetFromArrayA2(int index, byte value)
{
if ((uint)index >= 6)
throw new ArgumentException(nameof(index));
Data[0x52 + index] = value;
}
#endregion
#region Block B
public override string Nickname
{
get => GetString(0x40, 24);
set
{
if (!IsNicknamed)
{
int lang = SpeciesName.GetSpeciesNameLanguage(Species, Language, value, 8);
if (lang == (int)LanguageID.ChineseS || lang == (int)LanguageID.ChineseT)
{
StringConverter.SetString7(value, 12, lang, chinese: true).CopyTo(Data, 0x40);
return;
}
}
SetString(value, 12).CopyTo(Data, 0x40);
}
get => GetString(0x58, 24);
set => SetString(value, 12).CopyTo(Data, 0x58);
}
public override int Move1
{
get => BitConverter.ToUInt16(Data, 0x5A);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x5A);
}
// 2 bytes for \0, automatically handled above
public override int Move2
{
get => BitConverter.ToUInt16(Data, 0x5C);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x5C);
}
public override int Move1 { get => BitConverter.ToUInt16(Data, 0x72); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x72); }
public override int Move2 { get => BitConverter.ToUInt16(Data, 0x74); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x74); }
public override int Move3 { get => BitConverter.ToUInt16(Data, 0x76); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x76); }
public override int Move4 { get => BitConverter.ToUInt16(Data, 0x78); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x78); }
public override int Move3
{
get => BitConverter.ToUInt16(Data, 0x5E);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x5E);
}
public override int Move1_PP { get => Data[0x7A]; set => Data[0x7A] = (byte)value; }
public override int Move2_PP { get => Data[0x7B]; set => Data[0x7B] = (byte)value; }
public override int Move3_PP { get => Data[0x7C]; set => Data[0x7C] = (byte)value; }
public override int Move4_PP { get => Data[0x7D]; set => Data[0x7D] = (byte)value; }
public override int Move1_PPUps { get => Data[0x7E]; set => Data[0x7E] = (byte)value; }
public override int Move2_PPUps { get => Data[0x7F]; set => Data[0x7F] = (byte)value; }
public override int Move3_PPUps { get => Data[0x80]; set => Data[0x80] = (byte)value; }
public override int Move4_PPUps { get => Data[0x81]; set => Data[0x81] = (byte)value; }
public override int Move4
{
get => BitConverter.ToUInt16(Data, 0x60);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x60);
}
public override int RelearnMove1 { get => BitConverter.ToUInt16(Data, 0x82); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x82); }
public override int RelearnMove2 { get => BitConverter.ToUInt16(Data, 0x84); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x84); }
public override int RelearnMove3 { get => BitConverter.ToUInt16(Data, 0x86); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x86); }
public override int RelearnMove4 { get => BitConverter.ToUInt16(Data, 0x88); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x88); }
public override int Move1_PP { get => Data[0x62]; set => Data[0x62] = (byte)value; }
public override int Move2_PP { get => Data[0x63]; set => Data[0x63] = (byte)value; }
public override int Move3_PP { get => Data[0x64]; set => Data[0x64] = (byte)value; }
public override int Move4_PP { get => Data[0x65]; set => Data[0x65] = (byte)value; }
public override int Move1_PPUps { get => Data[0x66]; set => Data[0x66] = (byte)value; }
public override int Move2_PPUps { get => Data[0x67]; set => Data[0x67] = (byte)value; }
public override int Move3_PPUps { get => Data[0x68]; set => Data[0x68] = (byte)value; }
public override int Move4_PPUps { get => Data[0x69]; set => Data[0x69] = (byte)value; }
public override int Stat_HPCurrent { get => BitConverter.ToUInt16(Data, 0x8A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x8A); }
public override int RelearnMove1
{
get => BitConverter.ToUInt16(Data, 0x6A);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x6A);
}
public override int RelearnMove2
{
get => BitConverter.ToUInt16(Data, 0x6C);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x6C);
}
public override int RelearnMove3
{
get => BitConverter.ToUInt16(Data, 0x6E);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x6E);
}
public override int RelearnMove4
{
get => BitConverter.ToUInt16(Data, 0x70);
set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x70);
}
public bool SecretSuperTrainingUnlocked { get => (Data[0x72] & 1) == 1; set => Data[0x72] = (byte)((Data[0x72] & ~1) | (value ? 1 : 0)); }
public bool SecretSuperTrainingComplete { get => (Data[0x72] & 2) == 2; set => Data[0x72] = (byte)((Data[0x72] & ~2) | (value ? 2 : 0)); }
public byte _0x73 { get => Data[0x73]; set => Data[0x73] = value; }
private uint IV32 { get => BitConverter.ToUInt32(Data, 0x74); set => BitConverter.GetBytes(value).CopyTo(Data, 0x74); }
private uint IV32 { get => BitConverter.ToUInt32(Data, 0x8C); set => BitConverter.GetBytes(value).CopyTo(Data, 0x8C); }
public override int IV_HP { get => (int)(IV32 >> 00) & 0x1F; set => IV32 = (IV32 & ~(0x1Fu << 00)) | ((value > 31 ? 31u : (uint)value) << 00); }
public override int IV_ATK { get => (int)(IV32 >> 05) & 0x1F; set => IV32 = (IV32 & ~(0x1Fu << 05)) | ((value > 31 ? 31u : (uint)value) << 05); }
public override int IV_DEF { get => (int)(IV32 >> 10) & 0x1F; set => IV32 = (IV32 & ~(0x1Fu << 10)) | ((value > 31 ? 31u : (uint)value) << 10); }
@ -312,89 +417,164 @@ namespace PKHeX.Core
public override int IV_SPD { get => (int)(IV32 >> 25) & 0x1F; set => IV32 = (IV32 & ~(0x1Fu << 25)) | ((value > 31 ? 31u : (uint)value) << 25); }
public override bool IsEgg { get => ((IV32 >> 30) & 1) == 1; set => IV32 = (IV32 & ~0x40000000u) | (value ? 0x40000000u : 0u); }
public override bool IsNicknamed { get => ((IV32 >> 31) & 1) == 1; set => IV32 = (IV32 & 0x7FFFFFFFu) | (value ? 0x80000000u : 0u); }
public byte DynamaxLevel { get => Data[0x90]; set => Data[0x90] = value; }
public byte GetFromArrayB1(int index)
{
if ((uint)index >= 3)
throw new ArgumentException(nameof(index));
return Data[0x90 + index];
}
public void SetFromArrayB1(int index, byte value)
{
if ((uint)index >= 3)
throw new ArgumentException(nameof(index));
Data[0x90 + index] = value;
}
public override int Status_Condition { get => BitConverter.ToInt32(Data, 0x94); set => BitConverter.GetBytes(value).CopyTo(Data, 0x94); }
public int Unk98 { get => BitConverter.ToInt32(Data, 0x98); set => BitConverter.GetBytes(value).CopyTo(Data, 0x98); }
public byte GetFromArrayB2(int index)
{
if ((uint)index >= 14)
throw new ArgumentException(nameof(index));
return Data[0x9C + index];
}
public void SetFromArrayB2(int index, byte value)
{
if ((uint)index >= 14)
throw new ArgumentException(nameof(index));
Data[0x9C + index] = value;
}
#endregion
#region Block C
public override string HT_Name { get => GetString(0x78, 24); set => SetString(value, 12).CopyTo(Data, 0x78); }
public override int HT_Gender { get => Data[0x92]; set => Data[0x92] = (byte)value; }
public override int CurrentHandler { get => Data[0x93]; set => Data[0x93] = (byte)value; }
public int Geo1_Region { get => Data[0x94]; set => Data[0x94] = (byte)value; }
public int Geo1_Country { get => Data[0x95]; set => Data[0x95] = (byte)value; }
public int Geo2_Region { get => Data[0x96]; set => Data[0x96] = (byte)value; }
public int Geo2_Country { get => Data[0x97]; set => Data[0x97] = (byte)value; }
public int Geo3_Region { get => Data[0x98]; set => Data[0x98] = (byte)value; }
public int Geo3_Country { get => Data[0x99]; set => Data[0x99] = (byte)value; }
public int Geo4_Region { get => Data[0x9A]; set => Data[0x9A] = (byte)value; }
public int Geo4_Country { get => Data[0x9B]; set => Data[0x9B] = (byte)value; }
public int Geo5_Region { get => Data[0x9C]; set => Data[0x9C] = (byte)value; }
public int Geo5_Country { get => Data[0x9D]; set => Data[0x9D] = (byte)value; }
public byte _0x9E { get => Data[0x9E]; set => Data[0x9E] = value; }
public byte _0x9F { get => Data[0x9F]; set => Data[0x9F] = value; }
public byte _0xA0 { get => Data[0xA0]; set => Data[0xA0] = value; }
public byte _0xA1 { get => Data[0xA1]; set => Data[0xA1] = value; }
public override int HT_Friendship { get => Data[0xA2]; set => Data[0xA2] = (byte)value; }
public override int HT_Affection { get => Data[0xA3]; set => Data[0xA3] = (byte)value; }
public override int HT_Intensity { get => Data[0xA4]; set => Data[0xA4] = (byte)value; }
public override int HT_Memory { get => Data[0xA5]; set => Data[0xA5] = (byte)value; }
public override int HT_Feeling { get => Data[0xA6]; set => Data[0xA6] = (byte)value; }
public byte _0xA7 { get => Data[0xA7]; set => Data[0xA7] = value; }
public override int HT_TextVar { get => BitConverter.ToUInt16(Data, 0xA8); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0xA8); }
public byte _0xAA { get => Data[0xAA]; set => Data[0xAA] = value; }
public byte _0xAB { get => Data[0xAB]; set => Data[0xAB] = value; }
public byte _0xAC { get => Data[0xAC]; set => Data[0xAC] = value; }
public byte _0xAD { get => Data[0xAD]; set => Data[0xAD] = value; }
public override byte Fullness { get => Data[0xAE]; set => Data[0xAE] = value; }
public override byte Enjoyment { get => Data[0xAF]; set => Data[0xAF] = value; }
public override string HT_Name { get => GetString(0xA8, 24); set => SetString(value, 12).CopyTo(Data, 0xA8); }
public override int HT_Gender { get => Data[0xC2]; set => Data[0xC2] = (byte)value; }
public int HT_Language { get => Data[0xC3]; set => Data[0xC3] = (byte)value; }
public override int CurrentHandler { get => Data[0xC4]; set => Data[0xC4] = (byte)value; }
// 0xC5 unused (alignment)
public int HT_TrainerID { get => BitConverter.ToUInt16(Data, 0xC6); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0xC6); } // unused?
public override int HT_Friendship { get => Data[0xC8]; set => Data[0xC8] = (byte)value; }
public override int HT_Intensity { get => Data[0xC9]; set => Data[0xC9] = (byte)value; }
public override int HT_Memory { get => Data[0xCA]; set => Data[0xCA] = (byte)value; }
public override int HT_Feeling { get => Data[0xCB]; set => Data[0xCB] = (byte)value; }
public override int HT_TextVar { get => BitConverter.ToUInt16(Data, 0xCC); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0xCC); }
public byte GetFromArrayC1(int index)
{
if ((uint)index >= 14)
throw new ArgumentException(nameof(index));
return Data[0xCE + index];
}
public void SetFromArrayC1(int index, byte value)
{
if ((uint)index >= 14)
throw new ArgumentException(nameof(index));
Data[0xCE + index] = value;
}
public override byte Fullness { get => Data[0xDC]; set => Data[0xDC] = value; }
public override byte Enjoyment { get => Data[0xDD]; set => Data[0xDD] = value; }
public override int Version { get => Data[0xDE]; set => Data[0xDE] = (byte)value; }
public override int Country { get => Data[0xDF]; set => Data[0xDF] = (byte)value; }
public override int Region { get => Data[0xE0]; set => Data[0xE0] = (byte)value; }
public override int ConsoleRegion { get => Data[0xE1]; set => Data[0xE1] = (byte)value; }
public override int Language { get => Data[0xE2]; set => Data[0xE2] = (byte)value; }
public int UnkE3 { get => Data[0xE3]; set => Data[0xE3] = (byte)value; }
public uint FormDuration { get => BitConverter.ToUInt32(Data, 0xE4); set => BitConverter.GetBytes(value).CopyTo(Data, 0xE4); }
public sbyte AffixedRibbon { get => (sbyte)Data[0xE8]; set => Data[0xE8] = (byte)value; } // selected ribbon
public byte GetFromArrayC2(int index)
{
if ((uint)index >= 15)
throw new ArgumentException(nameof(index));
return Data[0xE9 + index];
}
public void SetFromArrayC2(int index, byte value)
{
if ((uint)index >= 15)
throw new ArgumentException(nameof(index));
Data[0xE9 + index] = value;
}
#endregion
#region Block D
public override string OT_Name { get => GetString(0xB0, 24); set => SetString(value, 12).CopyTo(Data, 0xB0); }
public override int OT_Friendship { get => Data[0xCA]; set => Data[0xCA] = (byte)value; }
public override int OT_Affection { get => Data[0xCB]; set => Data[0xCB] = (byte)value; }
public override int OT_Intensity { get => Data[0xCC]; set => Data[0xCC] = (byte)value; }
public override int OT_Memory { get => Data[0xCD]; set => Data[0xCD] = (byte)value; }
public override int OT_TextVar { get => BitConverter.ToUInt16(Data, 0xCE); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0xCE); }
public override int OT_Feeling { get => Data[0xD0]; set => Data[0xD0] = (byte)value; }
public override int Egg_Year { get => Data[0xD1]; set => Data[0xD1] = (byte)value; }
public override int Egg_Month { get => Data[0xD2]; set => Data[0xD2] = (byte)value; }
public override int Egg_Day { get => Data[0xD3]; set => Data[0xD3] = (byte)value; }
public override int Met_Year { get => Data[0xD4]; set => Data[0xD4] = (byte)value; }
public override int Met_Month { get => Data[0xD5]; set => Data[0xD5] = (byte)value; }
public override int Met_Day { get => Data[0xD6]; set => Data[0xD6] = (byte)value; }
public byte _0xD7 { get => Data[0xD7]; set => Data[0xD7] = value; }
public override int Egg_Location { get => BitConverter.ToUInt16(Data, 0xD8); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0xD8); }
public override int Met_Location { get => BitConverter.ToUInt16(Data, 0xDA); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0xDA); }
public override int Ball { get => Data[0xDC]; set => Data[0xDC] = (byte)value; }
public override int Met_Level { get => Data[0xDD] & ~0x80; set => Data[0xDD] = (byte)((Data[0xDD] & 0x80) | value); }
public override int OT_Gender { get => Data[0xDD] >> 7; set => Data[0xDD] = (byte)((Data[0xDD] & ~0x80) | (value << 7)); }
public int HyperTrainFlags { get => Data[0xDE]; set => Data[0xDE] = (byte)value; }
public override string OT_Name { get => GetString(0xF8, 24); set => SetString(value, 12).CopyTo(Data, 0xF8); }
public override int OT_Friendship { get => Data[0x112]; set => Data[0x112] = (byte)value; }
public override int OT_Intensity { get => Data[0x113]; set => Data[0x113] = (byte)value; }
public override int OT_Memory { get => Data[0x114]; set => Data[0x114] = (byte)value; }
// 0x115 unused align
public override int OT_TextVar { get => BitConverter.ToUInt16(Data, 0x116); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x116); }
public override int OT_Feeling { get => Data[0x118]; set => Data[0x118] = (byte)value; }
public override int Egg_Year { get => Data[0x119]; set => Data[0x119] = (byte)value; }
public override int Egg_Month { get => Data[0x11A]; set => Data[0x11A] = (byte)value; }
public override int Egg_Day { get => Data[0x11B]; set => Data[0x11B] = (byte)value; }
public override int Met_Year { get => Data[0x11C]; set => Data[0x11C] = (byte)value; }
public override int Met_Month { get => Data[0x11D]; set => Data[0x11D] = (byte)value; }
public override int Met_Day { get => Data[0x11E]; set => Data[0x11E] = (byte)value; }
// 0x11F unused align
public override int Egg_Location { get => BitConverter.ToUInt16(Data, 0x120); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x120); }
public override int Met_Location { get => BitConverter.ToUInt16(Data, 0x122); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x122); }
public override int Ball { get => Data[0x124]; set => Data[0x124] = (byte)value; }
public override int Met_Level { get => Data[0x125] & ~0x80; set => Data[0x125] = (byte)((Data[0x125] & 0x80) | value); }
public override int OT_Gender { get => Data[0x125] >> 7; set => Data[0x125] = (byte)((Data[0x125] & ~0x80) | (value << 7)); }
public int HyperTrainFlags { get => Data[0x126]; set => Data[0x126] = (byte)value; }
public bool HT_HP { get => ((HyperTrainFlags >> 0) & 1) == 1; set => HyperTrainFlags = (HyperTrainFlags & ~(1 << 0)) | ((value ? 1 : 0) << 0); }
public bool HT_ATK { get => ((HyperTrainFlags >> 1) & 1) == 1; set => HyperTrainFlags = (HyperTrainFlags & ~(1 << 1)) | ((value ? 1 : 0) << 1); }
public bool HT_DEF { get => ((HyperTrainFlags >> 2) & 1) == 1; set => HyperTrainFlags = (HyperTrainFlags & ~(1 << 2)) | ((value ? 1 : 0) << 2); }
public bool HT_SPA { get => ((HyperTrainFlags >> 3) & 1) == 1; set => HyperTrainFlags = (HyperTrainFlags & ~(1 << 3)) | ((value ? 1 : 0) << 3); }
public bool HT_SPD { get => ((HyperTrainFlags >> 4) & 1) == 1; set => HyperTrainFlags = (HyperTrainFlags & ~(1 << 4)) | ((value ? 1 : 0) << 4); }
public bool HT_SPE { get => ((HyperTrainFlags >> 5) & 1) == 1; set => HyperTrainFlags = (HyperTrainFlags & ~(1 << 5)) | ((value ? 1 : 0) << 5); }
public override int Version { get => Data[0xDF]; set => Data[0xDF] = (byte)value; }
public override int Country { get => Data[0xE0]; set => Data[0xE0] = (byte)value; }
public override int Region { get => Data[0xE1]; set => Data[0xE1] = (byte)value; }
public override int ConsoleRegion { get => Data[0xE2]; set => Data[0xE2] = (byte)value; }
public override int Language { get => Data[0xE3]; set => Data[0xE3] = (byte)value; }
public bool GetMoveRecordFlag(int index)
{
if ((uint) index > 112) // 14 bytes, 8 bits
throw new ArgumentException(nameof(index));
int ofs = index >> 3;
return FlagUtil.GetFlag(Data, 0x127 + ofs, index & 7);
}
public void SetMoveRecordFlag(int index, bool value)
{
if ((uint)index > 112) // 14 bytes, 8 bits
throw new ArgumentException(nameof(index));
int ofs = index >> 3;
FlagUtil.SetFlag(Data, 0x127 + ofs, index & 7, value);
}
public byte GetFromArrayD1(int index)
{
if ((uint)index >= 19)
throw new ArgumentException(nameof(index));
return Data[0x135 + index];
}
public void SetFromArrayD1(int index, byte value)
{
if ((uint)index >= 19)
throw new ArgumentException(nameof(index));
Data[0x135 + index] = value;
}
#endregion
#region Battle Stats
public override int Status_Condition { get => BitConverter.ToInt32(Data, 0xE8); set => BitConverter.GetBytes(value).CopyTo(Data, 0xE8); }
public override int Stat_Level { get => Data[0xEC]; set => Data[0xEC] = (byte)value; }
public byte DirtType { get => Data[0xED]; set => Data[0xED] = value; }
public byte DirtLocation { get => Data[0xEE]; set => Data[0xEE] = value; }
// 0xEF unused
public override int Stat_HPCurrent { get => BitConverter.ToUInt16(Data, 0xF0); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0xF0); }
public override int Stat_HPMax { get => BitConverter.ToUInt16(Data, 0xF2); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0xF2); }
public override int Stat_ATK { get => BitConverter.ToUInt16(Data, 0xF4); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0xF4); }
public override int Stat_DEF { get => BitConverter.ToUInt16(Data, 0xF6); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0xF6); }
public override int Stat_SPE { get => BitConverter.ToUInt16(Data, 0xF8); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0xF8); }
public override int Stat_SPA { get => BitConverter.ToUInt16(Data, 0xFA); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0xFA); }
public override int Stat_SPD { get => BitConverter.ToUInt16(Data, 0xFC); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0xFC); }
public override int Stat_Level { get => Data[0x148]; set => Data[0x148] = (byte)value; }
// 0x149 unused alignment
public override int Stat_HPMax { get => BitConverter.ToUInt16(Data, 0x14A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x14A); }
public override int Stat_ATK { get => BitConverter.ToUInt16(Data, 0x14C); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x14C); }
public override int Stat_DEF { get => BitConverter.ToUInt16(Data, 0x14E); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x14E); }
public override int Stat_SPE { get => BitConverter.ToUInt16(Data, 0x150); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x150); }
public override int Stat_SPA { get => BitConverter.ToUInt16(Data, 0x152); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x152); }
public override int Stat_SPD { get => BitConverter.ToUInt16(Data, 0x154); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x154); }
public int DynamaxType { get => BitConverter.ToUInt16(Data, 0x156); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x156); }
#endregion
public bool IsUntradedEvent6 => Geo1_Country == 0 && Geo1_Region == 0 && Met_Location / 10000 == 4 && Gen6;
public override int[] Markings
{
get
@ -422,7 +602,6 @@ namespace PKHeX.Core
{
HT_Friendship = HT_Affection = HT_TextVar = HT_Memory = HT_Intensity = HT_Feeling =
/* OT_Friendship */ OT_Affection = OT_TextVar = OT_Memory = OT_Intensity = OT_Feeling = 0;
this.ClearGeoLocationData();
// Clear Handler
HT_Name = string.Empty.PadRight(11, '\0');
@ -437,16 +616,13 @@ namespace PKHeX.Core
OT_TextVar = OT_Memory = OT_Intensity = OT_Feeling = 0;
}
this.SanitizeGeoLocationData();
if (GenNumber < 7) // must be transferred via bank, and must have memories
if (GenNumber < 8) // must be transferred via HOME, and must have memories
{
TradeMemory(Bank: true);
// georegions cleared on 6->7, no need to set
TradeMemory();
}
}
protected override bool TradeOT(ITrainerInfo tr)
private bool TradeOT(ITrainerInfo tr)
{
// Check to see if the OT matches the SAV's OT info.
if (!(tr.OT == OT_Name && tr.TID == TID && tr.SID == SID && tr.Gender == OT_Gender))
@ -456,9 +632,9 @@ namespace PKHeX.Core
return true;
}
protected override void TradeHT(ITrainerInfo tr)
private void TradeHT(ITrainerInfo tr)
{
if (tr.OT != HT_Name || tr.Gender != HT_Gender || (Geo1_Country == 0 && Geo1_Region == 0 && !IsUntradedEvent6))
if (tr.OT != HT_Name || tr.Gender != HT_Gender)
{
// No geolocations are set ingame -- except for bank transfers. Don't emulate bank transfers
// this.TradeGeoLocation(tr.Country, tr.SubRegion);
@ -472,13 +648,12 @@ namespace PKHeX.Core
}
CurrentHandler = 1;
HT_Gender = tr.Gender;
HT_Language = tr.Language;
}
// Misc Updates
public override void TradeMemory(bool Bank)
public static void TradeMemory()
{
if (Bank)
base.TradeMemory(true);
}
// Maximums
@ -488,5 +663,17 @@ namespace PKHeX.Core
public override int MaxItemID => Legal.MaxItemID_8;
public override int MaxBallID => Legal.MaxBallID_8;
public override int MaxGameID => Legal.MaxGameID_8;
public bool GetRibbon(int index) => FlagUtil.GetFlag(Data, GetRibbonByte(index), index & 7);
public void SetRibbon(int index, bool value = true) => FlagUtil.SetFlag(Data, GetRibbonByte(index), index & 7, value);
public int GetRibbonByte(int index)
{
if ((uint)index >= 128)
throw new ArgumentOutOfRangeException(nameof(index));
if (index < 64)
return 0x34 + (index >> 3);
return 0x40 + (index >> 3);
}
}
}

View file

@ -7,14 +7,14 @@ namespace PKHeX.Core
/// <summary>
/// Object representing a <see cref="PKM"/>'s data and derived properties.
/// </summary>
public abstract class PKM : ITrainerID, ILangNick, IGameValueLimit
public abstract class PKM : ITrainerID, ILangNick, IGameValueLimit, INature
{
public static readonly string[] Extensions = PKX.GetPKMExtensions();
public abstract int SIZE_PARTY { get; }
public abstract int SIZE_STORED { get; }
public string Extension => GetType().Name.ToLower();
public abstract PersonalInfo PersonalInfo { get; }
public abstract IReadOnlyList<byte> ExtraBytes { get; }
public virtual IReadOnlyList<ushort> ExtraBytes => Array.Empty<ushort>();
// Internal Attributes set on creation
public abstract byte[] Data { get; } // Raw Storage
@ -74,6 +74,7 @@ namespace PKHeX.Core
public abstract int HeldItem { get; set; }
public abstract int Gender { get; set; }
public abstract int Nature { get; set; }
public virtual int StatNature { get => Nature; set => Nature = value; }
public abstract int Ability { get; set; }
public abstract int CurrentFriendship { get; set; }
public abstract int AltForm { get; set; }
@ -320,6 +321,7 @@ namespace PKHeX.Core
protected bool PtHGSS => Pt || HGSS;
public bool VC => VC1 || VC2;
public bool Gen8 => Version >= 44 && Version <= 45;
public bool Gen7 => (Version >= 30 && Version <= 33) || GG;
public bool Gen6 => Version >= 24 && Version <= 29;
public bool Gen5 => Version >= 20 && Version <= 23;
@ -333,6 +335,7 @@ namespace PKHeX.Core
{
get
{
if (Gen8) return 8;
if (Gen7) return 7;
if (Gen6) return 6;
if (Gen5) return 5;
@ -360,7 +363,7 @@ namespace PKHeX.Core
}
public virtual bool ChecksumValid => Checksum == CalculateChecksum();
public int CurrentLevel { get => Experience.GetLevel(EXP, Species, AltForm); set => EXP = Experience.GetEXP(Stat_Level = value, Species, AltForm); }
public int CurrentLevel { get => Experience.GetLevel(EXP, PersonalInfo.EXPGrowth); set => EXP = Experience.GetEXP(Stat_Level = value, PersonalInfo.EXPGrowth); }
public int MarkCircle { get => Markings[0]; set { var marks = Markings; marks[0] = value; Markings = marks; } }
public int MarkTriangle { get => Markings[1]; set { var marks = Markings; marks[1] = value; Markings = marks; } }
public int MarkSquare { get => Markings[2]; set { var marks = Markings; marks[2] = value; Markings = marks; } }
@ -772,7 +775,7 @@ namespace PKHeX.Core
ushort[] stats = this is IHyperTrain t ? GetStats(p, t, level) : GetStats(p, level);
// Account for nature
PKX.ModifyStatsForNature(stats, Nature);
PKX.ModifyStatsForNature(stats, StatNature);
return stats;
}

View file

@ -16,7 +16,7 @@ namespace PKHeX.Core
public override int OTLength => Japanese ? 5 : 7;
public override int NickLength => Japanese ? 5 : 10;
public override IReadOnlyList<byte> ExtraBytes => Array.Empty<byte>();
public override IReadOnlyList<ushort> ExtraBytes => Array.Empty<ushort>();
public override string FileNameWithoutExtension
{

View file

@ -0,0 +1,7 @@
namespace PKHeX.Core
{
public interface IFavorite
{
bool Favorite { get; set; }
}
}

View file

@ -0,0 +1,12 @@
namespace PKHeX.Core
{
public interface IGigantamax
{
bool CanGigantamax { get; set; }
}
public interface IDynamaxLevel
{
byte DynamaxLevel { get; set; }
}
}

View file

@ -0,0 +1,7 @@
namespace PKHeX.Core
{
public interface IHandlerLanguage
{
int HT_Language { get; set; }
}
}

View file

@ -0,0 +1,7 @@
namespace PKHeX.Core
{
public interface INature
{
int Nature { get; set; }
}
}

View file

@ -0,0 +1,8 @@
namespace PKHeX.Core
{
public interface IScaledSize
{
int WeightScalar { get; set; }
int HeightScalar { get; set; }
}
}

View file

@ -0,0 +1,47 @@
namespace PKHeX.Core
{
public enum PokeSize
{
XS,
S,
AV,
L,
XL,
}
public static class PokeSizeExtensions
{
/// <summary>
/// Compares the sizing scalar to different thresholds to determine the size rating.
/// </summary>
/// <param name="scalar">Sizing scalar (0-255)</param>
/// <returns>0-4 rating</returns>
public static PokeSize GetSizeRating(int scalar)
{
if (scalar < 0x10)
return PokeSize.XS; // 1/16 = XS
if (scalar < 0x30u)
return PokeSize.S; // 2/16 = S
if (scalar < 0xD0u)
return PokeSize.AV; // average (10/16)
if (scalar < 0xF0u)
return PokeSize.L; // 2/16 = L
return PokeSize.XL; // 1/16 = XL
}
public static int GetRandomScalar(this PokeSize size)
{
return size switch
{
PokeSize.XS => (Util.Rand.Next(0x10) + 0x00),
PokeSize.S => (Util.Rand.Next(0x20) + 0x10),
PokeSize.AV => (Util.Rand.Next(0xA0) + 0x30),
PokeSize.L => (Util.Rand.Next(0x20) + 0xD0),
PokeSize.XL => (Util.Rand.Next(0x10) + 0xF0),
_ => GetRandomPokeSize() // Official code sums two randoms for triangular distribution.
};
}
public static int GetRandomPokeSize() => Util.Rand.Next(0x80) + Util.Rand.Next(0x81);
}
}

View file

@ -9,12 +9,10 @@
/// Gets the current level of a species.
/// </summary>
/// <param name="exp">Experience points</param>
/// <param name="species">National Dex number of the Pokémon.</param>
/// <param name="forme">AltForm ID (starters in Let's Go)</param>
/// <param name="growth">Experience growth rate</param>
/// <returns>Current level of the species.</returns>
public static int GetLevel(uint exp, int species, int forme = 0)
public static int GetLevel(uint exp, int growth)
{
int growth = PKX.Personal.GetFormeEntry(species, forme).EXPGrowth;
if (exp >= ExpTable[99, growth])
return 100;
int tl = 1; // Initial Level. Iterate upwards to find the level
@ -23,19 +21,6 @@
return tl;
}
/// <summary>
/// Gets the minimum Experience points for the specified level.
/// </summary>
/// <param name="level">Current level</param>
/// <param name="species">National Dex number of the Pokémon.</param>
/// <param name="forme">AltForm ID (starters in Let's Go)</param>
/// <returns>Experience points needed to have specified level.</returns>
public static uint GetEXP(int level, int species, int forme)
{
var growth = PKX.Personal.GetFormeEntry(species, forme).EXPGrowth;
return GetEXP(level, growth);
}
/// <summary>
/// Gets the minimum Experience points for the specified level.
/// </summary>
@ -62,14 +47,12 @@
/// Gets the amount of EXP to be earned until the next level-up occurs.
/// </summary>
/// <param name="level">Current Level</param>
/// <param name="species"><see cref="PKM.Species"/></param>
/// <param name="forme">AltForm ID (starters in Let's Go)</param>
/// <param name="growth">Growth Rate type</param>
/// <returns>Percentage [0,1.00)</returns>
public static uint GetEXPToLevelUp(int level, int species, int forme = 0)
public static uint GetEXPToLevelUp(int level, int growth)
{
if (level >= 100)
return 0;
var growth = PKX.Personal.GetFormeEntry(species, forme).EXPGrowth;
var current = ExpTable[level - 1, growth];
var next = ExpTable[level, growth];
return next - current;
@ -80,14 +63,12 @@
/// </summary>
/// <param name="level">Current Level</param>
/// <param name="exp">Current Experience</param>
/// <param name="species"><see cref="PKM.Species"/></param>
/// <param name="forme">AltForm ID (starters in Let's Go)</param>
/// <param name="growth">Growth Rate type</param>
/// <returns>Percentage [0,1.00)</returns>
public static double GetEXPToLevelUpPercentage(int level, uint exp, int species, int forme = 0)
public static double GetEXPToLevelUpPercentage(int level, uint exp, int growth)
{
if (level >= 100)
return 0;
var growth = PKX.Personal.GetFormeEntry(species, forme).EXPGrowth;
var current = ExpTable[level - 1, growth];
var next = ExpTable[level, growth];
var amount = next - current;

View file

@ -20,14 +20,8 @@ namespace PKHeX.Core
public static string[] GetFormList(int species, IReadOnlyList<string> types, IReadOnlyList<string> forms, IReadOnlyList<string> genders, int generation)
{
// Mega List
if (IsFormListSingleMega(species))
{
return new[]
{
types[000], // Normal
forms[804], // Mega
};
}
if (generation < 8 && IsFormListSingleMega(species))
return GetMegaSingle(types, forms);
if (generation == 7 && Legal.Totem_USUM.Contains(species))
return GetFormsTotem(species, types, forms);
@ -37,15 +31,16 @@ namespace PKHeX.Core
if (species <= Legal.MaxSpeciesID_2)
return GetFormsGen2(species, types, forms, generation);
if (species <= Legal.MaxSpeciesID_3)
return GetFormsGen3(species, types, forms);
return GetFormsGen3(species, types, forms, generation);
if (species <= Legal.MaxSpeciesID_4)
return GetFormsGen4(species, types, forms, generation);
if (species <= Legal.MaxSpeciesID_5)
return GetFormsGen5(species, types, forms);
return GetFormsGen5(species, types, forms, generation);
if (species <= Legal.MaxSpeciesID_6)
return GetFormsGen6(species, types, forms, genders);
//if (species <= Legal.MaxSpeciesID_7)
if (species <= Legal.MaxSpeciesID_7_USUM)
return GetFormsGen7(species, types, forms);
return GetFormsGen8(species, types, forms, genders);
}
private static bool IsGG() => GameVersion.GG.Contains(PKMConverter.Trainer.Game);
@ -95,14 +90,9 @@ namespace PKHeX.Core
{
switch ((Species)species)
{
case Charizard:
case Mewtwo:
return new[]
{
types[000], // Normal
forms[805], // Mega X
forms[806], // Mega Y
};
case Charizard when generation < 8:
case Mewtwo when generation < 8:
return GetMegaXY(types, forms);
case Eevee when IsGG():
return new[]
@ -114,6 +104,13 @@ namespace PKHeX.Core
case Pikachu:
return GetFormsPikachu(generation, types, forms);
case Weezing when generation >= 8:
case Ponyta when generation >= 8:
case Rapidash when generation >= 8:
case MrMime when generation >= 8:
case Farfetchd when generation >= 8:
return GetFormsGalar(types, forms);
default:
return GetFormsAlolan(generation, types, forms, species);
}
@ -123,19 +120,24 @@ namespace PKHeX.Core
{
return species switch
{
(int)Pichu => GetFormsPichu(generation, types, forms),
(int)Pichu when generation == 4 => GetFormsPichu(types, forms),
(int)Unown => GetFormsUnown(generation),
(int)Corsola when generation >= 8 => GetFormsGalar(types, forms),
_ => EMPTY
};
}
private static string[] GetFormsGen3(int species, IReadOnlyList<string> types, IReadOnlyList<string> forms)
private static string[] GetFormsGen3(int species, IReadOnlyList<string> types, IReadOnlyList<string> forms, int generation)
{
switch ((Species)species)
{
default:
return EMPTY;
case Zigzagoon when generation >= 8:
case Linoone when generation >= 8:
return GetFormsGalar(types, forms);
case Castform: // Casftorm
return new[]
{
@ -225,7 +227,7 @@ namespace PKHeX.Core
}
}
private static string[] GetFormsGen5(int species, IReadOnlyList<string> types, IReadOnlyList<string> forms)
private static string[] GetFormsGen5(int species, IReadOnlyList<string> types, IReadOnlyList<string> forms, int generation)
{
switch ((Species)species)
{
@ -239,12 +241,30 @@ namespace PKHeX.Core
forms[942], // Blue
};
case Darumaka when generation >= 8:
return GetFormsGalar(types, forms);
case Darmanitan:
{
if (generation <= 7)
{
return new[]
{
forms[555], // Standard
forms[943], // Zen
};
}
return new[]
{
forms[555], // Standard
forms[943], // Zen
types[0] + " " + forms[555], // Standard
types[0] + " " + forms[943], // Zen
forms[Galarian] + " " + forms[555], // Standard
forms[Galarian] + " " + forms[943], // Zen
};
}
case Yamask when generation >= 8:
return GetFormsGalar(types, forms);
case Deerling:
case Sawsbuck:
@ -256,6 +276,9 @@ namespace PKHeX.Core
forms[949], // Winter
};
case Stunfisk when generation >= 8:
return GetFormsGalar(types, forms);
case Tornadus:
case Thundurus:
case Landorus:
@ -505,6 +528,87 @@ namespace PKHeX.Core
}
}
private static string[] GetFormsGen8(int species, IReadOnlyList<string> types, IReadOnlyList<string> forms, IReadOnlyList<string> genders)
{
switch ((Species)species)
{
default:
return EMPTY;
case Cramorant:
return new[]
{
types[0], // Normal
forms[Gulping],
forms[Gorging],
};
case Toxtricity:
return new[]
{
types[0], // Normal
forms[LowKey],
};
case Indeedee:
return new[]
{
genders[000], // Male
genders[001], // Female
};
case Sinistea:
case Polteageist:
return new[]
{
"Cracked",
"Chipped",
};
case Alcremie:
return new[]
{
forms[RubyCream],
forms[MatchaCream],
forms[MintCream],
forms[LemonCream],
forms[SaltedCream],
forms[RubySwirl],
forms[CaramelSwirl],
forms[RainbowSwirl],
};
case Morpeko:
return new[]
{
types[0], // Normal
forms[HangryMode],
};
case Eiscue:
return new[]
{
types[0], // Normal
forms[NoiceFace],
};
case Zacian:
case Zamazenta:
return new[]
{
types[0], // Normal
forms[Crowned],
};
case Eternatus:
return new[]
{
types[0], // Normal
forms[Eternamax],
};
}
}
private static string[] GetFormsAlolan (int generation, IReadOnlyList<string> types, IReadOnlyList<string> forms, int species)
{
if (generation < 7)
@ -515,6 +619,14 @@ namespace PKHeX.Core
default:
return EMPTY;
case Meowth when generation >= 8:
return new[]
{
types[000],
forms[810], // Alolan
forms[Galarian], // Alolan
};
case Rattata:
case Raichu:
case Sandshrew:
@ -557,8 +669,9 @@ namespace PKHeX.Core
forms[733], // Libre
forms[734], // Cosplay
};
case 7:
var arr = new[]
case 7 when IsGG():
return new[]
{
types[000], // Normal
forms[813], // Original
@ -567,28 +680,33 @@ namespace PKHeX.Core
forms[816], // Unova
forms[817], // Kalos
forms[818], // Alola
forms[1063] // Partner
forms[1063], // Partner
Starter,
};
case 7:
case 8:
return new[]
{
types[000], // Normal
forms[813], // Original
forms[814], // Hoenn
forms[815], // Sinnoh
forms[816], // Unova
forms[817], // Kalos
forms[818], // Alola
forms[1063], // Partner
};
if (!IsGG())
return arr;
System.Array.Resize(ref arr, arr.Length + 1);
arr[arr.Length - 1] = Starter;
return arr;
}
}
private static string[] GetFormsPichu (int generation, IReadOnlyList<string> types, IReadOnlyList<string> forms)
private static string[] GetFormsPichu (IReadOnlyList<string> types, IReadOnlyList<string> forms)
{
if (generation == 4)
return new[]
{
return new[]
{
types[000], // Normal
forms[000], // Spiky
};
}
return EMPTY;
types[000], // Normal
forms[000], // Spiky
};
}
private static string[] GetFormsArceus (int generation, IReadOnlyList<string> types)
@ -757,5 +875,63 @@ namespace PKHeX.Core
(int)Mothim, // (Burmy forme carried over, not cleared)
(int)Scatterbug, (int)Spewpa, // Vivillon pre-evos
};
private static string[] GetMegaSingle(IReadOnlyList<string> types, IReadOnlyList<string> forms)
{
return new[]
{
types[000], // Normal
forms[804], // Mega
};
}
private static string[] GetMegaXY(IReadOnlyList<string> types, IReadOnlyList<string> forms)
{
return new[]
{
types[000], // Normal
forms[805], // Mega X
forms[806], // Mega Y
};
}
private static string[] GetFormsGalar(IReadOnlyList<string> types, IReadOnlyList<string> forms)
{
return new[]
{
types[000], // Normal
forms[Galarian], // Galarian
};
}
private const int Galarian = 1068;
private const int Gigantamax = 1069;
private const int Gulping = 1070;
private const int Gorging = 1071;
private const int LowKey = 1072;
private const int RubyCream = 1073;
private const int MatchaCream = 1074;
private const int MintCream = 1075;
private const int LemonCream = 1076;
private const int SaltedCream = 1077;
private const int RubySwirl = 1078;
private const int CaramelSwirl = 1079;
private const int RainbowSwirl = 1080;
private const int NoiceFace = 1081;
private const int HangryMode = 1082;
private const int Crowned = 1083;
private const int Eternamax = 1084;
private static string[] GetSingleGigantamax(IReadOnlyList<string> types, IReadOnlyList<string> forms)
{
return new[]
{
types[000], // Normal
forms[Gigantamax], // Gigantamax
};
}
}
}

View file

@ -10,7 +10,7 @@ namespace PKHeX.Core
/// </summary>
public static class PKX
{
internal static readonly PersonalTable Personal = PersonalTable.GG;
internal static readonly PersonalTable Personal = PersonalTable.SWSH;
public const int Generation = 7;
internal const int SIZE_1ULIST = 69;
@ -44,8 +44,8 @@ namespace PKHeX.Core
// Gen7 Format is the same size as Gen6.
internal const int SIZE_8STORED = 8 + (4 * SIZE_8BLOCK);
internal const int SIZE_8PARTY = SIZE_8STORED; // todo swsh
internal const int SIZE_8BLOCK = 72; // todo swsh
internal const int SIZE_8PARTY = SIZE_8STORED + 0x10;
internal const int SIZE_8BLOCK = 80;
private static readonly HashSet<int> Sizes = new HashSet<int>
{
@ -549,7 +549,7 @@ namespace PKHeX.Core
pkm = DecryptArray6(pkm);
return;
case 8:
if (BitConverter.ToUInt16(pkm, 4) != 0) // todo swsh: find hint of encrypted data
if (BitConverter.ToUInt16(pkm, 0x70) != 0 && BitConverter.ToUInt16(pkm, 0xC0) != 0)
pkm = DecryptArray8(pkm);
return;
default:

View file

@ -6,7 +6,7 @@ namespace PKHeX.Core
/// <summary> Generation 3 <see cref="PKM"/> format, exclusively for Pokémon XD. </summary>
public sealed class XK3 : G3PKM, IShadowPKM
{
private static readonly byte[] Unused =
private static readonly ushort[] Unused =
{
0x0A, 0x0B, 0x0C, 0x0D, 0x1E, 0x1F,
0x2A, 0x2B,
@ -14,7 +14,7 @@ namespace PKHeX.Core
0x7E, 0x7F
};
public override IReadOnlyList<byte> ExtraBytes => Unused;
public override IReadOnlyList<ushort> ExtraBytes => Unused;
public override int SIZE_PARTY => PKX.SIZE_3XSTORED;
public override int SIZE_STORED => PKX.SIZE_3XSTORED;

View file

@ -5,17 +5,96 @@ namespace PKHeX.Core
/// <summary>
/// <see cref="PersonalInfo"/> class with values from the <see cref="GameVersion.SWSH"/> games.
/// </summary>
public sealed class PersonalInfoSWSH : PersonalInfoSM
public sealed class PersonalInfoSWSH : PersonalInfo
{
public new const int SIZE = PersonalInfoSM.SIZE;
public const int SIZE = 0xA8;
// todo: this is a copy of lgpe class
public PersonalInfoSWSH(byte[] data) : base(data)
{
TMHM = GetBits(Data, 0x28, 8); // only 60 TMs used
TypeTutors = GetBits(Data, 0x38, 1); // at most 8 flags used
TMHM = new bool[200];
for (var i = 0; i < 100; i++)
{
TMHM[i] = FlagUtil.GetFlag(Data, 0x28 + (i >> 3), i);
TMHM[i + 100] = FlagUtil.GetFlag(Data, 0x3C + (i >> 3), i);
}
TypeTutors = Array.Empty<bool>();
}
public int GoSpecies { get => BitConverter.ToUInt16(Data, 0x48); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x48); }
public override byte[] Write()
{
for (var i = 0; i < 100; i++)
{
FlagUtil.SetFlag(Data, 0x28 + (i >> 3), i, TMHM[i]);
FlagUtil.SetFlag(Data, 0x3C + (i >> 3), i, TMHM[i + 100]);
}
return Data;
}
public override int HP { get => Data[0x00]; set => Data[0x00] = (byte)value; }
public override int ATK { get => Data[0x01]; set => Data[0x01] = (byte)value; }
public override int DEF { get => Data[0x02]; set => Data[0x02] = (byte)value; }
public override int SPE { get => Data[0x03]; set => Data[0x03] = (byte)value; }
public override int SPA { get => Data[0x04]; set => Data[0x04] = (byte)value; }
public override int SPD { get => Data[0x05]; set => Data[0x05] = (byte)value; }
public override int Type1 { get => Data[0x06]; set => Data[0x06] = (byte)value; }
public override int Type2 { get => Data[0x07]; set => Data[0x07] = (byte)value; }
public override int CatchRate { get => Data[0x08]; set => Data[0x08] = (byte)value; }
public override int EvoStage { get => Data[0x09]; set => Data[0x09] = (byte)value; }
private int EVYield { get => BitConverter.ToUInt16(Data, 0x0A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0A); }
public override int EV_HP { get => EVYield >> 0 & 0x3; set => EVYield = (EVYield & ~(0x3 << 0)) | (value & 0x3) << 0; }
public override int EV_ATK { get => EVYield >> 2 & 0x3; set => EVYield = (EVYield & ~(0x3 << 2)) | (value & 0x3) << 2; }
public override int EV_DEF { get => EVYield >> 4 & 0x3; set => EVYield = (EVYield & ~(0x3 << 4)) | (value & 0x3) << 4; }
public override int EV_SPE { get => EVYield >> 6 & 0x3; set => EVYield = (EVYield & ~(0x3 << 6)) | (value & 0x3) << 6; }
public override int EV_SPA { get => EVYield >> 8 & 0x3; set => EVYield = (EVYield & ~(0x3 << 8)) | (value & 0x3) << 8; }
public override int EV_SPD { get => EVYield >> 10 & 0x3; set => EVYield = (EVYield & ~(0x3 << 10)) | (value & 0x3) << 10; }
public int Item1 { get => BitConverter.ToInt16(Data, 0x0C); set => BitConverter.GetBytes((short)value).CopyTo(Data, 0x0C); }
public int Item2 { get => BitConverter.ToInt16(Data, 0x0E); set => BitConverter.GetBytes((short)value).CopyTo(Data, 0x0E); }
public int Item3 { get => BitConverter.ToInt16(Data, 0x10); set => BitConverter.GetBytes((short)value).CopyTo(Data, 0x10); }
public override int Gender { get => Data[0x12]; set => Data[0x12] = (byte)value; }
public override int HatchCycles { get => Data[0x13]; set => Data[0x13] = (byte)value; }
public override int BaseFriendship { get => Data[0x14]; set => Data[0x14] = (byte)value; }
public override int EXPGrowth { get => Data[0x15]; set => Data[0x15] = (byte)value; }
public override int EggGroup1 { get => Data[0x16]; set => Data[0x16] = (byte)value; }
public override int EggGroup2 { get => Data[0x17]; set => Data[0x17] = (byte)value; }
public int Ability1 { get => BitConverter.ToUInt16(Data, 0x18); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x18); }
public int Ability2 { get => BitConverter.ToUInt16(Data, 0x1A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x1A); }
public int AbilityH { get => BitConverter.ToUInt16(Data, 0x1C); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x1C); }
public override int EscapeRate { get => 0; set { } } // moved?
protected internal override int FormStatsIndex { get => BitConverter.ToUInt16(Data, 0x1E); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x1E); }
public override int FormeSprite { get => BitConverter.ToUInt16(Data, 0x1E); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x1E); } // ???
public override int FormeCount { get => Data[0x20]; set => Data[0x20] = (byte)value; }
public override int Color { get => Data[0x21] & 0x3F; set => Data[0x21] = (byte)((Data[0x21] & 0xC0) | (value & 0x3F)); }
public bool IsPresentInGame { get => ((Data[0x21] >> 6) & 1) == 1; set => Data[0x21] = (byte)((Data[0x21] & ~0x40) | (value ? 0x40 : 0)); }
public bool SpriteForme { get => ((Data[0x21] >> 7) & 1) == 1; set => Data[0x21] = (byte)((Data[0x21] & ~0x80) | (value ? 0x80 : 0)); }
public override int BaseEXP { get => BitConverter.ToUInt16(Data, 0x22); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x22); }
public override int Height { get => BitConverter.ToUInt16(Data, 0x24); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x24); }
public override int Weight { get => BitConverter.ToUInt16(Data, 0x26); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x26); }
public override int[] Items
{
get => new[] { Item1, Item2, Item3 };
set
{
if (value?.Length != 3) return;
Item1 = value[0];
Item2 = value[1];
Item3 = value[2];
}
}
public override int[] Abilities
{
get => new[] { Ability1, Ability2, AbilityH };
set
{
if (value?.Length != 3) return;
Ability1 = value[0];
Ability2 = value[1];
AbilityH = value[2];
}
}
public int BaseSpecies { get => BitConverter.ToUInt16(Data, 0x4C); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x4C); }
public int PokeDexIndex { get => BitConverter.ToUInt16(Data, 0x5C); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x5C); }
}
}

View file

@ -15,7 +15,7 @@ namespace PKHeX.Core
/// <summary>
/// Personal Table used in <see cref="GameVersion.SWSH"/>.
/// </summary>
public static readonly PersonalTable SWSH = GetTable("gg", GameVersion.SWSH); // todo
public static readonly PersonalTable SWSH = GetTable("swsh", GameVersion.SWSH); // todo
/// <summary>
/// Personal Table used in <see cref="GameVersion.GG"/>.
@ -164,7 +164,7 @@ namespace PKHeX.Core
case GameVersion.SM:
case GameVersion.USUM:
case GameVersion.GG: return PersonalInfoSM.SIZE;
case GameVersion.SWSH: return PersonalInfoSWSH.SIZE; // todo
case GameVersion.SWSH: return PersonalInfoSWSH.SIZE;
default: return -1;
}
@ -175,6 +175,7 @@ namespace PKHeX.Core
FixPersonalTableG1();
PopulateGen3Tutors();
PopulateGen4Tutors();
CopyDexitGenders();
}
private static void FixPersonalTableG1()
@ -207,6 +208,20 @@ namespace PKHeX.Core
HGSS[i].AddTypeTutors(tutors[i]);
}
/// <summary>
/// Sword/Shield do not contain personal data (stubbed) for all species that are not allowed to visit the game.
/// Copy all the genders from <see cref="USUM"/>'s table for all past species, since we need it for <see cref="PKX.Personal"/> gender lookups for all generations.
/// </summary>
private static void CopyDexitGenders()
{
for (int i = 1; i <= 807; i++)
{
var ss = SWSH[i];
if (ss.HP == 0)
ss.Gender = USUM[i].Gender;
}
}
public PersonalTable(byte[] data, GameVersion format)
{
var get = GetConstructor(format);

Binary file not shown.

View file

@ -1 +0,0 @@
todo :^)

Binary file not shown.

View file

@ -34,7 +34,7 @@ Edelmut
Wassertempo
Chlorophyll
Erleuchtung
Fährte
Erfassen
Kraftkoloss
Giftdorn
Konzentrator
@ -58,7 +58,7 @@ Charmebolzen
Plus
Minus
Prognose
Wertehalter
Klebekörper
Expidermis
Adrenalin
Notschutz
@ -140,7 +140,7 @@ Hitzewahn
Reiche Ernte
Telepathie
Gefühlswippe
Wetterfest
Partikelschutz
Giftgriff
Belebekraft
Brustbieter
@ -231,4 +231,29 @@ Gras-Erzeuger
Metallprotektor
Phantomschutz
Prismarüstung
Zerebralmacht
Zerebralmacht
Kühnes Schwert
Wackerer Schild
Libero
Apport
Wollflaum
Schraubflosse
Spiegelrüstung
Würggeschoss
Stahlrückgrat
Dampfantrieb
Punk Rock
Sandspeier
Eisflügelstaub
Heranreifen
Tiefkühlkopf
Kraftquelle
Mimese
Hemmungslos
Stählerner Wille
Unheilskörper
Rastlose Seele
Affenfokus
Reaktionsgas
Pastellhülle
Heißhunger

View file

@ -1065,4 +1065,21 @@ Partner
Abend
Abend
Morgen
Ultra
Ultra
Galar
Gigadynamax
Schlingform
Stopfform
Tief
Ruby
Matcha
Minz
Zitronen
Salz
Ruby
Karamell
Trio
Wohlfühlkopf
Kohldampfmuster
König
Unendynamax

View file

@ -1,6 +1,6 @@
irgendwo
irgendwo
in der ersten Stadt
in [VAR GENDBR(00FF,0506,0000)]dessenderen Zuhause
zu Hause
im Zuhause eines Freundes
in irgendjemandes Zuhause
in einer lebhaften Stadt
@ -28,7 +28,7 @@ in einem Museum
in einem Filmstudio
in einem Bahnhof
an einem Kampfschauplatz
in einem Schönheitssalon
in einem Friseursalon
in einem Restaurant
in einem Edelrestaurant
in einer Küstenstadt
@ -36,7 +36,7 @@ im Inneren eines hohen Gebäudes
in einer geheimnisvollen Stadt
in einer Stadt am Fluss
in einer schneebedeckten Stadt
in der Pokémon Liga
in der Pokémon-Liga
in einem Palast
in einer Höhle
in einem Wald
@ -60,12 +60,21 @@ auf einem Feld
in einer Ruine
auf einer Wasserroute
auf einer Safari
in einer Geheimbasis
auf einem großen Schiff
beim Flug durch die Lüfte
in einer Wettbewerbshalle
an einem geheimnisvollen Ort
auf einer kleinen Insel
auf einem aschebedeckten Weg
in einer Geheimbasis
in der Tiefe des Meeres
an einem wundersamen Ort
auf einem großen Schiff
auf einem aschebedeckten Weg
auf einer kleinen Insel
an einem geheimnisvollen Ort
beim Flug durch die Lüfte
auf einem Weg mit Seeblick
auf einer weiten Grasebene
in einem Stadion
in einem Pokémon-Hort
in einer Mine
in einer Stadt in den Bergen
in einer heruntergekommenen Stadt
in einem Tunnel
an einem gefährlichen Ort

View file

@ -56,11 +56,11 @@ Spezialität
Megablock
Angriffplus
X-Angriff
X-Abwehr
X-Tempo
X-Treffer
X-Spezial
X-Spezial-Vert.
X-Verteidigung
X-Initiative
X-Genauigkeit
X-Sp.-Ang.
X-Sp.-Vert.
Poképuppe
Eneco-Rute
Blaue Flöte
@ -108,7 +108,7 @@ Steinknochen
Leuchtstein
Finsterstein
Funkelstein
Ovalen Stein
Ovaler Stein
Spiritkern
Platinum-Orb
Tee
@ -228,7 +228,7 @@ Abysszahn
Abyssplatte
Rauchball
Ewigstein
Fokus-Band
Fokusband
Glücks-Ei
Scope-Linse
Metallmantel
@ -238,11 +238,11 @@ Kugelblitz
Pudersand
Granitstein
Wundersaat
Schattenglas
Schattenbrille
Schwarzgurt
Magnet
Zauberwasser
Hackattack
Spitzer Schnabel
Giftstich
Ewiges Eis
Bannsticker
@ -251,21 +251,21 @@ Holzkohle
Drachenzahn
Seidenschal
Up-Grade
Seegesang
Muschelglocke
Seerauch
Laxrauch
Lucky Punch
Metallstaub
Kampfknochen
Lauchstange
Roten Schal
Blauen Schal
Roter Schal
Blauer Schal
Rosa Schal
Grünen Schal
Gelben Schal
Grüner Schal
Gelber Schal
Großlinse
Muskelband
Schlauglas
Schlaubrille
Expertengurt
Lichtlehm
Leben-Orb
@ -295,7 +295,7 @@ Machtkette
Machtgewicht
Wechselhülle
Großwurzel
Wahlglas
Wahlbrille
Feuertafel
Wassertafel
Blitztafel
@ -426,7 +426,7 @@ VM05
VM06
???
???
Forschersack
Erkundungs-Set
Beutesack
Regelbuch
Pokéradar
@ -484,12 +484,12 @@ Silberflügel
Buntschwinge
Rätsel-Ei
Aprikoko Rot
Aprikoko Blu
Aprikoko Glb
Aprikoko Grn
Aprikoko Pnk
Aprikoko Wss
Aprikoko Swz
Aprikoko Blau
Aprikoko Gelb
Aprikoko Grün
Aprikoko Pink
Aprikoko Weiß
Aprikoko Schwarz
Turboball
Levelball
Köderball
@ -532,8 +532,8 @@ Datenkarte26
Datenkarte27
Grüne Kugel
Tresorkapsel
Roten Edelstein
Blauen Edelstein
Roter Edelstein
Blauer Edelstein
Mytokristall
Schönschuppe
Evolith
@ -582,33 +582,33 @@ Duftpilz
Riesennugget
Triperle
Kometstück
Alten Heller
Alten Taler
Alten Dukaten
Alter Heller
Alter Taler
Alter Dukat
Alte Vase
Alten Reif
Alter Reif
Alte Statue
Alte Krone
Stratos-Eis
Angriffplus2
X-Tempo2
X-Spezial2
X-Sp.-Vert.2
X-Abwehr2
X-Angriff2
X-Treffer2
X-Tempo3
X-Spezial3
X-Sp.-Vert.3
X-Abwehr3
X-Angriff3
X-Treffer3
X-Tempo6
X-Spezial6
X-Sp.-Vert.6
X-Abwehr6
X-Angriff6
X-Treffer6
X-Initiative 2
X-Sp.-Ang. 2
X-Sp.-Vert. 2
X-Verteidigung 2
X-Angriff 2
X-Genauigkeit 2
X-Initiative 3
X-Sp.-Ang. 3
X-Sp.-Vert. 3
X-Verteidigung 3
X-Angriff 3
X-Genauigkeit 3
X-Initiative 6
X-Sp.-Ang. 6
X-Sp.-Vert. 6
X-Verteidigung 6
X-Angriff 6
X-Genauigkeit 6
Fähigk.-Appell
Itemabwurf
Itemappell
@ -633,7 +633,7 @@ Ovalpin
Schillerpin
Plasmakarte
Schnäuztuch
Achromaten
Achromat
Fundsache
Fundsache
Wahrspiegel
@ -695,8 +695,8 @@ TM99
TM100
Kraftwerks-Pass
Mega-Ring
Kuriosen Stein
Normalen Stein
Kurioser Stein
Normaler Stein
Rabattmarke
Liftschlüssel
TMV-Pass
@ -726,7 +726,7 @@ Pokériegel-Set
Brief an Troy
Äon-Ticket
Scanner
Wüstenglas
Wüstenbrille
Meteorit
R1-Schlüssel
R2-Schlüssel
@ -851,10 +851,10 @@ Eisstein
PokéMobil-Funk
Ultraball
Maxi-Malasada
Roten Nektar
Gelben Nektar
Roter Nektar
Gelber Nektar
Rosa Nektar
Purpurnen Nektar
Purpurner Nektar
Sonnenflöte
Mondflöte
???
@ -1055,4 +1055,525 @@ Dratini-Bonbon
Mewtu-Bonbon
Mew-Bonbon
Meltan-Bonbon
Magmar-Bonbon
Magmar-Bonbon
???
???
???
???
???
???
???
???
???
???
???
???
???
???
???
???
Empfehlungsbrief
Pokémon-Box
Wunschstern
Dynamax-Band
???
???
Angel
Rotom-Rad
???
???
Würstchen
Pauls Feinkost
Bachs Feinkost
Dosenbohnen
Toastbrot
Spaghetti
Pilzmix
Röstrute
Dicker Lauch
Luxusapfel
Feine Knochen
Kartoffeln
Uferkraut
Gemüse
Frittiertes
Gekochtes Ei
Camping-Set
???
???
Rostiges Schwert
Rostiger Schild
Vogelfossil
Fischfossil
Drachenfossil
Paddelfossil
Zucker-Erdbeere
Zucker-Herz
Zucker-Beere
Zucker-Kleeblatt
Zucker-Blume
Zucker-Stern
Zucker-Schleife
Süßer Apfel
Saurer Apfel
Halsspray
Fluchttasche
Plateauschuhe
Fehlschlagschutz
Bizarroservice
Allzweckschirm
EP-Bonbon XS
EP-Bonbon S
EP-Bonbon M
EP-Bonbon L
EP-Bonbon XL
Dynamax-Bonbon
TP00
TP01
TP02
TP03
TP04
TP05
TP06
TP07
TP08
TP09
TP10
TP11
TP12
TP13
TP14
TP15
TP16
TP17
TP18
TP19
TP20
TP21
TP22
TP23
TP24
TP25
TP26
TP27
TP28
TP29
TP30
TP31
TP32
TP33
TP34
TP35
TP36
TP37
TP38
TP39
TP40
TP41
TP42
TP43
TP44
TP45
TP46
TP47
TP48
TP49
TP50
TP51
TP52
TP53
TP54
TP55
TP56
TP57
TP58
TP59
TP60
TP61
TP62
TP63
TP64
TP65
TP66
TP67
TP68
TP69
TP70
TP71
TP72
TP73
TP74
TP75
TP76
TP77
TP78
TP79
TP80
TP81
TP82
TP83
TP84
TP85
TP86
TP87
TP88
TP89
TP90
TP91
TP92
TP93
TP94
TP95
TP96
TP97
TP98
TP99
TM00
Solo-Minze
Hart-Minze
Frech-Minze
Mutig-Minze
Kühn-Minze
Pfiffig-Minze
Lasch-Minze
Locker-Minze
Mäßig-Minze
Mild-Minze
Hitzig-Minze
Ruhig-Minze
Still-Minze
Zart-Minze
Sacht-Minze
Forsch-Minze
Scheu-Minze
Hastig-Minze
Froh-Minze
Naiv-Minze
Ernst-Minze
Wunschbrocken
Rissige Kanne
Löchrige Kanne
Top-Ohrenstöpsel
Früchte
Kuhmuh-Käse
Gewürzmix
Frische Sahne
Fertigcurry
Kokosmilch
Fertignudeln
Frikadellen
Giga-Pulver
Wunschsplitter
Rotom-Rad
Superfangpin
???
Vergilbter Brief
Band-Autogramm
Sanias Buch
???
???
???
???
???
???
Rotom-Katalog
★And458
★And15
★And337
★And603
★And390
★Sgr6879
★Sgr6859
★Sgr6913
★Sgr7348
★Sgr7121
★Sgr6746
★Sgr7194
★Sgr7337
★Sgr7343
★Sgr6812
★Sgr7116
★Sgr7264
★Sgr7597
★Del7882
★Del7906
★Del7852
★Psc596
★Psc361
★Psc510
★Psc437
★Psc8773
★Lep1865
★Lep1829
★Boo5340
★Boo5506
★Boo5435
★Boo5602
★Boo5733
★Boo5235
★Boo5351
★Hya3748
★Hya3903
★Hya3418
★Hya3482
★Hya3845
★Eri1084
★Eri472
★Eri1666
★Eri897
★Eri1231
★Eri874
★Eri1298
★Eri1325
★Eri984
★Eri1464
★Eri1393
★Eri850
★Tau1409
★Tau1457
★Tau1165
★Tau1791
★Tau1910
★Tau1346
★Tau1373
★Tau1412
★CMa2491
★CMa2693
★CMa2294
★CMa2827
★CMa2282
★CMa2618
★CMa2657
★CMa2646
★UMa4905
★UMa4301
★UMa5191
★UMa5054
★UMa4295
★UMa4660
★UMa4554
★UMa4069
★UMa3569
★UMa3323
★UMa4033
★UMa4377
★UMa4375
★UMa4518
★UMa3594
★Vir5056
★Vir4825
★Vir4932
★Vir4540
★Vir4689
★Vir5338
★Vir4910
★Vir5315
★Vir5359
★Vir5409
★Vir5107
★Ari617
★Ari553
★Ari546
★Ari951
★Ori1713
★Ori2061
★Ori1790
★Ori1903
★Ori1948
★Ori2004
★Ori1852
★Ori1879
★Ori1899
★Ori1543
★Cas21
★Cas168
★Cas403
★Cas153
★Cas542
★Cas219
★Cas265
★Cnc3572
★Cnc3208
★Cnc3461
★Cnc3449
★Cnc3429
★Cnc3627
★Cnc3268
★Cnc3249
★Com4968
★Crv4757
★Crv4623
★Crv4662
★Crv4786
★Aur1708
★Aur2088
★Aur1605
★Aur2095
★Aur1577
★Aur1641
★Aur1612
★Pav7790
★Cet911
★Cet681
★Cet188
★Cet539
★Cet804
★Cep8974
★Cep8162
★Cep8238
★Cep8417
★Cen5267
★Cen5288
★Cen551
★Cen5459
★Cen5460
★CMi2943
★CMi2845
★Equ8131
★Vul7405
★UMi424
★UMi5563
★UMi5735
★UMi6789
★Crt4287
★Lyr7001
★Lyr7178
★Lyr7106
★Lyr7298
★Ara6585
★Sco6134
★Sco6527
★Sco6553
★Sco5953
★Sco5984
★Sco6508
★Sco6084
★Sco5944
★Sco6630
★Sco6027
★Sco6247
★Sco6252
★Sco5928
★Sco6241
★Sco6165
★Tri544
★Leo3982
★Leo4534
★Leo4357
★Leo4057
★Leo4359
★Leo4031
★Leo3852
★Leo3905
★Leo3773
★Gru8425
★Gru8636
★Gru8353
★Lib5685
★Lib5531
★Lib5787
★Lib5603
★Pup3165
★Pup3185
★Pup3045
★Cyg7924
★Cyg7417
★Cyg7796
★Cyg8301
★Cyg7949
★Cyg7528
★Oct7228
★Col1956
★Col2040
★Col2177
★Gem2990
★Gem2891
★Gem2421
★Gem2473
★Gem2216
★Gem2777
★Gem2650
★Gem2286
★Gem2484
★Gem2930
★Peg8775
★Peg8781
★Peg39
★Peg8308
★Peg8650
★Peg8634
★Peg8684
★Peg8450
★Peg8880
★Peg8905
★Oph6556
★Oph6378
★Oph6603
★Oph6149
★Oph6056
★Oph6075
★Ser5854
★Ser7141
★Ser5879
★Her6406
★Her6148
★Her6410
★Her6526
★Her6117
★Her6008
★Per936
★Per1017
★Per1131
★Per1228
★Per834
★Per941
★Phe99
★Phe338
★Vel3634
★Vel3485
★Vel3734
★Aqr8232
★Aqr8414
★Aqr8709
★Aqr8518
★Aqr7950
★Aqr8499
★Aqr8610
★Aqr8264
★Cru4853
★Cru4730
★Cru4763
★Cru4700
★Cru4656
★PsA8728
★TrA6217
★Cap7776
★Cap7754
★Cap8278
★Cap8322
★Cap7773
★Sge7479
★Car2326
★Car3685
★Car3307
★Car3699
★Dra5744
★Dra5291
★Dra6705
★Dra6536
★Dra7310
★Dra6688
★Dra4434
★Dra6370
★Dra7462
★Dra6396
★Dra6132
★Dra6636
★CVn4915
★CVn4785
★CVn4846
★Aql7595
★Aql7557
★Aql7525
★Aql7602
★Aql7235

View file

@ -36,72 +36,93 @@ wie müde es war
irgendein Item
irgendeine Attacke
Pokémon
Es scheint ein gutes Gedächtnis zu haben, aber es sieht so aus, als könnte es sich nicht erinnern...
{0} ist {1} {2} begegnet. {1} warf einen Pokéball und ihre gemeinsame Reise begann. {4} {3}.
{0} sah {1} zum ersten Mal, als es {2} aus seinem Ei geschlüpft ist. {4} {3}.
{0} scheint schöne Erinnerungen zu haben, kann sich aber gerade nicht entsinnen.
{0} ist {1} {2} begegnet. Die gemeinsame Reise begann mit einem gezielten Pokéball-Wurf. {4} {3}.
{0} hat {1} zum ersten Mal gesehen, als es {2} aus seinem Ei geschlüpft ist. {4} {3}.
{0} ist {1} {2} begegnet. {4} {3}.
{0} gelangte per Tausch {2} in das Team von {1}. {4} {3}.
{0} gelangte durch einen Tausch {2} in das Team von {1}. {4} {3}.
{0} ist mit {1} in ein Pokémon-Center gegangen, um {2} zu kaufen. {4} {3}.
{0} wurde von {1} irgendwo in ein Pokémon-Center gebracht und dort wieder aufgepäppelt.Wo war das noch gleich? Ach ja, {2}! {4} {3}.
{0} war mit {1} fischen. Zusammen haben sie ein {2} geangelt! {4} {3}.
{0} war mit {1} angeln und {1} hat ein mühsam an Land gezogenes Pokémon entkommen lassen. {4} {3}.
{0} wurde von {1} ins Pokémon-Center gebracht und aufgepäppelt. {4} {3}.
{0} war mit {1} angeln. Zusammen haben sie ein {2} an Land gezogen. {4} {3}.
{0} war mit {1} angeln, als ihnen ein mühsam an Land gezogenes Pokémon doch noch entkommen ist. {4} {3}.
{0} hat gesehen, wie {1} sich um ein {2} gekümmert hat. {4} {3}.
{0} hat von {1} Süßigkeiten bekommen. {4} {3}.
{0} war mit {1} shoppen. {4} {3}.
{0} hat von {1} {2} gelernt. {4} {3}.
{0} war mit {1} Klamotten shoppen. {4} {3}.
{0} bekam von {1} die Attacke {2} beigebracht. {4} {3}.
{0} hat {1} dabei geholfen, ein {2} aus einem Ei schlüpfen zu lassen. {4} {3}.
{0} war dabei, als {1} ein {2} gefangen hat. {4} {3}.
Als {0} nur noch wenige KP hatte, setzte {1} ein Item ein.Wie hieß das Item noch gleich? Ach ja, {2}! {4} {3}.
{0} hat auf Anweisung von {1} {2} eingesetzt, aber die Attacke hat keinerlei Wirkung gezeigt. {4} {3}.
{0} hat zusammen mit {1} gekämpft und ein {2} besiegt. {4} {3}.
Als {0} in der Klemme steckte, hat {1} {2} eingesetzt. {4} {3}.
{0} hat auf Anweisung von {1} die Attacke {2} eingesetzt, aber sie zeigte keine Wirkung. {4} {3}.
{0} hat an der Seite von {1} gekämpft und ein {2} besiegt. {4} {3}.
{0} wurde von einem {2} besiegt und ist mit {1} geflüchtet. {4} {3}.
{0} wurde von {1} trainiert und hat sich {2} entwickelt. {4} {3}.
{0} ist mit {1} auf seinem Rücken übers Wasser gesurft. {4} {3}.
{0} wurde von {1} trainiert und hat sich dann {2} entwickelt. {4} {3}.
{0} ist übers Wasser gesurft und hat dabei {1} auf dem Rücken getragen. {4} {3}.
{0} hat gesehen, wie {1} von einem {2} auf dessen Rücken getragen wurde. {4} {3}.
{0} und {1} haben zusammen einen Arenaorden errungen. {4} {3}.
{0} hat mit {1} einen Arenaleiterkampf gewonnen. {4} {3}.
Als {1} sich der Herausforderung im Kampfhaus gestellt hat, war {0} extrem nervös. {4} {3}.
{0} ist mit {1} auf seinem Rücken geflogen und sie landeten {2}. {4} {3}.
{0} ist mit {1} auf dem Rücken losgeflogen, um dann {2} zu landen. {4} {3}.
{0} wurde zusammen mit {1} von einem wilden {2} überrascht. {4} {3}.
{0} hat gesehen, wie {1} ein Item eingesetzt hat.Wie hieß das Item noch gleich? Ach ja, {2}! {4} {3}.
{0} hat gesehen, wie {1} {2} eingesetzt hat. {4} {3}.
{0} hat zusammen mit {1} den Champ besiegt. {4} {3}.
{0} war dabei, als {1} den Pokédex vervollständigt hat. {4} {3}.
{0} und {1} sind zusammen {2} begegnet. {4} {3}.
{0} war dabei, als {1} eine Kampf-Châtelaine besiegt hat. {4} {3}.
{0} und {1} sind zusammen einem {2} begegnet. {4} {3}.
{0} war dabei, als {1} die höchste Autorität in Sachen Kämpfe besiegt hat. {4} {3}.
{0} hat mit {1} {2} mit dem Itemradar nach versteckten Items gesucht. {4} {3}.
{0} war mit {1} {2} Radfahren. {4} {3}.
{0} hat mit {1} {2} ein neues Reiseziel auf der Karte festgelegt. {4} {3}.
{0} hat zusammen mit {1} eine {2} gepflanzt und sich vorgestellt, wie reich die Ernte sein würde. {4} {3}.
{0} hat auf Befehl von {1} {2} die Attacke Stärke eingesetzt. {4} {3}.
{0} hat auf Befehl von {1} {2} die Attacke Zerschneider eingesetzt. {4} {3}.
{0} hat auf Befehl von {1} {2} einen Felsen zertrümmert. {4} {3}.
{0} hat mit {1} auf seinem Rücken {2} die Attacke Kaskade eingesetzt. {4} {3}.
{0} hat gesehen, wie {1} {2} heimlich etwas aufgehoben hat. {4} {3}.
{0} hat von {1} ein Item zum Tragen bekommen.Wie hieß das Item noch gleich? Ach ja, {2}! {4} {3}.
{0} ist mit {1} zur Siegesstraße aufgebrochen. {4} {3}.
{0} hat mit {1} ein Schild {2} gelesen. {4} {3}.
{0} hat mit {1} {2} auf der Karte überprüft, wo es langgeht. {4} {3}.
{0} hat mit {1} {2} gepflanzt und sich vorgestellt, wie reich die Ernte sein würde. {4} {3}.
{0} hat auf Wunsch von {1} stolz die Attacke Stärke {2} eingesetzt. {4} {3}.
{0} hat auf Wunsch von {1} die Attacke Zerschneider {2} zur Schau gestellt. {4} {3}.
{0} hat auf Wunsch von {1} mit aller Kraft {2} einen Felsen zertrümmert. {4} {3}.
{0} hat die Attacke Kaskade {2} eingesetzt, während {1} auf seinem Rücken saß. {4} {3}.
{0} hat gesehen, wie {1} heimlich etwas {2} aufgehoben hat. {4} {3}.
{0} hat von {1} {2} zum Tragen bekommen. {4} {3}.
{0} ist mit {1} zur Siegesstraße gegangen. {4} {3}.
{0} hat mit {1} {2} ein Schild gelesen. {4} {3}.
{0} war sehr beeindruckt von der Geschwindigkeit des Zugs, den es mit {1} genommen hatte. {4} {3}.
{0} hat mit {1} das Pokéradar benutzt und zusammen sind sie einem {2} begegnet. {4} {3}.
{0} war mit {1} unterwegs, als sie plötzlich von einem wilden {2} angegriffen wurden. Völlig überrumpelt haben sie das Weite gesucht. {4} {3}.
{0} hat mit {1} im Haus der Prüfung eine hohe Punktzahl erzielt. {4} {3}.
{0} hat mit {1} im Haus der Prüfung eine hohe Punktzahl erreicht. {4} {3}.
{0} hat über {1} den Richter kennengelernt, der es unverwandt angestarrt hat. {4} {3}.
{0} hat über {1} den Attacken-Verlerner kennengelernt, durch den es {2} vergessen hat. {4} {3}.
{0} konnte sich unter Anleitung von {1} wieder an {2} erinnern. {4} {3}.
{0} wurde von {1} in der Pokémon-Pension abgegeben und verbrachte seine Zeit dort zusammen mit einem {2}. {4} {3}.
{0} war neidisch, als {1} mit einem Los ein Item gewonnen hat.Wie hieß das Item noch gleich? Ach ja, {2}! {4} {3}.
{0} war dabei, als {1} {2} das Item Schutz eingesetzt hat. {4} {3}.
{0} hatte ein anstrengendes Spezialtraining mit {1}. {4} {3}.
{0} ist mit {1} Fahrstuhl gefahren. {4} {3}.
{0} wurde von {1} zum Namenbewerter gebracht und hat einen schicksalhaften Namen erhalten. {4} {3}.
{0} wurde von {1} in der Pokémon-Pension abgegeben und verbrachte seine Zeit dort mit einem {2}. {4} {3}.
{0} war neidisch, als {1} mit einem Los {2} gewonnen hat. {4} {3}.
{0} war dabei, als {1} das Item Schutz {2} eingesetzt hat. {4} {3}.
{0} hat mit {1} ein anstrengendes Spezialtraining absolviert. {4} {3}.
{0} hat mit {1} einen Fahrstuhl genommen. {4} {3}.
{0} wurde von {1} zum Namenbewerter gebracht und hat dort einen schicksalhaften Namen erhalten. {4} {3}.
{0} war mit {1} in einer Boutique. {1} hat einiges anprobiert, aber nichts gekauft. {4} {3}.
{0} war mit {1} in einem tollen Restaurant und hat dort ordentlich gemampft. {4} {3}.
{0} wurde von {1} zu einer freundlichen Frau gebracht, die sich liebevoll um es gekümmert hat. {4} {3}.
{0} hat zusammen mit {1} {2} einen Abfalleimer durchstöbert. {4} {3}.
{0} hat mit {1} {2} einen Abfalleimer durchstöbert. {4} {3}.
{0} hat mit {1} gegen ein {2} gekämpft und sich dabei so sehr angestrengt, dass es sogar Verzweifler eingesetzt hat. {4} {3}.
{0} war mit {1} auf einem hohen Turm und hat von dort auf die Welt hinabgeblickt. {4} {3}.
{0} war mit {1} in der Spiegelhöhle und hat dort sein Spiegelbild gesehen. {4} {3}.
{0} war mit {1} auf einem hohen Turm und hat von dort die Welt unter sich betrachtet. {4} {3}.
{0} war mit {1} in der Spiegelhöhle und hat dort sein Spiegelbild betrachtet. {4} {3}.
{0} hat sich mit {1} fast verlaufen, als sie gemeinsam einen Wald erkundet haben. {4} {3}.
{0} war mit {1} in einer Fabrik und hat dort viele kompliziert erscheinende Maschinen gesehen. {4} {3}.
{0} war mit {1} in einer Fabrik, in der es viele kompliziert aussehende Maschinen gab. {4} {3}.
{0} war dabei, als {1} eine Geheimbasis eingerichtet hat. {4} {3}.
{0} hat mit {1} an einem Wettbewerb teilgenommen und dabei viele Leute beeindruckt. {4} {3}.
{0} hat mit {1} an einem Wettbewerb teilgenommen und einen spektakulären Sieg errungen. {4} {3}.
{0} ist zusammen mit {1} per Überflieger durch die Lüfte gesaust und zu verschiedenen Orten geflogen. {4} {3}.
{0} wurde von {1} gebeten, in die Tiefe hinabzutauchen und den Meeresboden zu erkunden. {4} {3}.
{0} ist mit {1} per Überflieger durch die Lüfte gesaust und zu vielen verschiedenen Orten geflogen. {4} {3}.
{0} wurde von {1} gebeten, in die Tiefe hinabzutauchen und den Meeresboden zu erkunden. {4} {3}.
{0} hat sich mit {1} {2} auf eine Bank gesetzt. {4} {3}.
{0} hat mit {1} gegen ein dynamaximiertes {2} gekämpft. {4} {3}.
{0} hat sich auf Befehl von {1} dynamaximiert und gegen ein {2} gekämpft. {4} {3}.
{0} war mit {1} campen. {4} {3}.
{0} hat zusammen mit {1} gekocht. {4} {3}.
{0} wurde von {1} im Pokémon-Hort abgegeben und verbrachte seine Zeit dort mit einem {2}. {4} {3}.
{0} hat mit {1} im Pokémon-Center Geburtstag gefeiert. {4} {3}.
{0} war mit {1} im Friseursalon und hat gesehen, wie schwer es {1} gefallen ist, sich für eine Frisur zu entscheiden. {4} {3}.
{0} war mit {1} unterwegs, als es anfing zu regnen. Beide wurden klitschnass. {4} {3}.
{0} hat mit {1} an einer Rallye teilgenommen, bei der sie rasend schnell waren. {4} {3}.
Als {0} in einer Box war, hat es sich {1} zuliebe überlegt, wie es {2} gut einsetzen könnte. {4} {3}.
Als {0} in einer Box war, hat es eine besonders coole Pose für die Attacke {2} geübt, damit es von {1} gelobt wird. {4} {3}.
{0} war in derselben Box wie {2} und hat sich gut mit ihm über {1} unterhalten. {4} {3}.
{0} hat sich in einer Box mit {2} angefreundet. Zusammen haben sie Attacken geübt und über den Tag geredet, an dem sie von {1} gelobt werden würden. {4} {3}.
Als {0} in einer Box war, hat es sich darüber Sorgen gemacht, dass {1} das Item suchen könnte, das es bei sich trug. Es war {2}. {4} {3}.
Als {1} in einer Box nach {0} sehen kam, war es so nervös, dass es den Blick nicht heben konnte. {4} {3}.
Als {0} in einer Box war, hat es gehört, wie {1} {2} ankam. Es konnte sich diesen Moment bildlich vorstellen. {4} {3}.
Als {0} in derselben Box wie {2} war, haben sie sich über {1} gestritten. {4} {3}.
Als {0} in einer Box war, hat es darüber nachgedacht, warum {1} ihm {2} zum Tragen gegeben hatte. {4} {3}.
Als {0} in einer Box war, hatte es einen seltsamen Traum, in dem {1} {2} eingesetzt hat. {4} {3}.

View file

@ -1,5 +1,5 @@
-----
Pfund
-----
Klaps
Karateschlag
Duplexhieb
Kometenhieb
@ -62,7 +62,7 @@ Psystrahl
Blubbstrahl
Aurorastrahl
Hyperstrahl
Schnabel
Pikser
Bohrschnabel
Überroller
Fußkick
@ -107,7 +107,7 @@ Genesung
Härtner
Komprimator
Rauchwolke
Konfustrahl
Konfusstrahl
Panzerschutz
Einigler
Barriere
@ -135,7 +135,7 @@ Amnesie
Psykraft
Weichei
Turmkick
Giftblick
Schlangenblick
Traumfresser
Giftwolke
Stakkato
@ -191,7 +191,7 @@ Lehmschelle
Octazooka
Stachler
Blitzkanone
Gesichte
Scharfblick
Abgangsbund
Abgesang
Eissturm
@ -270,7 +270,7 @@ Ladevorgang
Verhöhner
Rechte Hand
Trickbetrug
Rollentausch
Rollenspiel
Wunschtraum
Zuschuss
Verwurzler
@ -283,7 +283,7 @@ Gähner
Abschlag
Notsituation
Eruption
Wertewechsel
Fähigkeitstausch
Begrenzer
Heilung
Nachspiel
@ -740,4 +740,58 @@ Sprießbomben
Klirrfrost
Glitzersturm
Evo-Crash
Panzerfäuste
Panzerfäuste
Dyna-Wall
Dynamax-Kanone
Präzisionsschuss
Fesselbiss
Backenstopfer
Finalformation
Teerschuss
Magiepuder
Drachenpfeile
Teatime
Octoklammer
Schockschnabel
Kiemenbiss
Seitenwechsel
Dyna-Brand
Dyna-Schwarm
Dyna-Gewitter
Dyna-Angriff
Dyna-Faust
Dyna-Spuk
Dyna-Frost
Dyna-Giftschwall
Dyna-Flut
Dyna-Düse
Dyna-Zauber
Dyna-Wyrm
Dyna-Kinese
Dyna-Brocken
Dyna-Erdstoß
Dyna-Dunkel
Dyna-Flora
Dyna-Stahlzacken
Seelentanz
Body Press
Verzierung
Trommelschläge
Fangeisen
Feuerball
Gigantenhieb
Gigantenstoß
Aura-Rad
Breitseite
Zweigstoß
Overdrive
Apfelsäure
Gravitation
Seelenbruch
Wunderdampf
Lebenstropfen
Abblocker
Kniefalltrick
Sternensturm
Unendynastrahlen
Stahlstrahl

View file

@ -100,4 +100,52 @@ RibbonCountG3Tough = Stärke
RibbonChampionAlola Alola Champion
RibbonBattleRoyale Battle Royal Champion
RibbonBattleTreeGreat Battle Tree Great
RibbonBattleTreeMaster Battle Tree Master
RibbonBattleTreeMaster Battle Tree Master
RibbonChampionGalar Galar-Champs
RibbonTowerMaster Turmmeister
RibbonMasterRank Meisterrang
RibbonMarkLunchtime Mittags-Zeichen
RibbonMarkSleepyTime Mitternachts-Zeichen
RibbonMarkDusk Abenddämmerungs-Zeichen
RibbonMarkDawn Morgendämmerungs-Zeichen
RibbonMarkCloudy Wolken-Zeichen
RibbonMarkRainy Regen-Zeichen
RibbonMarkStormy Gewitter-Zeichen
RibbonMarkSnowy Schneefall-Zeichen
RibbonMarkBlizzard Schneesturm-Zeichen
RibbonMarkDry Dürre-Zeichen
RibbonMarkSandstorm Sandsturm-Zeichen
RibbonMarkMisty Nebel-Zeichen
RibbonMarkDestiny Schicksals-Zeichen
RibbonMarkFishing Angel-Zeichen
RibbonMarkCurry Curry-Zeichen
RibbonMarkUncommon Gängigkeits-Zeichen
RibbonMarkRare Raritäts-Zeichen
RibbonMarkRowdy Raufbold-Zeichen
RibbonMarkAbsentMinded Sorglos-Zeichen
RibbonMarkJittery Spannungs-Zeichen
RibbonMarkExcited Vorfreude-Zeichen
RibbonMarkCharismatic Charisma-Zeichen
RibbonMarkCalmness Gelassenheits-Zeichen
RibbonMarkIntense Hitzkopf-Zeichen
RibbonMarkZonedOut Achtlos-Zeichen
RibbonMarkJoyful Glücklichkeits-Zeichen
RibbonMarkAngry Wut-Zeichen
RibbonMarkSmiley Lächel-Zeichen
RibbonMarkTeary Trübsal-Zeichen
RibbonMarkUpbeat Heiterkeits-Zeichen
RibbonMarkPeeved Missmut-Zeichen
RibbonMarkIntellectual Verstands-Zeichen
RibbonMarkFerocious Impulsiv-Zeichen
RibbonMarkCrafty Listigkeits-Zeichen
RibbonMarkScowling Grimmig-Zeichen
RibbonMarkKindly Sanftmut-Zeichen
RibbonMarkFlustered Panik-Zeichen
RibbonMarkPumpedUp Ansporn-Zeichen
RibbonMarkZeroEnergy Lustlos-Zeichen
RibbonMarkPrideful Selbstvertrauens-Zeichen
RibbonMarkUnsure Selbstzweifel-Zeichen
RibbonMarkHumble Arglos-Zeichen
RibbonMarkThorny Scheinheilig-Zeichen
RibbonMarkVigor Elan-Zeichen
RibbonMarkSlump Formtief-Zeichen

View file

@ -807,4 +807,85 @@ Muramura
Kopplosio
Zeraora
Meltan
Melmetal
Melmetal
Chimpep
Chimstix
Gortrom
Hopplo
Kickerlo
Liberlo
Memmeon
Phlegleon
Intelleon
Raffel
Schlaraffel
Meikro
Kranoviz
Krarmor
Sensect
Keradar
Maritellit
Kleptifux
Gaunux
Cottini
Cottomi
Wolly
Zwollock
Kamehaps
Kamalm
Voldi
Bellektro
Klonkett
Wagong
Montecarbo
Knapfel
Drapfel
Schlapfel
Salanga
Sanaconda
Urgl
Pikuda
Barrakiefa
Toxel
Riffex
Thermopod
Infernopod
Klopptopus
Kaocto
Fatalitee
Mortipot
Brimova
Brimano
Silembrim
Bähmon
Pelzebub
Olangaar
Barrikadax
Mauzinger
Gorgasonn
Lauchzelot
Pantifrost
Oghnatoll
Hokumil
Pokusan
Legios
Britzigel
Snomnom
Mottineva
Humanolith
Kubuin
Servol
Morpeko
Kupfanti
Patinaraja
Lectragon
Lecryodon
Pescragon
Pescryodon
Duraludon
Grolldra
Phandra
Katapuldra
Zacian
Zamazenta
Endynalos

View file

@ -1 +1,163 @@
todo
an einem mysteriösen Ort
an einem fernen Ort
in Furlongham
im Schlummerwald
[~ 10]
[~ 11]
auf Route 1
in Brassbury
am Brassbury-Bahnhof
auf Route 2
in Engine City
am Engine-City-Bahnhof
im Engine-Stadion
[~ 26]
[~ 27]
auf Route 3
in der Galar-Mine 1
auf Route 4
in Turffield
im Turffield-Stadion
[~ 38]
[~ 39]
auf Route 5
[~ 42]
[~ 43]
in Keelton
am Keelton-Bahnhof
im Keelton-Stadion
[~ 50]
[~ 51]
am Engine-Ortsrand
in der Galar-Mine 2
in Claw City
am Claw-City-Bahnhof
im Claw-Stadion
[~ 62]
[~ 63]
im Energiewerk
auf der Turmspitze
auf Route 6
in Passbeck
im Passbeck-Stadion
[~ 74]
[~ 75]
im Wirrschein-Wald
in Fairballey
im Fairballey-Stadion
[~ 82]
[~ 83]
auf Route 7
auf Route 8
auf Route 8
auf dem Dampfschwaden-Pfad
auf Route 9
auf Route 9
in der Circhester-Bucht
auf Route 9
am Spikeford-Ortsrand
in Circhester
im Circhester-Stadion
[~ 100]
[~ 101]
in Spikeford
im Route-9-Tunnel
auf Route 10
am White-Hill-Bahnhof
in Score City
am Score-City-Bahnhof
im Score-Stadion
im Liga-Hauptquartier
im Score-Stadion
im Wartebereich
im Score-Stadion
am Treffpunkt
in der Naturzone
auf den Wonnewiesen
in der Naturzone
im Wipfelscheinwald
in der Naturzone
bei der Wachturmruine
in der Naturzone
am Milza-See (Osten)
in der Naturzone
am Milza-See (Westen)
in der Naturzone
am Milza-See (Auge)
in der Naturzone
am Milotic-See (Süden)
in der Naturzone
beim Sitz des Giganten
in der Naturzone
am Milotic-See (Norden)
in der Naturzone
am Engine-Flussufer
in der Naturzone
im Brückental
in der Naturzone
auf der Megalithen-Ebene
in der Naturzone
im Sandsturmkessel
in der Naturzone
beim Spiegel des Giganten
in der Naturzone
auf dem Claw-Plateau
in der Naturzone
beim Hut des Giganten
in der Naturzone
am Wutanfall-See
in der Naturzone
am Naturzonen-Bahnhof
im Kampfturm
am Rose Tower
Ein Pokémon-Nest

View file

@ -1 +1,19 @@
todo
Link-Tausch
Link-Tausch
Kanto-Region
Johto-Region
Hoenn-Region
Sinnoh-Region
Fernes Land
Einall-Region
Kalos-Region
Pokémon-Link
Pokémon GO
Kanto-Region
Hoenn-Region
Alola-Region
Pokémon-Resort
Johto-Region
Pokémon HOME
Kanto-Region

Some files were not shown because too many files have changed in this diff Show more