diff --git a/pkNX.Containers/Misc/GFPack.cs b/pkNX.Containers/Misc/GFPack.cs index 791b71c3..c4612db5 100644 --- a/pkNX.Containers/Misc/GFPack.cs +++ b/pkNX.Containers/Misc/GFPack.cs @@ -98,6 +98,7 @@ private void ReadPack(BinaryReader br) } public int GetIndexFull(ulong hash) => Array.FindIndex(HashAbsolute, z => z.HashFnv1aPathFull == hash); + public int GetIndexFull(string path) => GetIndexFull(FnvHash.HashFnv1a_64(path)); public int GetIndexFileName(ulong hash) { diff --git a/pkNX.Structures.FlatBuffers/Arceus/Placement/PlacementSpawner8a.cs b/pkNX.Structures.FlatBuffers/Arceus/Placement/PlacementSpawner8a.cs index 8f818381..15b90a6f 100644 --- a/pkNX.Structures.FlatBuffers/Arceus/Placement/PlacementSpawner8a.cs +++ b/pkNX.Structures.FlatBuffers/Arceus/Placement/PlacementSpawner8a.cs @@ -68,7 +68,7 @@ public string Field_22_Value public IEnumerable GetIntersectingLocations(IReadOnlyList locations, float bias) { var c = Parameters.Coordinates; - return GetIntersectingLocations(locations, bias, c, Scalar + bias); + return GetIntersectingLocations(locations, bias, c, Scalar); } private static IEnumerable GetIntersectingLocations(IReadOnlyList locations, float bias, PlacementV3f8a c, float scalar) @@ -78,7 +78,7 @@ private static IEnumerable GetIntersectingLocations(IReadOn { if (!loc.IsNamedPlace) continue; - if (loc.IntersectsSphere(c.X, c.Y, c.Z, scalar)) + if (loc.IntersectsSphere(c.X, c.Y, c.Z, scalar + bias)) result.Add(loc); } @@ -141,24 +141,23 @@ public IEnumerable GetContainingLocations(IReadOnlyList GetIntersectingLocations(IReadOnlyList locations, float bias) { var c = Parameters.Coordinates; - return GetIntersectingLocations(locations, bias, c, 0 + bias); + return GetIntersectingLocations(locations, bias, c, 0); } private static IEnumerable GetIntersectingLocations(IReadOnlyList locations, float bias, PlacementV3f8a c, float scalar) @@ -50,7 +50,7 @@ private static IEnumerable GetIntersectingLocations(IReadOn { if (!loc.IsNamedPlace) continue; - if (loc.IntersectsSphere(c.X, c.Y, c.Z, scalar)) + if (loc.IntersectsSphere(c.X, c.Y, c.Z, scalar + bias)) result.Add(loc); } diff --git a/pkNX.Structures.FlatBuffers/Arceus/Resident/AreaInstance8a.cs b/pkNX.Structures.FlatBuffers/Arceus/Resident/AreaInstance8a.cs index b8f010f7..4c4ea60c 100644 --- a/pkNX.Structures.FlatBuffers/Arceus/Resident/AreaInstance8a.cs +++ b/pkNX.Structures.FlatBuffers/Arceus/Resident/AreaInstance8a.cs @@ -1,5 +1,4 @@ -using System; -using pkNX.Containers; +using pkNX.Containers; using System.Collections.Generic; namespace pkNX.Structures.FlatBuffers; @@ -8,77 +7,34 @@ namespace pkNX.Structures.FlatBuffers; public sealed class AreaInstance8a { // Area Info + private readonly ResidentArea8a Area; public readonly AreaInstance8a? ParentArea; private readonly List Children = new(); - private readonly AreaSettings8a Settings; - private readonly GFPack Resident; - public string AreaName => Settings.Name; public bool IsSubArea => ParentArea != null; public IReadOnlyList SubAreas => Children; + public string AreaName => Area.AreaName; // Encount - public EncounterTable8a[] Encounters { get; private set; } = Array.Empty(); + public EncounterTable8a[] Encounters => Area.Encounters; // Placement - public PlacementLocation8a[] Locations { get; private set; } = Array.Empty(); - public PlacementSpawner8a[] Spawners { get; private set; } = Array.Empty(); - public PlacementSpawner8a[] Wormholes { get; private set; } = Array.Empty(); - public LandmarkItemSpawn8a[] LandItems { get; private set; } = Array.Empty(); - public LandmarkItem8a[] LandMarks { get; private set; } = Array.Empty(); - public PlacementUnnnEntry[] Unown { get; private set; } = Array.Empty(); - public PlacementMkrgEntry[] Mikaruge { get; private set; } = Array.Empty(); - public PlacementSearchItem[] SearchItem { get; private set; } = Array.Empty(); + public PlacementLocation8a[] Locations => Area.Locations; + public PlacementSpawner8a[] Spawners => Area.Spawners; + public PlacementSpawner8a[] Wormholes => Area.Wormholes; + public LandmarkItemSpawn8a[] LandItems => Area.LandItems; + public LandmarkItem8a[] LandMarks => Area.LandMarks; + public PlacementUnnnEntry[] Unown => Area.Unown; + public PlacementMkrgEntry[] Mikaruge => Area.Mikaruge; + public PlacementSearchItem[] SearchItem => Area.SearchItem; private AreaInstance8a(GFPack resident, AreaSettings8a settings, AreaInstance8a? parentArea = null) { // General area properties - Resident = resident; - Settings = settings; + Area = new ResidentArea8a(resident, settings); ParentArea = parentArea; - - LoadInfo(); + Area.LoadInfo(); } - - private void LoadInfo() - { - // Load encount - var enc = Resident.GetDataFullPath(Settings.Encounters); - Encounters = FlatBufferConverter.DeserializeFrom(enc).Table; - - // Load placement - var locationf = Resident.GetDataFullPath(Settings.Locations); - var spawnerf = Resident.GetDataFullPath(Settings.Spawners); - var wh_spawnerf = Resident.GetDataFullPath(Settings.WormholeSpawners); - var l_spawnerf = Resident.GetDataFullPath(Settings.LandmarkItemSpawns); - var l_markf = Resident.GetDataFullPath(Settings.LandmarkItems); - var unnf = Resident.GetDataFullPath(Settings.UnownSpawners); - var mkrgf = Resident.GetDataFullPath(Settings.Mkrg); - var psif = Resident.GetDataFullPath(Settings.SearchItem); - - Locations = FlatBufferConverter.DeserializeFrom(locationf).Table; - Spawners = FlatBufferConverter.DeserializeFrom(spawnerf).Table; - Wormholes = FlatBufferConverter.DeserializeFrom(wh_spawnerf).Table; - LandItems = FlatBufferConverter.DeserializeFrom(l_spawnerf).Table; - LandMarks = FlatBufferConverter.DeserializeFrom(l_markf).Table; - Unown = FlatBufferConverter.DeserializeFrom(unnf).Table; - Mikaruge = FlatBufferConverter.DeserializeFrom(mkrgf).Table; - SearchItem = FlatBufferConverter.DeserializeFrom(psif).Table; - } - - private void SaveInfo() - { - Resident.SetDataFullPath(Settings.Encounters, new EncounterDataArchive8a { Table = Encounters }.Write()); - Resident.SetDataFullPath(Settings.Locations, new PlacementLocationArchive8a { Table = Locations }.Write()); - Resident.SetDataFullPath(Settings.Spawners, new PlacementSpawnerArchive8a { Table = Spawners }.Write()); - Resident.SetDataFullPath(Settings.WormholeSpawners, new PlacementSpawnerArchive8a { Table = Wormholes }.Write()); - Resident.SetDataFullPath(Settings.LandmarkItemSpawns, new LandmarkItemSpawnTable8a { Table = LandItems }.Write()); - Resident.SetDataFullPath(Settings.LandmarkItems, new LandmarkItemTable8a { Table = LandMarks }.Write()); - Resident.SetDataFullPath(Settings.UnownSpawners, new PlacementUnnnTable { Table = Unown }.Write()); - Resident.SetDataFullPath(Settings.Mkrg, new PlacementMkrgTable { Table = Mikaruge }.Write()); - Resident.SetDataFullPath(Settings.SearchItem, new PlacementSearchItemTable { Table = SearchItem }.Write()); - } - public static AreaInstance8a Create(GFPack resident, ResidentAreaSet areaNameList, AreaSettingsTable8a settingsTable) { var parentSettings = settingsTable.Find(areaNameList.ParentName); diff --git a/pkNX.Structures.FlatBuffers/Arceus/Resident/Editing/ResidentArea8a.cs b/pkNX.Structures.FlatBuffers/Arceus/Resident/Editing/ResidentArea8a.cs new file mode 100644 index 00000000..9065c094 --- /dev/null +++ b/pkNX.Structures.FlatBuffers/Arceus/Resident/Editing/ResidentArea8a.cs @@ -0,0 +1,81 @@ +using System; +using pkNX.Containers; + +namespace pkNX.Structures.FlatBuffers; + +// Not a flatbuffer; wraps the fields into a single object. +public sealed class ResidentArea8a +{ + public readonly AreaSettings8a Settings; + private readonly GFPack Resident; + + public ResidentArea8a(GFPack resident, AreaSettings8a settings) + { + Resident = resident; + Settings = settings; + } + + public string AreaName => Settings.Name; + + // Encount + public EncounterTable8a[] Encounters { get; private set; } = Array.Empty(); + + // Placement + public PlacementLocation8a[] Locations { get; private set; } = Array.Empty(); + public PlacementSpawner8a[] Spawners { get; private set; } = Array.Empty(); + public PlacementSpawner8a[] Wormholes { get; private set; } = Array.Empty(); + public LandmarkItemSpawn8a[] LandItems { get; private set; } = Array.Empty(); + public LandmarkItem8a[] LandMarks { get; private set; } = Array.Empty(); + public PlacementUnnnEntry[] Unown { get; private set; } = Array.Empty(); + public PlacementMkrgEntry[] Mikaruge { get; private set; } = Array.Empty(); + public PlacementSearchItem[] SearchItem { get; private set; } = Array.Empty(); + + private T2[] TryRead(string path) where T1 : class, IFlatBufferArchive where T2 : class + { + var index = Resident.GetIndexFull(path); + if (index == -1) + return Array.Empty(); + + var data = Resident[index]; + return FlatBufferConverter.DeserializeFrom(data).Table; + } + + private void TryWrite(string path, byte[] obj) + { + var index = Resident.GetIndexFull(path); + if (index == -1) + return; + + Resident[index] = obj; + } + + private void TryWrite(string path, T1 obj) where T1 : class => + TryWrite(path, FlatBufferConverter.SerializeFrom(obj)); + + public void LoadInfo() + { + // Load encount + Encounters = TryRead(Settings.Encounters); + Locations = TryRead(Settings.Locations); + Spawners = TryRead(Settings.Spawners); + Wormholes = TryRead(Settings.WormholeSpawners); + LandItems = TryRead(Settings.LandmarkItemSpawns); + LandMarks = TryRead(Settings.LandmarkItems); + Unown = TryRead(Settings.UnownSpawners); + Mikaruge = TryRead(Settings.Mkrg); + SearchItem = TryRead(Settings.SearchItem); + } + + public void SaveInfo() + { + TryWrite(Settings.Encounters, new EncounterDataArchive8a { Table = Encounters }.Write()); + TryWrite(Settings.Locations, new PlacementLocationArchive8a { Table = Locations }.Write()); + TryWrite(Settings.Spawners, new PlacementSpawnerArchive8a { Table = Spawners }.Write()); + TryWrite(Settings.WormholeSpawners, new PlacementSpawnerArchive8a { Table = Wormholes }.Write()); + TryWrite(Settings.LandmarkItemSpawns, new LandmarkItemSpawnTable8a { Table = LandItems }.Write()); + TryWrite(Settings.LandmarkItems, new LandmarkItemTable8a { Table = LandMarks }.Write()); + TryWrite(Settings.UnownSpawners, new PlacementUnnnTable { Table = Unown }.Write()); + TryWrite(Settings.Mkrg, new PlacementMkrgTable { Table = Mikaruge }.Write()); + TryWrite(Settings.SearchItem, new PlacementSearchItemTable { Table = SearchItem }.Write()); + } +} diff --git a/pkNX.Structures.FlatBuffers/Arceus/Resident/ResidentInfo.cs b/pkNX.Structures.FlatBuffers/Arceus/Resident/Editing/ResidentInfo.cs similarity index 98% rename from pkNX.Structures.FlatBuffers/Arceus/Resident/ResidentInfo.cs rename to pkNX.Structures.FlatBuffers/Arceus/Resident/Editing/ResidentInfo.cs index fb547df8..b7c07a77 100644 --- a/pkNX.Structures.FlatBuffers/Arceus/Resident/ResidentInfo.cs +++ b/pkNX.Structures.FlatBuffers/Arceus/Resident/Editing/ResidentInfo.cs @@ -6,7 +6,7 @@ namespace pkNX.Structures.FlatBuffers; /// /// Manually entered metadata about the interesting areas. /// -public class ResidentAreaSet +public sealed class ResidentAreaSet { public readonly string ParentName; public readonly IReadOnlyList SubAreas; diff --git a/pkNX.Structures.FlatBuffers/Arceus/Slots/EncounterTable8a.cs b/pkNX.Structures.FlatBuffers/Arceus/Slots/EncounterTable8a.cs index d944f1d4..eb1c2fbd 100644 --- a/pkNX.Structures.FlatBuffers/Arceus/Slots/EncounterTable8a.cs +++ b/pkNX.Structures.FlatBuffers/Arceus/Slots/EncounterTable8a.cs @@ -27,9 +27,10 @@ public class EncounterTable8a private static Dictionary GenerateTableMap() { - var result = new Dictionary(); - - result[0xCBF29CE484222645] = ""; + var result = new Dictionary + { + [0xCBF29CE484222645] = "", + }; var prefixes = new[] { "eve", "fly", "gmk", "lnd", "mas", "oyb", "swm", "whl" }; var kinds = new[] { "ex", "no", "ra" }; diff --git a/pkNX.Structures.FlatBuffers/Gen8/Placement/Zone/PlacementZone8.cs b/pkNX.Structures.FlatBuffers/Gen8/Placement/Zone/PlacementZone8.cs index 8361ccaf..3461a393 100644 --- a/pkNX.Structures.FlatBuffers/Gen8/Placement/Zone/PlacementZone8.cs +++ b/pkNX.Structures.FlatBuffers/Gen8/Placement/Zone/PlacementZone8.cs @@ -7,7 +7,6 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedType.Global // ReSharper disable UnusedMember.Global -#pragma warning disable CA1819 // Properties should not return arrays namespace pkNX.Structures.FlatBuffers { diff --git a/pkNX.WinForms/Controls/EncounterTableEditor8a.Designer.cs b/pkNX.WinForms/Controls/EncounterTableEditor8a.Designer.cs new file mode 100644 index 00000000..e1c5d3b3 --- /dev/null +++ b/pkNX.WinForms/Controls/EncounterTableEditor8a.Designer.cs @@ -0,0 +1,100 @@ +namespace pkNX.WinForms.Controls +{ + partial class EncounterTableEditor8a + { + /// + /// 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.B_NoShinyLocks = new System.Windows.Forms.Button(); + this.PG_Encounters = new System.Windows.Forms.PropertyGrid(); + this.CB_Encounters = new System.Windows.Forms.ComboBox(); + this.L_EncTableName = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // B_NoShinyLocks + // + this.B_NoShinyLocks.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.B_NoShinyLocks.Location = new System.Drawing.Point(614, 0); + this.B_NoShinyLocks.Name = "B_NoShinyLocks"; + this.B_NoShinyLocks.Size = new System.Drawing.Size(148, 23); + this.B_NoShinyLocks.TabIndex = 8; + this.B_NoShinyLocks.Text = "Remove All Shiny Locks"; + this.B_NoShinyLocks.UseVisualStyleBackColor = true; + this.B_NoShinyLocks.Click += new System.EventHandler(this.B_NoShinyLocks_Click); + // + // PG_Encounters + // + this.PG_Encounters.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.PG_Encounters.Location = new System.Drawing.Point(3, 38); + this.PG_Encounters.Name = "PG_Encounters"; + this.PG_Encounters.Size = new System.Drawing.Size(759, 548); + this.PG_Encounters.TabIndex = 7; + // + // CB_Encounters + // + this.CB_Encounters.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend; + this.CB_Encounters.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems; + this.CB_Encounters.FormattingEnabled = true; + this.CB_Encounters.Location = new System.Drawing.Point(3, 15); + this.CB_Encounters.Name = "CB_Encounters"; + this.CB_Encounters.Size = new System.Drawing.Size(174, 21); + this.CB_Encounters.TabIndex = 6; + this.CB_Encounters.SelectedIndexChanged += new System.EventHandler(this.CB_Encounters_SelectedIndexChanged); + // + // L_EncTableName + // + this.L_EncTableName.AutoSize = true; + this.L_EncTableName.Location = new System.Drawing.Point(3, 1); + this.L_EncTableName.Name = "L_EncTableName"; + this.L_EncTableName.Size = new System.Drawing.Size(35, 13); + this.L_EncTableName.TabIndex = 9; + this.L_EncTableName.Text = "label1"; + // + // EncounterTableEditor8a + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.L_EncTableName); + this.Controls.Add(this.B_NoShinyLocks); + this.Controls.Add(this.PG_Encounters); + this.Controls.Add(this.CB_Encounters); + this.Name = "EncounterTableEditor8a"; + this.Size = new System.Drawing.Size(765, 589); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button B_NoShinyLocks; + private System.Windows.Forms.PropertyGrid PG_Encounters; + private System.Windows.Forms.ComboBox CB_Encounters; + private System.Windows.Forms.Label L_EncTableName; + } +} diff --git a/pkNX.WinForms/Controls/EncounterTableEditor8a.cs b/pkNX.WinForms/Controls/EncounterTableEditor8a.cs new file mode 100644 index 00000000..0413d83f --- /dev/null +++ b/pkNX.WinForms/Controls/EncounterTableEditor8a.cs @@ -0,0 +1,61 @@ +using System; +using System.Linq; +using System.Windows.Forms; +using pkNX.Structures.FlatBuffers; + +namespace pkNX.WinForms.Controls; + +public partial class EncounterTableEditor8a : UserControl +{ + public EncounterTable8a[] Tables = Array.Empty(); + + public EncounterTableEditor8a() => InitializeComponent(); + + public void LoadTable(EncounterTable8a[] table, string path) + { + Tables = table; + L_EncTableName.Text = path; + + var items = table.Select(z => new ComboItem(z.TableName.Replace("\"", ""), z)).ToArray(); + CB_Encounters.DisplayMember = nameof(ComboItem.Text); + CB_Encounters.ValueMember = nameof(ComboItem.Value); + CB_Encounters.DataSource = new BindingSource(items, null); + + CB_Encounters.SelectedIndex = 0; + } + + private class ComboItem + { + public ComboItem(string text, EncounterTable8a value) + { + Text = text; + Value = value; + } + + public string Text { get; } + public EncounterTable8a Value { get; } + } + + private void CB_Encounters_SelectedIndexChanged(object sender, EventArgs e) + { + PG_Encounters.SelectedObject = (EncounterTable8a)CB_Encounters.SelectedValue; + } + + private void B_NoShinyLocks_Click(object sender, EventArgs e) + { + int ctr = 0; + foreach (var table in Tables) + { + foreach (var slot in table.Table) + { + if (slot.ShinyLock != ShinyType8a.Never) + continue; + slot.ShinyLock = ShinyType8a.Random; + ctr++; + } + } + + WinFormsUtil.Alert($"Removed {ctr} locked slots."); + CB_Encounters_SelectedIndexChanged(sender, e); + } +} diff --git a/pkNX.WinForms/Controls/EncounterTableEditor8a.resx b/pkNX.WinForms/Controls/EncounterTableEditor8a.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/pkNX.WinForms/Controls/EncounterTableEditor8a.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/Dumping/GameDumperPLA.cs b/pkNX.WinForms/Dumping/GameDumperPLA.cs index 24f8054e..7f62019c 100644 --- a/pkNX.WinForms/Dumping/GameDumperPLA.cs +++ b/pkNX.WinForms/Dumping/GameDumperPLA.cs @@ -375,7 +375,8 @@ public void DumpWilds() var residentpak = ROM.GetFile(GameFile.Resident)[0]; var resident = new GFPack(residentpak); - var settings = FlatBufferConverter.DeserializeFrom(resident[2042]); + var bin_settings = resident.GetDataFullPath("bin/field/resident/AreaSettings.bin"); + var settings = FlatBufferConverter.DeserializeFrom(bin_settings); const string wild = "wild"; Directory.CreateDirectory(GetPath(wild)); @@ -466,7 +467,8 @@ public void DumpResident() { var residentpak = ROM.GetFile(GameFile.Resident)[0]; var resident = new GFPack(residentpak); - var settings = FlatBufferConverter.DeserializeFrom(resident[2042]); + var bin_settings = resident.GetDataFullPath("bin/field/resident/AreaSettings.bin"); + var settings = FlatBufferConverter.DeserializeFrom(bin_settings); var dir = GetPath("Resident"); var props = typeof(AreaSettings8a).GetProperties(); foreach (var x in settings.Table) @@ -504,7 +506,8 @@ public void DumpPlacement() { var residentpak = ROM.GetFile(GameFile.Resident)[0]; var resident = new GFPack(residentpak); - var settings = FlatBufferConverter.DeserializeFrom(resident[2042]); + var bin_settings = resident.GetDataFullPath("bin/field/resident/AreaSettings.bin"); + var settings = FlatBufferConverter.DeserializeFrom(bin_settings); Dictionary map = GetPlaceNameMap(); diff --git a/pkNX.WinForms/MainEditor/EditorGG.cs b/pkNX.WinForms/MainEditor/EditorGG.cs index 2ed682d2..ec3077cc 100644 --- a/pkNX.WinForms/MainEditor/EditorGG.cs +++ b/pkNX.WinForms/MainEditor/EditorGG.cs @@ -357,7 +357,7 @@ void Randomize() else { var table = shop.Shop2; - var names = table.Select((z, i) => $"{(z.LGPE.TryGetValue(z.Hash, out var shopName) ? shopName : z.Hash.ToString("X"))}").ToArray(); + var names = table.Select((z, _) => $"{(z.LGPE.TryGetValue(z.Hash, out var shopName) ? shopName : z.Hash.ToString("X"))}").ToArray(); var cache = new DirectCache(table); using var form = new GenericEditor(cache, names, $"{nameof(Shop2)} Editor", Randomize); form.ShowDialog(); diff --git a/pkNX.WinForms/MainEditor/EditorPLA.cs b/pkNX.WinForms/MainEditor/EditorPLA.cs index 7ea6756c..23613d31 100644 --- a/pkNX.WinForms/MainEditor/EditorPLA.cs +++ b/pkNX.WinForms/MainEditor/EditorPLA.cs @@ -233,6 +233,12 @@ public void EditSpawns() form.ShowDialog(); } + public void EditAreas() + { + using var form = new AreaEditor8a((GameManagerPLA)ROM); + form.ShowDialog(); + } + public void EditMoves() { var obj = ROM[GameFile.MoveStats]; // folder diff --git a/pkNX.WinForms/Subforms/AreaEditor8a.Designer.cs b/pkNX.WinForms/Subforms/AreaEditor8a.Designer.cs new file mode 100644 index 00000000..749e14e7 --- /dev/null +++ b/pkNX.WinForms/Subforms/AreaEditor8a.Designer.cs @@ -0,0 +1,162 @@ +namespace pkNX.WinForms.Subforms +{ + partial class AreaEditor8a + { + /// + /// 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.CB_Area = new System.Windows.Forms.ComboBox(); + this.TC_Editor = new System.Windows.Forms.TabControl(); + this.Tab_Encounters = new System.Windows.Forms.TabPage(); + this.Tab_Regular = new System.Windows.Forms.TabPage(); + this.Tab_Wormhole = new System.Windows.Forms.TabPage(); + this.Tab_Landmarks = new System.Windows.Forms.TabPage(); + this.Edit_Encounters = new pkNX.WinForms.Controls.EncounterTableEditor8a(); + this.Tab_Randomize = new System.Windows.Forms.TabPage(); + this.B_Save = new System.Windows.Forms.Button(); + this.TC_Editor.SuspendLayout(); + this.Tab_Encounters.SuspendLayout(); + this.SuspendLayout(); + // + // CB_Area + // + this.CB_Area.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend; + this.CB_Area.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems; + this.CB_Area.FormattingEnabled = true; + this.CB_Area.Location = new System.Drawing.Point(12, 12); + this.CB_Area.Name = "CB_Area"; + this.CB_Area.Size = new System.Drawing.Size(212, 21); + this.CB_Area.TabIndex = 1; + this.CB_Area.SelectedIndexChanged += new System.EventHandler(this.CB_Map_SelectedIndexChanged); + // + // TC_Editor + // + this.TC_Editor.Controls.Add(this.Tab_Encounters); + this.TC_Editor.Controls.Add(this.Tab_Regular); + this.TC_Editor.Controls.Add(this.Tab_Wormhole); + this.TC_Editor.Controls.Add(this.Tab_Landmarks); + this.TC_Editor.Controls.Add(this.Tab_Randomize); + this.TC_Editor.Location = new System.Drawing.Point(12, 39); + this.TC_Editor.Name = "TC_Editor"; + this.TC_Editor.SelectedIndex = 0; + this.TC_Editor.Size = new System.Drawing.Size(685, 481); + this.TC_Editor.TabIndex = 2; + // + // Tab_Encounters + // + this.Tab_Encounters.Controls.Add(this.Edit_Encounters); + this.Tab_Encounters.Location = new System.Drawing.Point(4, 22); + this.Tab_Encounters.Name = "Tab_Encounters"; + this.Tab_Encounters.Padding = new System.Windows.Forms.Padding(3); + this.Tab_Encounters.Size = new System.Drawing.Size(677, 455); + this.Tab_Encounters.TabIndex = 0; + this.Tab_Encounters.Text = "Encounters"; + this.Tab_Encounters.UseVisualStyleBackColor = true; + // + // Tab_Regular + // + this.Tab_Regular.Location = new System.Drawing.Point(4, 22); + this.Tab_Regular.Name = "Tab_Regular"; + this.Tab_Regular.Padding = new System.Windows.Forms.Padding(3); + this.Tab_Regular.Size = new System.Drawing.Size(677, 455); + this.Tab_Regular.TabIndex = 1; + this.Tab_Regular.Text = "*Regular"; + this.Tab_Regular.UseVisualStyleBackColor = true; + // + // Tab_Wormhole + // + this.Tab_Wormhole.Location = new System.Drawing.Point(4, 22); + this.Tab_Wormhole.Name = "Tab_Wormhole"; + this.Tab_Wormhole.Size = new System.Drawing.Size(677, 455); + this.Tab_Wormhole.TabIndex = 2; + this.Tab_Wormhole.Text = "*Wormhole"; + this.Tab_Wormhole.UseVisualStyleBackColor = true; + // + // Tab_Landmarks + // + this.Tab_Landmarks.Location = new System.Drawing.Point(4, 22); + this.Tab_Landmarks.Name = "Tab_Landmarks"; + this.Tab_Landmarks.Size = new System.Drawing.Size(677, 455); + this.Tab_Landmarks.TabIndex = 3; + this.Tab_Landmarks.Text = "*Landmarks"; + this.Tab_Landmarks.UseVisualStyleBackColor = true; + // + // Edit_Encounters + // + this.Edit_Encounters.Dock = System.Windows.Forms.DockStyle.Fill; + this.Edit_Encounters.Location = new System.Drawing.Point(3, 3); + this.Edit_Encounters.Name = "Edit_Encounters"; + this.Edit_Encounters.Size = new System.Drawing.Size(671, 449); + this.Edit_Encounters.TabIndex = 0; + // + // Tab_Randomize + // + this.Tab_Randomize.Location = new System.Drawing.Point(4, 22); + this.Tab_Randomize.Name = "Tab_Randomize"; + this.Tab_Randomize.Padding = new System.Windows.Forms.Padding(3); + this.Tab_Randomize.Size = new System.Drawing.Size(677, 455); + this.Tab_Randomize.TabIndex = 4; + this.Tab_Randomize.Text = "Randomize"; + this.Tab_Randomize.UseVisualStyleBackColor = true; + // + // B_Save + // + this.B_Save.Location = new System.Drawing.Point(633, 1); + this.B_Save.Name = "B_Save"; + this.B_Save.Size = new System.Drawing.Size(75, 23); + this.B_Save.TabIndex = 3; + this.B_Save.Text = "Save All"; + this.B_Save.UseVisualStyleBackColor = true; + this.B_Save.Click += new System.EventHandler(this.B_Save_Click); + // + // AreaEditor8a + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(709, 532); + this.Controls.Add(this.B_Save); + this.Controls.Add(this.TC_Editor); + this.Controls.Add(this.CB_Area); + this.Name = "AreaEditor8a"; + this.Text = "Area Editor"; + this.TC_Editor.ResumeLayout(false); + this.Tab_Encounters.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + private System.Windows.Forms.ComboBox CB_Area; + private System.Windows.Forms.TabControl TC_Editor; + private System.Windows.Forms.TabPage Tab_Encounters; + private System.Windows.Forms.TabPage Tab_Regular; + private System.Windows.Forms.TabPage Tab_Wormhole; + private System.Windows.Forms.TabPage Tab_Landmarks; + private Controls.EncounterTableEditor8a Edit_Encounters; + private System.Windows.Forms.TabPage Tab_Randomize; + private System.Windows.Forms.Button B_Save; + } +} \ No newline at end of file diff --git a/pkNX.WinForms/Subforms/AreaEditor8a.cs b/pkNX.WinForms/Subforms/AreaEditor8a.cs new file mode 100644 index 00000000..7203e6d3 --- /dev/null +++ b/pkNX.WinForms/Subforms/AreaEditor8a.cs @@ -0,0 +1,81 @@ +using System; +using System.Diagnostics; +using System.Linq; +using System.Windows.Forms; +using pkNX.Containers; +using pkNX.Game; +using pkNX.Structures.FlatBuffers; + +namespace pkNX.WinForms.Subforms; + +public partial class AreaEditor8a : Form +{ + private readonly GameManagerPLA ROM; + private readonly GFPack Resident; + private readonly AreaSettingsTable8a Settings; + + private readonly string[] AreaNames; + + private ResidentArea8a Area; + private int AreaIndex; + private readonly bool Loading; + + public AreaEditor8a(GameManagerPLA rom) + { + ROM = rom; + + var residentpak = ROM.GetFile(GameFile.Resident)[0]; + Resident = new GFPack(residentpak); + var bin_settings = Resident.GetDataFullPath("bin/field/resident/AreaSettings.bin"); + Settings = FlatBufferConverter.DeserializeFrom(bin_settings); + + AreaNames = Settings.Table.Select(z => z.Name).ToArray(); + + const string startingArea = "ha_area01"; + (AreaIndex, Area) = LoadAreaByName(startingArea); + + InitializeComponent(); + + Loading = true; + CB_Area.Items.AddRange(AreaNames); + CB_Area.SelectedIndex = AreaIndex; + LoadArea(); + Loading = false; + } + + private (int index, ResidentArea8a area) LoadAreaByName(string name) + { + var index = Array.IndexOf(AreaNames, name); + var area = new ResidentArea8a(Resident, Settings.Find(name)); + area.LoadInfo(); + return (index, area); + } + + private void CB_Map_SelectedIndexChanged(object sender, EventArgs e) + { + if (Loading) + return; + SaveArea(); + (AreaIndex, Area) = LoadAreaByName(AreaNames[CB_Area.SelectedIndex]); + LoadArea(); + } + + private void LoadArea() + { + Debug.WriteLine($"Loading Area {AreaIndex}"); + Edit_Encounters.LoadTable(Area.Encounters, Area.Settings.Encounters); + } + + private void SaveArea() + { + Debug.WriteLine($"Saving Area {AreaIndex}"); + Area.SaveInfo(); + } + + private void B_Save_Click(object sender, EventArgs e) + { + SaveArea(); + ROM.GetFile(GameFile.Resident)[0] = Resident.Write(); + Close(); + } +} diff --git a/pkNX.WinForms/Subforms/MapViewer8a.cs b/pkNX.WinForms/Subforms/MapViewer8a.cs index f768f9e6..b86ff52c 100644 --- a/pkNX.WinForms/Subforms/MapViewer8a.cs +++ b/pkNX.WinForms/Subforms/MapViewer8a.cs @@ -22,7 +22,8 @@ public MapViewer8a(GameManagerPLA rom, GFPack resident) { ROM = rom; Resident = resident; - Settings = FlatBufferConverter.DeserializeFrom(resident[2042]); + var bin_settings = resident.GetDataFullPath("bin/field/resident/AreaSettings.bin"); + Settings = FlatBufferConverter.DeserializeFrom(bin_settings); InitializeComponent(); @@ -52,7 +53,8 @@ public MapViewer8a(GameManagerPLA rom, GFPack resident) Loading = false; CB_Map.SelectedIndex = 0; } - public class ComboItem + + private class ComboItem { public ComboItem(string text, int value) { diff --git a/pkNX.WinForms/Subforms/TextEditor.cs b/pkNX.WinForms/Subforms/TextEditor.cs index 8a2ef308..76ac792b 100644 --- a/pkNX.WinForms/Subforms/TextEditor.cs +++ b/pkNX.WinForms/Subforms/TextEditor.cs @@ -154,9 +154,7 @@ private bool ImportTextFiles(string fileName) for (int i = 0; i < TextData.Length; i++) { try { TextData[i] = textLines[i]; } -#pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) { WinFormsUtil.Error($"The input Text File (# {i}) failed to convert:", e.ToString()); return false; } -#pragma warning restore CA1031 // Do not catch general exception types } return true; @@ -171,9 +169,7 @@ private void ChangeEntry(object sender, EventArgs e) { TextData[entry] = GetCurrentDGLines(); } -#pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) { WinFormsUtil.Error(ex.ToString()); } -#pragma warning restore CA1031 // Do not catch general exception types } // Reset @@ -235,9 +231,7 @@ private void B_AddLine_Click(object sender, EventArgs e) { int currentRow = 0; try { currentRow = dgv.CurrentRow.Index; } -#pragma warning disable CA1031 // Do not catch general exception types catch { dgv.Rows.Add(); } -#pragma warning restore CA1031 // Do not catch general exception types if (dgv.Rows.Count != 1 && (currentRow < dgv.Rows.Count - 1 || currentRow == 0)) { if (ModifierKeys != Keys.Control && currentRow != 0)