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