Merge branch 'master' of https://github.com/kwsch/PKHeX into rhydon-merge

Merge master to verify Main menu compatibility.
This commit is contained in:
Michael Scire
2016-08-29 20:03:00 -07:00
12 changed files with 466 additions and 179 deletions

View File

@@ -525,7 +525,7 @@ private static IEnumerable<DexLevel> getValidPreEvolutions(PK6 pk6, int lvl = -1
if (lvl >= pk6.Met_Level && lvl >= evo.Level)
dl.Add(new DexLevel {Species = evo.Species, Level = lvl});
else break;
if (evo.Level > 1) // Level Up (from previous level)
if (evo.Level > 2) // Level Up (from previous level)
lvl--;
}
return dl;

View File

@@ -3008,6 +3008,7 @@ public void InitializeComponent()
this.tabBoxMulti.Size = new System.Drawing.Size(310, 225);
this.tabBoxMulti.TabIndex = 50;
this.tabBoxMulti.Click += new System.EventHandler(this.clickBoxSort);
this.tabBoxMulti.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.clickBoxDouble);
//
// Tab_Box
//

View File

@@ -151,6 +151,7 @@ public Main()
public static string[] wallpapernames, puffs = { };
public static bool unicode;
public static List<ComboItem> MoveDataSource, ItemDataSource, SpeciesDataSource, BallDataSource, NatureDataSource, AbilityDataSource, VersionDataSource;
private static List<ComboItem> metGen1, metGen2, metGen3, metGen4, metGen5, metGen6;
public static volatile bool formInitialized, fieldsInitialized, fieldsLoaded;
private static int colorizedbox = -1;
@@ -172,7 +173,7 @@ public Main()
"中文", // CHN
"Português", // Portuguese
};
private static string origintrack;
private static GameVersion origintrack;
private readonly PictureBox[] SlotPictureBoxes, movePB, relearnPB;
private readonly ToolTip Tip1 = new ToolTip(), Tip2 = new ToolTip(), Tip3 = new ToolTip(), NatureTip = new ToolTip();
#endregion
@@ -1122,7 +1123,7 @@ private void InitializeStrings()
abilitylist[0] = itemlist[0] = movelist[0] = metXY_00000[0] = metBW2_00000[0] = metHGSS_00000[0] = "(" + itemlist[0] + ")";
// Force an update to the met locations
origintrack = "";
origintrack = GameVersion.Unknown;
// Update Legality Analysis strings
LegalityAnalysis.movelist = movelist;
@@ -1179,6 +1180,48 @@ private void InitializeLanguage()
MoveDataSource = Util.getCBList(movelist, null);
#region Met Locations
// Gen 3
{
var met_list = Util.getCBList(metRSEFRLG_00000, Enumerable.Range(0, 213).ToArray());
met_list = Util.getOffsetCBList(met_list, metRSEFRLG_00000, 00000, new[] { 253, 254, 255 });
metGen3 = met_list;
}
// Gen 4
{
var met_list = Util.getCBList(metHGSS_00000, new[] { 0 });
met_list = Util.getOffsetCBList(met_list, metHGSS_02000, 2000, new[] { 2000 });
met_list = Util.getOffsetCBList(met_list, metHGSS_02000, 2000, new[] { 2002 });
met_list = Util.getOffsetCBList(met_list, metHGSS_03000, 3000, new[] { 3001 });
met_list = Util.getOffsetCBList(met_list, metHGSS_00000, 0000, Legal.Met_HGSS_0);
met_list = Util.getOffsetCBList(met_list, metHGSS_02000, 2000, Legal.Met_HGSS_2);
met_list = Util.getOffsetCBList(met_list, metHGSS_03000, 3000, Legal.Met_HGSS_3);
metGen4 = met_list;
}
// Gen 5
{
var met_list = Util.getCBList(metBW2_00000, new[] { 0 });
met_list = Util.getOffsetCBList(met_list, metBW2_60000, 60001, new[] { 60002 });
met_list = Util.getOffsetCBList(met_list, metBW2_30000, 30001, new[] { 30003 });
met_list = Util.getOffsetCBList(met_list, metBW2_00000, 00000, Legal.Met_BW2_0);
met_list = Util.getOffsetCBList(met_list, metBW2_30000, 30001, Legal.Met_BW2_3);
met_list = Util.getOffsetCBList(met_list, metBW2_40000, 40001, Legal.Met_BW2_4);
met_list = Util.getOffsetCBList(met_list, metBW2_60000, 60001, Legal.Met_BW2_6);
metGen5 = met_list;
}
// Gen 6
{
var met_list = Util.getCBList(metXY_00000, new[] { 0 });
met_list = Util.getOffsetCBList(met_list, metXY_60000, 60001, new[] { 60002 });
met_list = Util.getOffsetCBList(met_list, metXY_30000, 30001, new[] { 30002 });
met_list = Util.getOffsetCBList(met_list, metXY_00000, 00000, Legal.Met_XY_0);
met_list = Util.getOffsetCBList(met_list, metXY_30000, 30001, Legal.Met_XY_3);
met_list = Util.getOffsetCBList(met_list, metXY_40000, 40001, Legal.Met_XY_4);
met_list = Util.getOffsetCBList(met_list, metXY_60000, 60001, Legal.Met_XY_6);
metGen6 = met_list;
}
#endregion
CB_EncounterType.DataSource = Util.getCBList(encountertypelist, new[] { 0 }, Legal.Gen4EncounterTypes);
CB_HPType.DataSource = Util.getCBList(types.Skip(1).Take(16).ToArray(), null);
CB_Nature.DataSource = new BindingSource(NatureDataSource, null);
@@ -1812,7 +1855,10 @@ private void updateForm(object sender, EventArgs e)
if (Util.getIndex(CB_Species) == 201)
{
if (fieldsLoaded && SAV.Generation == 3)
updateRandomPID(sender, e); // Fix AltForm
{
pkm.setPIDUnown3(CB_Form.SelectedIndex);
TB_PID.Text = pkm.PID.ToString("X8");
}
}
else if (PKX.getGender(CB_Form.Text) < 2)
Label_Gender.Text = CB_Form.Text;
@@ -1963,114 +2009,112 @@ private void updateSpecies(object sender, EventArgs e)
updateLegality();
}
private IEnumerable<ComboItem> getLocationList(GameVersion Version, int SaveFormat, bool egg)
{
if (egg)
{
if (Version < GameVersion.W && SaveFormat >= 5)
return metGen4;
}
switch (Version)
{
case GameVersion.CXD:
if (SaveFormat == 3)
return metGen3;
break;
case GameVersion.R:
case GameVersion.S:
if (SaveFormat == 3)
return metGen3.OrderByDescending(loc => loc.Value <= 87); // Ferry
break;
case GameVersion.E:
if (SaveFormat == 3)
return metGen3.OrderByDescending(loc => loc.Value <= 87 || (loc.Value >= 196 && loc.Value <= 212)); // Trainer Hill
break;
case GameVersion.FR:
case GameVersion.LG:
if (SaveFormat == 3)
return metGen3.OrderByDescending(loc => loc.Value > 87 && loc.Value < 197); // Celadon Dept.
break;
case GameVersion.D:
case GameVersion.P:
if (SaveFormat == 4 || (SaveFormat >= 5 && egg))
return metGen4.Take(4).Concat(metGen6.Skip(4).OrderByDescending(loc => loc.Value <= 111)); // Battle Park
break;
case GameVersion.Pt:
if (SaveFormat == 4 || (SaveFormat >= 5 && egg))
return metGen4.Take(4).Concat(metGen6.Skip(4).OrderByDescending(loc => loc.Value <= 125)); // Rock Peak Ruins
break;
case GameVersion.HG:
case GameVersion.SS:
if (SaveFormat == 4 || (SaveFormat >= 5 && egg))
return metGen4.Take(4).Concat(metGen6.Skip(4).OrderByDescending(loc => loc.Value > 125 && loc.Value < 234)); // Celadon Dept.
break;
case GameVersion.B:
case GameVersion.W:
return metGen5;
case GameVersion.B2:
case GameVersion.W2:
return metGen5.Take(3).Concat(metGen5.Skip(3).OrderByDescending(loc => loc.Value <= 116)); // Abyssal Ruins
case GameVersion.X:
case GameVersion.Y:
return metGen6.Take(3).Concat(metGen6.Skip(3).OrderByDescending(loc => loc.Value <= 168)); // Unknown Dungeon
case GameVersion.OR:
case GameVersion.AS:
return metGen6.Take(3).Concat(metGen6.Skip(3).OrderByDescending(loc => loc.Value > 168 && loc.Value <= 354)); // Secret Base
}
// Currently on a future game, return corresponding list for generation
if (Version <= GameVersion.CXD && SaveFormat == 4)
return metGen4.Where(loc => loc.Value == 0x37) // Pal Park to front
.Concat(metGen4.Take(4))
.Concat(metGen4.Skip(4).Where(loc => loc.Value != 0x37));
if (Version < GameVersion.X && SaveFormat >= 5) // PokéTransfer to front
return metGen5.Where(loc => loc.Value == 30001)
.Concat(metGen5.Take(3))
.Concat(metGen5.Skip(3).Where(loc => loc.Value != 30001));
return metGen6;
}
private void updateOriginGame(object sender, EventArgs e)
{
int Version = Util.getIndex(CB_GameOrigin);
if (SAV.Generation == 3 && origintrack != "Gen3")
GameVersion Version = (GameVersion)Util.getIndex(CB_GameOrigin);
// check if differs
GameVersion newTrack = SaveUtil.getVersionGroup(Version);
if (newTrack != origintrack)
{
var met_list = Util.getCBList(metRSEFRLG_00000, Enumerable.Range(0, 213).ToArray());
met_list = Util.getOffsetCBList(met_list, metRSEFRLG_00000, 00000, new[] {253, 254, 255});
origintrack = "Gen3";
var met_list = getLocationList(Version, SAV.Generation, egg:false);
CB_MetLocation.DisplayMember = "Text";
CB_MetLocation.ValueMember = "Value";
CB_MetLocation.DataSource = met_list;
CB_MetLocation.SelectedValue = 0;
}
else if (SAV.Generation == 4 && origintrack != "Gen4")
{
var met_list = Util.getCBList(metHGSS_00000, new[] { 0 });
met_list = Util.getOffsetCBList(met_list, metHGSS_02000, 2000, new[] { 2000 });
met_list = Util.getOffsetCBList(met_list, metHGSS_02000, 2000, new[] { 2002 });
met_list = Util.getOffsetCBList(met_list, metHGSS_03000, 3000, new[] { 3001 });
met_list = Util.getOffsetCBList(met_list, metHGSS_00000, 0000, Legal.Met_HGSS_0);
met_list = Util.getOffsetCBList(met_list, metHGSS_02000, 2000, Legal.Met_HGSS_2);
met_list = Util.getOffsetCBList(met_list, metHGSS_03000, 3000, Legal.Met_HGSS_3);
CB_MetLocation.DisplayMember = "Text";
CB_MetLocation.ValueMember = "Value";
CB_MetLocation.DataSource = met_list;
CB_MetLocation.DataSource = new BindingSource(met_list, null);
CB_MetLocation.SelectedIndex = 0; // transporter or pal park for past gen pkm
var egg_list = getLocationList(Version, SAV.Generation, egg:true);
CB_EggLocation.DisplayMember = "Text";
CB_EggLocation.ValueMember = "Value";
CB_EggLocation.DataSource = new BindingSource(met_list, null);
CB_EggLocation.SelectedValue = 0;
CB_MetLocation.SelectedValue = 0;
origintrack = "Gen4";
}
else if (Version < 24 && origintrack != "Past" && SAV.Generation >= 5)
{
// Load Past Gen Locations
#region B2W2 Met Locations
{
// Build up our met list
var met_list = Util.getCBList(metBW2_00000, new[] { 0 });
met_list = Util.getOffsetCBList(met_list, metBW2_60000, 60001, new[] { 60002 });
met_list = Util.getOffsetCBList(met_list, metBW2_30000, 30001, new[] { 30003 });
met_list = Util.getOffsetCBList(met_list, metBW2_00000, 00000, Legal.Met_BW2_0);
met_list = Util.getOffsetCBList(met_list, metBW2_30000, 30001, Legal.Met_BW2_3);
met_list = Util.getOffsetCBList(met_list, metBW2_40000, 40001, Legal.Met_BW2_4);
met_list = Util.getOffsetCBList(met_list, metBW2_60000, 60001, Legal.Met_BW2_6);
CB_MetLocation.DisplayMember = "Text";
CB_MetLocation.ValueMember = "Value";
CB_MetLocation.DataSource = met_list;
CB_EggLocation.DisplayMember = "Text";
CB_EggLocation.ValueMember = "Value";
CB_EggLocation.DataSource = new BindingSource(met_list, null);
CB_EggLocation.SelectedValue = 0;
CB_MetLocation.SelectedValue = Version < 20 ? 30001 : 60001;
origintrack = "Past";
}
#endregion
}
else if (Version > 23 && origintrack != "XY")
{
// Load X/Y/OR/AS locations
#region ORAS Met Locations
{
// Build up our met list
var met_list = Util.getCBList(metXY_00000, new[] { 0 });
met_list = Util.getOffsetCBList(met_list, metXY_60000, 60001, new[] { 60002 });
met_list = Util.getOffsetCBList(met_list, metXY_30000, 30001, new[] { 30002 });
met_list = Util.getOffsetCBList(met_list, metXY_00000, 00000, Legal.Met_XY_0);
met_list = Util.getOffsetCBList(met_list, metXY_30000, 30001, Legal.Met_XY_3);
met_list = Util.getOffsetCBList(met_list, metXY_40000, 40001, Legal.Met_XY_4);
met_list = Util.getOffsetCBList(met_list, metXY_60000, 60001, Legal.Met_XY_6);
CB_MetLocation.DisplayMember = "Text";
CB_MetLocation.ValueMember = "Value";
CB_MetLocation.DataSource = met_list;
CB_EggLocation.DisplayMember = "Text";
CB_EggLocation.ValueMember = "Value";
CB_EggLocation.DataSource = new BindingSource(met_list, null);
CB_EggLocation.SelectedValue = 0;
CB_MetLocation.SelectedValue = 0;
origintrack = "XY";
}
#endregion
}
CB_EggLocation.DataSource = new BindingSource(egg_list, null);
CB_EggLocation.SelectedIndex = CHK_AsEgg.Checked ? 1 : 0; // daycare : none
if (SAV.Generation >= 4 && Version < 0x10 && origintrack != "Gen4")
{
// Load Gen 4 egg locations if Gen 4 Origin.
#region HGSS Met Locations
var met_list = Util.getCBList(metHGSS_00000, new[] { 0 });
met_list = Util.getOffsetCBList(met_list, metHGSS_02000, 2000, new[] { 2000 });
met_list = Util.getOffsetCBList(met_list, metHGSS_02000, 2000, new[] { 2002 });
met_list = Util.getOffsetCBList(met_list, metHGSS_03000, 3000, new[] { 3001 });
met_list = Util.getOffsetCBList(met_list, metHGSS_00000, 0000, Legal.Met_HGSS_0);
met_list = Util.getOffsetCBList(met_list, metHGSS_02000, 2000, Legal.Met_HGSS_2);
met_list = Util.getOffsetCBList(met_list, metHGSS_03000, 3000, Legal.Met_HGSS_3);
CB_EggLocation.DisplayMember = "Text";
CB_EggLocation.ValueMember = "Value";
CB_EggLocation.DataSource = met_list;
CB_EggLocation.SelectedValue = 0;
origintrack = "Gen4";
#endregion
origintrack = newTrack;
}
// Visibility logic for Gen 4 encounter type; only show for Gen 4 Pokemon.
if (SAV.Generation >= 4)
{
bool g4 = Version >= 7 && Version <= 12 && Version != 9;
bool g4 = Version >= GameVersion.HG && Version <= GameVersion.Pt;
if ((int) Version == 9) // invalid
g4 = false;
CB_EncounterType.Visible = Label_EncounterType.Visible = g4;
if (!g4)
CB_EncounterType.SelectedValue = 0;
@@ -2079,7 +2123,7 @@ private void updateOriginGame(object sender, EventArgs e)
setMarkings(); // Set/Remove KB marking
if (!fieldsLoaded)
return;
pkm.Version = Version;
pkm.Version = (int)Version;
updateLegality();
}
private void updateExtraByteValue(object sender, EventArgs e)
@@ -2325,28 +2369,13 @@ private void validateMove(object sender, EventArgs e)
if (new[] { CB_Move1, CB_Move2, CB_Move3, CB_Move4 }.Contains(sender)) // Move
updatePP(sender, e);
// Refresh Relearn if...
if (new[] { CB_RelearnMove1, CB_RelearnMove2, CB_RelearnMove3, CB_RelearnMove4 }.Contains(sender))
{
if (pkm.Format < 6)
return;
((PK6) pkm).RelearnMoves = new[] { Util.getIndex(CB_RelearnMove1), Util.getIndex(CB_RelearnMove2), Util.getIndex(CB_RelearnMove3), Util.getIndex(CB_RelearnMove4) };
Legality.updateRelearnLegality();
for (int i = 0; i < 4; i++)
movePB[i].Visible = !Legality.vRelearn[i].Valid;
}
// else, Refresh Moves
{
pkm.Moves = new[] { Util.getIndex(CB_Move1), Util.getIndex(CB_Move2), Util.getIndex(CB_Move3), Util.getIndex(CB_Move4) };
Legality.updateMoveLegality();
for (int i = 0; i < 4; i++)
movePB[i].Visible = !Legality.vMoves[i].Valid;
}
if (relearnPB.Any(p => p.Visible) || movePB.Any(p => p.Visible))
{
Legality.Valid = false;
PB_Legal.Image = Properties.Resources.warn;
}
if (pkm.Format < 6)
return;
// Legality
pkm.Moves = new[] { Util.getIndex(CB_Move1), Util.getIndex(CB_Move2), Util.getIndex(CB_Move3), Util.getIndex(CB_Move4) };
pkm.RelearnMoves = new[] { Util.getIndex(CB_RelearnMove1), Util.getIndex(CB_RelearnMove2), Util.getIndex(CB_RelearnMove3), Util.getIndex(CB_RelearnMove4) };
updateLegality();
}
private void validateLocation(object sender, EventArgs e)
{
@@ -2382,8 +2411,15 @@ private void updateLegality(LegalityAnalysis la = null)
// Refresh Move Legality
for (int i = 0; i < 4; i++)
movePB[i].Visible = !Legality.vMoves[i].Valid && !HaX;
int[] suggested = Legality.getSuggestedRelearn();
for (int i = 0; i < 4; i++)
relearnPB[i].Visible = !Legality.vRelearn[i].Valid && !HaX;
{
if (pkm.RelearnMoves[i] == 0 && suggested[i] != 0)
relearnPB[i].Visible = !HaX;
else
relearnPB[i].Visible = !Legality.vRelearn[i].Valid && !HaX;
}
}
private void updateStats()
{
@@ -2718,14 +2754,20 @@ private void clickBoxSort(object sender, EventArgs e)
setPKXBoxes();
Util.Alert("Current Box sorted!");
}
else if (ModifierKeys == Keys.Shift)
}
private void clickBoxDouble(object sender, MouseEventArgs e)
{
if (tabBoxMulti.SelectedIndex != 0)
return;
if (!SAV.HasBox)
return;
if (ModifierKeys != Keys.Shift)
{
var z = Application.OpenForms.Cast<Form>().FirstOrDefault(form => form.GetType() == typeof(SAV_BoxViewer)) as SAV_BoxViewer;
if (z != null)
{ Util.CenterToForm(z, this); z.BringToFront(); return; }
new SAV_BoxViewer(this).Show();
}
new SAV_BoxViewer(this).Show();
}
public int swapBoxesViewer(int viewBox)
{

View File

@@ -411,18 +411,6 @@ public int OppositeFriendship
public bool IsUntraded => string.IsNullOrWhiteSpace(HT_Name);
public bool IsUntradedEvent6 => Geo1_Country == 0 && Geo1_Region == 0 && Met_Location / 10000 == 4 && Gen6;
public int[] RelearnMoves
{
get { return 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];
}
}
// Complex Generated Attributes
public override int Characteristic

