diff --git a/PKHeX.Core/Saves/SAV7.cs b/PKHeX.Core/Saves/SAV7.cs
index bc6f02244..181aaeaf0 100644
--- a/PKHeX.Core/Saves/SAV7.cs
+++ b/PKHeX.Core/Saves/SAV7.cs
@@ -8,7 +8,7 @@ namespace PKHeX.Core
///
/// Generation 7 object.
///
- public sealed class SAV7 : SaveFile
+ public sealed class SAV7 : SaveFile, ITrainerStatRecord
{
// Save Data Attributes
public override string BAKName => $"{FileName} [{OT} ({Version}) - {LastSavedTime}].bak";
@@ -727,8 +727,8 @@ namespace PKHeX.Core
return Record + recordID*2 + 200; // first 100 are 4bytes, so bias the difference
return -1;
}
-
- public static int GetRecordMax(int recordID, int[] maxes = null) => recordID < 200 ? RecordMax[(maxes ?? RecordMaxType_USUM)[recordID]] : 0;
+ public int GetRecordMax(int recordID) => GetRecordMax(recordID, USUM ? RecordMaxType_USUM : RecordMaxType_SM);
+ private static int GetRecordMax(int recordID, int[] maxes) => recordID < 200 ? RecordMax[(maxes ?? RecordMaxType_USUM)[recordID]] : 0;
private static readonly int[] RecordMax = {999999999, 9999999, 999999, 99999, 65535, 9999, 999};
private static readonly int[] RecordMaxType_SM =
{
diff --git a/PKHeX.Core/Saves/Substructures/ITrainerStatRecord.cs b/PKHeX.Core/Saves/Substructures/ITrainerStatRecord.cs
new file mode 100644
index 000000000..502b451a0
--- /dev/null
+++ b/PKHeX.Core/Saves/Substructures/ITrainerStatRecord.cs
@@ -0,0 +1,10 @@
+namespace PKHeX.Core
+{
+ public interface ITrainerStatRecord
+ {
+ int GetRecord(int recordID);
+ int GetRecordOffset(int recordID);
+ int GetRecordMax(int recordID);
+ void SetRecord(int recordID, int value);
+ }
+}
diff --git a/PKHeX.WinForms/PKHeX.WinForms.csproj b/PKHeX.WinForms/PKHeX.WinForms.csproj
index 9097c7d80..a429ecedd 100644
--- a/PKHeX.WinForms/PKHeX.WinForms.csproj
+++ b/PKHeX.WinForms/PKHeX.WinForms.csproj
@@ -557,6 +557,12 @@
SAV_Wondercard.cs
+
+ UserControl
+
+
+ TrainerStat.cs
+
Form
@@ -788,6 +794,9 @@
SAV_Wondercard.cs
+
+ TrainerStat.cs
+
SAV_Database.cs
diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7.cs
index 75d41d218..b4b757e83 100644
--- a/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7.cs
+++ b/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7.cs
@@ -581,7 +581,7 @@ namespace PKHeX.WinForms
{
editing = true;
int index = CB_Stats.SelectedIndex;
- NUD_Stat.Maximum = SAV7.GetRecordMax(index);
+ NUD_Stat.Maximum = SAV.GetRecordMax(index);
NUD_Stat.Value = SAV.GetRecord(index);
int offset = SAV.GetRecordOffset(index);
@@ -616,14 +616,15 @@ namespace PKHeX.WinForms
if (RecordList.TryGetValue(index, out string tip))
Tip3.SetToolTip(CB_Stats, tip);
}
- private static string ConvertDateValueToString(int value, int refval = -1)
+ private static string ConvertDateValueToString(int value, int secondsBias = -1)
{
- string tip = "";
- if (value >= 86400)
- tip += value / 86400 + "d ";
+ 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 (refval >= 0)
- tip += Environment.NewLine + $"Date: {new DateTime(2000, 1, 1).AddSeconds(refval + value)}";
+ if (secondsBias >= 0)
+ tip += Environment.NewLine + $"Date: {new DateTime(2000, 1, 1).AddSeconds(value + secondsBias)}";
return tip;
}
diff --git a/PKHeX.WinForms/Subforms/Save Editors/TrainerStat.Designer.cs b/PKHeX.WinForms/Subforms/Save Editors/TrainerStat.Designer.cs
new file mode 100644
index 000000000..fc9945824
--- /dev/null
+++ b/PKHeX.WinForms/Subforms/Save Editors/TrainerStat.Designer.cs
@@ -0,0 +1,100 @@
+namespace PKHeX.WinForms.Subforms.Save_Editors
+{
+ partial class TrainerStat
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.NUD_Stat = new System.Windows.Forms.NumericUpDown();
+ this.L_Offset = new System.Windows.Forms.Label();
+ this.L_Value = new System.Windows.Forms.Label();
+ this.CB_Stats = new System.Windows.Forms.ComboBox();
+ ((System.ComponentModel.ISupportInitialize)(this.NUD_Stat)).BeginInit();
+ this.SuspendLayout();
+ //
+ // NUD_Stat
+ //
+ this.NUD_Stat.Location = new System.Drawing.Point(40, 25);
+ this.NUD_Stat.Name = "NUD_Stat";
+ this.NUD_Stat.Size = new System.Drawing.Size(103, 20);
+ this.NUD_Stat.TabIndex = 35;
+ this.NUD_Stat.ValueChanged += new System.EventHandler(this.ChangeStatVal);
+ //
+ // L_Offset
+ //
+ this.L_Offset.Font = new System.Drawing.Font("Courier New", 8.25F);
+ this.L_Offset.Location = new System.Drawing.Point(3, 48);
+ this.L_Offset.Name = "L_Offset";
+ this.L_Offset.Size = new System.Drawing.Size(140, 20);
+ this.L_Offset.TabIndex = 34;
+ this.L_Offset.Text = "(offset)";
+ this.L_Offset.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+ //
+ // L_Value
+ //
+ this.L_Value.AutoSize = true;
+ this.L_Value.Location = new System.Drawing.Point(0, 27);
+ this.L_Value.Name = "L_Value";
+ this.L_Value.Size = new System.Drawing.Size(34, 13);
+ this.L_Value.TabIndex = 32;
+ this.L_Value.Text = "Value";
+ //
+ // CB_Stats
+ //
+ this.CB_Stats.DropDownHeight = 256;
+ this.CB_Stats.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.CB_Stats.DropDownWidth = 200;
+ this.CB_Stats.FormattingEnabled = true;
+ this.CB_Stats.IntegralHeight = false;
+ this.CB_Stats.Location = new System.Drawing.Point(3, 3);
+ this.CB_Stats.Name = "CB_Stats";
+ this.CB_Stats.Size = new System.Drawing.Size(140, 21);
+ this.CB_Stats.TabIndex = 33;
+ this.CB_Stats.SelectedIndexChanged += new System.EventHandler(this.ChangeStat);
+ //
+ // TrainerStat
+ //
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+ this.Controls.Add(this.NUD_Stat);
+ this.Controls.Add(this.L_Offset);
+ this.Controls.Add(this.L_Value);
+ this.Controls.Add(this.CB_Stats);
+ this.Name = "TrainerStat";
+ this.Size = new System.Drawing.Size(146, 72);
+ ((System.ComponentModel.ISupportInitialize)(this.NUD_Stat)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.NumericUpDown NUD_Stat;
+ private System.Windows.Forms.Label L_Offset;
+ private System.Windows.Forms.Label L_Value;
+ private System.Windows.Forms.ComboBox CB_Stats;
+ }
+}
diff --git a/PKHeX.WinForms/Subforms/Save Editors/TrainerStat.cs b/PKHeX.WinForms/Subforms/Save Editors/TrainerStat.cs
new file mode 100644
index 000000000..6c4761f7a
--- /dev/null
+++ b/PKHeX.WinForms/Subforms/Save Editors/TrainerStat.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using PKHeX.Core;
+
+namespace PKHeX.WinForms.Subforms.Save_Editors
+{
+ public partial class TrainerStat : UserControl
+ {
+ public TrainerStat()
+ {
+ InitializeComponent();
+ }
+
+ private bool Editing;
+ private ITrainerStatRecord SAV;
+
+ public void LoadRecords(ITrainerStatRecord sav, Dictionary records)
+ {
+ SAV = sav;
+ RecordList = records;
+ CB_Stats.Items.Clear();
+ for (int i = 0; i < 200; i++)
+ {
+ if (!RecordList.TryGetValue(i, out string name))
+ name = $"{i:D3}";
+
+ CB_Stats.Items.Add(name);
+ }
+ CB_Stats.SelectedIndex = RecordList.First().Key;
+ }
+
+ private Dictionary RecordList; // index, description
+
+ private void ChangeStat(object sender, EventArgs e)
+ {
+ Editing = true;
+ int index = CB_Stats.SelectedIndex;
+ NUD_Stat.Maximum = SAV.GetRecordMax(index);
+ NUD_Stat.Value = SAV.GetRecord(index);
+
+ int offset = SAV.GetRecordOffset(index);
+ L_Offset.Text = $"Offset: 0x{offset:X3}";
+ UpdateTip(index, true);
+ Editing = false;
+ }
+ private void ChangeStatVal(object sender, EventArgs e)
+ {
+ if (Editing)
+ return;
+ int index = CB_Stats.SelectedIndex;
+ SAV.SetRecord(index, (int)NUD_Stat.Value);
+ UpdateTip(index, false);
+ }
+
+ private readonly ToolTip Tip3 = new ToolTip();
+ public Func GetToolTipText { private get; set; }
+ private void UpdateTip(int index, bool updateStats)
+ {
+ if (GetToolTipText != null)
+ UpdateToolTipSpecial(index, updateStats);
+ else
+ UpdateToolTipDefault(index, updateStats);
+ }
+
+ private void UpdateToolTipSpecial(int index, bool updateStats)
+ {
+ var str = GetToolTipText(index);
+ if (str != null)
+ {
+ Tip3.SetToolTip(NUD_Stat, str);
+ return;
+ }
+ UpdateToolTipDefault(index, updateStats); // fallback
+ }
+ private void UpdateToolTipDefault(int index, bool updateStats)
+ {
+ if (!updateStats || !RecordList.TryGetValue(index, out string tip))
+ {
+ Tip3.RemoveAll();
+ return;
+ }
+ Tip3.SetToolTip(CB_Stats, tip);
+ }
+ }
+}
diff --git a/PKHeX.WinForms/Subforms/Save Editors/TrainerStat.resx b/PKHeX.WinForms/Subforms/Save Editors/TrainerStat.resx
new file mode 100644
index 000000000..1af7de150
--- /dev/null
+++ b/PKHeX.WinForms/Subforms/Save Editors/TrainerStat.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file