Relocate gen6 trainer stat records to core

use trainerstat editor control in gen6 editor

fill in some details from the disassembly via setrecord usages
still slightly fuzzy on some:
fureai (based on usum idb name, similar logic)
soaring sky counts

looks like there's some other usages of the fields which were outside
the stat range, throwing an exception when loading to NumericUpDown,
added bypass logic

Thanks Holla!
This commit is contained in:
Kurt 2018-08-06 21:27:31 -07:00
parent 37e5c9fc69
commit 98f21a12dd
6 changed files with 272 additions and 249 deletions

View file

@ -7,7 +7,7 @@ namespace PKHeX.Core
/// <summary>
/// Generation 6 <see cref="SaveFile"/> object.
/// </summary>
public sealed class SAV6 : SaveFile
public sealed class SAV6 : SaveFile, ITrainerStatRecord
{
// Save Data Attributes
protected override string BAKText => $"{OT} ({Version}) - {LastSavedTime}";
@ -94,7 +94,7 @@ namespace PKHeX.Core
/* 12: */ // = 0x04C00; [00004] // 87B1A23F const
/* 13: */ // = 0x04E00; [00048] // Repel Info, (Swarm?) and other overworld info
/* 14: */ SUBE = 0x05000;
/* 15: */ PSSStats = 0x05400;
/* 15: */ Record = 0x05400;
OFS_PouchHeldItem = Bag + 0;
OFS_PouchKeyItem = Bag + 0x640;
@ -118,7 +118,7 @@ namespace PKHeX.Core
TrainerCard = 0x14000;
Party = 0x14200;
EventConst = 0x14A00;
PSSStats = 0x1E400;
Record = 0x1E400;
PokeDex = 0x15000;
Fused = 0x16000;
OPower = 0x16A00;
@ -174,7 +174,7 @@ namespace PKHeX.Core
BerryField = 0x1C400;
WondercardFlags = 0x1CC00;
SUBE = 0x1D890;
PSSStats = 0x1F400;
Record = 0x1F400;
SuperTrain = 0x20200;
LinkInfo = 0x20E00;
Contest = 0x23600;
@ -221,7 +221,7 @@ namespace PKHeX.Core
// Accessible as SAV6
public int TrainerCard { get; private set; } = 0x14000;
public int PCFlags { get; private set; } = int.MinValue;
public int PSSStats { get; private set; } = int.MinValue;
public int Record { get; private set; } = int.MinValue;
public int MaisonStats { get; private set; } = int.MinValue;
public int EonTicket { get; private set; } = int.MinValue;
public int PCBackgrounds { get; private set; } = int.MinValue;
@ -500,8 +500,6 @@ namespace PKHeX.Core
public override int SecondsToStart { get => BitConverter.ToInt32(Data, AdventureInfo + 0x18); set => BitConverter.GetBytes(value).CopyTo(Data, AdventureInfo + 0x18); }
public override int SecondsToFame { get => BitConverter.ToInt32(Data, AdventureInfo + 0x20); set => BitConverter.GetBytes(value).CopyTo(Data, AdventureInfo + 0x20); }
public uint GetPSSStat(int index) { return BitConverter.ToUInt32(Data, PSSStats + 4*index); }
public void SetPSSStat(int index, uint value) { BitConverter.GetBytes(value).CopyTo(Data, PSSStats + 4*index); }
public ushort GetMaisonStat(int index) { return BitConverter.ToUInt16(Data, MaisonStats + 2 * index); }
public void SetMaisonStat(int index, ushort value) { BitConverter.GetBytes(value).CopyTo(Data, MaisonStats + 2*index); }
public uint GetEncounterCount(int index) { return BitConverter.ToUInt16(Data, EncounterCount + 2*index); }
@ -1049,5 +1047,30 @@ namespace PKHeX.Core
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
}.CopyTo(Data, Accessories);
}
public int RecordCount => 200;
public int GetRecord(int recordID)
{
int ofs = Records.GetOffset(Record, recordID);
if (recordID < 100)
return BitConverter.ToInt32(Data, ofs);
if (recordID < 200)
return BitConverter.ToInt16(Data, ofs);
return 0;
}
public void SetRecord(int recordID, int value)
{
int ofs = Records.GetOffset(Record, recordID);
var maxes = XY ? Records.MaxType_XY : Records.MaxType_AO;
int max = Records.GetMax(recordID, maxes);
if (value > max)
return; // out of range, don't set value
if (recordID < 100)
BitConverter.GetBytes(value).CopyTo(Data, ofs);
if (recordID < 200)
BitConverter.GetBytes((ushort)value).CopyTo(Data, ofs);
}
public int GetRecordMax(int recordID) => Records.GetMax(recordID, XY ? Records.MaxType_XY : Records.MaxType_AO);
public int GetRecordOffset(int recordID) => Records.GetOffset(Record, recordID);
}
}

View file

@ -32,13 +32,13 @@ namespace PKHeX.Core
private static readonly int[] MaxByType = {999999999, 9999999, 999999, 99999, 65535, 9999, 999, 7};
public static int[] SpecialIndexes_6 = {29, 30, 110, 111, 112, 113, 114, 115, 116, 117};
public static int[] SpecialIndexes_7 = {22, 23, 110, 111, 112, 113, 114, 115, 116, 117};
public static int[] DailyPairs_6 = {29, 30, 110, 111, 112, 113, 114, 115, 116, 117};
public static int[] DailyPairs_7 = {22, 23, 110, 111, 112, 113, 114, 115, 116, 117};
/// <summary>
/// Festa pairs; if updating the lower index record, update the Festa Mission record if currently active?
/// </summary>
public static int[] FestaPairs_USUM =
public static int[] FestaPairs_7 =
{
175, 6,
176, 33,
@ -151,6 +151,192 @@ namespace PKHeX.Core
5, 5, 4, 4, 4, 5, 5, 4, 5, 5
};
public static readonly Dictionary<int, string> RecordList_6 = new Dictionary<int, string>
{
{000, "Steps Taken"},
{001, "Times Saved"},
{002, "Storyline Completed Time"},
{003, "Times Bicycled"},
{004, "Total Battles"},
{005, "Wild Pokémon Battles"},
{006, "Trainer Battles"},
{007, "Pokemon Caught"},
{008, "Pokemon Caught Fishing"},
{009, "Eggs Hatched"},
{010, "Pokémon Evolved"},
{011, "Pokémon Healed at Pokémon Centers"},
{012, "Link Trades"},
{013, "Link Battles"},
{014, "Link Battle Wins"},
{015, "Link Battle Losses"},
{016, "WiFi Trades"},
{017, "WiFi Battles"},
{018, "WiFi Battle Wins"},
{019, "WiFi Battle Losses"},
{020, "IR Trades"},
{021, "IR Battles"},
{022, "IR Battle Wins"},
{023, "IR Battle Losses"},
{024, "Mart Stack Purchases"},
{025, "Money Spent"},
{026, "Times watched TV"},
{027, "Pokémon deposited at Nursery"},
{028, "Pokémon Defeated"},
{029, "Exp. Points Collected (Highest)"},
{030, "Exp. Points Collected (Today)"},
{031, "Deposited in the GTS"},
{032, "Nicknames Given"},
{033, "Bonus Premier Balls Received"},
{034, "Battle Points Earned"},
{035, "Battle Points Spent"},
{037, "Tips at Restaurant: ★☆☆"},
{038, "Tips at Restaurant: ★★☆"},
{039, "Tips at Restaurant: ★★★"},
{040, "Tips at Restaurant: Sushi High Roller"},
{041, "Tips at Café 1"},
{042, "Tips at Café 2"},
{043, "Tips at Café 3"},
{044, "Tips at Cameraman"},
{045, "Tips at Drink Vendors"},
{046, "Tips at Poet"},
{047, "Tips at Furfrou Trimmer"},
{048, "Tips at Battle Maison 1"},
{049, "Tips at Battle Maison 2"},
{050, "Tips at Battle Maison 3"},
{051, "Tips at Battle Maison 4"},
{052, "Tips at Maid"},
{053, "Tips at Butler"},
{054, "Tips at Scary House"},
{055, "Tips at Traveling Minstrel"},
{056, "Tips at Special BGM 1"},
{057, "Tips at Special BGM 2"},
{058, "Tips at Frieser Furfrou"},
{059, "Nice! Received"},
{060, "Birthday Wishes"},
{061, "Total People Met Online"},
{062, "Total People Passed By"},
{063, "Current Pokemiles"},
{064, "Total Pokemiles Received"},
{065, "Total Pokemiles sent to PGL"},
{066, "Total Super Training Attempts"},
{067, "Total Super Training Cleared"},
{068, "IV Judge Evaluations"},
{069, "Trash Cans inspected"},
{070, "Inverse Battles"},
{071, "Maison Battles"},
{072, "Times changed character clothing"},
{073, "Times changed character hairstyle"},
{074, "Berries harvested"},
{075, "Berry Field mutations"},
{076, "PR Videos"},
{077, "Friend Safari Encounters"},
{078, "O-Powers Used"},
{079, "Secret Base Updates"},
{080, "Secret Base Flags Captured"},
{081, "Contests Participated Count"},
{082, "GTS Trades"},
{083, "Wonder Trades"},
{084, "Steps Sneaked"},
{085, "Multiplayer Contests"},
{086, "Pokeblocks used"},
{087, "Times AreaNav Used"},
{088, "Times DexNav Used"},
{089, "Times BuzzNav Used"},
{090, "Times PlayNav Used"},
{100, "Champion Title Defense"},
{101, "Times rested at home"},
{102, "Times Splash used"},
{103, "Times Struggle used"},
{104, "Moves used with No Effect"},
{105, "Own Fainted Pokémon"},
{106, "Times attacked ally in battle"},
{107, "Failed Run Attempts"},
{108, "Wild encounters that fled"},
{109, "Failed Fishing Attempts"},
{110, "Pokemon Defeated (Highest)"},
{111, "Pokemon Defeated (Today)"},
{112, "Pokemon Caught (Highest)"},
{113, "Pokemon Caught (Today)"},
{114, "Trainers Battled (Highest)"},
{115, "Trainers Battled (Today)"},
{116, "Pokemon Evolved (Highest)"},
{117, "Pokemon Evolved (Today)"},
{118, "Fossils Restored"},
{119, "Sweet Scent Encounters"},
{120, "Battle Institute Tests"},
{121, "Battle Institute Rank"},
{122, "Battle Institute Score"},
{123, "Last Tip at Restaurant: ★☆☆"},
{124, "Last Tip at Restaurant: ★★☆"},
{125, "Last Tip at Restaurant: ★★★"},
{126, "Last Tip at Restaurant: Sushi High Roller"},
{127, "Last Tip at Café 1"},
{128, "Last Tip at Café 2"},
{129, "Last Tip at Café 3"},
{130, "Last Tip at Cameraman"},
{131, "Last Tip at Drink Vendors"},
{132, "Last Tip at Poet"},
{133, "Last Tip at Furfrou Trimmer"},
{134, "Last Tip at Battle Maison 1"},
{135, "Last Tip at Battle Maison 2"},
{136, "Last Tip at Battle Maison 3"},
{137, "Last Tip at Battle Maison 4"},
{138, "Last Tip at Maid"},
{139, "Last Tip at Butler"},
{140, "Last Tip at Scary House"},
{141, "Last Tip at Traveling Minstrel"},
{142, "Last Tip at Special BGM 1"},
{143, "Last Tip at Special BGM 2"},
{144, "Last Tip at Frieser Furfrou"},
{145, "Photos Taken"},
{146, "Sky Wild Battles (?)"},
{147, "Battle Maison Streak: Singles"},
{148, "Battle Maison Streak: Doubles"},
{149, "Battle Maison Streak: Triples"},
{150, "Battle Maison Streak: Rotation"},
{151, "Battle Maison Streak: Multi"},
{152, "Loto-ID Wins"},
{153, "PP Ups used"},
{154, "PSS Passerby Count (Today)"},
{155, "Amie Used"},
{156, "Roller Skate Count: Spin Left"},
{157, "Roller Skate Count: Spin Right"},
{158, "Roller Skate Count: Running Start"},
{159, "Roller Skate Count: Parallel Swizzle"},
{160, "Roller Skate Count: Drift-and-dash"},
{161, "Roller Skate Count: 360 right"},
{162, "Roller Skate Count: 360 left"},
{163, "Roller Skate Count: Flips"},
{164, "Roller Skate Count: Grind"},
{165, "Roller Skate Count: Combos"},
{166, "Fishing Chains"},
{167, "Secret Base Battles in your base"},
{168, "Secret Base Battles in another base"},
{169, "Contest Spectacular Photos taken"},
{170, "Times used Fly"},
{171, "Times used Soaring in the Sky"},
{172, "Times used Dive"},
{173, "Times used Sky Holes"},
{174, "Times healed by Mom"},
{175, "Times used Escape Rope"},
{176, "Times used Dowsing Machine"},
{177, "Trainer's Eye Rematches"},
{178, "FUREAI Interest ???"}, // similar to USUM idb
{179, "Shiny Pokemon Encountered"},
{180, "Trick House Clears"},
{181, "Eon Ticket 1 (Spotpass)"},
{182, "Eon Ticket 2 (Mystery Gift)"},
};
public static readonly Dictionary<int, string> RecordList_7 = new Dictionary<int, string>
{
{000, "Steps Taken"},
@ -226,9 +412,14 @@ namespace PKHeX.Core
{074, "Battle Agency Wins"},
{100, "Champion Title Defense"},
{101, "Times rested at home"},
{102, "Times Splash used"},
{103, "Times Struggle used"},
{104, "Moves used with No Effect"},
{105, "Own Fainted Pokémon"},
{106, "Times attacked ally in battle"},
{107, "Failed Run Attempts"},
{108, "Wild encounters that fled"},
{109, "Failed Fishing Attempts"},
{110, "Pokemon Defeated (Highest)"},
{111, "Pokemon Defeated (Today)"},

View file

@ -213,7 +213,7 @@ namespace PKHeX.WinForms
private void B_Save_Click(object sender, EventArgs e)
{
uint flags = Util.ToUInt32(MT_Flags.Text);
Array.Copy(BitConverter.GetBytes(flags), 0, SAV.Data, SAV.PSSStats + 0x140, 4); // write pss
Array.Copy(BitConverter.GetBytes(flags), 0, SAV.Data, SAV.Record + 0x140, 4); // write pss
Array.Copy(BitConverter.GetBytes(flags), 0, SAV.Data, SAV.SecretBase + 0x62C, 4); // write counter
Origin.SetData(SAV.Data, 0);
Close();

View file

@ -173,10 +173,6 @@ namespace PKHeX.WinForms
this.L_MultiplayerSprite = new System.Windows.Forms.Label();
this.PB_Sprite = new System.Windows.Forms.PictureBox();
this.CB_MultiplayerSprite = new System.Windows.Forms.ComboBox();
this.L_Offset = new System.Windows.Forms.Label();
this.CB_Stats = new System.Windows.Forms.ComboBox();
this.L_Value = new System.Windows.Forms.Label();
this.MT_Stat = new System.Windows.Forms.MaskedTextBox();
this.TC_Editor = new System.Windows.Forms.TabControl();
this.Tab_Overview = new System.Windows.Forms.TabPage();
this.GB_Stats = new System.Windows.Forms.GroupBox();
@ -205,6 +201,7 @@ namespace PKHeX.WinForms
this.Tab_Appearance = new System.Windows.Forms.TabPage();
this.L_TRNick = new System.Windows.Forms.Label();
this.TB_TRNick = new System.Windows.Forms.TextBox();
this.TrainerStats = new PKHeX.WinForms.Subforms.Save_Editors.TrainerStat();
((System.ComponentModel.ISupportInitialize)(this.PB_Badge8)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.PB_Badge6)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.PB_Badge4)).BeginInit();
@ -1714,49 +1711,6 @@ namespace PKHeX.WinForms
this.CB_MultiplayerSprite.TabIndex = 25;
this.CB_MultiplayerSprite.SelectedIndexChanged += new System.EventHandler(this.CB_Multi_SelectedIndexChanged);
//
// L_Offset
//
this.L_Offset.AutoSize = true;
this.L_Offset.Location = new System.Drawing.Point(22, 126);
this.L_Offset.Name = "L_Offset";
this.L_Offset.Size = new System.Drawing.Size(39, 13);
this.L_Offset.TabIndex = 28;
this.L_Offset.Text = "(offset)";
//
// CB_Stats
//
this.CB_Stats.DropDownHeight = 156;
this.CB_Stats.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.CB_Stats.DropDownWidth = 180;
this.CB_Stats.FormattingEnabled = true;
this.CB_Stats.IntegralHeight = false;
this.CB_Stats.Location = new System.Drawing.Point(25, 86);
this.CB_Stats.Name = "CB_Stats";
this.CB_Stats.Size = new System.Drawing.Size(121, 21);
this.CB_Stats.TabIndex = 23;
this.CB_Stats.SelectedIndexChanged += new System.EventHandler(this.ChangeStat);
//
// L_Value
//
this.L_Value.AutoSize = true;
this.L_Value.Location = new System.Drawing.Point(22, 110);
this.L_Value.Name = "L_Value";
this.L_Value.Size = new System.Drawing.Size(34, 13);
this.L_Value.TabIndex = 22;
this.L_Value.Text = "Value";
//
// MT_Stat
//
this.MT_Stat.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.MT_Stat.Location = new System.Drawing.Point(69, 107);
this.MT_Stat.Mask = "0000000000";
this.MT_Stat.Name = "MT_Stat";
this.MT_Stat.Size = new System.Drawing.Size(77, 20);
this.MT_Stat.TabIndex = 21;
this.MT_Stat.Text = "1231231234";
this.MT_Stat.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.MT_Stat.TextChanged += new System.EventHandler(this.ChangeStatVal);
//
// TC_Editor
//
this.TC_Editor.Controls.Add(this.Tab_Overview);
@ -1805,16 +1759,13 @@ namespace PKHeX.WinForms
//
// GB_Stats
//
this.GB_Stats.Controls.Add(this.TrainerStats);
this.GB_Stats.Controls.Add(this.TB_BP);
this.GB_Stats.Controls.Add(this.TB_PM);
this.GB_Stats.Controls.Add(this.L_PM);
this.GB_Stats.Controls.Add(this.TB_Style);
this.GB_Stats.Controls.Add(this.L_Offset);
this.GB_Stats.Controls.Add(this.L_BP);
this.GB_Stats.Controls.Add(this.L_Value);
this.GB_Stats.Controls.Add(this.L_Style);
this.GB_Stats.Controls.Add(this.MT_Stat);
this.GB_Stats.Controls.Add(this.CB_Stats);
this.GB_Stats.Location = new System.Drawing.Point(209, 99);
this.GB_Stats.Name = "GB_Stats";
this.GB_Stats.Size = new System.Drawing.Size(171, 151);
@ -2183,6 +2134,13 @@ namespace PKHeX.WinForms
this.TB_TRNick.Text = "WWWWWWWWWWWW";
this.TB_TRNick.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// TrainerStats
//
this.TrainerStats.Location = new System.Drawing.Point(23, 81);
this.TrainerStats.Name = "TrainerStats";
this.TrainerStats.Size = new System.Drawing.Size(146, 72);
this.TrainerStats.TabIndex = 9;
//
// SAV_Trainer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -2352,10 +2310,6 @@ namespace PKHeX.WinForms
private System.Windows.Forms.Label L_MultiplayerSprite;
private System.Windows.Forms.PictureBox PB_Sprite;
private System.Windows.Forms.ComboBox CB_MultiplayerSprite;
private System.Windows.Forms.ComboBox CB_Stats;
private System.Windows.Forms.Label L_Value;
private System.Windows.Forms.MaskedTextBox MT_Stat;
private System.Windows.Forms.Label L_Offset;
private System.Windows.Forms.Label L_Seconds;
private System.Windows.Forms.Label L_Minutes;
private System.Windows.Forms.MaskedTextBox MT_Seconds;
@ -2414,5 +2368,6 @@ namespace PKHeX.WinForms
private System.Windows.Forms.Label L_TRNick;
private System.Windows.Forms.TextBox TB_TRNick;
private System.Windows.Forms.CheckBox CHK_MegaUnlocked;
private Subforms.Save_Editors.TrainerStat TrainerStats;
}
}

View file

@ -32,6 +32,9 @@ namespace PKHeX.WinForms
CB_Gender.Items.Clear();
CB_Gender.Items.AddRange(Main.GenderSymbols.Take(2).ToArray()); // m/f depending on unicode selection
TrainerStats.LoadRecords(SAV, Records.RecordList_6);
TrainerStats.GetToolTipText = UpdateTip;
MaisonRecords = new[]
{
TB_MCSN,TB_MCSS,TB_MBSN,TB_MBSS,
@ -55,175 +58,15 @@ namespace PKHeX.WinForms
if (SAV.MaisonStats < 0)
TC_Editor.TabPages.Remove(Tab_Maison);
editing = true;
GetComboBoxes();
GetTextBoxes();
GetBadges();
statdata = new[] {
"0x000", "0x000", // Steps taken?
"0x004", "0x004", // Minutes Played / Pokemon Encountered?
"0x008", "0x008",
"0x00C", "0x00C",
"0x010", "0x010",
"0x014", "0x014",
"0x018", "0x018",
"0x01C", "Pokémon Captured",
"0x020", "0x020",
"0x024", "Eggs Hatched",
"0x028", "Pokémon Evolved",
"0x02C", "0x02C",
"0x030", "~People Passed", // I think the following ones are Passerby actions...
"0x034", "0x034",
"0x038", "0x038",
"0x03C", "0x03C",
"0x040", "Link Trades",
"0x044", "Link Battles",
"0x048", "Link Battle Wins",
"0x04C", "0x04C",
"0x050", "0x050",
"0x054", "0x054",
"0x058", "0x058",
"0x05C", "0x05C",
"0x060", "0x060",
"0x064", "0x064",
"0x068", "0x068",
"0x06C", "0x06C",
"0x070", "0x070",
"0x074", "0x074",
"0x078", "0x078",
"0x07C", "0x07C",
"0x080", "0x080",
"0x084", "0x084",
"0x088", "BP Earned",
"0x08C", "0x08C",
"0x090", "0x090",
"0x094", "0x094",
"0x098", "0x098",
"0x09C", "0x09C",
"0x0A0", "0x0A0",
"0x0A4", "0x0A4",
"0x0A8", "0x0A8",
"0x0AC", "0x0AC",
"0x0B0", "0x0B0",
"0x0B4", "0x0B4",
"0x0B8", "0x0B8",
"0x0BC", "0x0BC",
"0x0C0", "0x0C0",
"0x0C4", "0x0C4",
"0x0C8", "0x0C8",
"0x0CC", "0x0CC",
"0x0D0", "0x0D0",
"0x0D4", "0x0D4",
"0x0D8", "0x0D8",
"0x0DC", "0x0DC",
"0x0E0", "0x0E0",
"0x0E4", "0x0E4",
"0x0E8", "0x0E8",
"0x0EC", "Nice! Received",
"0x0F0", "Birthday Wishes",
"0x0F4", "Total People Met Online",
"0x0F8", "0x0F8",
//"0x0FC", "Current Pokemiles",
"0x100", "Obtained Pokemiles",
"0x104", "0x104",
"0x108", "0x108",
"0x10C", "Super Training Clears",
"0x110", "Judge Evaluations",
"0x114", "0x114",
"0x118", "0x118", // Link Trades?
"0x11C", "Link Battle", // Wins", // ?
"0x120", "0x120", // Link Battle Losses?
"0x124", "0x124",
"0x128", "0x128",
"0x12C", "0x12C",
"0x130", "0x130",
"0x134", "0x134",
"0x138", "0x138",
"0x13C", "0x13C",
"0x140", "Flags Captured",
"0x144", "0x144",
"0x148", "0x148",
"0x14C", "0x14C",
"0x150", "0x150",
"0x154", "0x154",
"0x158", "0x158",
"0x15C", "0x15C",
"0x160", "0x160",
"0x164", "0x164",
"0x168", "0x168",
"0x16C", "0x16C",
"0x170", "0x170",
"0x174", "0x174",
"0x178", "0x178",
"0x17C", "0x17C",
"0x180", "0x180",
"0x184", "0x184",
"0x188", "0x188",
"0x18C", "0x18C",
"0x190", "0x190",
"0x194", "0x194",
"0x198", "0x198",
"0x19C", "0x19C",
"0x1A0", "0x1A0",
"0x1A4", "0x1A4",
"0x1A8", "0x1A8",
"0x1AC", "0x1AC",
"0x1B0", "0x1B0",
"0x1B4", "0x1B4",
"0x1B8", "0x1B8",
"0x1BC", "Battle Tests",
"0x1C0", "0x1C0",
"0x1C4", "0x1C4",
"0x1C8", "0x1C8",
"0x1CC", "0x1CC",
"0x1D0", "0x1D0",
"0x1D4", "0x1D4",
"0x1D8", "0x1D8",
"0x1DC", "0x1DC",
"0x1E0", "0x1E0",
"0x1E4", "0x1E4",
"0x1E8", "0x1E8",
"0x1EC", "0x1EC",
"0x1F0", "0x1F0",
"0x1F4", "0x1F4",
"0x1F8", "0x1F8",
"0x1FC", "0x1FC",
"0x200", "0x200",
"0x204", "0x204",
"0x208", "0x208",
"0x20C", "0x20C",
"0x210", "0x210",
"0x214", "0x214",
"0x218", "0x218",
"0x21C", "0x21C",
"0x220", "0x220",
"0x224", "0x224",
"0x228", "0x228",
"0x22C", "0x22C",
"0x230", "0x230",
"0x234", "0x234",
"0x238", "0x238",
"0x23C", "0x23C",
"0x240", "0x240",
"0x244", "0x244",
"0x248", "0x248",
"0x24C", "0x24C",
"0x250", "0x250",
"0x254", "0x254",
"0x258", "0x258",
}; // Offset, Title. Horrible implementation, but works.
CB_Stats.Items.Clear();
for (int i = 0; i < statdata.Length / 2; i++)
CB_Stats.Items.Add(statdata[(2 * i) + 1]);
CB_Stats.SelectedIndex = 0;
editing = false;
CHK_MegaUnlocked.Checked = SAV.IsMegaEvolutionUnlocked;
}
private readonly string[] statdata;
private bool editing;
private readonly bool editing = true;
private readonly ToolTip Tip1 = new ToolTip(), Tip2 = new ToolTip();
private readonly MaskedTextBox[] MaisonRecords;
private readonly CheckBox[] cba;
@ -421,7 +264,7 @@ namespace PKHeX.WinForms
// Load BP and PokeMiles
TB_BP.Text = SAV.BP.ToString();
TB_PM.Text = SAV.GetPSSStat(0xFC/4).ToString();
TB_PM.Text = SAV.GetRecord(63).ToString();
TB_Style.Text = SAV.Style.ToString();
@ -516,9 +359,9 @@ namespace PKHeX.WinForms
SAV.BP = ushort.Parse(TB_BP.Text);
// Set Current PokéMiles
SAV.SetPSSStat(0xFC / 4, Util.ToUInt32(TB_PM.Text));
SAV.SetRecord(63, Util.ToInt32(TB_PM.Text));
// Set Max Obtained Pokémiles
SAV.SetPSSStat(0x100 / 4, Util.ToUInt32(TB_PM.Text));
SAV.SetRecord(64, Util.ToInt32(TB_PM.Text));
SAV.Style = byte.Parse(TB_Style.Text);
// Copy Badges
@ -640,22 +483,6 @@ namespace PKHeX.WinForms
if (Util.ToInt32(box.Text) > 65535) box.Text = "65535";
}
private void ChangeStat(object sender, EventArgs e)
{
editing = true;
int offset = Convert.ToInt32(statdata[CB_Stats.SelectedIndex * 2].Substring(2), 16);
MT_Stat.Text = SAV.GetPSSStat(offset/4).ToString();
L_Offset.Text = $"0x{offset:X3}";
editing = false;
}
private void ChangeStatVal(object sender, EventArgs e)
{
if (editing) return;
int offset = Convert.ToInt32(statdata[CB_Stats.SelectedIndex * 2].Substring(2), 16);
SAV.SetPSSStat(offset/4, uint.Parse(MT_Stat.Text));
}
private void GiveAllAccessories(object sender, EventArgs e)
{
SAV.UnlockAllAccessories();
@ -686,5 +513,31 @@ namespace PKHeX.WinForms
SAV.MultiplayerSpriteID = WinFormsUtil.GetIndex(CB_MultiplayerSprite);
PB_Sprite.Image = SAV.Sprite();
}
private string UpdateTip(int index)
{
switch (index)
{
case 2: // Storyline Completed Time
int seconds = (int)(CAL_AdventureStartDate.Value - new DateTime(2000, 1, 1)).TotalSeconds;
seconds -= seconds % 86400;
seconds += (int)(CAL_AdventureStartTime.Value - new DateTime(2000, 1, 1)).TotalSeconds;
return ConvertDateValueToString(SAV.GetRecord(index), seconds);
default:
return null;
}
}
private static string ConvertDateValueToString(int value, int secondsBias = -1)
{
const int spd = 86400; // seconds per day
string tip = string.Empty;
if (value >= spd)
tip += (value / spd) + "d ";
tip += new DateTime(0).AddSeconds(value).ToString("HH:mm:ss");
if (secondsBias >= 0)
tip += Environment.NewLine + $"Date: {new DateTime(2000, 1, 1).AddSeconds(value + secondsBias)}";
return tip;
}
}
}

View file

@ -34,8 +34,9 @@ namespace PKHeX.WinForms.Subforms.Save_Editors
{
Editing = true;
int index = CB_Stats.SelectedIndex;
NUD_Stat.Maximum = SAV.GetRecordMax(index);
NUD_Stat.Value = SAV.GetRecord(index);
int val = SAV.GetRecord(index);
NUD_Stat.Maximum = Math.Max(val, SAV.GetRecordMax(index));
NUD_Stat.Value = val;
int offset = SAV.GetRecordOffset(index);
L_Offset.Text = $"Offset: 0x{offset:X3}";