diff --git a/NHSE.Core/Structures/Acres/Terrain/AcreCoordinate.cs b/NHSE.Core/Structures/Acres/Terrain/AcreCoordinate.cs index e4d002e..d7e2056 100644 --- a/NHSE.Core/Structures/Acres/Terrain/AcreCoordinate.cs +++ b/NHSE.Core/Structures/Acres/Terrain/AcreCoordinate.cs @@ -5,10 +5,10 @@ public class AcreCoordinate public readonly string Name; public readonly int X, Y; - public AcreCoordinate(int x, int y) + public AcreCoordinate(int x, int y) : this((char)('0' + x), (char)('A' + y), x, y) { } + + public AcreCoordinate(char xName, char yName, int x, int y) { - char yName = (char)('A' + y); - char xName = (char)('0' + x); Name = $"{yName}{xName}"; X = x; Y = y; @@ -25,5 +25,21 @@ public static AcreCoordinate[] GetGrid(int width, int height) } return result; } + + public static AcreCoordinate[] GetGridWithExterior(int width, int height) + { + var result = new AcreCoordinate[width * height]; + int i = 0; + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + var xn = (x == 0) ? 'L' : x == width - 1 ? 'R' : (char)('0' + x - 1); + var yn = (y == 0) ? 'T' : y == height - 1 ? 'B' : (char)('A' + y - 1); + result[i++] = new AcreCoordinate(xn, yn, x, y); + } + } + return result; + } } } diff --git a/NHSE.Core/Util/ComboItem.cs b/NHSE.Core/Util/ComboItem.cs index 3151571..b2ddd77 100644 --- a/NHSE.Core/Util/ComboItem.cs +++ b/NHSE.Core/Util/ComboItem.cs @@ -42,6 +42,18 @@ public static List GetArray(string[] items) return result; } + public static List GetArray(Type t) where T : struct, IFormattable + { + var names = Enum.GetNames(t); + var values = (T[])Enum.GetValues(t); + + var acres = new List(names.Length); + for (int i = 0; i < names.Length; i++) + acres.Add(new ComboItem($"{names[i]} - {values[i]:X}", (ushort)(object)values[i])); + acres.SortByText(); + return acres; + } + public static List GetArray(IReadOnlyList values, string[] names) { var result = new List(values.Count); diff --git a/NHSE.WinForms/Subforms/Map/AcreEditor.cs b/NHSE.WinForms/Subforms/Map/AcreEditor.cs index dcc5ed6..6982b6e 100644 --- a/NHSE.WinForms/Subforms/Map/AcreEditor.cs +++ b/NHSE.WinForms/Subforms/Map/AcreEditor.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.IO; using System.Windows.Forms; using NHSE.Core; @@ -51,17 +50,9 @@ private void UpdateAcre(ushort val, int x, int y) private void LoadHintComboBox() { - var names = Enum.GetNames(typeof(OutsideAcre)); - var values = (OutsideAcre[])Enum.GetValues(typeof(OutsideAcre)); - - var acres = new List(names.Length); - for (int i = 0; i < names.Length; i++) - acres.Add(new ComboItem($"{names[i]} - {values[i]:X}", (ushort) values[i])); - acres.SortByText(); - CB_AcreNames.DisplayMember = nameof(ComboItem.Text); CB_AcreNames.ValueMember = nameof(ComboItem.Value); - CB_AcreNames.DataSource = acres; + CB_AcreNames.DataSource = ComboItemUtil.GetArray(typeof(OutsideAcre)); CB_AcreNames.SelectedIndex = 0; } diff --git a/NHSE.WinForms/Subforms/Map/FieldItemEditor.Designer.cs b/NHSE.WinForms/Subforms/Map/FieldItemEditor.Designer.cs index 828d561..fd3e4f3 100644 --- a/NHSE.WinForms/Subforms/Map/FieldItemEditor.Designer.cs +++ b/NHSE.WinForms/Subforms/Map/FieldItemEditor.Designer.cs @@ -69,7 +69,6 @@ private void InitializeComponent() this.GB_Remove = new System.Windows.Forms.Label(); this.TC_Editor = new System.Windows.Forms.TabControl(); this.Tab_Item = new System.Windows.Forms.TabPage(); - this.ItemEdit = new NHSE.WinForms.ItemEditor(); this.B_DumpLoadField = new System.Windows.Forms.Button(); this.CM_DLField = new System.Windows.Forms.ContextMenuStrip(this.components); this.B_DumpAcre = new System.Windows.Forms.ToolStripMenuItem(); @@ -112,6 +111,14 @@ private void InitializeComponent() this.L_FieldItemTransparency = new System.Windows.Forms.Label(); this.B_DumpLoadTerrain = new System.Windows.Forms.Button(); this.B_ModifyAllTerrain = new System.Windows.Forms.Button(); + this.Tab_Acres = new System.Windows.Forms.TabPage(); + this.CB_MapAcreSelect = new System.Windows.Forms.ComboBox(); + this.B_DumpLoadAcres = new System.Windows.Forms.Button(); + this.CM_DLMapAcres = new System.Windows.Forms.ContextMenuStrip(this.components); + this.B_DumpMapAcres = new System.Windows.Forms.ToolStripMenuItem(); + this.B_ImportMapAcres = new System.Windows.Forms.ToolStripMenuItem(); + this.label1 = new System.Windows.Forms.Label(); + this.CB_MapAcre = new System.Windows.Forms.ComboBox(); this.CM_DLTerrain = new System.Windows.Forms.ContextMenuStrip(this.components); this.B_DumpTerrainAcre = new System.Windows.Forms.ToolStripMenuItem(); this.B_DumpTerrainAll = new System.Windows.Forms.ToolStripMenuItem(); @@ -123,6 +130,7 @@ private void InitializeComponent() this.RB_Item = new System.Windows.Forms.RadioButton(); this.RB_Terrain = new System.Windows.Forms.RadioButton(); this.L_TileMode = new System.Windows.Forms.Label(); + this.ItemEdit = new NHSE.WinForms.ItemEditor(); this.CM_Click.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.PB_Map)).BeginInit(); this.CM_Picture.SuspendLayout(); @@ -148,6 +156,8 @@ private void InitializeComponent() this.Tab_Terrain.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.TR_Terrain)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.TR_BuildingTransparency)).BeginInit(); + this.Tab_Acres.SuspendLayout(); + this.CM_DLMapAcres.SuspendLayout(); this.CM_DLTerrain.SuspendLayout(); this.CM_Terrain.SuspendLayout(); this.SuspendLayout(); @@ -509,6 +519,7 @@ private void InitializeComponent() this.TC_Editor.Controls.Add(this.Tab_Item); this.TC_Editor.Controls.Add(this.Tab_Building); this.TC_Editor.Controls.Add(this.Tab_Terrain); + this.TC_Editor.Controls.Add(this.Tab_Acres); this.TC_Editor.Location = new System.Drawing.Point(767, 12); this.TC_Editor.Name = "TC_Editor"; this.TC_Editor.SelectedIndex = 0; @@ -529,14 +540,6 @@ private void InitializeComponent() this.Tab_Item.Text = "Items"; this.Tab_Item.UseVisualStyleBackColor = true; // - // ItemEdit - // - this.ItemEdit.Dock = System.Windows.Forms.DockStyle.Top; - this.ItemEdit.Location = new System.Drawing.Point(3, 3); - this.ItemEdit.Name = "ItemEdit"; - this.ItemEdit.Size = new System.Drawing.Size(238, 390); - this.ItemEdit.TabIndex = 40; - // // B_DumpLoadField // this.B_DumpLoadField.ContextMenuStrip = this.CM_DLField; @@ -1010,6 +1013,83 @@ private void InitializeComponent() this.B_ModifyAllTerrain.UseVisualStyleBackColor = true; this.B_ModifyAllTerrain.Click += new System.EventHandler(this.B_ModifyAllTerrain_Click); // + // Tab_Acres + // + this.Tab_Acres.Controls.Add(this.CB_MapAcreSelect); + this.Tab_Acres.Controls.Add(this.B_DumpLoadAcres); + this.Tab_Acres.Controls.Add(this.label1); + this.Tab_Acres.Controls.Add(this.CB_MapAcre); + this.Tab_Acres.Location = new System.Drawing.Point(4, 22); + this.Tab_Acres.Name = "Tab_Acres"; + this.Tab_Acres.Padding = new System.Windows.Forms.Padding(3); + this.Tab_Acres.Size = new System.Drawing.Size(244, 458); + this.Tab_Acres.TabIndex = 3; + this.Tab_Acres.Text = "Acres"; + this.Tab_Acres.UseVisualStyleBackColor = true; + // + // CB_MapAcreSelect + // + this.CB_MapAcreSelect.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.CB_MapAcreSelect.FormattingEnabled = true; + this.CB_MapAcreSelect.Location = new System.Drawing.Point(9, 33); + this.CB_MapAcreSelect.Name = "CB_MapAcreSelect"; + this.CB_MapAcreSelect.Size = new System.Drawing.Size(213, 21); + this.CB_MapAcreSelect.TabIndex = 102; + this.CB_MapAcreSelect.SelectedValueChanged += new System.EventHandler(this.CB_MapAcreSelect_SelectedValueChanged); + // + // B_DumpLoadAcres + // + this.B_DumpLoadAcres.ContextMenuStrip = this.CM_DLMapAcres; + this.B_DumpLoadAcres.Location = new System.Drawing.Point(6, 413); + this.B_DumpLoadAcres.Name = "B_DumpLoadAcres"; + this.B_DumpLoadAcres.Size = new System.Drawing.Size(112, 40); + this.B_DumpLoadAcres.TabIndex = 101; + this.B_DumpLoadAcres.Text = "Dump/Import"; + this.B_DumpLoadAcres.UseVisualStyleBackColor = true; + this.B_DumpLoadAcres.Click += new System.EventHandler(this.B_DumpLoadAcres_Click); + // + // CM_DLMapAcres + // + this.CM_DLMapAcres.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.B_DumpMapAcres, + this.B_ImportMapAcres}); + this.CM_DLMapAcres.Name = "CM_Picture"; + this.CM_DLMapAcres.ShowImageMargin = false; + this.CM_DLMapAcres.Size = new System.Drawing.Size(156, 70); + // + // B_DumpMapAcres + // + this.B_DumpMapAcres.Name = "B_DumpMapAcres"; + this.B_DumpMapAcres.Size = new System.Drawing.Size(155, 22); + this.B_DumpMapAcres.Text = "Dump Map Acres"; + this.B_DumpMapAcres.Click += new System.EventHandler(this.B_DumpMapAcres_Click); + // + // B_ImportMapAcres + // + this.B_ImportMapAcres.Name = "B_ImportMapAcres"; + this.B_ImportMapAcres.Size = new System.Drawing.Size(155, 22); + this.B_ImportMapAcres.Text = "Import Map Acres"; + this.B_ImportMapAcres.Click += new System.EventHandler(this.B_ImportMapAcres_Click); + // + // label1 + // + this.label1.Location = new System.Drawing.Point(6, 6); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(89, 19); + this.label1.TabIndex = 99; + this.label1.Text = "Acre:"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // + // CB_MapAcre + // + this.CB_MapAcre.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.CB_MapAcre.FormattingEnabled = true; + this.CB_MapAcre.Location = new System.Drawing.Point(101, 6); + this.CB_MapAcre.Name = "CB_MapAcre"; + this.CB_MapAcre.Size = new System.Drawing.Size(49, 21); + this.CB_MapAcre.TabIndex = 98; + this.CB_MapAcre.SelectedIndexChanged += new System.EventHandler(this.CB_MapAcre_SelectedIndexChanged); + // // CM_DLTerrain // this.CM_DLTerrain.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -1103,6 +1183,14 @@ private void InitializeComponent() this.L_TileMode.Text = "Tile Editor Mode"; this.L_TileMode.TextAlign = System.Drawing.ContentAlignment.MiddleRight; // + // ItemEdit + // + this.ItemEdit.Dock = System.Windows.Forms.DockStyle.Top; + this.ItemEdit.Location = new System.Drawing.Point(3, 3); + this.ItemEdit.Name = "ItemEdit"; + this.ItemEdit.Size = new System.Drawing.Size(238, 390); + this.ItemEdit.TabIndex = 40; + // // FieldItemEditor // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -1162,6 +1250,8 @@ private void InitializeComponent() this.Tab_Terrain.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.TR_Terrain)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.TR_BuildingTransparency)).EndInit(); + this.Tab_Acres.ResumeLayout(false); + this.CM_DLMapAcres.ResumeLayout(false); this.CM_DLTerrain.ResumeLayout(false); this.CM_Terrain.ResumeLayout(false); this.ResumeLayout(false); @@ -1264,5 +1354,13 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem B_RemoveShells; private System.Windows.Forms.ToolStripMenuItem B_RemoveFlowers; private ItemEditor ItemEdit; + private System.Windows.Forms.TabPage Tab_Acres; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.ComboBox CB_MapAcre; + private System.Windows.Forms.Button B_DumpLoadAcres; + private System.Windows.Forms.ContextMenuStrip CM_DLMapAcres; + private System.Windows.Forms.ToolStripMenuItem B_DumpMapAcres; + private System.Windows.Forms.ToolStripMenuItem B_ImportMapAcres; + private System.Windows.Forms.ComboBox CB_MapAcreSelect; } } \ No newline at end of file diff --git a/NHSE.WinForms/Subforms/Map/FieldItemEditor.cs b/NHSE.WinForms/Subforms/Map/FieldItemEditor.cs index 3f0c6b1..067001b 100644 --- a/NHSE.WinForms/Subforms/Map/FieldItemEditor.cs +++ b/NHSE.WinForms/Subforms/Map/FieldItemEditor.cs @@ -31,26 +31,48 @@ public FieldItemEditor(MainSave sav) View = new MapViewer(Map); Loading = true; + + LoadComboBoxes(); + LoadBuildings(sav); + ReloadMapBackground(); + LoadEditors(); + LB_Items.SelectedIndex = 0; + CB_Acre.SelectedIndex = 0; + CB_MapAcre.SelectedIndex = 0; + Loading = false; + LoadItemGridAcre(); + } + + private void LoadComboBoxes() + { foreach (var acre in MapGrid.Acres) CB_Acre.Items.Add(acre.Name); + var exterior = AcreCoordinate.GetGridWithExterior(9, 7); + foreach (var acre in exterior) + CB_MapAcre.Items.Add(acre.Name); + + CB_MapAcreSelect.DisplayMember = nameof(ComboItem.Text); + CB_MapAcreSelect.ValueMember = nameof(ComboItem.Value); + CB_MapAcreSelect.DataSource = ComboItemUtil.GetArray(typeof(OutsideAcre)); + } + + private void LoadBuildings(MainSave sav) + { NUD_PlazaX.Value = sav.EventPlazaLeftUpX; NUD_PlazaY.Value = sav.EventPlazaLeftUpZ; foreach (var obj in Map.Buildings) LB_Items.Items.Add(obj.ToString()); + } - ReloadMapBackground(); - + private void LoadEditors() + { var data = GameInfo.Strings.ItemDataSource.ToList(); var field = FieldItemList.Items.Select(z => z.Value).ToList(); data.Add(field, GameInfo.Strings.InternalNameTranslation); ItemEdit.Initialize(data, true); PG_TerrainTile.SelectedObject = new TerrainTile(); - LB_Items.SelectedIndex = 0; - CB_Acre.SelectedIndex = 0; - Loading = false; - LoadItemGridAcre(); } private int AcreIndex => CB_Acre.SelectedIndex; @@ -268,6 +290,7 @@ private void B_Save_Click(object sender, EventArgs e) Map.Items.Save(); SAV.SetTerrainTiles(Map.Terrain.Tiles); + SAV.SetAcreBytes(Map.Terrain.BaseAcres); SAV.Buildings = Map.Buildings; SAV.EventPlazaLeftUpX = Map.PlazaX; SAV.EventPlazaLeftUpZ = Map.PlazaY; @@ -531,6 +554,7 @@ private void Remove(ToolStripItem sender, Func removal) private void B_DumpLoadTerrain_Click(object sender, EventArgs e) => ShowContextMenuBelow(CM_DLTerrain, B_DumpLoadTerrain); private void B_DumpLoadBuildings_Click(object sender, EventArgs e) => ShowContextMenuBelow(CM_DLBuilding, B_DumpLoadBuildings); private void B_ModifyAllTerrain_Click(object sender, EventArgs e) => ShowContextMenuBelow(CM_Terrain, B_ModifyAllTerrain); + private void B_DumpLoadAcres_Click(object sender, EventArgs e) => ShowContextMenuBelow(CM_DLMapAcres, B_DumpLoadAcres); private void TR_Transparency_Scroll(object sender, EventArgs e) => ReloadItems(); private void TR_BuildingTransparency_Scroll(object sender, EventArgs e) => ReloadBuildingsTerrain(); private void TR_Terrain_Scroll(object sender, EventArgs e) => ReloadBuildingsTerrain(); @@ -610,5 +634,46 @@ private void NUD_BuildingType_ValueChanged(object sender, EventArgs e) ReloadBuildingsTerrain(); } #endregion + + #region Acres + + private void CB_MapAcre_SelectedIndexChanged(object sender, EventArgs e) + { + var acre = Map.Terrain.BaseAcres[CB_MapAcre.SelectedIndex * 2]; + CB_MapAcreSelect.SelectedValue = (int)acre; + } + + private void CB_MapAcreSelect_SelectedValueChanged(object sender, EventArgs e) + { + if (Loading) + return; + + var index = CB_MapAcre.SelectedIndex; + var value = WinFormsUtil.GetIndex(CB_MapAcreSelect); + + var oldValue = Map.Terrain.BaseAcres[index * 2]; + if (value == oldValue) + return; + Map.Terrain.BaseAcres[index * 2] = (byte)value; + ReloadBuildingsTerrain(); + } + + private void B_DumpMapAcres_Click(object sender, EventArgs e) + { + if (!MapDumpHelper.DumpMapAcresAll(Map.Terrain.BaseAcres)) + return; + ReloadBuildingsTerrain(); + System.Media.SystemSounds.Asterisk.Play(); + } + + private void B_ImportMapAcres_Click(object sender, EventArgs e) + { + if (!MapDumpHelper.ImportMapAcresAll(Map.Terrain.BaseAcres)) + return; + ReloadBuildingsTerrain(); + System.Media.SystemSounds.Asterisk.Play(); + } + + #endregion } } diff --git a/NHSE.WinForms/Subforms/Map/FieldItemEditor.resx b/NHSE.WinForms/Subforms/Map/FieldItemEditor.resx index 4bd5a9a..8b99e1b 100644 --- a/NHSE.WinForms/Subforms/Map/FieldItemEditor.resx +++ b/NHSE.WinForms/Subforms/Map/FieldItemEditor.resx @@ -129,6 +129,9 @@ 465, 17 + + 17, 56 + 620, 17 diff --git a/NHSE.WinForms/Subforms/Map/MapDumpHelper.cs b/NHSE.WinForms/Subforms/Map/MapDumpHelper.cs index 1eb7505..00ec343 100644 --- a/NHSE.WinForms/Subforms/Map/MapDumpHelper.cs +++ b/NHSE.WinForms/Subforms/Map/MapDumpHelper.cs @@ -209,5 +209,44 @@ public static bool ImportBuildings(IReadOnlyList buildings) buildings[i].CopyFrom(arr[i]); return true; } + + public static bool DumpMapAcresAll(byte[] data) + { + using var sfd = new SaveFileDialog + { + Filter = "New Horizons Acres (*.nha)|*.nha|All files (*.*)|*.*", + FileName = "acres.nha", + }; + + if (sfd.ShowDialog() != DialogResult.OK) + return false; + + File.WriteAllBytes(sfd.FileName, data); + return true; + } + + public static bool ImportMapAcresAll(byte[] data) + { + using var ofd = new OpenFileDialog + { + Filter = "New Horizons Acres (*.nha)|*.nha|All files (*.*)|*.*", + FileName = "acres.nha", + }; + + if (ofd.ShowDialog() != DialogResult.OK) + return false; + + var path = ofd.FileName; + var original = data; + var modified = File.ReadAllBytes(path); + if (original.Length != modified.Length) + { + WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, modified.Length, original.Length), path); + return false; + } + + modified.CopyTo(data, modified.Length); + return true; + } } } \ No newline at end of file