diff --git a/pkNX.Game/Editors/TMEditorGG.cs b/pkNX.Game/Editors/TMEditorGG.cs new file mode 100644 index 00000000..395791f4 --- /dev/null +++ b/pkNX.Game/Editors/TMEditorGG.cs @@ -0,0 +1,45 @@ +using System; +using System.Linq; +using pkNX.Containers; +using pkNX.Structures; + +namespace pkNX.Game +{ + public class TMEditorGG + { + private readonly int Offset; + private readonly NSO NSO; + private readonly byte[] Data; + + private const int count = 60; + + public TMEditorGG(byte[] data) + { + NSO = new NSO(data); + Data = NSO.DecompressedRO; + + // tm list is stored immediately after TM item index list + var pattern = CodePattern.TMHM_GG; + Offset = CodePattern.IndexOfBytes(Data, pattern, 0x200_000); + if (Valid) + Offset += pattern.Length; + } + + public ushort[] GetMoves() + { + var moves = new ushort[count]; + for (int i = 0; i < moves.Length; i++) + moves[i] = BitConverter.ToUInt16(Data, Offset + (2 * i)); + return moves; + } + + public void SetMoves(ushort[] finalMoves) + { + var result = finalMoves.SelectMany(BitConverter.GetBytes).ToArray(); + result.CopyTo(Data, Offset); + } + + public bool Valid => Offset > 0; + public byte[] Write() => NSO.Write(); + } +} diff --git a/pkNX.Structures/Legality/Legal.cs b/pkNX.Structures/Legality/Legal.cs index 4b831d00..73e156d2 100644 --- a/pkNX.Structures/Legality/Legal.cs +++ b/pkNX.Structures/Legality/Legal.cs @@ -168,12 +168,20 @@ public static int[] GetRandomItemList(GameVersion game) {080, new[] {760}}, // Slowbro @ Slowbronite }; - public static int[] GetBannedMoves(GameVersion infoGame, IEnumerable moves) + public static int[] GetBannedMoves(GameVersion infoGame, int moveCount) { if (!GameVersion.GG.Contains(infoGame)) return Array.Empty(); - return Enumerable.Range(0, moves.Count()).Except(AllowedMovesGG).ToArray(); + return Enumerable.Range(0, moveCount).Except(AllowedMovesGG).ToArray(); + } + + public static int[] GetAllowedMoves(GameVersion infoGame, int moveCount) + { + if (GameVersion.GG.Contains(infoGame)) + return AllowedMovesGG; + + return Enumerable.Range(0, moveCount).ToArray(); } private static readonly int[] AllowedMovesGG = diff --git a/pkNX.WinForms/MainEditor/EditorGG.cs b/pkNX.WinForms/MainEditor/EditorGG.cs index 113cef87..f962fabe 100644 --- a/pkNX.WinForms/MainEditor/EditorGG.cs +++ b/pkNX.WinForms/MainEditor/EditorGG.cs @@ -243,5 +243,29 @@ public void EditShinyRate() nso.DecompressedText = shiny.Data; FileMitm.WriteAllBytes(path, nso.Write()); } + + public void EditTM() + { + var path = Path.Combine(ROM.PathExeFS, "main"); + var data = FileMitm.ReadAllBytes(path); + var list = new TMEditorGG(data); + if (!list.Valid) + { + WinFormsUtil.Alert("Not able to find tm data in exefs."); + return; + } + + var moves = list.GetMoves(); + var allowed = Legal.GetAllowedMoves(ROM.Game, ROM.Data.MoveData.Length); + var names = ROM.GetStrings(TextName.MoveNames); + var editor = new TMList(moves, allowed, names); + editor.ShowDialog(); + if (!editor.Modified) + return; + + list.SetMoves(editor.FinalMoves); + data = list.Write(); + FileMitm.WriteAllBytes(path, data); + } } } \ No newline at end of file diff --git a/pkNX.WinForms/Subforms/BTTE.cs b/pkNX.WinForms/Subforms/BTTE.cs index b59ab33f..5ecd4fa9 100644 --- a/pkNX.WinForms/Subforms/BTTE.cs +++ b/pkNX.WinForms/Subforms/BTTE.cs @@ -535,7 +535,7 @@ private void B_Randomize_Click(object sender, EventArgs e) SaveEntry(); var moves = Game.Data.MoveData.LoadAll(); var rmove = new MoveRandomizer(Game.Info, moves, Personal); - int[] banned = Legal.GetBannedMoves(Game.Info.Game, moves); + int[] banned = Legal.GetBannedMoves(Game.Info.Game, moves.Length); rmove.Initialize((MovesetRandSettings)PG_Moves.SelectedObject, banned); var rspec = new SpeciesRandomizer(Game.Info, Personal); rspec.Initialize((SpeciesSettings)PG_Species.SelectedObject); diff --git a/pkNX.WinForms/Subforms/PokeDataUI.cs b/pkNX.WinForms/Subforms/PokeDataUI.cs index de5c6726..0f744902 100644 --- a/pkNX.WinForms/Subforms/PokeDataUI.cs +++ b/pkNX.WinForms/Subforms/PokeDataUI.cs @@ -479,7 +479,7 @@ private void B_RandLearn_Click(object sender, EventArgs e) var settings = (LearnSettings)PG_Learn.SelectedObject; var rand = new LearnsetRandomizer(ROM.Info, Editor.Learn.LoadAll(), Editor.Personal); var moves = ROM.Data.MoveData.LoadAll(); - int[] banned = Legal.GetBannedMoves(ROM.Info.Game, moves); + int[] banned = Legal.GetBannedMoves(ROM.Info.Game, moves.Length); rand.Initialize(moves, settings, EditUtil.Settings.Move, banned); rand.Execute(); LoadIndex(CB_Species.SelectedIndex); diff --git a/pkNX.WinForms/Subforms/TMList.Designer.cs b/pkNX.WinForms/Subforms/TMList.Designer.cs new file mode 100644 index 00000000..27850ce5 --- /dev/null +++ b/pkNX.WinForms/Subforms/TMList.Designer.cs @@ -0,0 +1,97 @@ +namespace pkNX.WinForms +{ + partial class TMList + { + /// + /// 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 Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.B_Save = new System.Windows.Forms.Button(); + this.B_RTM = new System.Windows.Forms.Button(); + this.dgvTM = new System.Windows.Forms.DataGridView(); + ((System.ComponentModel.ISupportInitialize)(this.dgvTM)).BeginInit(); + this.SuspendLayout(); + // + // B_Save + // + this.B_Save.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.B_Save.Location = new System.Drawing.Point(185, 12); + this.B_Save.Name = "B_Save"; + this.B_Save.Size = new System.Drawing.Size(60, 23); + this.B_Save.TabIndex = 1; + this.B_Save.Text = "Save"; + this.B_Save.UseVisualStyleBackColor = true; + this.B_Save.Click += new System.EventHandler(this.B_Save_Click); + // + // B_RTM + // + this.B_RTM.Location = new System.Drawing.Point(12, 12); + this.B_RTM.Name = "B_RTM"; + this.B_RTM.Size = new System.Drawing.Size(75, 23); + this.B_RTM.TabIndex = 7; + this.B_RTM.Text = "Randomize"; + this.B_RTM.UseVisualStyleBackColor = true; + this.B_RTM.Click += new System.EventHandler(this.B_RTM_Click); + // + // dgvTM + // + this.dgvTM.AllowUserToAddRows = false; + this.dgvTM.AllowUserToDeleteRows = false; + this.dgvTM.AllowUserToResizeColumns = false; + this.dgvTM.AllowUserToResizeRows = false; + this.dgvTM.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.dgvTM.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dgvTM.Location = new System.Drawing.Point(12, 41); + this.dgvTM.Name = "dgvTM"; + this.dgvTM.RowHeadersVisible = false; + this.dgvTM.Size = new System.Drawing.Size(233, 333); + this.dgvTM.TabIndex = 6; + // + // TMList + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(257, 386); + this.Controls.Add(this.B_RTM); + this.Controls.Add(this.dgvTM); + this.Controls.Add(this.B_Save); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + this.MaximizeBox = false; + this.Name = "TMList"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "TM List"; + ((System.ComponentModel.ISupportInitialize)(this.dgvTM)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + private System.Windows.Forms.Button B_Save; + private System.Windows.Forms.Button B_RTM; + private System.Windows.Forms.DataGridView dgvTM; + } +} \ No newline at end of file diff --git a/pkNX.WinForms/Subforms/TMList.cs b/pkNX.WinForms/Subforms/TMList.cs new file mode 100644 index 00000000..dc346239 --- /dev/null +++ b/pkNX.WinForms/Subforms/TMList.cs @@ -0,0 +1,97 @@ +using System; +using System.Linq; +using System.Windows.Forms; +using pkNX.Game; +using pkNX.Randomization; + +namespace pkNX.WinForms +{ + public sealed partial class TMList : Form + { + private readonly int[] AllowedMoves; + private readonly string[] MoveNames; + private readonly ushort[] OriginalMoves; + + public TMList(ushort[] moves, int[] allowed, string[] movenames) + { + InitializeComponent(); + MoveNames = EditorUtil.SanitizeMoveList(movenames); + AllowedMoves = allowed; + SetupDGV(MoveNames); + LoadMoves(moves); + OriginalMoves = moves; + } + + public bool Modified { get; set; } + public ushort[] FinalMoves { get; private set; } + + private void SetupDGV(string[] list) + { + dgvTM.Columns.Clear(); + DataGridViewColumn dgvIndex = new DataGridViewTextBoxColumn(); + { + dgvIndex.HeaderText = "Index"; + dgvIndex.DisplayIndex = 0; + dgvIndex.Width = 45; + dgvIndex.ReadOnly = true; + dgvIndex.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; + dgvIndex.SortMode = DataGridViewColumnSortMode.NotSortable; + } + DataGridViewComboBoxColumn dgvMove = new DataGridViewComboBoxColumn(); + { + dgvMove.HeaderText = "Move"; + dgvMove.DisplayIndex = 1; + foreach (string t in list) + dgvMove.Items.Add(t); // add only the Names + + dgvMove.Width = 133; + dgvMove.FlatStyle = FlatStyle.Flat; + dgvIndex.SortMode = DataGridViewColumnSortMode.NotSortable; + } + dgvTM.Columns.Add(dgvIndex); + dgvTM.Columns.Add(dgvMove); + } + + public void LoadMoves(ushort[] tmlist) + { + dgvTM.Rows.Clear(); + + for (int i = 0; i < tmlist.Length; i++) + { + dgvTM.Rows.Add(); + dgvTM.Rows[i].Cells[0].Value = (i + 1).ToString(); + dgvTM.Rows[i].Cells[1].Value = MoveNames[tmlist[i]]; + } + } + + public ushort[] SaveMoves() + { + ushort[] moves = new ushort[dgvTM.RowCount]; + for (int i = 0; i < moves.Length; i++) + moves[i] = (ushort)Array.IndexOf(MoveNames, dgvTM.Rows[i].Cells[1].Value); + + return moves; + } + + private void B_Save_Click(object sender, EventArgs e) + { + Modified = true; + FinalMoves = SaveMoves(); + Close(); + } + + private void B_RTM_Click(object sender, EventArgs e) + { + var moves = GetRandomMoves(); + LoadMoves(moves); + System.Media.SystemSounds.Asterisk.Play(); + } + + private ushort[] GetRandomMoves() + { + var allowed = AllowedMoves.Select(z => (ushort)z).Except(new ushort[] { 0 }).ToArray(); + var rand = new GenericRandomizer(allowed); + return rand.GetMany(OriginalMoves.Length); + } + } +} diff --git a/pkNX.WinForms/Subforms/TMList.resx b/pkNX.WinForms/Subforms/TMList.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/pkNX.WinForms/Subforms/TMList.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 diff --git a/pkNX.WinForms/pkNX.WinForms.csproj b/pkNX.WinForms/pkNX.WinForms.csproj index 25660b96..d05a01d8 100644 --- a/pkNX.WinForms/pkNX.WinForms.csproj +++ b/pkNX.WinForms/pkNX.WinForms.csproj @@ -89,6 +89,12 @@ BTTE.cs + + Form + + + TMList.cs + Form @@ -149,6 +155,9 @@ BTTE.cs + + TMList.cs + ShinyRate.cs