mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-23 12:33:06 +00:00
Extract gen4 pokedex logic
This commit is contained in:
parent
f308be38fd
commit
c11cf3d6d4
6 changed files with 669 additions and 472 deletions
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
|
@ -29,6 +28,7 @@ namespace PKHeX.Core
|
|||
protected abstract int StorageSize { get; }
|
||||
protected abstract int GeneralSize { get; }
|
||||
protected abstract int StorageStart { get; }
|
||||
public abstract Zukan4 Dex { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool GetFlag(int offset, int bitIndex) => FlagUtil.GetFlag(General, offset, bitIndex);
|
||||
|
@ -573,286 +573,9 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
|
||||
protected override void SetDex(PKM pkm)
|
||||
{
|
||||
if (pkm.Species == 0)
|
||||
return;
|
||||
if (pkm.Species > MaxSpeciesID)
|
||||
return;
|
||||
|
||||
const int brSize = 0x40;
|
||||
int bit = pkm.Species - 1;
|
||||
byte mask = (byte)(1 << (bit & 7));
|
||||
int ofs = PokeDex + (bit >> 3) + 0x4;
|
||||
|
||||
/* 4 BitRegions with 0x40*8 bits
|
||||
* Region 0: Caught (Captured/Owned) flags
|
||||
* Region 1: Seen flags
|
||||
* Region 2/3: Toggle for gender display
|
||||
* 4 possible states: 00, 01, 10, 11
|
||||
* 00 - 1Seen: Male Only
|
||||
* 01 - 2Seen: Male First, Female Second
|
||||
* 10 - 2Seen: Female First, Male Second
|
||||
* 11 - 1Seen: Female Only
|
||||
* (bit1 ^ bit2) + 1 = forms in dex
|
||||
* bit2 = male/female shown first toggle
|
||||
*/
|
||||
|
||||
// Set the Species Owned Flag
|
||||
General[ofs + (brSize * 0)] |= mask;
|
||||
|
||||
// Check if already Seen
|
||||
if ((General[ofs + (brSize * 1)] & mask) == 0) // Not seen
|
||||
{
|
||||
General[ofs + (brSize * 1)] |= mask; // Set seen
|
||||
int gr = pkm.PersonalInfo.Gender;
|
||||
switch (gr)
|
||||
{
|
||||
case 255: // Genderless
|
||||
case 0: // Male Only
|
||||
General[ofs + (brSize * 2)] &= (byte)~mask; // unset
|
||||
General[ofs + (brSize * 3)] &= (byte)~mask; // unset
|
||||
break;
|
||||
case 254: // Female Only
|
||||
General[ofs + (brSize * 2)] |= mask;
|
||||
General[ofs + (brSize * 3)] |= mask;
|
||||
break;
|
||||
default: // Male or Female
|
||||
bool m = (General[ofs + (brSize * 2)] & mask) != 0;
|
||||
bool f = (General[ofs + (brSize * 3)] & mask) != 0;
|
||||
if (m || f) // bit already set?
|
||||
break;
|
||||
int gender = pkm.Gender & 1;
|
||||
General[ofs + (brSize * 2)] &= (byte)~mask; // unset
|
||||
General[ofs + (brSize * 3)] &= (byte)~mask; // unset
|
||||
gender ^= 1; // Set OTHER gender seen bit so it appears second
|
||||
General[ofs + (brSize * (2 + gender))] |= mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int FormOffset1 = PokeDex + 4 + (brSize * 4) + 4;
|
||||
var forms = GetForms(pkm.Species);
|
||||
if (forms.Length > 0)
|
||||
{
|
||||
if (pkm.Species == (int)Species.Unown) // Unown
|
||||
{
|
||||
for (int i = 0; i < 0x1C; i++)
|
||||
{
|
||||
byte val = General[FormOffset1 + 4 + i];
|
||||
if (val == pkm.Form)
|
||||
break; // already set
|
||||
if (val != 0xFF)
|
||||
continue; // keep searching
|
||||
|
||||
General[FormOffset1 + 4 + i] = (byte)pkm.Form;
|
||||
break; // form now set
|
||||
}
|
||||
}
|
||||
else if (pkm.Species == (int)Species.Pichu && HGSS) // Pichu (HGSS Only)
|
||||
{
|
||||
int form = pkm.Form == 1 ? 2 : pkm.Gender;
|
||||
if (TryInsertForm(forms, form))
|
||||
SetForms(pkm.Species, forms);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TryInsertForm(forms, pkm.Form))
|
||||
SetForms(pkm.Species, forms);
|
||||
}
|
||||
}
|
||||
|
||||
int dpl = 1 + Array.IndexOf(DPLangSpecies, pkm.Species);
|
||||
if (DP && dpl <= 0)
|
||||
return;
|
||||
|
||||
// Set the Language
|
||||
int PokeDexLanguageFlags = FormOffset1 + (HGSS ? 0x3C : 0x20);
|
||||
int lang = GetGen4LanguageBitIndex(pkm.Language);
|
||||
General[PokeDexLanguageFlags + (DP ? dpl : pkm.Species)] |= (byte)(1 << lang);
|
||||
}
|
||||
|
||||
private static readonly int[] DPLangSpecies = { 23, 25, 54, 77, 120, 129, 202, 214, 215, 216, 228, 278, 287, 315 };
|
||||
|
||||
private static int GetGen4LanguageBitIndex(int lang) => --lang switch
|
||||
{
|
||||
3 => 4, // invert ITA/GER
|
||||
4 => 3, // invert ITA/GER
|
||||
> 5 => 0, // Japanese
|
||||
< 0 => 1, // English
|
||||
_ => lang,
|
||||
};
|
||||
|
||||
public override bool GetCaught(int species)
|
||||
{
|
||||
int bit = species - 1;
|
||||
int bd = bit >> 3; // div8
|
||||
int bm = bit & 7; // mod8
|
||||
int ofs = PokeDex // Raw Offset
|
||||
+ 0x4; // Magic
|
||||
return (1 << bm & General[ofs + bd]) != 0;
|
||||
}
|
||||
|
||||
public override bool GetSeen(int species)
|
||||
{
|
||||
const int brSize = 0x40;
|
||||
|
||||
int bit = species - 1;
|
||||
int bd = bit >> 3; // div8
|
||||
int bm = bit & 7; // mod8
|
||||
int ofs = PokeDex // Raw Offset
|
||||
+ 0x4; // Magic
|
||||
|
||||
return (1 << bm & General[ofs + bd + (brSize * 1)]) != 0;
|
||||
}
|
||||
|
||||
public int[] GetForms(int species)
|
||||
{
|
||||
const int brSize = 0x40;
|
||||
if (species == (int)Species.Deoxys)
|
||||
{
|
||||
uint val = (uint) (General[PokeDex + 0x4 + (1 * brSize) - 1] | General[PokeDex + 0x4 + (2 * brSize) - 1] << 8);
|
||||
return GetDexFormValues(val, 4, 4);
|
||||
}
|
||||
|
||||
int FormOffset1 = PokeDex + 4 + (4 * brSize) + 4;
|
||||
switch (species)
|
||||
{
|
||||
case (int)Species.Shellos: // Shellos
|
||||
return GetDexFormValues(General[FormOffset1 + 0], 1, 2);
|
||||
case (int)Species.Gastrodon: // Gastrodon
|
||||
return GetDexFormValues(General[FormOffset1 + 1], 1, 2);
|
||||
case (int)Species.Burmy: // Burmy
|
||||
return GetDexFormValues(General[FormOffset1 + 2], 2, 3);
|
||||
case (int)Species.Wormadam: // Wormadam
|
||||
return GetDexFormValues(General[FormOffset1 + 3], 2, 3);
|
||||
case (int)Species.Unown: // Unown
|
||||
return General.Slice(FormOffset1 + 4, 0x1C).Select(i => (int)i).ToArray();
|
||||
}
|
||||
if (DP)
|
||||
return Array.Empty<int>();
|
||||
|
||||
int PokeDexLanguageFlags = FormOffset1 + (HGSS ? 0x3C : 0x20);
|
||||
int FormOffset2 = PokeDexLanguageFlags + 0x1F4;
|
||||
return species switch
|
||||
{
|
||||
(int)Species.Rotom => GetDexFormValues(BitConverter.ToUInt32(General, FormOffset2), 3, 6),
|
||||
(int)Species.Shaymin => GetDexFormValues(General[FormOffset2 + 4], 1, 2),
|
||||
(int)Species.Giratina => GetDexFormValues(General[FormOffset2 + 5], 1, 2),
|
||||
(int)Species.Pichu when HGSS => GetDexFormValues(General[FormOffset2 + 6], 2, 3),
|
||||
_ => Array.Empty<int>()
|
||||
};
|
||||
}
|
||||
|
||||
public void SetForms(int species, int[] forms)
|
||||
{
|
||||
const int brSize = 0x40;
|
||||
switch (species)
|
||||
{
|
||||
case (int)Species.Deoxys: // Deoxys
|
||||
uint newval = SetDexFormValues(forms, 4, 4);
|
||||
General[PokeDex + 0x4 + (1 * brSize) - 1] = (byte) (newval & 0xFF);
|
||||
General[PokeDex + 0x4 + (2 * brSize) - 1] = (byte) ((newval >> 8) & 0xFF);
|
||||
break;
|
||||
}
|
||||
|
||||
int FormOffset1 = PokeDex + 4 + (4 * brSize) + 4;
|
||||
switch (species)
|
||||
{
|
||||
case (int)Species.Shellos: // Shellos
|
||||
General[FormOffset1 + 0] = (byte)SetDexFormValues(forms, 1, 2);
|
||||
return;
|
||||
case (int)Species.Gastrodon: // Gastrodon
|
||||
General[FormOffset1 + 1] = (byte)SetDexFormValues(forms, 1, 2);
|
||||
return;
|
||||
case (int)Species.Burmy: // Burmy
|
||||
General[FormOffset1 + 2] = (byte)SetDexFormValues(forms, 2, 3);
|
||||
return;
|
||||
case (int)Species.Wormadam: // Wormadam
|
||||
General[FormOffset1 + 3] = (byte)SetDexFormValues(forms, 2, 3);
|
||||
return;
|
||||
case (int)Species.Unown: // Unown
|
||||
int ofs = FormOffset1 + 4;
|
||||
int len = forms.Length;
|
||||
Array.Resize(ref forms, 0x1C);
|
||||
for (int i = len; i < forms.Length; i++)
|
||||
forms[i] = 0xFF;
|
||||
Array.Copy(forms.Select(b => (byte)b).ToArray(), 0, General, ofs, forms.Length);
|
||||
return;
|
||||
}
|
||||
|
||||
if (DP)
|
||||
return;
|
||||
|
||||
int PokeDexLanguageFlags = FormOffset1 + (HGSS ? 0x3C : 0x20);
|
||||
int FormOffset2 = PokeDexLanguageFlags + 0x1F4;
|
||||
switch (species)
|
||||
{
|
||||
case (int)Species.Rotom: // Rotom
|
||||
BitConverter.GetBytes(SetDexFormValues(forms, 3, 6)).CopyTo(General, FormOffset2);
|
||||
return;
|
||||
case (int)Species.Shaymin: // Shaymin
|
||||
General[FormOffset2 + 4] = (byte)SetDexFormValues(forms, 1, 2);
|
||||
return;
|
||||
case (int)Species.Giratina: // Giratina
|
||||
General[FormOffset2 + 5] = (byte)SetDexFormValues(forms, 1, 2);
|
||||
return;
|
||||
case (int)Species.Pichu when HGSS: // Pichu
|
||||
General[FormOffset2 + 6] = (byte)SetDexFormValues(forms, 2, 3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] GetDexFormValues(uint Value, int BitsPerForm, int readCt)
|
||||
{
|
||||
int[] Forms = new int[readCt];
|
||||
int n1 = 0xFF >> (8 - BitsPerForm);
|
||||
for (int i = 0; i < Forms.Length; i++)
|
||||
{
|
||||
int val = (int)(Value >> (i * BitsPerForm)) & n1;
|
||||
if (n1 == val && BitsPerForm > 1)
|
||||
Forms[i] = -1;
|
||||
else
|
||||
Forms[i] = val;
|
||||
}
|
||||
|
||||
// (BitsPerForm > 1) was already handled, handle (BitsPerForm == 1)
|
||||
if (BitsPerForm == 1 && Forms[0] == Forms[1] && Forms[0] == 1)
|
||||
Forms[0] = Forms[1] = -1;
|
||||
|
||||
return Forms;
|
||||
}
|
||||
|
||||
private static uint SetDexFormValues(int[] Forms, int BitsPerForm, int readCt)
|
||||
{
|
||||
int n1 = 0xFF >> (8 - BitsPerForm);
|
||||
uint Value = 0xFFFFFFFF << (readCt * BitsPerForm);
|
||||
for (int i = 0; i < Forms.Length; i++)
|
||||
{
|
||||
int val = Forms[i];
|
||||
if (val == -1)
|
||||
val = n1;
|
||||
|
||||
Value |= (uint)(val << (BitsPerForm*i));
|
||||
if (i >= readCt)
|
||||
throw new ArgumentException("Array count should be less than bitfield count", nameof(Forms));
|
||||
}
|
||||
return Value;
|
||||
}
|
||||
|
||||
private static bool TryInsertForm(int[] forms, int form)
|
||||
{
|
||||
if (Array.IndexOf(forms, form) >= 0)
|
||||
return false; // already in list
|
||||
|
||||
// insert at first empty
|
||||
var index = Array.IndexOf(forms, -1);
|
||||
if (index < 0)
|
||||
return false; // no free slots?
|
||||
|
||||
forms[index] = form;
|
||||
return true;
|
||||
}
|
||||
protected override void SetDex(PKM pkm) => Dex.SetDex(pkm);
|
||||
public override bool GetCaught(int species) => Dex.GetCaught(species);
|
||||
public override bool GetSeen(int species) => Dex.GetSeen(species);
|
||||
|
||||
public int DexUpgraded
|
||||
{
|
||||
|
|
|
@ -8,8 +8,20 @@ namespace PKHeX.Core
|
|||
/// </summary>
|
||||
public sealed class SAV4DP : SAV4Sinnoh
|
||||
{
|
||||
public SAV4DP() => Initialize();
|
||||
public SAV4DP(byte[] data) : base(data) => Initialize();
|
||||
public SAV4DP()
|
||||
{
|
||||
Initialize();
|
||||
Dex = new Zukan4(this, PokeDex);
|
||||
}
|
||||
|
||||
public SAV4DP(byte[] data) : base(data)
|
||||
{
|
||||
Initialize();
|
||||
Dex = new Zukan4(this, PokeDex);
|
||||
}
|
||||
|
||||
public override Zukan4 Dex { get; }
|
||||
|
||||
protected override SAV4 CloneInternal4() => State.Exportable ? new SAV4DP(Data) : new SAV4DP();
|
||||
public override PersonalTable Personal => PersonalTable.DP;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_DP;
|
||||
|
|
|
@ -8,8 +8,19 @@ namespace PKHeX.Core
|
|||
/// </summary>
|
||||
public sealed class SAV4HGSS : SAV4
|
||||
{
|
||||
public SAV4HGSS() => Initialize();
|
||||
public SAV4HGSS(byte[] data) : base(data) => Initialize();
|
||||
public SAV4HGSS()
|
||||
{
|
||||
Initialize();
|
||||
Dex = new Zukan4(this, PokeDex);
|
||||
}
|
||||
|
||||
public SAV4HGSS(byte[] data) : base(data)
|
||||
{
|
||||
Initialize();
|
||||
Dex = new Zukan4(this, PokeDex);
|
||||
}
|
||||
|
||||
public override Zukan4 Dex { get; }
|
||||
protected override SAV4 CloneInternal4() => State.Exportable ? new SAV4HGSS(Data) : new SAV4HGSS();
|
||||
|
||||
public override PersonalTable Personal => PersonalTable.HGSS;
|
||||
|
|
|
@ -7,8 +7,19 @@ namespace PKHeX.Core
|
|||
/// </summary>
|
||||
public sealed class SAV4Pt : SAV4Sinnoh
|
||||
{
|
||||
public SAV4Pt() => Initialize();
|
||||
public SAV4Pt(byte[] data) : base(data) => Initialize();
|
||||
public SAV4Pt()
|
||||
{
|
||||
Initialize();
|
||||
Dex = new Zukan4(this, PokeDex);
|
||||
}
|
||||
|
||||
public SAV4Pt(byte[] data) : base(data)
|
||||
{
|
||||
Initialize();
|
||||
Dex = new Zukan4(this, PokeDex);
|
||||
}
|
||||
|
||||
public override Zukan4 Dex { get; }
|
||||
protected override SAV4 CloneInternal4() => State.Exportable ? new SAV4Pt(Data) : new SAV4Pt();
|
||||
public override PersonalTable Personal => PersonalTable.Pt;
|
||||
public override IReadOnlyList<ushort> HeldItems => Legal.HeldItems_Pt;
|
||||
|
@ -94,4 +105,4 @@ namespace PKHeX.Core
|
|||
set => value.SaveAll(General);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
532
PKHeX.Core/Saves/Substructures/PokeDex/Zukan4.cs
Normal file
532
PKHeX.Core/Saves/Substructures/PokeDex/Zukan4.cs
Normal file
|
@ -0,0 +1,532 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Pokédex structure used by <see cref="SAV4"/> games.
|
||||
/// </summary>
|
||||
public sealed class Zukan4 : ZukanBase
|
||||
{
|
||||
private readonly byte[] Data;
|
||||
private readonly int Offset;
|
||||
|
||||
// General structure: u32 magic, 4*bitflags, u32 spinda, form flags, language flags, more form flags, upgrade flags
|
||||
|
||||
/* 4 BitRegions with 0x40*8 bits
|
||||
* Region 0: Caught (Captured/Owned) flags
|
||||
* Region 1: Seen flags
|
||||
* Region 2: First Seen Gender
|
||||
* Region 3: Second Seen Gender
|
||||
* When setting a newly seen species (first time), we set the gender bit to both First and Second regions.
|
||||
* When setting an already-seen species, we set the Second region bit if the now-seen gender-bit is not equal to the first-seen bit.
|
||||
* 4 possible states: 00, 01, 10, 11
|
||||
* 00 - 1Seen: Male Only
|
||||
* 01 - 2Seen: Male First, Female Second
|
||||
* 10 - 2Seen: Female First, Male Second
|
||||
* 11 - 1Seen: Female Only
|
||||
* assuming the species is seen, (bit1 ^ bit2) + 1 = genders in dex
|
||||
*/
|
||||
|
||||
public const string GENDERLESS = "Genderless";
|
||||
public const string MALE = "Male";
|
||||
public const string FEMALE = "Female";
|
||||
private const int SIZE_REGION = 0x40;
|
||||
private const int COUNT_REGION = 4;
|
||||
private const int OFS_SPINDA = sizeof(uint) + (COUNT_REGION * SIZE_REGION);
|
||||
private const int OFS_FORM1 = OFS_SPINDA + sizeof(uint);
|
||||
|
||||
private bool HGSS => SAV is SAV4HGSS;
|
||||
private bool DP => SAV is SAV4DP;
|
||||
|
||||
public Zukan4(SAV4 sav, int offset) : base(sav, offset)
|
||||
{
|
||||
Data = sav.General;
|
||||
Offset = offset;
|
||||
}
|
||||
|
||||
public uint Magic { get => BitConverter.ToUInt32(Data, Offset); set => BitConverter.GetBytes(value).CopyTo(Data, Offset); }
|
||||
|
||||
public override bool GetCaught(int species) => GetRegionFlag(0, species - 1);
|
||||
public override bool GetSeen(int species) => GetRegionFlag(1, species - 1);
|
||||
public int GetSeenGenderFirst(int species) => GetRegionFlag(2, species - 1) ? 1 : 0;
|
||||
public int GetSeenGenderSecond(int species) => GetRegionFlag(3, species - 1) ? 1 : 0;
|
||||
public bool GetSeenSingleGender(int species) => GetSeenGenderFirst(species) == GetSeenGenderSecond(species);
|
||||
|
||||
private bool GetRegionFlag(int region, int index)
|
||||
{
|
||||
var ofs = Offset + 4 + (region * SIZE_REGION) + (index >> 3);
|
||||
return FlagUtil.GetFlag(Data, ofs, index);
|
||||
}
|
||||
|
||||
public void SetCaught(int species, bool value = true) => SetRegionFlag(0, species - 1, value);
|
||||
public void SetSeen(int species, bool value = true) => SetRegionFlag(1, species - 1, value);
|
||||
public void SetSeenGenderFirst(int species, int value = 0) => SetRegionFlag(2, species - 1, value == 1);
|
||||
public void SetSeenGenderSecond(int species, int value = 0) => SetRegionFlag(3, species - 1, value == 1);
|
||||
|
||||
private void SetRegionFlag(int region, int index, bool value)
|
||||
{
|
||||
var ofs = Offset + 4 + (region * SIZE_REGION) + (index >> 3);
|
||||
FlagUtil.SetFlag(Data, ofs, index, value);
|
||||
}
|
||||
|
||||
public uint SpindaPID { get => BitConverter.ToUInt32(Data, Offset + OFS_SPINDA); set => BitConverter.GetBytes(value).CopyTo(Data, Offset); }
|
||||
|
||||
public static string[] GetFormNames4Dex(int species)
|
||||
{
|
||||
string[] formNames = FormConverter.GetFormList(species, GameInfo.Strings.types, GameInfo.Strings.forms, Array.Empty<string>(), 4);
|
||||
if (species == (int)Species.Pichu)
|
||||
formNames = new[] { MALE, FEMALE, formNames[1] }; // Spiky
|
||||
return formNames;
|
||||
}
|
||||
|
||||
public int[] GetForms(int species)
|
||||
{
|
||||
const int brSize = 0x40;
|
||||
if (species == (int)Species.Deoxys)
|
||||
{
|
||||
uint val = (uint)(Data[Offset + 0x4 + (1 * brSize) - 1] | Data[Offset + 0x4 + (2 * brSize) - 1] << 8);
|
||||
return GetDexFormValues(val, 4, 4);
|
||||
}
|
||||
|
||||
int FormOffset1 = Offset + 4 + (4 * brSize) + 4;
|
||||
switch (species)
|
||||
{
|
||||
case (int)Species.Shellos: // Shellos
|
||||
return GetDexFormValues(Data[FormOffset1 + 0], 1, 2);
|
||||
case (int)Species.Gastrodon: // Gastrodon
|
||||
return GetDexFormValues(Data[FormOffset1 + 1], 1, 2);
|
||||
case (int)Species.Burmy: // Burmy
|
||||
return GetDexFormValues(Data[FormOffset1 + 2], 2, 3);
|
||||
case (int)Species.Wormadam: // Wormadam
|
||||
return GetDexFormValues(Data[FormOffset1 + 3], 2, 3);
|
||||
case (int)Species.Unown: // Unown
|
||||
return Data.Slice(FormOffset1 + 4, 0x1C).Select(i => (int)i).ToArray();
|
||||
}
|
||||
if (DP)
|
||||
return Array.Empty<int>();
|
||||
|
||||
int PokeDexLanguageFlags = FormOffset1 + (HGSS ? 0x3C : 0x20);
|
||||
int FormOffset2 = PokeDexLanguageFlags + 0x1F4;
|
||||
return species switch
|
||||
{
|
||||
(int)Species.Rotom => GetDexFormValues(BitConverter.ToUInt32(Data, FormOffset2), 3, 6),
|
||||
(int)Species.Shaymin => GetDexFormValues(Data[FormOffset2 + 4], 1, 2),
|
||||
(int)Species.Giratina => GetDexFormValues(Data[FormOffset2 + 5], 1, 2),
|
||||
(int)Species.Pichu when HGSS => GetDexFormValues(Data[FormOffset2 + 6], 2, 3),
|
||||
_ => Array.Empty<int>()
|
||||
};
|
||||
}
|
||||
|
||||
public void SetForms(int species, int[] forms)
|
||||
{
|
||||
const int brSize = 0x40;
|
||||
switch (species)
|
||||
{
|
||||
case (int)Species.Deoxys: // Deoxys
|
||||
uint newval = SetDexFormValues(forms, 4, 4);
|
||||
Data[Offset + 0x4 + (1 * brSize) - 1] = (byte)(newval & 0xFF);
|
||||
Data[Offset + 0x4 + (2 * brSize) - 1] = (byte)((newval >> 8) & 0xFF);
|
||||
break;
|
||||
}
|
||||
|
||||
int FormOffset1 = Offset + OFS_FORM1;
|
||||
switch (species)
|
||||
{
|
||||
case (int)Species.Shellos: // Shellos
|
||||
Data[FormOffset1 + 0] = (byte)SetDexFormValues(forms, 1, 2);
|
||||
return;
|
||||
case (int)Species.Gastrodon: // Gastrodon
|
||||
Data[FormOffset1 + 1] = (byte)SetDexFormValues(forms, 1, 2);
|
||||
return;
|
||||
case (int)Species.Burmy: // Burmy
|
||||
Data[FormOffset1 + 2] = (byte)SetDexFormValues(forms, 2, 3);
|
||||
return;
|
||||
case (int)Species.Wormadam: // Wormadam
|
||||
Data[FormOffset1 + 3] = (byte)SetDexFormValues(forms, 2, 3);
|
||||
return;
|
||||
case (int)Species.Unown: // Unown
|
||||
int ofs = FormOffset1 + 4;
|
||||
int len = forms.Length;
|
||||
Array.Resize(ref forms, 0x1C);
|
||||
for (int i = len; i < forms.Length; i++)
|
||||
forms[i] = 0xFF;
|
||||
Array.Copy(forms.Select(b => (byte)b).ToArray(), 0, Data, ofs, forms.Length);
|
||||
return;
|
||||
}
|
||||
|
||||
if (DP)
|
||||
return;
|
||||
|
||||
int PokeDexLanguageFlags = FormOffset1 + (HGSS ? 0x3C : 0x20);
|
||||
int FormOffset2 = PokeDexLanguageFlags + 0x1F4;
|
||||
switch (species)
|
||||
{
|
||||
case (int)Species.Rotom: // Rotom
|
||||
BitConverter.GetBytes(SetDexFormValues(forms, 3, 6)).CopyTo(Data, FormOffset2);
|
||||
return;
|
||||
case (int)Species.Shaymin: // Shaymin
|
||||
Data[FormOffset2 + 4] = (byte)SetDexFormValues(forms, 1, 2);
|
||||
return;
|
||||
case (int)Species.Giratina: // Giratina
|
||||
Data[FormOffset2 + 5] = (byte)SetDexFormValues(forms, 1, 2);
|
||||
return;
|
||||
case (int)Species.Pichu when HGSS: // Pichu
|
||||
Data[FormOffset2 + 6] = (byte)SetDexFormValues(forms, 2, 3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] GetDexFormValues(uint Value, int BitsPerForm, int readCt)
|
||||
{
|
||||
int[] Forms = new int[readCt];
|
||||
int n1 = 0xFF >> (8 - BitsPerForm);
|
||||
for (int i = 0; i < Forms.Length; i++)
|
||||
{
|
||||
int val = (int)(Value >> (i * BitsPerForm)) & n1;
|
||||
if (n1 == val && BitsPerForm > 1)
|
||||
Forms[i] = -1;
|
||||
else
|
||||
Forms[i] = val;
|
||||
}
|
||||
|
||||
// (BitsPerForm > 1) was already handled, handle (BitsPerForm == 1)
|
||||
if (BitsPerForm == 1 && Forms[0] == Forms[1] && Forms[0] == 1)
|
||||
Forms[0] = Forms[1] = -1;
|
||||
|
||||
return Forms;
|
||||
}
|
||||
|
||||
private static uint SetDexFormValues(int[] Forms, int BitsPerForm, int readCt)
|
||||
{
|
||||
int n1 = 0xFF >> (8 - BitsPerForm);
|
||||
uint Value = 0xFFFFFFFF << (readCt * BitsPerForm);
|
||||
for (int i = 0; i < Forms.Length; i++)
|
||||
{
|
||||
int val = Forms[i];
|
||||
if (val == -1)
|
||||
val = n1;
|
||||
|
||||
Value |= (uint)(val << (BitsPerForm * i));
|
||||
if (i >= readCt)
|
||||
throw new ArgumentException("Array count should be less than bitfield count", nameof(Forms));
|
||||
}
|
||||
return Value;
|
||||
}
|
||||
|
||||
private static bool TryInsertForm(int[] forms, int form)
|
||||
{
|
||||
if (Array.IndexOf(forms, form) >= 0)
|
||||
return false; // already in list
|
||||
|
||||
// insert at first empty
|
||||
var index = Array.IndexOf(forms, -1);
|
||||
if (index < 0)
|
||||
return false; // no free slots?
|
||||
|
||||
forms[index] = form;
|
||||
return true;
|
||||
}
|
||||
|
||||
public int GetUnownFormIndex(int form)
|
||||
{
|
||||
var ofs = Offset + OFS_FORM1 + 4;
|
||||
for (int i = 0; i < 0x1C; i++)
|
||||
{
|
||||
byte val = Data[ofs + i];
|
||||
if (val == form)
|
||||
return i;
|
||||
if (val == 0xFF)
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int GetUnownFormIndexNext(int form)
|
||||
{
|
||||
var ofs = Offset + OFS_FORM1 + 4;
|
||||
for (int i = 0; i < 0x1C; i++)
|
||||
{
|
||||
byte val = Data[ofs + i];
|
||||
if (val == form)
|
||||
return i;
|
||||
if (val == 0xFF)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void ClearUnownForms()
|
||||
{
|
||||
var ofs = Offset + OFS_FORM1 + 4;
|
||||
for (int i = 0; i < 0x1C; i++)
|
||||
Data[ofs + i] = 0xFF;
|
||||
}
|
||||
|
||||
public bool GetUnownForm(int form) => GetUnownFormIndex(form) != -1;
|
||||
|
||||
public void AddUnownForm(int form)
|
||||
{
|
||||
var index = GetUnownFormIndexNext(form);
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
var ofs = Offset + OFS_FORM1 + 4;
|
||||
Data[ofs + index] = (byte)form;
|
||||
}
|
||||
|
||||
public override void SetDex(PKM pkm)
|
||||
{
|
||||
int species = pkm.Species;
|
||||
if (species == 0)
|
||||
return;
|
||||
if (species > Legal.MaxSpeciesID_4)
|
||||
return;
|
||||
|
||||
var gender = pkm.Gender;
|
||||
var form = pkm.Form;
|
||||
var language = pkm.Language;
|
||||
SetDex(species, gender, form, language);
|
||||
}
|
||||
|
||||
private void SetDex(int species, int gender, int form, int language)
|
||||
{
|
||||
SetCaught(species);
|
||||
SetSeenGender(species, gender);
|
||||
SetForms(species, form, gender);
|
||||
SetLanguage(species, language);
|
||||
}
|
||||
|
||||
public void SetSeenGender(int species, int gender)
|
||||
{
|
||||
if (!GetSeen(species))
|
||||
SetSeenGenderNew(species, gender);
|
||||
else if (GetSeenSingleGender(species))
|
||||
SetSeenGenderSecond(species, gender);
|
||||
}
|
||||
|
||||
public void SetSeenGenderNew(int species, int gender)
|
||||
{
|
||||
SetSeenGenderFirst(species, gender);
|
||||
SetSeenGenderSecond(species, gender);
|
||||
}
|
||||
|
||||
public void SetSeenGenderNeither(int species)
|
||||
{
|
||||
SetSeenGenderFirst(species, 0);
|
||||
SetSeenGenderSecond(species, 0);
|
||||
}
|
||||
|
||||
private void SetForms(int species, int form, int gender)
|
||||
{
|
||||
if (species == (int)Species.Unown) // Unown
|
||||
{
|
||||
AddUnownForm(form);
|
||||
return;
|
||||
}
|
||||
|
||||
var forms = GetForms(species);
|
||||
if (forms.Length == 0)
|
||||
return;
|
||||
|
||||
if (species == (int)Species.Pichu && HGSS) // Pichu (HGSS Only)
|
||||
{
|
||||
int formID = form == 1 ? 2 : gender;
|
||||
if (TryInsertForm(forms, formID))
|
||||
SetForms(species, forms);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TryInsertForm(forms, form))
|
||||
SetForms(species, forms);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetLanguage(int species, int language, bool value = true)
|
||||
{
|
||||
int lang = GetGen4LanguageBitIndex(language);
|
||||
SetLanguageBitIndex(species, lang, value);
|
||||
}
|
||||
|
||||
public bool GetLanguageBitIndex(int species, int lang)
|
||||
{
|
||||
int dpl = 1 + Array.IndexOf(DPLangSpecies, species);
|
||||
if (DP && dpl < 0)
|
||||
return false;
|
||||
int FormOffset1 = Offset + OFS_FORM1;
|
||||
int PokeDexLanguageFlags = FormOffset1 + (HGSS ? 0x3C : 0x20);
|
||||
|
||||
var ofs = PokeDexLanguageFlags + (DP ? dpl : species);
|
||||
return FlagUtil.GetFlag(Data, ofs, lang & 7);
|
||||
}
|
||||
|
||||
public void SetLanguageBitIndex(int species, int lang, bool value)
|
||||
{
|
||||
int dpl = 1 + Array.IndexOf(DPLangSpecies, species);
|
||||
if (DP && dpl <= 0)
|
||||
return;
|
||||
int FormOffset1 = Offset + OFS_FORM1;
|
||||
int PokeDexLanguageFlags = FormOffset1 + (HGSS ? 0x3C : 0x20);
|
||||
|
||||
var ofs = PokeDexLanguageFlags + (DP ? dpl : species);
|
||||
FlagUtil.SetFlag(Data, ofs, lang & 7, value);
|
||||
}
|
||||
|
||||
public bool HasLanguage(int species) => GetSpeciesLanguageByteIndex(species) >= 0;
|
||||
|
||||
private int GetSpeciesLanguageByteIndex(int species)
|
||||
{
|
||||
if (DP)
|
||||
return Array.IndexOf(DPLangSpecies, species);
|
||||
return species;
|
||||
}
|
||||
|
||||
private static readonly int[] DPLangSpecies = { 23, 25, 54, 77, 120, 129, 202, 214, 215, 216, 228, 278, 287, 315 };
|
||||
|
||||
public static int GetGen4LanguageBitIndex(int lang) => --lang switch
|
||||
{
|
||||
3 => 4, // invert ITA/GER
|
||||
4 => 3, // invert ITA/GER
|
||||
> 5 => 0, // Japanese
|
||||
< 0 => 1, // English
|
||||
_ => lang,
|
||||
};
|
||||
|
||||
[Flags]
|
||||
public enum SetDexArgs
|
||||
{
|
||||
None,
|
||||
SeenAll = 1 << 0,
|
||||
|
||||
CaughtNone = 1 << 1,
|
||||
CaughtAll = 1 << 2,
|
||||
|
||||
SetNoLanguages = 1 << 3,
|
||||
SetAllLanguages = 1 << 4,
|
||||
SetSingleLanguage = 1 << 5,
|
||||
|
||||
SetAllForms = 1 << 6,
|
||||
|
||||
Complete = SeenAll | CaughtAll | SetAllLanguages | SetAllForms,
|
||||
}
|
||||
|
||||
public void ModifyAll(int species, SetDexArgs args, int lang = 0)
|
||||
{
|
||||
if (args == SetDexArgs.None)
|
||||
{
|
||||
ClearSeen(species);
|
||||
return;
|
||||
}
|
||||
if ((args & SetDexArgs.SeenAll) != 0)
|
||||
CompleteSeen(species);
|
||||
|
||||
if ((args & SetDexArgs.CaughtNone) != 0)
|
||||
{
|
||||
SetCaught(species, false);
|
||||
ClearLanguages(species);
|
||||
}
|
||||
else if ((args & SetDexArgs.CaughtAll) != 0)
|
||||
{
|
||||
SetCaught(species);
|
||||
}
|
||||
|
||||
if ((args & SetDexArgs.SetNoLanguages) != 0)
|
||||
{
|
||||
ClearLanguages(species);
|
||||
}
|
||||
if ((args & SetDexArgs.SetAllLanguages) != 0)
|
||||
{
|
||||
SetLanguages(species);
|
||||
}
|
||||
else if ((args & SetDexArgs.SetSingleLanguage) != 0)
|
||||
{
|
||||
SetLanguage(species, lang);
|
||||
}
|
||||
|
||||
if ((args & SetDexArgs.SetAllForms) != 0)
|
||||
{
|
||||
CompleteForms(species);
|
||||
}
|
||||
}
|
||||
|
||||
private void CompleteForms(int species)
|
||||
{
|
||||
var forms = GetFormNames4Dex(species);
|
||||
if (forms.Length <= 1)
|
||||
return;
|
||||
|
||||
var values = forms.Select((_, i) => i).ToArray();
|
||||
SetForms(species, values);
|
||||
}
|
||||
|
||||
private void CompleteSeen(int species)
|
||||
{
|
||||
SetSeen(species);
|
||||
var pi = PersonalTable.HGSS[species];
|
||||
if (pi.IsDualGender)
|
||||
{
|
||||
SetSeenGenderFirst(species, 0);
|
||||
SetSeenGenderSecond(species, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSeenGender(species, pi.FixedGender & 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearSeen(int species)
|
||||
{
|
||||
SetCaught(species, false);
|
||||
SetSeen(species, false);
|
||||
SetSeenGenderNeither(species);
|
||||
|
||||
SetForms(species, Array.Empty<int>());
|
||||
ClearLanguages(species);
|
||||
}
|
||||
|
||||
private const int LangCount = 6;
|
||||
private void ClearLanguages(int species)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
SetLanguageBitIndex(species, i, false);
|
||||
}
|
||||
|
||||
private void SetLanguages(int species, bool value = true)
|
||||
{
|
||||
for (int i = 0; i < LangCount; i++)
|
||||
SetLanguageBitIndex(species, i, value);
|
||||
}
|
||||
|
||||
// Bulk Manipulation
|
||||
public override void CompleteDex(bool shinyToo = false) => IterateAll(z => ModifyAll(z, SetDexArgs.Complete));
|
||||
public override void SeenNone() => IterateAll(ClearSeen);
|
||||
public override void CaughtNone() => IterateAll(z => SetCaught(z, false));
|
||||
public override void SeenAll(bool shinyToo = false) => IterateAll(CompleteSeen);
|
||||
|
||||
public override void SetDexEntryAll(int species, bool shinyToo = false) => ModifyAll(species, SetDexArgs.Complete);
|
||||
public override void ClearDexEntryAll(int species) => ModifyAll(species, SetDexArgs.None);
|
||||
|
||||
private static void IterateAll(Action<int> a)
|
||||
{
|
||||
for (int i = 1; i <= Legal.MaxSpeciesID_4; i++)
|
||||
a(i);
|
||||
}
|
||||
|
||||
public override void SetAllSeen(bool value = true, bool shinyToo = false)
|
||||
{
|
||||
if (!value)
|
||||
{
|
||||
SeenNone();
|
||||
return;
|
||||
}
|
||||
IterateAll(CompleteSeen);
|
||||
}
|
||||
|
||||
public override void CaughtAll(bool shinyToo = false)
|
||||
{
|
||||
SeenAll();
|
||||
IterateAll(z => SetCaught(z));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ using System.Drawing;
|
|||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using PKHeX.Core;
|
||||
using static PKHeX.Core.Zukan4;
|
||||
|
||||
namespace PKHeX.WinForms
|
||||
{
|
||||
|
@ -46,12 +47,12 @@ namespace PKHeX.WinForms
|
|||
private readonly CheckBox[] CL;
|
||||
private bool editing;
|
||||
private int species = -1;
|
||||
private const int brSize = 0x40;
|
||||
private const int LangCount = 6; // No Korean
|
||||
|
||||
private void ChangeCBSpecies(object sender, EventArgs e)
|
||||
{
|
||||
if (editing) return;
|
||||
if (editing)
|
||||
return;
|
||||
SetEntry();
|
||||
|
||||
editing = true;
|
||||
|
@ -64,7 +65,8 @@ namespace PKHeX.WinForms
|
|||
|
||||
private void ChangeLBSpecies(object sender, EventArgs e)
|
||||
{
|
||||
if (editing) return;
|
||||
if (editing)
|
||||
return;
|
||||
SetEntry();
|
||||
|
||||
editing = true;
|
||||
|
@ -74,71 +76,45 @@ namespace PKHeX.WinForms
|
|||
editing = false;
|
||||
}
|
||||
|
||||
private const string GENDERLESS = "Genderless";
|
||||
private const string MALE = "Male";
|
||||
private const string FEMALE = "Female";
|
||||
private static readonly int[] DPLangSpecies = { 23, 25, 54, 77, 120, 129, 202, 214, 215, 216, 228, 278, 287, 315 };
|
||||
|
||||
private void GetEntry()
|
||||
{
|
||||
// Load Bools for the data
|
||||
int bit = species - 1;
|
||||
byte mask = (byte)(1 << (bit & 7));
|
||||
int ofs = SAV.PokeDex + (bit >> 3) + 0x4;
|
||||
int FormOffset1 = SAV.PokeDex + 4 + (brSize * 4) + 4;
|
||||
int PokeDexLanguageFlags = FormOffset1 + (SAV.HGSS ? 0x3C : 0x20);
|
||||
int l_ofs = !SAV.DP ? species : 1 + Array.IndexOf(DPLangSpecies, species);
|
||||
if (l_ofs > 0)
|
||||
var dex = SAV.Dex;
|
||||
|
||||
CHK_Caught.Checked = dex.GetCaught(species);
|
||||
CHK_Seen.Checked = dex.GetSeen(species);
|
||||
|
||||
// Genders
|
||||
LoadGenders(CHK_Seen.Checked);
|
||||
|
||||
// Forms
|
||||
LoadForms();
|
||||
|
||||
// Language
|
||||
LoadLanguage();
|
||||
}
|
||||
|
||||
private void LoadLanguage()
|
||||
{
|
||||
var dex = SAV.Dex;
|
||||
if (dex.HasLanguage(species))
|
||||
{
|
||||
l_ofs += PokeDexLanguageFlags;
|
||||
for (int i = 0; i < LangCount; i++)
|
||||
{
|
||||
CL[i].Enabled = true;
|
||||
CL[i].Checked = SAV.GetFlag(l_ofs, i);
|
||||
}
|
||||
CL[i].Checked = dex.GetLanguageBitIndex(species, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
GB_Language.Enabled = false;
|
||||
for (int i = 0; i < LangCount; i++)
|
||||
CL[i].Enabled = CL[i].Checked = false;
|
||||
CL[i].Checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool bit2 = (SAV.General[ofs + (brSize * 2)] & mask) != 0;
|
||||
bool bit3 = (SAV.General[ofs + (brSize * 3)] & mask) != 0;
|
||||
|
||||
CHK_Seen.Checked = (SAV.General[ofs + (brSize * 1)] & mask) != 0;
|
||||
CHK_Caught.Checked = (SAV.General[ofs + (brSize * 0)] & mask) != 0;
|
||||
|
||||
// Genders
|
||||
LB_Gender.Items.Clear();
|
||||
LB_NGender.Items.Clear();
|
||||
|
||||
var active = CHK_Seen.Checked ? LB_Gender : LB_NGender;
|
||||
var inactive = LB_NGender;
|
||||
var other = bit2 ^ bit3 ? active : inactive;
|
||||
|
||||
switch (SAV.Personal[species].Gender)
|
||||
{
|
||||
case 255: // Genderless
|
||||
active.Items.Add(GENDERLESS);
|
||||
break;
|
||||
case 0:
|
||||
active.Items.Add(MALE);
|
||||
break;
|
||||
case 254:
|
||||
active.Items.Add(FEMALE);
|
||||
break;
|
||||
default:
|
||||
active.Items.Add(bit2 ? FEMALE : MALE);
|
||||
other.Items.Add(bit2 ? MALE : FEMALE);
|
||||
break;
|
||||
}
|
||||
|
||||
// Forms
|
||||
private void LoadForms()
|
||||
{
|
||||
LB_Form.Items.Clear();
|
||||
LB_NForm.Items.Clear();
|
||||
|
||||
var forms = SAV.GetForms(species);
|
||||
var forms = SAV.Dex.GetForms(species);
|
||||
if (forms.Length == 0)
|
||||
return;
|
||||
|
||||
|
@ -151,12 +127,33 @@ namespace PKHeX.WinForms
|
|||
LB_NForm.Items.AddRange(not);
|
||||
}
|
||||
|
||||
private static string[] GetFormNames4Dex(int species)
|
||||
private void LoadGenders(bool seen)
|
||||
{
|
||||
string[] formNames = FormConverter.GetFormList(species, GameInfo.Strings.types, GameInfo.Strings.forms, Main.GenderSymbols, 4);
|
||||
if (species == (int)Species.Pichu)
|
||||
formNames = new[] { MALE, FEMALE, formNames[1] }; // Spiky
|
||||
return formNames;
|
||||
var dex = SAV.Dex;
|
||||
var first = seen ? LB_Gender : LB_NGender;
|
||||
var second = dex.GetSeenSingleGender(species) ? LB_NGender : first;
|
||||
|
||||
LB_Gender.Items.Clear();
|
||||
LB_NGender.Items.Clear();
|
||||
var pi = SAV.Personal[species];
|
||||
var gr = pi.Gender;
|
||||
switch (gr)
|
||||
{
|
||||
case 255: // Genderless
|
||||
first.Items.Add(GENDERLESS);
|
||||
break;
|
||||
case 0:
|
||||
first.Items.Add(MALE);
|
||||
break;
|
||||
case 254:
|
||||
first.Items.Add(FEMALE);
|
||||
break;
|
||||
default:
|
||||
var firstFem = dex.GetSeenGenderFirst(species) == 1;
|
||||
first.Items.Add(firstFem ? FEMALE : MALE);
|
||||
second.Items.Add(firstFem ? MALE : FEMALE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetEntry()
|
||||
|
@ -164,73 +161,34 @@ namespace PKHeX.WinForms
|
|||
if (species < 0)
|
||||
return;
|
||||
|
||||
int bit = species - 1;
|
||||
byte mask = (byte)(1 << (bit & 7));
|
||||
int ofs = SAV.PokeDex + (bit >> 3) + 0x4;
|
||||
|
||||
// Check if already Seen
|
||||
if (!CHK_Seen.Checked || LB_Gender.Items.Count == 0)
|
||||
var dex = SAV.Dex;
|
||||
dex.SetCaught(species, CHK_Caught.Checked);
|
||||
dex.SetSeen(species, CHK_Seen.Checked);
|
||||
dex.SetSeenGenderNeither(species);
|
||||
if (LB_Gender.Items.Count != 0)
|
||||
{
|
||||
SAV.General[ofs + (brSize * 0)] &= (byte)~mask;
|
||||
SAV.General[ofs + (brSize * 1)] &= (byte)~mask;
|
||||
SAV.General[ofs + (brSize * 2)] &= (byte)~mask;
|
||||
SAV.General[ofs + (brSize * 3)] &= (byte)~mask;
|
||||
}
|
||||
else // Is Seen
|
||||
{
|
||||
// Set the Species Owned Flag
|
||||
if (CHK_Caught.Checked)
|
||||
SAV.General[ofs + (brSize * 0)] |= mask;
|
||||
else
|
||||
SAV.General[ofs + (brSize * 0)] &= (byte)~mask;
|
||||
|
||||
SAV.General[ofs + (brSize * 1)] |= mask;
|
||||
switch ((string)LB_Gender.Items[0])
|
||||
{
|
||||
case GENDERLESS:
|
||||
SAV.General[ofs + (brSize * 2)] &= (byte)~mask;
|
||||
SAV.General[ofs + (brSize * 3)] &= (byte)~mask;
|
||||
break;
|
||||
case FEMALE:
|
||||
SAV.General[ofs + (brSize * 2)] |= mask; // set
|
||||
if (LB_Gender.Items.Count != 1) // Male present
|
||||
SAV.General[ofs + (brSize * 3)] &= (byte)~mask; // unset
|
||||
else
|
||||
SAV.General[ofs + (brSize * 3)] |= mask; // set
|
||||
break;
|
||||
case MALE:
|
||||
SAV.General[ofs + (brSize * 2)] &= (byte)~mask; // unset
|
||||
if (LB_Gender.Items.Count != 1) // Female present
|
||||
SAV.General[ofs + (brSize * 3)] |= mask; // set
|
||||
else
|
||||
SAV.General[ofs + (brSize * 3)] &= (byte)~mask; // unset
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Invalid Gender???");
|
||||
}
|
||||
var femaleFirst = LB_Gender.Items[0].ToString() == FEMALE;
|
||||
var firstGender = femaleFirst ? 1 : 0;
|
||||
dex.SetSeenGenderNew(species, firstGender);
|
||||
if (LB_Gender.Items.Count != 1)
|
||||
dex.SetSeenGenderSecond(species, firstGender ^ 1);
|
||||
}
|
||||
|
||||
int FormOffset1 = SAV.PokeDex + 4 + (4 * brSize) + 4;
|
||||
int PokeDexLanguageFlags = FormOffset1 + (SAV.HGSS ? 0x3C : 0x20);
|
||||
int l_ofs = !SAV.DP ? species : (1 + Array.IndexOf(DPLangSpecies, species));
|
||||
if (l_ofs > 0)
|
||||
if (dex.HasLanguage(species))
|
||||
{
|
||||
l_ofs += PokeDexLanguageFlags;
|
||||
for (int i = 0; i < LangCount; i++)
|
||||
SAV.SetFlag(l_ofs, i, CL[i].Checked);
|
||||
dex.SetLanguageBitIndex(species, i, CL[i].Checked);
|
||||
}
|
||||
|
||||
var forms = SAV.GetForms(species);
|
||||
var forms = SAV.Dex.GetForms(species);
|
||||
if (forms.Length > 0)
|
||||
{
|
||||
int[] arr = new int[LB_Form.Items.Count];
|
||||
string[] formNames = GetFormNames4Dex(species);
|
||||
for (int i = 0; i < LB_Form.Items.Count; i++)
|
||||
arr[i] = Array.IndexOf(formNames, (string)LB_Form.Items[i]);
|
||||
SAV.SetForms(species, arr);
|
||||
SAV.Dex.SetForms(species, arr);
|
||||
}
|
||||
|
||||
editing = false;
|
||||
}
|
||||
|
||||
private void B_Cancel_Click(object sender, EventArgs e)
|
||||
|
@ -250,21 +208,10 @@ namespace PKHeX.WinForms
|
|||
|
||||
private void B_GiveAll_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (GB_Language.Enabled)
|
||||
{
|
||||
CHK_L1.Checked =
|
||||
CHK_L2.Checked =
|
||||
CHK_L3.Checked =
|
||||
CHK_L4.Checked =
|
||||
CHK_L5.Checked =
|
||||
CHK_L6.Checked = ModifierKeys != Keys.Control;
|
||||
}
|
||||
CHK_Caught.Checked = CHK_Seen.Checked = ModifierKeys != Keys.Control;
|
||||
|
||||
if (ModifierKeys == Keys.Control)
|
||||
SeenNone();
|
||||
else
|
||||
SeenAll();
|
||||
bool all = ModifierKeys != Keys.Control;
|
||||
var args = all ? SetDexArgs.Complete : SetDexArgs.None;
|
||||
SAV.Dex.ModifyAll(species, args, GetGen4LanguageBitIndex(SAV.Language));
|
||||
GetEntry();
|
||||
}
|
||||
|
||||
private void B_Modify_Click(object sender, EventArgs e)
|
||||
|
@ -273,67 +220,28 @@ namespace PKHeX.WinForms
|
|||
modifyMenu.Show(btn.PointToScreen(new Point(0, btn.Height)));
|
||||
}
|
||||
|
||||
private void SeenNone()
|
||||
{
|
||||
LB_NGender.Items.AddRange(LB_Gender.Items);
|
||||
LB_Gender.Items.Clear();
|
||||
|
||||
LB_NForm.Items.AddRange(LB_Form.Items);
|
||||
LB_Form.Items.Clear();
|
||||
CHK_Seen.Checked = false;
|
||||
foreach (var c in CL)
|
||||
c.Checked = false;
|
||||
}
|
||||
|
||||
private void SeenAll()
|
||||
{
|
||||
LB_Gender.Items.AddRange(LB_NGender.Items);
|
||||
LB_NGender.Items.Clear();
|
||||
|
||||
LB_Form.Items.AddRange(LB_NForm.Items);
|
||||
LB_NForm.Items.Clear();
|
||||
CHK_Seen.Checked = true;
|
||||
}
|
||||
|
||||
private void ModifyAll(object sender, EventArgs e)
|
||||
{
|
||||
int lang = SAV.Language - 1;
|
||||
if (lang is < 0 or > 5) // KOR or Invalid
|
||||
lang = 0;
|
||||
SetEntry();
|
||||
|
||||
bool seenA = sender == mnuSeenAll || sender == mnuCaughtAll || sender == mnuComplete;
|
||||
bool seenN = sender == mnuSeenNone;
|
||||
bool caughtA = sender == mnuCaughtAll || sender == mnuComplete;
|
||||
bool caughtN = sender == mnuCaughtNone || sender == mnuSeenNone;
|
||||
var lang = GetGen4LanguageBitIndex(SAV.Language);
|
||||
SetDexArgs args;
|
||||
if (sender == mnuComplete)
|
||||
args = SetDexArgs.Complete;
|
||||
else if (sender == mnuCaughtAll)
|
||||
args = SetDexArgs.CaughtAll;
|
||||
else if (sender == mnuCaughtNone)
|
||||
args = SetDexArgs.CaughtNone;
|
||||
else if (sender == mnuSeenAll)
|
||||
args = SetDexArgs.SeenAll;
|
||||
else
|
||||
args = SetDexArgs.None;
|
||||
|
||||
for (int i = 0; i < LB_Species.Items.Count; i++)
|
||||
{
|
||||
LB_Species.SelectedIndex = i;
|
||||
SAV.Dex.ModifyAll(i + 1, args, lang);
|
||||
|
||||
if (seenN) // move all to none
|
||||
SeenNone();
|
||||
else if (seenA) // move all to seen
|
||||
SeenAll();
|
||||
|
||||
if (caughtA)
|
||||
{
|
||||
CHK_Caught.Checked = true;
|
||||
for (int j = 0; j < CL.Length; j++) // set SAV language (and others if Complete)
|
||||
CL[j].Checked = sender == mnuComplete || (mnuCaughtNone != sender && j == lang);
|
||||
}
|
||||
else if (caughtN)
|
||||
{
|
||||
CHK_Caught.Checked = false;
|
||||
}
|
||||
else if (!CHK_Seen.Checked)
|
||||
{
|
||||
foreach (CheckBox t in CL)
|
||||
t.Checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
SetEntry();
|
||||
GetEntry();
|
||||
System.Media.SystemSounds.Asterisk.Play();
|
||||
}
|
||||
|
||||
private void CHK_Seen_CheckedChanged(object sender, EventArgs e)
|
||||
|
@ -342,8 +250,8 @@ namespace PKHeX.WinForms
|
|||
{
|
||||
if (!CHK_Seen.Checked) // move all to none
|
||||
{
|
||||
CHK_Caught.Checked = false;
|
||||
SeenNone();
|
||||
SAV.Dex.ClearSeen(species);
|
||||
GetEntry();
|
||||
}
|
||||
else if (LB_NGender.Items.Count > 0)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue