Add gen3 record editing

in misc edits window
This commit is contained in:
Kurt 2019-02-19 20:46:58 -08:00
parent fb8aa3bba0
commit fa4318ae2f
4 changed files with 357 additions and 9 deletions

View file

@ -325,7 +325,7 @@ namespace PKHeX.Core
// Trainer Info
public override GameVersion Version { get; protected set; }
private uint SecurityKey
public uint SecurityKey
{
get
{

View file

@ -0,0 +1,277 @@
using System;
using System.Collections.Generic;
namespace PKHeX.Core
{
public sealed class Record3
{
private readonly SAV3 SAV;
public uint GetRecord(int record) => BitConverter.ToUInt32(SAV.Data, GetRecordOffset(record)) ^ GetKey(SAV);
public void SetRecord(int record, uint value) => SAV.SetData(BitConverter.GetBytes(value ^ GetKey(SAV)), GetRecordOffset(record));
private int GetRecordOffset(int record)
{
var baseOffset = GetOffset(SAV.Version);
var offset = baseOffset + (4 * record);
SAV3.GetLargeBlockOffset(offset, out var chunk, out var ofs);
return SAV.GetBlockOffset(chunk) + ofs;
}
public Record3(SAV3 sav) => SAV = sav;
public static int GetOffset(GameVersion ver)
{
switch (ver)
{
case GameVersion.RS:
return 0x1540;
case GameVersion.FRLG:
return 0x1200;
case GameVersion.E:
return 0x159C;
default:
throw new ArgumentException(nameof(ver));
}
}
public static uint GetKey(SAV3 sav)
{
if (sav.Version == GameVersion.RS)
return 0;
return sav.SecurityKey;
}
public static int[] GetEnumValues(GameVersion ver)
{
switch (ver)
{
case GameVersion.RS:
return (int[])Enum.GetValues(typeof(RecID3RuSa));
case GameVersion.FRLG:
return (int[])Enum.GetValues(typeof(RecID3FRLG));
case GameVersion.E:
return (int[])Enum.GetValues(typeof(RecID3Emerald));
default:
throw new ArgumentException(nameof(ver));
}
}
public static string[] GetEnumNames(GameVersion ver)
{
switch (ver)
{
case GameVersion.RS:
return Enum.GetNames(typeof(RecID3RuSa));
case GameVersion.FRLG:
return Enum.GetNames(typeof(RecID3FRLG));
case GameVersion.E:
return Enum.GetNames(typeof(RecID3Emerald));
default:
throw new ArgumentException(nameof(ver));
}
}
public static IList<ComboItem> GetItems(SAV3 sav)
{
var ver = sav.Version;
var names = GetEnumNames(ver);
var values = GetEnumValues(ver);
var result = new ComboItem[values.Length];
for (int i = 0; i < result.Length; i++)
result[i] = new ComboItem {Text = Util.ToTitleCase(names[i].Replace('_', ' ')), Value = values[i]};
return result;
}
}
/// <summary>
/// Record IDs for <see cref="GameVersion.R"/> and <see cref="GameVersion.S"/>
/// </summary>
/// <remarks>
/// https://github.com/pret/pokeruby/blob/f839afb24aa2c7b70e9c28a5c069aacc46993099/include/constants/game_stat.h
/// </remarks>
public enum RecID3RuSa
{
SAVED_GAME = 0,
FIRST_HOF_PLAY_TIME = 1,
STARTED_TRENDS = 2,
PLANTED_BERRIES = 3,
TRADED_BIKES = 4,
STEPS = 5,
GOT_INTERVIEWED = 6,
TOTAL_BATTLES = 7,
WILD_BATTLES = 8,
TRAINER_BATTLES = 9,
ENTERED_HOF = 10,
POKEMON_CAPTURES = 11,
FISHING_CAPTURES = 12,
HATCHED_EGGS = 13,
EVOLVED_POKEMON = 14,
USED_POKECENTER = 15,
RESTED_AT_HOME = 16,
ENTERED_SAFARI_ZONE = 17,
USED_CUT = 18,
USED_ROCK_SMASH = 19,
MOVED_SECRET_BASE = 20,
POKEMON_TRADES = 21,
UNKNOWN_22 = 22,
LINK_BATTLE_WINS = 23,
LINK_BATTLE_LOSSES = 24,
LINK_BATTLE_DRAWS = 25,
USED_SPLASH = 26,
USED_STRUGGLE = 27,
SLOT_JACKPOTS = 28,
CONSECUTIVE_ROULETTE_WINS = 29,
ENTERED_BATTLE_TOWER = 30,
UNKNOWN_31 = 31,
BATTLE_TOWER_BEST_STREAK = 32,
POKEBLOCKS = 33,
POKEBLOCKS_WITH_FRIENDS = 34,
WON_LINK_CONTEST = 35,
ENTERED_CONTEST = 36,
WON_CONTEST = 37,
SHOPPED = 38,
USED_ITEMFINDER = 39,
GOT_RAINED_ON = 40,
CHECKED_POKEDEX = 41,
RECEIVED_RIBBONS = 42,
JUMPED_DOWN_LEDGES = 43,
WATCHED_TV = 44,
CHECKED_CLOCK = 45,
WON_POKEMON_LOTTERY = 46,
USED_DAYCARE = 47,
RODE_CABLE_CAR = 48,
ENTERED_HOT_SPRINGS = 49,
// NUM_GAME_STATS = 50
}
/// <summary>
/// Record IDs for <see cref="GameVersion.E"/>
/// </summary>
/// <remarks>
/// https://github.com/pret/pokeemerald/blob/3a40f5203baafb29f94dda8abdce6489d81635ae/include/constants/game_stat.h
/// </remarks>
public enum RecID3Emerald
{
SAVED_GAME = 0,
FIRST_HOF_PLAY_TIME = 1,
STARTED_TRENDS = 2,
PLANTED_BERRIES = 3,
TRADED_BIKES = 4,
STEPS = 5,
GOT_INTERVIEWED = 6,
TOTAL_BATTLES = 7,
WILD_BATTLES = 8,
TRAINER_BATTLES = 9,
ENTERED_HOF = 10,
POKEMON_CAPTURES = 11,
FISHING_CAPTURES = 12,
HATCHED_EGGS = 13,
EVOLVED_POKEMON = 14,
USED_POKECENTER = 15,
RESTED_AT_HOME = 16,
ENTERED_SAFARI_ZONE = 17,
USED_CUT = 18,
USED_ROCK_SMASH = 19,
MOVED_SECRET_BASE = 20,
POKEMON_TRADES = 21,
UNKNOWN_22 = 22,
LINK_BATTLE_WINS = 23,
LINK_BATTLE_LOSSES = 24,
LINK_BATTLE_DRAWS = 25,
USED_SPLASH = 26,
USED_STRUGGLE = 27,
SLOT_JACKPOTS = 28,
CONSECUTIVE_ROULETTE_WINS = 29,
ENTERED_BATTLE_TOWER = 30,
UNKNOWN_31 = 31,
BATTLE_TOWER_BEST_STREAK = 32,
POKEBLOCKS = 33,
POKEBLOCKS_WITH_FRIENDS = 34,
WON_LINK_CONTEST = 35,
ENTERED_CONTEST = 36,
WON_CONTEST = 37,
SHOPPED = 38,
USED_ITEMFINDER = 39,
GOT_RAINED_ON = 40,
CHECKED_POKEDEX = 41,
RECEIVED_RIBBONS = 42,
JUMPED_DOWN_LEDGES = 43,
WATCHED_TV = 44,
CHECKED_CLOCK = 45,
WON_POKEMON_LOTTERY = 46,
USED_DAYCARE = 47,
RODE_CABLE_CAR = 48,
ENTERED_HOT_SPRINGS = 49,
STAT_50 = 50,
STAT_51 = 51,
// NUM_USED_GAME_STATS = 52,
// NUM_GAME_STATS = 64
}
/// <summary>
/// Record IDs for <see cref="GameVersion.FR"/> and <see cref="GameVersion.LG"/>
/// </summary>
/// <remarks>
/// https://github.com/pret/pokefirered/blob/8367b0015fbf99070cc5a5244d8213420419d2c8/include/constants/game_stat.h
/// </remarks>
public enum RecID3FRLG
{
SAVED_GAME = 0,
FIRST_HOF_PLAY_TIME = 1,
STARTED_TRENDS = 2,
PLANTED_BERRIES = 3,
TRADED_BIKES = 4,
STEPS = 5,
GOT_INTERVIEWED = 6,
TOTAL_BATTLES = 7,
WILD_BATTLES = 8,
TRAINER_BATTLES = 9,
ENTERED_HOF = 10,
POKEMON_CAPTURES = 11,
FISHING_CAPTURES = 12,
HATCHED_EGGS = 13,
EVOLVED_POKEMON = 14,
USED_POKECENTER = 15,
RESTED_AT_HOME = 16,
ENTERED_SAFARI_ZONE = 17,
USED_CUT = 18,
USED_ROCK_SMASH = 19,
MOVED_SECRET_BASE = 20,
POKEMON_TRADES = 21,
UNKNOWN_22 = 22,
LINK_BATTLE_WINS = 23,
LINK_BATTLE_LOSSES = 24,
LINK_BATTLE_DRAWS = 25,
USED_SPLASH = 26,
USED_STRUGGLE = 27,
SLOT_JACKPOTS = 28,
CONSECUTIVE_ROULETTE_WINS = 29,
ENTERED_BATTLE_TOWER = 30,
UNKNOWN_31 = 31,
BATTLE_TOWER_BEST_STREAK = 32,
POKEBLOCKS = 33,
POKEBLOCKS_WITH_FRIENDS = 34,
WON_LINK_CONTEST = 35,
ENTERED_CONTEST = 36,
WON_CONTEST = 37,
SHOPPED = 38,
USED_ITEMFINDER = 39,
GOT_RAINED_ON = 40,
CHECKED_POKEDEX = 41,
RECEIVED_RIBBONS = 42,
JUMPED_DOWN_LEDGES = 43,
WATCHED_TV = 44,
CHECKED_CLOCK = 45,
WON_POKEMON_LOTTERY = 46,
USED_DAYCARE = 47,
RODE_CABLE_CAR = 48,
ENTERED_HOT_SPRINGS = 49,
// NUM_GAME_STATS = 64,
}
}

View file

@ -100,6 +100,9 @@
this.BTN_SymbolT = new System.Windows.Forms.Button();
this.BTN_SymbolA = new System.Windows.Forms.Button();
this.CHK_ActivatePass = new System.Windows.Forms.CheckBox();
this.Tab_Records = new System.Windows.Forms.TabPage();
this.NUD_RecordValue = new System.Windows.Forms.NumericUpDown();
this.CB_Record = new System.Windows.Forms.ComboBox();
this.tabControl1.SuspendLayout();
this.TAB_Main.SuspendLayout();
this.GB_TCM.SuspendLayout();
@ -117,12 +120,14 @@
((System.ComponentModel.ISupportInitialize)(this.NUD_Stat0)).BeginInit();
this.GB_FrontierPass.SuspendLayout();
this.GB_Icons.SuspendLayout();
this.Tab_Records.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.NUD_RecordValue)).BeginInit();
this.SuspendLayout();
//
// B_Save
//
this.B_Save.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.B_Save.Location = new System.Drawing.Point(213, 262);
this.B_Save.Location = new System.Drawing.Point(252, 262);
this.B_Save.Name = "B_Save";
this.B_Save.Size = new System.Drawing.Size(75, 23);
this.B_Save.TabIndex = 73;
@ -133,7 +138,7 @@
// B_Cancel
//
this.B_Cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.B_Cancel.Location = new System.Drawing.Point(132, 262);
this.B_Cancel.Location = new System.Drawing.Point(171, 262);
this.B_Cancel.Name = "B_Cancel";
this.B_Cancel.Size = new System.Drawing.Size(75, 23);
this.B_Cancel.TabIndex = 72;
@ -150,10 +155,11 @@
this.tabControl1.Controls.Add(this.TAB_Joyful);
this.tabControl1.Controls.Add(this.TAB_Ferry);
this.tabControl1.Controls.Add(this.TAB_BF);
this.tabControl1.Controls.Add(this.Tab_Records);
this.tabControl1.Location = new System.Drawing.Point(12, 12);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(274, 244);
this.tabControl1.Size = new System.Drawing.Size(313, 244);
this.tabControl1.TabIndex = 74;
//
// TAB_Main
@ -168,7 +174,7 @@
this.TAB_Main.Location = new System.Drawing.Point(4, 22);
this.TAB_Main.Name = "TAB_Main";
this.TAB_Main.Padding = new System.Windows.Forms.Padding(3);
this.TAB_Main.Size = new System.Drawing.Size(266, 218);
this.TAB_Main.Size = new System.Drawing.Size(305, 218);
this.TAB_Main.TabIndex = 0;
this.TAB_Main.Text = "Main";
this.TAB_Main.UseVisualStyleBackColor = true;
@ -333,7 +339,7 @@
this.TAB_Joyful.Location = new System.Drawing.Point(4, 22);
this.TAB_Joyful.Name = "TAB_Joyful";
this.TAB_Joyful.Padding = new System.Windows.Forms.Padding(3);
this.TAB_Joyful.Size = new System.Drawing.Size(266, 218);
this.TAB_Joyful.Size = new System.Drawing.Size(305, 218);
this.TAB_Joyful.TabIndex = 1;
this.TAB_Joyful.Text = "Joyful";
this.TAB_Joyful.UseVisualStyleBackColor = true;
@ -473,7 +479,7 @@
this.TAB_Ferry.Location = new System.Drawing.Point(4, 22);
this.TAB_Ferry.Name = "TAB_Ferry";
this.TAB_Ferry.Padding = new System.Windows.Forms.Padding(3);
this.TAB_Ferry.Size = new System.Drawing.Size(266, 218);
this.TAB_Ferry.Size = new System.Drawing.Size(305, 218);
this.TAB_Ferry.TabIndex = 2;
this.TAB_Ferry.Text = "Ferry";
this.TAB_Ferry.UseVisualStyleBackColor = true;
@ -621,7 +627,7 @@
this.TAB_BF.Controls.Add(this.GB_FrontierPass);
this.TAB_BF.Location = new System.Drawing.Point(4, 22);
this.TAB_BF.Name = "TAB_BF";
this.TAB_BF.Size = new System.Drawing.Size(266, 218);
this.TAB_BF.Size = new System.Drawing.Size(305, 218);
this.TAB_BF.TabIndex = 3;
this.TAB_BF.Text = "Battle Frontier";
this.TAB_BF.UseVisualStyleBackColor = true;
@ -932,11 +938,39 @@
this.CHK_ActivatePass.Text = "Activated";
this.CHK_ActivatePass.UseVisualStyleBackColor = true;
//
// Tab_Records
//
this.Tab_Records.Controls.Add(this.NUD_RecordValue);
this.Tab_Records.Controls.Add(this.CB_Record);
this.Tab_Records.Location = new System.Drawing.Point(4, 22);
this.Tab_Records.Name = "Tab_Records";
this.Tab_Records.Padding = new System.Windows.Forms.Padding(3);
this.Tab_Records.Size = new System.Drawing.Size(305, 218);
this.Tab_Records.TabIndex = 4;
this.Tab_Records.Text = "Records";
this.Tab_Records.UseVisualStyleBackColor = true;
//
// NUD_RecordValue
//
this.NUD_RecordValue.Location = new System.Drawing.Point(74, 33);
this.NUD_RecordValue.Name = "NUD_RecordValue";
this.NUD_RecordValue.Size = new System.Drawing.Size(120, 20);
this.NUD_RecordValue.TabIndex = 1;
//
// CB_Record
//
this.CB_Record.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.CB_Record.FormattingEnabled = true;
this.CB_Record.Location = new System.Drawing.Point(6, 6);
this.CB_Record.Name = "CB_Record";
this.CB_Record.Size = new System.Drawing.Size(188, 21);
this.CB_Record.TabIndex = 0;
//
// SAV_Misc3
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(295, 297);
this.ClientSize = new System.Drawing.Size(334, 297);
this.Controls.Add(this.tabControl1);
this.Controls.Add(this.B_Save);
this.Controls.Add(this.B_Cancel);
@ -969,6 +1003,8 @@
this.GB_FrontierPass.ResumeLayout(false);
this.GB_FrontierPass.PerformLayout();
this.GB_Icons.ResumeLayout(false);
this.Tab_Records.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.NUD_RecordValue)).EndInit();
this.ResumeLayout(false);
}
@ -1045,5 +1081,8 @@
private System.Windows.Forms.ComboBox CB_TCM3;
private System.Windows.Forms.ComboBox CB_TCM2;
private System.Windows.Forms.ComboBox CB_TCM1;
private System.Windows.Forms.TabPage Tab_Records;
private System.Windows.Forms.NumericUpDown NUD_RecordValue;
private System.Windows.Forms.ComboBox CB_Record;
}
}

View file

@ -17,6 +17,8 @@ namespace PKHeX.WinForms
WinFormsUtil.TranslateInterface(this, Main.CurrentLanguage);
SAV = (SAV3)(Origin = sav).Clone();
LoadRecords();
if (SAV.FRLG || SAV.E)
ReadJoyful();
else
@ -441,5 +443,35 @@ namespace PKHeX.WinForms
}
#endregion
private void LoadRecords()
{
var records = new Record3(SAV);
var items = Record3.GetItems(SAV);
CB_Record.InitializeBinding();
CB_Record.DataSource = items;
NUD_RecordValue.Minimum = int.MinValue;
NUD_RecordValue.Maximum = int.MaxValue;
CB_Record.SelectedIndexChanged += (s, e) =>
{
if (CB_Record.SelectedValue == null)
return;
var index = WinFormsUtil.GetIndex(CB_Record);
LoadRecordID(index);
};
CB_Record.SelectedIndex = 0;
LoadRecordID(0);
NUD_RecordValue.ValueChanged += (s, e) =>
{
if (CB_Record.SelectedValue == null)
return;
var index = WinFormsUtil.GetIndex(CB_Record);
records.SetRecord(index, (uint)NUD_RecordValue.Value);
};
void LoadRecordID(int index) => NUD_RecordValue.Value = records.GetRecord(index);
}
}
}