View File

@@ -287,6 +287,17 @@ public int[] Moves
get { return new[] { Move1, Move2, Move3, Move4 }; }
set { if (value?.Length != 4) return; Move1 = value[0]; Move2 = value[1]; Move3 = value[2]; Move4 = value[3]; }
}
public int[] RelearnMoves
{
get { return 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 int PIDAbility
{
get
@@ -465,5 +476,9 @@ public void setPIDNature(int nature)
if (GenNumber < 6)
EncryptionConstant = PID;
}
public void setPIDUnown3(int form)
{
do PID = Util.rnd32(); while (PKX.getUnownForm(PID) != form);
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -687,12 +687,162 @@ protected override void setDex(PKM pkm)
int bit = pkm.Species - 1;
// Set the Species Owned Flag
Data[PokeDex + brSize * 0 + bit / 8 + 0x4] |= (byte)(1 << (bit % 8));
Data[PokeDex + brSize*0 + bit/8 + 0x4] |= (byte) (1 << (bit%8));
// Set the Species Seen Flag
Data[PokeDex + brSize * 1 + bit / 8 + 0x4] |= (byte)(1 << (bit % 8));
Data[PokeDex + brSize*1 + bit/8 + 0x4] |= (byte) (1 << (bit%8));
// Formes : todo
int FormOffset1 = PokeDex + 0x108;
int PokeDexLanguageFlags = FormOffset1 + 0x20;
// Formes : Castform & Cherrim do not have entries (Battle Only formes)
// Lowest sub-value of formevalue is displayed, else is order of formes displayed.
// Deoxys forms 1-2 are stored in the last byte of the first bitRegion.
// Deoxys forms 3-4 are stored in the last byte of the second bitRegion.
if (pkm.Species == 386)
{
uint val = (uint)(Data[PokeDex + 0x4 + 1*brSize - 1] | Data[PokeDex + 0x4 + 2*brSize - 1] << 8);
int[] forms = getDexFormValues(val, 4, 4);
checkInsertForm(ref forms, pkm.AltForm);
uint newval = setDexFormValues(forms, 4, 4);
Data[PokeDex + 0x4 + 1*brSize - 1] = (byte)(newval & 0xFF);
Data[PokeDex + 0x4 + 2*brSize - 1] = (byte)((newval>>8) & 0xFF);
}
// After the BitRegions is 0x20 bytes for the rest of the formes.
// Standard Forme Bytes (DP)
// [Shellos-Gastrodon-Burmy-Wormadam],[Unown*0x1C]
if (pkm.Species == 422) // Shellos
{
int[] forms = getDexFormValues(Data[FormOffset1 + 0], 2, 2);
checkInsertForm(ref forms, pkm.AltForm);
uint newval = setDexFormValues(forms, 2, 2);
Data[FormOffset1 + 0] = (byte)newval;
}
if (pkm.Species == 423) // Gastrodon
{
int[] forms = getDexFormValues(Data[FormOffset1 + 1], 2, 2);
checkInsertForm(ref forms, pkm.AltForm);
uint newval = setDexFormValues(forms, 2, 2);
Data[FormOffset1 + 1] = (byte)newval;
}
if (pkm.Species == 412) // Burmy
{
int[] forms = getDexFormValues(Data[FormOffset1 + 2], 2, 3);
checkInsertForm(ref forms, pkm.AltForm);
uint newval = setDexFormValues(forms, 2, 3);
Data[FormOffset1 + 2] = (byte)newval;
}
if (pkm.Species == 413) // Wormadam
{
int[] forms = getDexFormValues(Data[FormOffset1 + 3], 2, 3);
checkInsertForm(ref forms, pkm.AltForm);
uint newval = setDexFormValues(forms, 2, 3);
Data[FormOffset1 + 3] = (byte)newval;
}
if (pkm.Species == 201) // Unown
{
for (int i = 0; i < 0x1C; i++)
{
byte val = Data[FormOffset1 + 4 + i];
if (val == pkm.AltForm)
break; // already set
if (val != 0xFF)
continue; // keep searching
Data[FormOffset1 + 4 + i] = (byte)pkm.AltForm;
break; // form now set
}
}
// DP stops here.
if (DP)
return;
// Set the Language
int lang = pkm.Language - 1;
if (lang > 5) lang = 0; // no KOR
if (lang < 0) lang = 1;
Data[PokeDexLanguageFlags + pkm.Species] |= (byte) (1 << lang);
int FormOffset2 = PokeDexLanguageFlags + 0x210;
// PtHGSS added more forms.
// [Rotom*4-highest bits unused],[Shaymin],[Giratina],[Pichu-HGSS ONLY]
if (pkm.Species == 479) // Rotom
{
int[] forms = getDexFormValues(BitConverter.ToUInt32(Data, FormOffset2), 3, 6);
checkInsertForm(ref forms, pkm.AltForm);
uint newval = setDexFormValues(forms, 3, 6);
BitConverter.GetBytes(newval).CopyTo(Data, FormOffset2);
}
if (pkm.Species == 492) // Shaymin
{
int[] forms = getDexFormValues(Data[FormOffset2 + 4], 2, 2);
uint newval = setDexFormValues(forms, 2, 2);
Data[FormOffset1 + 3] = (byte)newval;
}
if (pkm.Species == 487) // Giratina
{
int[] forms = getDexFormValues(Data[FormOffset2 + 5], 2, 2);
uint newval = setDexFormValues(forms, 2, 2);
Data[FormOffset1 + 3] = (byte)newval;
}
if (pkm.Species == 172 && HGSS) // Pichu
{
int[] forms = getDexFormValues(Data[FormOffset2 + 6], 2, 3);
uint newval = setDexFormValues(forms, 2, 3);
Data[FormOffset1 + 3] = (byte)newval;
}
}
private 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)
Forms[i] = -1;
else
Forms[i] = val;
}
return Forms;
}
private uint setDexFormValues(int[] Forms, int BitsPerForm, int readCt)
{
int n1 = 0xFF >> (8 - BitsPerForm);
uint Value = 0xFFFFFFFF << (Forms.Length*BitsPerForm);
for (int i = 0; i < Forms.Length; i++)
{
int val = Forms[i];
if (val == -1)
val = n1;
Value |= (uint)(val << (BitsPerForm*i));
}
return Value;
}
private bool checkInsertForm(ref int[] Forms, int FormNum)
{
if (Forms.Any(num => num == FormNum))
{
return false; // already in list
}
if (Forms.All(num => num == -1))
{
Forms[0] = FormNum;
return true; // none in list, insert at top
}
// insert at first empty
int n1 = Array.IndexOf(Forms, -1);
if (n1 < 0)
return false;
Forms[n1] = FormNum;
return true;
}
}
}

View File

@@ -622,25 +622,47 @@ protected override void setDex(PKM pkm)
int shiftoff = shiny * brSize * 2 + gender * brSize + brSize;
// Set the Species Owned Flag
Data[PokeDex + bit / 8 + 0x8] |= (byte)(1 << (bit % 8));
Data[PokeDex + 0x8 + bit / 8] |= (byte)(1 << (bit % 8));
// Set the [Species/Gender/Shiny] Seen Flag
Data[PokeDex + shiftoff + bit / 8 + 0x8] |= (byte)(1 << (bit % 8));
Data[PokeDex + 0x8 + shiftoff + bit / 8] |= (byte)(1 << (bit % 8));
// Set the Display flag if none are set
bool Displayed = false;
Displayed |= (Data[PokeDex + brSize * 5 + bit / 8 + 0x8] & (byte)(1 << (bit % 8))) != 0;
Displayed |= (Data[PokeDex + brSize * 6 + bit / 8 + 0x8] & (byte)(1 << (bit % 8))) != 0;
Displayed |= (Data[PokeDex + brSize * 7 + bit / 8 + 0x8] & (byte)(1 << (bit % 8))) != 0;
Displayed |= (Data[PokeDex + brSize * 8 + bit / 8 + 0x8] & (byte)(1 << (bit % 8))) != 0;
if (!Displayed) // offset is already biased by 0x60, reuse shiftoff but for the display flags.
Data[PokeDex + shiftoff + brSize * 4 + bit / 8 + 0x8] |= (byte)(1 << (bit % 8));
Displayed |= (Data[PokeDex + 0x8 + brSize*5 + bit/8] & (byte)(1 << (bit%8))) != 0;
Displayed |= (Data[PokeDex + 0x8 + brSize*6 + bit/8] & (byte)(1 << (bit%8))) != 0;
Displayed |= (Data[PokeDex + 0x8 + brSize*7 + bit/8] & (byte)(1 << (bit%8))) != 0;
Displayed |= (Data[PokeDex + 0x8 + brSize*8 + bit/8] & (byte)(1 << (bit%8))) != 0;
if (!Displayed) // offset is already biased by brSize, reuse shiftoff but for the display flags.
Data[PokeDex + 0x8 + shiftoff + brSize*4 + bit/8] |= (byte)(1 << (bit%8));
// Set the Language
if (lang < 0) lang = 1;
Data[PokeDexLanguageFlags + (bit * 7 + lang) / 8] |= (byte)(1 << ((bit * 7 + lang) % 8));
Data[PokeDexLanguageFlags + (bit*7 + lang) / 8] |= (byte)(1 << ((bit*7 + lang) % 8));
// Formes : todo
// Formes
int fc = Personal[pkm.Species].FormeCount;
int f = B2W2 ? SaveUtil.getDexFormIndexB2W2(pkm.Species, fc) : SaveUtil.getDexFormIndexBW(pkm.Species, fc);
if (f < 0) return;
int FormLen = B2W2 ? 0xB : 0x9;
int FormDex = PokeDex + 0x8 + brSize*9;
bit = f + pkm.AltForm;
// Set Form Seen Flag
Data[FormDex + FormLen*shiny + bit/8] |= (byte)(1 << (bit%8));
// Set Displayed Flag if necessary, check all flags
for (int i = 0; i < fc; i++)
{
bit = f + i;
if ((Data[FormDex + FormLen*2 + bit/8] & (byte)(1 << (bit%8))) != 0) // Nonshiny
return; // already set
if ((Data[FormDex + FormLen*3 + bit/8] & (byte)(1 << (bit%8))) != 0) // Shiny
return; // already set
}
bit = f + pkm.AltForm;
Data[FormDex + FormLen * (2 + shiny) + bit / 8] |= (byte)(1 << (bit % 8));
}
}
}

View File

@@ -730,35 +730,33 @@ protected override void setDex(PKM pkm)
if (lang < 0) lang = 1;
Data[PokeDexLanguageFlags + (bit * 7 + lang) / 8] |= (byte)(1 << ((bit * 7 + lang) % 8));
// Set Form flags
int fc = Personal[pkm.Species].FormeCount;
int f = ORAS ? SaveUtil.getDexFormIndexORAS(pkm.Species, fc) : SaveUtil.getDexFormIndexXY(pkm.Species, fc);
if (f >= 0)
{
int FormLen = ORAS ? 0x26 : 0x18;
int FormDex = PokeDex + 0x368;
bit = f + pkm.AltForm;
// Set Seen Flag
Data[FormDex + FormLen * shiny + bit / 8] |= (byte)(1 << (bit % 8));
// Set Displayed Flag if necessary, check all flags
bool FormDisplayed = false;
for (int i = 0; i < fc; i++)
{
bit = f + i;
FormDisplayed |= (Data[FormDex + FormLen * 2 + bit / 8] & (byte)(1 << (bit % 8))) != 0; // Nonshiny
FormDisplayed |= (Data[FormDex + FormLen * 3 + bit / 8] & (byte)(1 << (bit % 8))) != 0; // Shiny
}
if (!FormDisplayed)
{
bit = f + pkm.AltForm;
Data[FormDex + FormLen * (2 + shiny) + bit / 8] |= (byte)(1 << (bit % 8));
}
}
// Set DexNav count (only if not encountered previously)
if (ORAS && getEncounterCount(pkm.Species - 1) == 0)
setEncounterCount(pkm.Species - 1, 1);
// Set Form flags
int fc = Personal[pkm.Species].FormeCount;
int f = ORAS ? SaveUtil.getDexFormIndexORAS(pkm.Species, fc) : SaveUtil.getDexFormIndexXY(pkm.Species, fc);
if (f < 0) return;
int FormLen = ORAS ? 0x26 : 0x18;
int FormDex = PokeDex + 0x8 + brSize*9;
bit = f + pkm.AltForm;
// Set Form Seen Flag
Data[FormDex + FormLen*shiny + bit/8] |= (byte)(1 << (bit%8));
// Set Displayed Flag if necessary, check all flags
for (int i = 0; i < fc; i++)
{
bit = f + i;
if ((Data[FormDex + FormLen*2 + bit/8] & (byte) (1 << (bit%8))) != 0) // Nonshiny
return; // already set
if ((Data[FormDex + FormLen*3 + bit/8] & (byte) (1 << (bit%8))) != 0) // Shiny
return; // already set
}
bit = f + pkm.AltForm;
Data[FormDex + FormLen * (2 + shiny) + bit / 8] |= (byte)(1 << (bit % 8));
}
public override byte[] decryptPKM(byte[] data)
{

View File

@@ -205,6 +205,59 @@ public static GameVersion getIsG6SAV(byte[] data)
return GameVersion.Invalid;
}
/// <summary>Determines the Version Grouping of an input Version ID</summary>
/// <param name="Version">Version of which to determine the group</param>
/// <returns>Version Group Identifier or Invalid if type cannot be determined.</returns>
public static GameVersion getVersionGroup(GameVersion Version)
{
switch (Version)
{
case GameVersion.CXD:
return GameVersion.CXD;
case GameVersion.R:
case GameVersion.S:
return GameVersion.RS;
case GameVersion.E:
return GameVersion.E;
case GameVersion.FR:
case GameVersion.LG:
return GameVersion.FR;
case GameVersion.D:
case GameVersion.P:
return GameVersion.DP;
case GameVersion.Pt:
return GameVersion.Pt;
case GameVersion.HG:
case GameVersion.SS:
return GameVersion.HGSS;
case GameVersion.B:
case GameVersion.W:
return GameVersion.BW;
case GameVersion.B2:
case GameVersion.W2:
return GameVersion.B2W2;
case GameVersion.X:
case GameVersion.Y:
return GameVersion.XY;
case GameVersion.OR:
case GameVersion.AS:
return GameVersion.ORAS;
default:
return GameVersion.Invalid;
}
}
/// <summary>Creates an instance of a SaveFile using the given save data.</summary>
/// <param name="data">Save data from which to create a SaveFile.</param>
/// <returns>An appropriate type of save file for the given data, or null if the save data is invalid.</returns>
@@ -335,7 +388,7 @@ internal static ushort check32(byte[] data)
return (ushort)((val & 0xFFFF) + (val >> 16));
}
public static int getDexFormIndexXY(int species, int formct)
public static int getDexFormIndexBW(int species, int formct)
{
if (formct < 1 || species < 0)
return -1; // invalid
@@ -357,11 +410,29 @@ public static int getDexFormIndexXY(int species, int formct)
case 648: return 066; // 2 Meloetta
case 555: return 068; // 2 Darmanitan
case 550: return 070; // 2 Basculin
default: return -1;
}
}
public static int getDexFormIndexB2W2(int species, int formct)
{
if (formct < 1 || species < 0)
return -1; // invalid
switch (species)
{
case 646: return 072; // 3 Kyurem
case 647: return 075; // 2 Keldeo
case 642: return 077; // 2 Thundurus
case 641: return 079; // 2 Tornadus
case 645: return 081; // 2 Landorus
default: return getDexFormIndexBW(species, formct);
}
}
public static int getDexFormIndexXY(int species, int formct)
{
if (formct < 1 || species < 0)
return -1; // invalid
switch (species)
{
case 666: return 083; // 20 Vivillion
case 669: return 103; // 5 Flabébé
case 670: return 108; // 6 Floette
@@ -398,7 +469,7 @@ public static int getDexFormIndexXY(int species, int formct)
case 445: return 183; // 2 Garchomp
case 448: return 185; // 2 Lucario
case 460: return 187; // 2 Abomasnow
default: return -1;
default: return getDexFormIndexB2W2(species, formct);
}
}
public static int getDexFormIndexORAS(int species, int formct)