From 91731e1a42ffe21fe9af67a2893596640d190d3b Mon Sep 17 00:00:00 2001 From: AsY!um- <377468+AsYlum-@users.noreply.github.com> Date: Fri, 24 Apr 2026 17:02:36 +0200 Subject: [PATCH 1/6] Replace from folder for Items and Land tiles. #102 --- .../ReplaceFromFolderResultForm.Designer.cs | 86 +++++++++++++ .../Forms/ReplaceFromFolderResultForm.cs | 24 ++++ .../Forms/ReplaceFromFolderResultForm.resx | 120 ++++++++++++++++++ .../UserControls/ItemsControl.Designer.cs | 13 +- .../UserControls/ItemsControl.cs | 91 +++++++++++++ .../UserControls/LandTilesControl.Designer.cs | 13 +- .../UserControls/LandTilesControl.cs | 97 ++++++++++++++ 7 files changed, 440 insertions(+), 4 deletions(-) create mode 100644 UoFiddler.Controls/Forms/ReplaceFromFolderResultForm.Designer.cs create mode 100644 UoFiddler.Controls/Forms/ReplaceFromFolderResultForm.cs create mode 100644 UoFiddler.Controls/Forms/ReplaceFromFolderResultForm.resx diff --git a/UoFiddler.Controls/Forms/ReplaceFromFolderResultForm.Designer.cs b/UoFiddler.Controls/Forms/ReplaceFromFolderResultForm.Designer.cs new file mode 100644 index 00000000..42b91c5e --- /dev/null +++ b/UoFiddler.Controls/Forms/ReplaceFromFolderResultForm.Designer.cs @@ -0,0 +1,86 @@ +namespace UoFiddler.Controls.Forms +{ + partial class ReplaceFromFolderResultForm + { + private System.ComponentModel.IContainer components = null; + + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + private void InitializeComponent() + { + reportTextBox = new System.Windows.Forms.TextBox(); + buttonPanel = new System.Windows.Forms.Panel(); + closeButton = new System.Windows.Forms.Button(); + buttonPanel.SuspendLayout(); + SuspendLayout(); + // + // reportTextBox + // + reportTextBox.BackColor = System.Drawing.SystemColors.Window; + reportTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + reportTextBox.Font = new System.Drawing.Font("Consolas", 9F); + reportTextBox.Location = new System.Drawing.Point(8, 8); + reportTextBox.Multiline = true; + reportTextBox.Name = "reportTextBox"; + reportTextBox.ReadOnly = true; + reportTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + reportTextBox.Size = new System.Drawing.Size(368, 210); + reportTextBox.TabIndex = 1; + // + // buttonPanel + // + buttonPanel.Controls.Add(closeButton); + buttonPanel.Dock = System.Windows.Forms.DockStyle.Bottom; + buttonPanel.Location = new System.Drawing.Point(8, 218); + buttonPanel.Name = "buttonPanel"; + buttonPanel.Padding = new System.Windows.Forms.Padding(0, 4, 8, 4); + buttonPanel.Size = new System.Drawing.Size(368, 43); + buttonPanel.TabIndex = 0; + // + // closeButton + // + closeButton.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + closeButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + closeButton.Location = new System.Drawing.Point(267, 7); + closeButton.Name = "closeButton"; + closeButton.Size = new System.Drawing.Size(90, 28); + closeButton.TabIndex = 2; + closeButton.Text = "Close"; + closeButton.UseVisualStyleBackColor = true; + // + // ReplaceFromFolderResultForm + // + AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + ClientSize = new System.Drawing.Size(384, 261); + Controls.Add(reportTextBox); + Controls.Add(buttonPanel); + MaximizeBox = false; + MinimizeBox = false; + MinimumSize = new System.Drawing.Size(400, 300); + Name = "ReplaceFromFolderResultForm"; + Padding = new System.Windows.Forms.Padding(8, 8, 8, 0); + ShowInTaskbar = false; + StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + Text = "Replace from Folder"; + buttonPanel.ResumeLayout(false); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private System.Windows.Forms.TextBox reportTextBox; + private System.Windows.Forms.Panel buttonPanel; + private System.Windows.Forms.Button closeButton; + } +} diff --git a/UoFiddler.Controls/Forms/ReplaceFromFolderResultForm.cs b/UoFiddler.Controls/Forms/ReplaceFromFolderResultForm.cs new file mode 100644 index 00000000..efbfda68 --- /dev/null +++ b/UoFiddler.Controls/Forms/ReplaceFromFolderResultForm.cs @@ -0,0 +1,24 @@ +/*************************************************************************** + * + * $Author: Turley + * + * "THE BEER-WARE LICENSE" + * As long as you retain this notice you can do whatever you want with + * this stuff. If we meet some day, and you think this stuff is worth it, + * you can buy me a beer in return. + * + ***************************************************************************/ + +using System.Windows.Forms; + +namespace UoFiddler.Controls.Forms +{ + public sealed partial class ReplaceFromFolderResultForm : Form + { + public ReplaceFromFolderResultForm(string report) + { + InitializeComponent(); + reportTextBox.Text = report; + } + } +} diff --git a/UoFiddler.Controls/Forms/ReplaceFromFolderResultForm.resx b/UoFiddler.Controls/Forms/ReplaceFromFolderResultForm.resx new file mode 100644 index 00000000..4edf53f8 --- /dev/null +++ b/UoFiddler.Controls/Forms/ReplaceFromFolderResultForm.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/UoFiddler.Controls/UserControls/ItemsControl.Designer.cs b/UoFiddler.Controls/UserControls/ItemsControl.Designer.cs index 04605df6..4773dcfc 100644 --- a/UoFiddler.Controls/UserControls/ItemsControl.Designer.cs +++ b/UoFiddler.Controls/UserControls/ItemsControl.Designer.cs @@ -69,6 +69,7 @@ private void InitializeComponent() replaceToolStripMenuItem = new ToolStripMenuItem(); replaceStartingFromToolStripMenuItem = new ToolStripMenuItem(); ReplaceStartingFromText = new ToolStripTextBox(); + replaceFromFolderToolStripMenuItem = new ToolStripMenuItem(); insertAtToolStripMenuItem = new ToolStripMenuItem(); InsertText = new ToolStripTextBox(); removeToolStripMenuItem = new ToolStripMenuItem(); @@ -217,7 +218,7 @@ private void InitializeComponent() // // TileViewContextMenuStrip // - TileViewContextMenuStrip.Items.AddRange(new ToolStripItem[] { showFreeSlotsToolStripMenuItem, findNextFreeSlotToolStripMenuItem, ChangeBackgroundColorToolStripMenuItem, toolStripSeparator3, extractToolStripMenuItem, toolStripSeparator7, selectInTileDataTabToolStripMenuItem, selectInRadarColorTabToolStripMenuItem, selectInGumpsTabMaleToolStripMenuItem, selectInGumpsTabFemaleToolStripMenuItem, toolStripSeparator2, replaceToolStripMenuItem, replaceStartingFromToolStripMenuItem, insertAtToolStripMenuItem, removeToolStripMenuItem, toolStripSeparator1, saveToolStripMenuItem }); + TileViewContextMenuStrip.Items.AddRange(new ToolStripItem[] { showFreeSlotsToolStripMenuItem, findNextFreeSlotToolStripMenuItem, ChangeBackgroundColorToolStripMenuItem, toolStripSeparator3, extractToolStripMenuItem, toolStripSeparator7, selectInTileDataTabToolStripMenuItem, selectInRadarColorTabToolStripMenuItem, selectInGumpsTabMaleToolStripMenuItem, selectInGumpsTabFemaleToolStripMenuItem, toolStripSeparator2, replaceToolStripMenuItem, replaceStartingFromToolStripMenuItem, replaceFromFolderToolStripMenuItem, insertAtToolStripMenuItem, removeToolStripMenuItem, toolStripSeparator1, saveToolStripMenuItem }); TileViewContextMenuStrip.Name = "contextMenuStrip1"; TileViewContextMenuStrip.Size = new System.Drawing.Size(213, 314); TileViewContextMenuStrip.Opening += TileViewContextMenuStrip_Opening; @@ -343,7 +344,14 @@ private void InitializeComponent() ReplaceStartingFromText.Name = "ReplaceStartingFromText"; ReplaceStartingFromText.Size = new System.Drawing.Size(100, 23); ReplaceStartingFromText.KeyDown += ReplaceStartingFromText_KeyDown; - // + // + // replaceFromFolderToolStripMenuItem + // + replaceFromFolderToolStripMenuItem.Name = "replaceFromFolderToolStripMenuItem"; + replaceFromFolderToolStripMenuItem.Size = new System.Drawing.Size(212, 22); + replaceFromFolderToolStripMenuItem.Text = "Replace from Folder..."; + replaceFromFolderToolStripMenuItem.Click += OnClickReplaceFromFolder; + // // insertAtToolStripMenuItem // insertAtToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { InsertText }); @@ -635,6 +643,7 @@ private void InitializeComponent() private ToolStripMenuItem selectInGumpsTabFemaleToolStripMenuItem; private ToolStripMenuItem replaceStartingFromToolStripMenuItem; private ToolStripTextBox ReplaceStartingFromText; + private ToolStripMenuItem replaceFromFolderToolStripMenuItem; private ToolStripLabel toolStripLabel1; private ToolStripTextBox searchByIdToolStripTextBox; private ToolStripLabel toolStripLabel2; diff --git a/UoFiddler.Controls/UserControls/ItemsControl.cs b/UoFiddler.Controls/UserControls/ItemsControl.cs index 4abd0840..eeb55c51 100644 --- a/UoFiddler.Controls/UserControls/ItemsControl.cs +++ b/UoFiddler.Controls/UserControls/ItemsControl.cs @@ -16,6 +16,7 @@ using System.Drawing.Imaging; using System.IO; using System.Text; +using System.Text.RegularExpressions; using System.Windows.Forms; using Ultima; using UoFiddler.Controls.Classes; @@ -37,6 +38,8 @@ public ItemsControl() DetailTextBox.AddBasicContextMenu(); } + private static readonly Regex _hexIndexRegex = new(@"0[xX][0-9a-fA-F]+", RegexOptions.Compiled); + private List _itemList = new List(); private bool _showFreeSlots; @@ -1187,6 +1190,94 @@ private static bool IsIndexValid(int index) return index >= 0 && index <= Art.GetMaxItemId(); } + private void OnClickReplaceFromFolder(object sender, EventArgs e) + { + using FolderBrowserDialog dialog = new FolderBrowserDialog(); + dialog.Description = "Select folder containing images to replace"; + + if (dialog.ShowDialog() != DialogResult.OK) + { + return; + } + + string[] allFiles = Directory.GetFiles(dialog.SelectedPath); + var replacedLines = new List(); + var skippedLines = new List(); + + foreach (string file in allFiles) + { + string ext = Path.GetExtension(file).ToLowerInvariant(); + if (ext != ".bmp" && ext != ".jpg" && ext != ".jpeg" && ext != ".png" && ext != ".tif" && ext != ".tiff") + { + continue; + } + + string name = Path.GetFileName(file); + Match match = _hexIndexRegex.Match(Path.GetFileNameWithoutExtension(file)); + if (!match.Success) + { + skippedLines.Add($" {name} (no hex ID in filename)"); + continue; + } + + int index; + try + { + index = Convert.ToInt32(match.Value, 16); + } + catch + { + skippedLines.Add($" {name} (invalid hex value)"); + continue; + } + + if (!IsIndexValid(index)) + { + skippedLines.Add($" {name} (index 0x{index:X} out of range)"); + continue; + } + + try + { + AddSingleItem(file, index); + replacedLines.Add($" 0x{index:X4} {name}"); + } + catch + { + skippedLines.Add($" {name} (failed to load image)"); + } + } + + ItemsTileView.VirtualListSize = _itemList.Count; + ItemsTileView.Invalidate(); + + var sb = new StringBuilder(); + sb.AppendLine($"Replaced: {replacedLines.Count} Skipped: {skippedLines.Count}"); + + if (replacedLines.Count > 0) + { + sb.AppendLine(); + sb.AppendLine($"Replaced ({replacedLines.Count}):"); + foreach (string line in replacedLines) + { + sb.AppendLine(line); + } + } + + if (skippedLines.Count > 0) + { + sb.AppendLine(); + sb.AppendLine($"Skipped ({skippedLines.Count}):"); + foreach (string line in skippedLines) + { + sb.AppendLine(line); + } + } + + using var resultForm = new ReplaceFromFolderResultForm(sb.ToString()); + resultForm.ShowDialog(this); + } + private void SearchByIdToolStripTextBox_KeyUp(object sender, KeyEventArgs e) { if (!Utils.ConvertStringToInt(searchByIdToolStripTextBox.Text, out int indexValue)) diff --git a/UoFiddler.Controls/UserControls/LandTilesControl.Designer.cs b/UoFiddler.Controls/UserControls/LandTilesControl.Designer.cs index 67a01c4c..00fb1d78 100644 --- a/UoFiddler.Controls/UserControls/LandTilesControl.Designer.cs +++ b/UoFiddler.Controls/UserControls/LandTilesControl.Designer.cs @@ -62,6 +62,7 @@ private void InitializeComponent() replaceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); replaceStartingFromToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); ReplaceStartingFromTb = new System.Windows.Forms.ToolStripTextBox(); + replaceFromFolderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); insertAtToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); InsertText = new System.Windows.Forms.ToolStripTextBox(); removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -97,7 +98,7 @@ private void InitializeComponent() // // LandTilesContextMenuStrip // - LandTilesContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { showFreeSlotsToolStripMenuItem, findNextFreeSlotToolStripMenuItem, changeBackgroundColorToolStripMenuItem, toolStripSeparator6, exportImageToolStripMenuItem, toolStripSeparator3, selectInTileDataTabToolStripMenuItem, selectInRadarColorTabToolStripMenuItem, selectInTexturesTabToolStripMenuItem, toolStripSeparator2, replaceToolStripMenuItem, replaceStartingFromToolStripMenuItem, insertAtToolStripMenuItem, removeToolStripMenuItem, toolStripSeparator1, saveToolStripMenuItem }); + LandTilesContextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { showFreeSlotsToolStripMenuItem, findNextFreeSlotToolStripMenuItem, changeBackgroundColorToolStripMenuItem, toolStripSeparator6, exportImageToolStripMenuItem, toolStripSeparator3, selectInTileDataTabToolStripMenuItem, selectInRadarColorTabToolStripMenuItem, selectInTexturesTabToolStripMenuItem, toolStripSeparator2, replaceToolStripMenuItem, replaceStartingFromToolStripMenuItem, replaceFromFolderToolStripMenuItem, insertAtToolStripMenuItem, removeToolStripMenuItem, toolStripSeparator1, saveToolStripMenuItem }); LandTilesContextMenuStrip.Name = "contextMenuStrip1"; LandTilesContextMenuStrip.Size = new System.Drawing.Size(201, 270); LandTilesContextMenuStrip.Opening += LandTilesContextMenuStrip_Opening; @@ -214,7 +215,14 @@ private void InitializeComponent() ReplaceStartingFromTb.Name = "ReplaceStartingFromTb"; ReplaceStartingFromTb.Size = new System.Drawing.Size(100, 23); ReplaceStartingFromTb.KeyDown += ReplaceStartingFromTb_KeyDown; - // + // + // replaceFromFolderToolStripMenuItem + // + replaceFromFolderToolStripMenuItem.Name = "replaceFromFolderToolStripMenuItem"; + replaceFromFolderToolStripMenuItem.Size = new System.Drawing.Size(200, 22); + replaceFromFolderToolStripMenuItem.Text = "Replace from Folder..."; + replaceFromFolderToolStripMenuItem.Click += OnClickReplaceFromFolder; + // // insertAtToolStripMenuItem // insertAtToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { InsertText }); @@ -476,6 +484,7 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; private System.Windows.Forms.ToolStripMenuItem replaceStartingFromToolStripMenuItem; private System.Windows.Forms.ToolStripTextBox ReplaceStartingFromTb; + private System.Windows.Forms.ToolStripMenuItem replaceFromFolderToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem showFreeSlotsToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator6; private System.Windows.Forms.StatusStrip StatusStrip; diff --git a/UoFiddler.Controls/UserControls/LandTilesControl.cs b/UoFiddler.Controls/UserControls/LandTilesControl.cs index 9616c60d..f3d51754 100644 --- a/UoFiddler.Controls/UserControls/LandTilesControl.cs +++ b/UoFiddler.Controls/UserControls/LandTilesControl.cs @@ -14,6 +14,8 @@ using System.Drawing; using System.Drawing.Imaging; using System.IO; +using System.Text; +using System.Text.RegularExpressions; using System.Windows.Forms; using Ultima; using UoFiddler.Controls.Classes; @@ -35,6 +37,8 @@ public LandTilesControl() public bool IsLoaded { get; private set; } + private static readonly Regex _hexIndexRegex = new(@"0[xX][0-9a-fA-F]+", RegexOptions.Compiled); + private const int _landTileMax = 0x4000; private static LandTilesControl _refMarker; @@ -801,6 +805,99 @@ private static bool IsIndexValid(int index) return index < 0x4000; } + private void OnClickReplaceFromFolder(object sender, EventArgs e) + { + using FolderBrowserDialog dialog = new FolderBrowserDialog(); + dialog.Description = "Select folder containing images to replace"; + + if (dialog.ShowDialog() != DialogResult.OK) + { + return; + } + + string[] allFiles = Directory.GetFiles(dialog.SelectedPath); + var replacedLines = new List(); + var skippedLines = new List(); + + foreach (string file in allFiles) + { + string ext = Path.GetExtension(file).ToLowerInvariant(); + if (ext != ".bmp" && ext != ".jpg" && ext != ".jpeg" && ext != ".png" && ext != ".tif" && ext != ".tiff") + { + continue; + } + + string name = Path.GetFileName(file); + Match match = _hexIndexRegex.Match(Path.GetFileNameWithoutExtension(file)); + if (!match.Success) + { + skippedLines.Add($" {name} (no hex ID in filename)"); + continue; + } + + int index; + try + { + index = Convert.ToInt32(match.Value, 16); + } + catch + { + skippedLines.Add($" {name} (invalid hex value)"); + continue; + } + + if (!IsIndexValid(index)) + { + skippedLines.Add($" {name} (index 0x{index:X} out of range)"); + continue; + } + + try + { + AddSingleLandTile(file, index); + replacedLines.Add($" 0x{index:X4} {name}"); + } + catch + { + skippedLines.Add($" {name} (failed to load image)"); + } + } + + LandTilesTileView.VirtualListSize = _tileList.Count; + LandTilesTileView.Invalidate(); + + if (replacedLines.Count > 0) + { + Options.ChangedUltimaClass["Art"] = true; + } + + var sb = new StringBuilder(); + sb.AppendLine($"Replaced: {replacedLines.Count} Skipped: {skippedLines.Count}"); + + if (replacedLines.Count > 0) + { + sb.AppendLine(); + sb.AppendLine($"Replaced ({replacedLines.Count}):"); + foreach (string line in replacedLines) + { + sb.AppendLine(line); + } + } + + if (skippedLines.Count > 0) + { + sb.AppendLine(); + sb.AppendLine($"Skipped ({skippedLines.Count}):"); + foreach (string line in skippedLines) + { + sb.AppendLine(line); + } + } + + using var resultForm = new ReplaceFromFolderResultForm(sb.ToString()); + resultForm.ShowDialog(this); + } + /// /// Adds a single land tile. /// From 9e42fc2ddc478f7a728de5f62c31b76ab682a9ec Mon Sep 17 00:00:00 2001 From: AsY!um- <377468+AsYlum-@users.noreply.github.com> Date: Fri, 24 Apr 2026 18:10:10 +0200 Subject: [PATCH 2/6] Map copy/replace uop support. #105 --- UoFiddler.Controls/Forms/MapReplaceForm.cs | 64 +++++++--------------- 1 file changed, 20 insertions(+), 44 deletions(-) diff --git a/UoFiddler.Controls/Forms/MapReplaceForm.cs b/UoFiddler.Controls/Forms/MapReplaceForm.cs index 98b62b84..abe2f51a 100644 --- a/UoFiddler.Controls/Forms/MapReplaceForm.cs +++ b/UoFiddler.Controls/Forms/MapReplaceForm.cs @@ -157,32 +157,27 @@ private void OnClickCopy(object sender, EventArgs e) if (checkBoxMap.Checked) { - string copyMap = Path.Combine(path, $"map{replaceMap.Id}.mul"); - if (!File.Exists(copyMap)) + string copyMapMul = Path.Combine(path, $"map{replaceMap.Id}.mul"); + string copyMapUop = Path.Combine(path, $"map{replaceMap.Id}LegacyMUL.uop"); + if (!File.Exists(copyMapMul) && !File.Exists(copyMapUop)) { MessageBox.Show("Map file not found!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } - FileStream mMapCopy = new FileStream(copyMap, FileMode.Open, FileAccess.Read, FileShare.Read); - BinaryReader mMapReaderCopy = new BinaryReader(mMapCopy); - string mapPath = Files.GetFilePath($"map{_workingMap.FileIndex}.mul"); - - BinaryReader mMapReader; - - if (mapPath != null) - { - FileStream mMap = new FileStream(mapPath, FileMode.Open, FileAccess.Read, FileShare.Read); - mMapReader = new BinaryReader(mMap); - } - else + string workingMapMul = Files.GetFilePath($"map{_workingMap.FileIndex}.mul"); + string workingMapUop = Files.GetFilePath($"map{_workingMap.FileIndex}LegacyMUL.uop"); + if (workingMapMul == null && workingMapUop == null) { MessageBox.Show("Map file not found!", "Map Replace", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); return; } + var copyTileMatrix = new TileMatrix(replaceMap.Id, replaceMap.Id, replaceMap.Width, replaceMap.Height, path); + var workTileMatrix = new TileMatrix(_workingMap.FileIndex, _workingMap.FileIndex, _workingMap.Width, _workingMap.Height, null); + string mul = Path.Combine(Options.OutputPath, $"map{_workingMap.FileIndex}.mul"); using (FileStream fsMul = new FileStream(mul, FileMode.Create, FileAccess.Write, FileShare.Write)) { @@ -192,35 +187,16 @@ private void OnClickCopy(object sender, EventArgs e) { for (int y = 0; y < blockY; ++y) { - if (tox <= x && x <= tox2 && toy <= y && y <= toy2) - { - mMapReaderCopy.BaseStream.Seek((((x - tox + x1) * blockYReplace) + (y - toy) + y1) * 196, SeekOrigin.Begin); - int header = mMapReaderCopy.ReadInt32(); - binMul.Write(header); - } - else - { - mMapReader.BaseStream.Seek(((x * blockY) + y) * 196, SeekOrigin.Begin); - int header = mMapReader.ReadInt32(); - binMul.Write(header); - } - for (int i = 0; i < 64; ++i) - { - ushort tileId; - sbyte z; - - if (tox <= x && x <= tox2 && toy <= y && y <= toy2) - { - tileId = mMapReaderCopy.ReadUInt16(); - z = mMapReaderCopy.ReadSByte(); - } - else - { - tileId = mMapReader.ReadUInt16(); - z = mMapReader.ReadSByte(); - } + bool inRegion = tox <= x && x <= tox2 && toy <= y && y <= toy2; + Tile[] tiles = inRegion + ? copyTileMatrix.GetLandBlock(x - tox + x1, y - toy + y1, false) + : workTileMatrix.GetLandBlock(x, y, false); - tileId = Art.GetLegalItemId(tileId); + binMul.Write(0); // 4-byte block header + foreach (Tile tile in tiles) + { + ushort tileId = Art.GetLegalItemId(tile.Id); + sbyte z = tile.Z; if (z < -128) { @@ -241,8 +217,8 @@ private void OnClickCopy(object sender, EventArgs e) } } - mMapReader.Close(); - mMapReaderCopy.Close(); + copyTileMatrix.CloseStreams(); + workTileMatrix.CloseStreams(); } if (checkBoxStatics.Checked) From edd5b839c4d5d9cbb683da593456daade5b09f66 Mon Sep 17 00:00:00 2001 From: AsY!um- <377468+AsYlum-@users.noreply.github.com> Date: Fri, 24 Apr 2026 18:33:32 +0200 Subject: [PATCH 3/6] More updates with file save dialog. --- UoFiddler.Controls/Forms/MapDiffInsertForm.cs | 2 +- .../UserControls/AnimationListControl.cs | 7 ++- .../UserControls/FontsControl.cs | 3 +- .../UserControls/GumpControl.cs | 3 +- .../UserControls/HuesControl.cs | 5 +- .../UserControls/ItemsControl.cs | 3 +- .../UserControls/LandTilesControl.cs | 3 +- .../UserControls/LightControl.cs | 12 ++--- UoFiddler.Controls/UserControls/MapControl.cs | 11 ++-- .../UserControls/MultiMapControl.cs | 3 +- .../UserControls/MultisControl.cs | 53 ++++++++----------- .../UserControls/RadarColorControl.cs | 4 +- .../UserControls/SoundsControl.cs | 3 +- .../UserControls/SpeechControl.cs | 3 +- .../UserControls/CompareGumpControl.cs | 9 ++-- .../UserControls/CompareItemControl.cs | 8 +-- .../UserControls/CompareLandControl.cs | 8 +-- .../UserControls/CompareTextureControl.cs | 7 ++- .../Forms/MassImportForm.cs | 6 +-- .../UserControls/MultiEditorControl.cs | 4 +- 20 files changed, 70 insertions(+), 87 deletions(-) diff --git a/UoFiddler.Controls/Forms/MapDiffInsertForm.cs b/UoFiddler.Controls/Forms/MapDiffInsertForm.cs index 6624aa4e..a48d98ed 100644 --- a/UoFiddler.Controls/Forms/MapDiffInsertForm.cs +++ b/UoFiddler.Controls/Forms/MapDiffInsertForm.cs @@ -487,7 +487,7 @@ private void OnClickCopy(object sender, EventArgs e) mStaticsReader.Close(); } - MessageBox.Show($"Files saved to {Options.OutputPath}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), Options.OutputPath, "Files saved successfully."); } } } diff --git a/UoFiddler.Controls/UserControls/AnimationListControl.cs b/UoFiddler.Controls/UserControls/AnimationListControl.cs index 0c51f304..04f77848 100644 --- a/UoFiddler.Controls/UserControls/AnimationListControl.cs +++ b/UoFiddler.Controls/UserControls/AnimationListControl.cs @@ -944,8 +944,7 @@ private void ExportAnimationFrames(ImageFormat imageFormat) } } - MessageBox.Show($"{what} saved to '{fileName}-X.{fileExtension}'", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), Options.OutputPath, $"Files with following format {fileName}-X.{fileExtension} saved successfully."); } private void OnClickExportFrameBmp(object sender, EventArgs e) @@ -1007,8 +1006,8 @@ private void ExportAnimatedGif(bool looping) var outputFile = Path.Combine(Options.OutputPath, $"{(_displayType == 1 ? "Equipment" : "Mob")} {_currentSelect}.gif"); MainPictureBox.Frames.ToGif(outputFile, looping: looping, delay: 150, showFrameBounds: MainPictureBox.ShowFrameBounds); - MessageBox.Show($"InGame Anim saved to {outputFile}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + + FileSavedDialog.Show(FindForm(), outputFile, "InGame Anim saved successfully."); } private void OnClickExtractAnimGifLooping(object sender, EventArgs e) diff --git a/UoFiddler.Controls/UserControls/FontsControl.cs b/UoFiddler.Controls/UserControls/FontsControl.cs index 7c3abaaa..28b34867 100644 --- a/UoFiddler.Controls/UserControls/FontsControl.cs +++ b/UoFiddler.Controls/UserControls/FontsControl.cs @@ -226,8 +226,7 @@ private void OnClickExport(object sender, EventArgs e) bmp.Save(fileName, ImageFormat.Tiff); } - MessageBox.Show($"Character saved to {fileName}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, - MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "Character saved successfully."); } private static int AsciiFontOffset => 32; diff --git a/UoFiddler.Controls/UserControls/GumpControl.cs b/UoFiddler.Controls/UserControls/GumpControl.cs index 22c1e4f5..04ffa04b 100644 --- a/UoFiddler.Controls/UserControls/GumpControl.cs +++ b/UoFiddler.Controls/UserControls/GumpControl.cs @@ -807,8 +807,7 @@ private void ExportAllGumps(ImageFormat imageFormat) Cursor.Current = Cursors.Default; - MessageBox.Show($"All Gumps saved to {dialog.SelectedPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), dialog.SelectedPath, "All Gumps saved successfully."); } } diff --git a/UoFiddler.Controls/UserControls/HuesControl.cs b/UoFiddler.Controls/UserControls/HuesControl.cs index b4648374..b4e02d4a 100644 --- a/UoFiddler.Controls/UserControls/HuesControl.cs +++ b/UoFiddler.Controls/UserControls/HuesControl.cs @@ -20,6 +20,7 @@ using UoFiddler.Controls.Classes; using UoFiddler.Controls.Forms; using UoFiddler.Controls.Helpers; +using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window; namespace UoFiddler.Controls.UserControls { @@ -272,7 +273,7 @@ private void OnExport(object sender, EventArgs e) string path = Options.OutputPath; string fileName = Path.Combine(path, $"Hue {_selected}.txt"); Hues.List[_selected].Export(fileName); - MessageBox.Show($"Hue saved to {fileName}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "Hue saved successfully."); } private void OnImport(object sender, EventArgs e) @@ -396,7 +397,7 @@ private void ExportAllHueNamesListToolStripMenuItem_Click(object sender, EventAr Hues.ExportHueList(fileName); - MessageBox.Show($"Hue names list saved to {fileName}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "Hue names list saved successfully."); } private void IndexOffsetButton_CheckedChanged(object sender, EventArgs e) diff --git a/UoFiddler.Controls/UserControls/ItemsControl.cs b/UoFiddler.Controls/UserControls/ItemsControl.cs index eeb55c51..4a345a0d 100644 --- a/UoFiddler.Controls/UserControls/ItemsControl.cs +++ b/UoFiddler.Controls/UserControls/ItemsControl.cs @@ -836,8 +836,7 @@ private void ExportAllItemImages(ImageFormat imageFormat) Cursor.Current = Cursors.Default; - MessageBox.Show($"All items saved to {dialog.SelectedPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), dialog.SelectedPath, "All items saved successfully."); } } diff --git a/UoFiddler.Controls/UserControls/LandTilesControl.cs b/UoFiddler.Controls/UserControls/LandTilesControl.cs index f3d51754..a170fdc9 100644 --- a/UoFiddler.Controls/UserControls/LandTilesControl.cs +++ b/UoFiddler.Controls/UserControls/LandTilesControl.cs @@ -665,8 +665,7 @@ private void ExportAllLandTiles(ImageFormat imageFormat) Cursor.Current = Cursors.Default; - MessageBox.Show($"All land tiles saved to {dialog.SelectedPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), dialog.SelectedPath, "All land tiles saved successfully."); } } diff --git a/UoFiddler.Controls/UserControls/LightControl.cs b/UoFiddler.Controls/UserControls/LightControl.cs index 9ee277ce..5a975066 100644 --- a/UoFiddler.Controls/UserControls/LightControl.cs +++ b/UoFiddler.Controls/UserControls/LightControl.cs @@ -18,6 +18,7 @@ using UoFiddler.Controls.Classes; using UoFiddler.Controls.Forms; using UoFiddler.Controls.Helpers; +using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window; namespace UoFiddler.Controls.UserControls { @@ -348,9 +349,8 @@ private void OnClickExportBmp(object sender, EventArgs e) string path = Options.OutputPath; int i = (int)treeViewLights.SelectedNode.Tag; string fileName = Path.Combine(path, $"Light {i}.bmp"); - Ultima.Light.GetLight(i).Save(fileName, ImageFormat.Bmp); - MessageBox.Show($"Light saved to {fileName}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, - MessageBoxDefaultButton.Button1); + Light.GetLight(i).Save(fileName, ImageFormat.Bmp); + FileSavedDialog.Show(FindForm(), fileName, "Light saved successfully."); } private void OnClickExportTiff(object sender, EventArgs e) @@ -364,8 +364,7 @@ private void OnClickExportTiff(object sender, EventArgs e) int i = (int)treeViewLights.SelectedNode.Tag; string fileName = Path.Combine(path, $"Light {i}.tiff"); Ultima.Light.GetLight(i).Save(fileName, ImageFormat.Tiff); - MessageBox.Show($"Light saved to {fileName}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, - MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "Light saved successfully."); } private void OnClickExportJpg(object sender, EventArgs e) @@ -379,8 +378,7 @@ private void OnClickExportJpg(object sender, EventArgs e) int i = (int)treeViewLights.SelectedNode.Tag; string fileName = Path.Combine(path, $"Light {i}.jpg"); Ultima.Light.GetLight(i).Save(fileName, ImageFormat.Jpeg); - MessageBox.Show($"Light saved to {fileName}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, - MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "Light saved successfully."); } private void IgPreviewClicked(object sender, EventArgs e) diff --git a/UoFiddler.Controls/UserControls/MapControl.cs b/UoFiddler.Controls/UserControls/MapControl.cs index 88ad56c2..c7709611 100644 --- a/UoFiddler.Controls/UserControls/MapControl.cs +++ b/UoFiddler.Controls/UserControls/MapControl.cs @@ -854,8 +854,7 @@ private void ExtractMapImage(ImageFormat imageFormat) Cursor.Current = Cursors.Default; } - MessageBox.Show($"Map saved to {fileName}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, - MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "Map saved successfully."); } private MapMarkerForm _mapMarkerForm; @@ -1108,7 +1107,8 @@ private void OnClickDefragStatics(object sender, EventArgs e) Map.DefragStatics(Options.OutputPath, CurrentMap, CurrentMap.Width, CurrentMap.Height, false); Cursor.Current = Cursors.Default; - MessageBox.Show($"Statics saved to {Options.OutputPath}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + + FileSavedDialog.Show(FindForm(), Options.OutputPath, "Statics saved successfully."); } private void OnClickDefragRemoveStatics(object sender, EventArgs e) @@ -1117,7 +1117,7 @@ private void OnClickDefragRemoveStatics(object sender, EventArgs e) Map.DefragStatics(Options.OutputPath, CurrentMap, CurrentMap.Width, CurrentMap.Height, true); Cursor.Current = Cursors.Default; - MessageBox.Show($"Statics saved to {Options.OutputPath}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), Options.OutputPath, "Statics saved successfully."); } private void OnResizeMap(object sender, EventArgs e) @@ -1158,8 +1158,7 @@ private void OnClickReportInvalidMapIDs(object sender, EventArgs e) Cursor.Current = Cursors.WaitCursor; CurrentMap.ReportInvalidMapIDs(Options.OutputPath); Cursor.Current = Cursors.Default; - MessageBox.Show($"Report saved to {Options.OutputPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), Options.OutputPath, "Report saved successfully."); } private MapReplaceForm _showForm; diff --git a/UoFiddler.Controls/UserControls/MultiMapControl.cs b/UoFiddler.Controls/UserControls/MultiMapControl.cs index bb3141d4..02a377ec 100644 --- a/UoFiddler.Controls/UserControls/MultiMapControl.cs +++ b/UoFiddler.Controls/UserControls/MultiMapControl.cs @@ -222,8 +222,7 @@ private void ExportMultiMapImage(ImageFormat imageFormat) pictureBox.Image.Save(fileName, imageFormat); - MessageBox.Show($"{CheckedToString()} saved to {fileName}", "Export", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, $"{CheckedToString()} saved successfully."); } private string CheckedToString() diff --git a/UoFiddler.Controls/UserControls/MultisControl.cs b/UoFiddler.Controls/UserControls/MultisControl.cs index 2d4f81fc..ac3394ab 100644 --- a/UoFiddler.Controls/UserControls/MultisControl.cs +++ b/UoFiddler.Controls/UserControls/MultisControl.cs @@ -20,6 +20,7 @@ using UoFiddler.Controls.Classes; using UoFiddler.Controls.Forms; using UoFiddler.Controls.Helpers; +using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window; namespace UoFiddler.Controls.UserControls { @@ -673,8 +674,7 @@ private void ExportAllMultis(ImageFormat imageFormat, Color backgroundColor) } } - MessageBox.Show($"All Multis saved to {dialog.SelectedPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), dialog.SelectedPath, "All Multis saved successfully."); } } @@ -706,8 +706,8 @@ private void OnClick_SaveAllText(object sender, EventArgs e) string fileName = Path.Combine(dialog.SelectedPath, $"Multi 0x{index:X4}.txt"); multi.ExportToTextFile(fileName); } - MessageBox.Show($"All Multis saved to {dialog.SelectedPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + + FileSavedDialog.Show(FindForm(), dialog.SelectedPath, "All Multis saved successfully."); } } @@ -739,8 +739,8 @@ private void OnClick_SaveAllUOA(object sender, EventArgs e) string fileName = Path.Combine(dialog.SelectedPath, $"Multi 0x{index:X4}.uoa"); multi.ExportToUOAFile(fileName); } - MessageBox.Show($"All Multis saved to {dialog.SelectedPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + + FileSavedDialog.Show(FindForm(), dialog.SelectedPath, "All Multis saved successfully."); } } @@ -772,8 +772,8 @@ private void OnClick_SaveAllWSC(object sender, EventArgs e) string fileName = Path.Combine(dialog.SelectedPath, $"Multi 0x{index:X4}.wsc"); multi.ExportToWscFile(fileName); } - MessageBox.Show($"All Multis saved to {dialog.SelectedPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + + FileSavedDialog.Show(FindForm(), dialog.SelectedPath, "All Multis saved successfully."); } } @@ -805,8 +805,8 @@ private void OnClick_SaveAllCSV(object sender, EventArgs e) string fileName = Path.Combine(dialog.SelectedPath, $"{index:D4}.csv"); multi.ExportToCsvFile(fileName); } - MessageBox.Show($"All Multis saved to {dialog.SelectedPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + + FileSavedDialog.Show(FindForm(), dialog.SelectedPath, "All Multis saved successfully."); } } @@ -838,8 +838,8 @@ private void OnClick_SaveAllUox3(object sender, EventArgs e) string fileName = Path.Combine(dialog.SelectedPath, $"Multi 0x{index:X4}.uox3"); multi.ExportToUox3File(fileName); } - MessageBox.Show($"All Multis saved to {dialog.SelectedPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + + FileSavedDialog.Show(FindForm(), dialog.SelectedPath, "All Multis saved successfully."); } } @@ -861,8 +861,7 @@ private void OnExportCsvFile(object sender, EventArgs e) string path = Options.OutputPath; string fileName = Path.Combine(path, $"{id:D4}.csv"); multi.ExportToCsvFile(fileName); - MessageBox.Show($"Multi saved to {fileName}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, - MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "Multi saved successfully."); } private void OnExportUox3File(object sender, EventArgs e) @@ -883,8 +882,7 @@ private void OnExportUox3File(object sender, EventArgs e) string path = Options.OutputPath; string fileName = Path.Combine(path, $"Multi 0x{id:X4}.uox3"); multi.ExportToUox3File(fileName); - MessageBox.Show($"Multi saved to {fileName}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, - MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "Multi saved successfully."); } private void ChangeBackgroundColorToolStripMenuItem_Click(object sender, EventArgs e) @@ -1365,8 +1363,7 @@ private void ExportAllUopMultis(ImageFormat imageFormat, Color backgroundColor) } } - MessageBox.Show($"All UOP Multis saved to {dialog.SelectedPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), dialog.SelectedPath, "All UOP Multis saved successfully."); } private void OnUopClick_SaveAllText(object sender, EventArgs e) @@ -1392,8 +1389,7 @@ private void OnUopClick_SaveAllText(object sender, EventArgs e) multi.ExportToTextFile(Path.Combine(dialog.SelectedPath, $"UopMulti 0x{index:X4}.txt")); } - MessageBox.Show($"All UOP Multis saved to {dialog.SelectedPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), dialog.SelectedPath, "All UOP Multis saved successfully."); } private void OnUopClick_SaveAllUOA(object sender, EventArgs e) @@ -1419,8 +1415,7 @@ private void OnUopClick_SaveAllUOA(object sender, EventArgs e) multi.ExportToUOAFile(Path.Combine(dialog.SelectedPath, $"UopMulti 0x{index:X4}.uoa")); } - MessageBox.Show($"All UOP Multis saved to {dialog.SelectedPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), dialog.SelectedPath, "All UOP Multis saved successfully."); } private void OnUopClick_SaveAllWSC(object sender, EventArgs e) @@ -1446,8 +1441,7 @@ private void OnUopClick_SaveAllWSC(object sender, EventArgs e) multi.ExportToWscFile(Path.Combine(dialog.SelectedPath, $"UopMulti 0x{index:X4}.wsc")); } - MessageBox.Show($"All UOP Multis saved to {dialog.SelectedPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), dialog.SelectedPath, "All UOP Multis saved successfully."); } private void OnUopClick_SaveAllCSV(object sender, EventArgs e) @@ -1473,8 +1467,7 @@ private void OnUopClick_SaveAllCSV(object sender, EventArgs e) multi.ExportToCsvFile(Path.Combine(dialog.SelectedPath, $"{index:D4}_uop.csv")); } - MessageBox.Show($"All UOP Multis saved to {dialog.SelectedPath}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), dialog.SelectedPath, "All UOP Multis saved successfully."); } private void OnClick_SaveAllToXML(object sender, EventArgs e) @@ -1545,20 +1538,20 @@ private void OnClick_SaveAllToXML(object sender, EventArgs e) groupWriter.WriteEndDocument(); } - MessageBox.Show($"All Multis saved to {fileName}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "All Multis saved successfully."); } private sealed class MouseWheelFilter : IMessageFilter { - private const int WmMouseWheel = 0x020A; + private const int _wmMouseWheel = 0x020A; + private readonly MultisControl _owner; public MouseWheelFilter(MultisControl owner) => _owner = owner; public bool PreFilterMessage(ref Message m) { - if (m.Msg != WmMouseWheel) + if (m.Msg != _wmMouseWheel) { return false; } diff --git a/UoFiddler.Controls/UserControls/RadarColorControl.cs b/UoFiddler.Controls/UserControls/RadarColorControl.cs index dc33bbdd..6ce5b68d 100644 --- a/UoFiddler.Controls/UserControls/RadarColorControl.cs +++ b/UoFiddler.Controls/UserControls/RadarColorControl.cs @@ -831,8 +831,8 @@ private void OnClickExport(object sender, EventArgs e) string path = Options.OutputPath; string fileName = Path.Combine(path, "RadarColor.csv"); RadarCol.ExportToCSV(fileName); - MessageBox.Show($"RadarColor saved to {fileName}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + + FileSavedDialog.Show(FindForm(), fileName, "RadarColor saved successfully."); } private void OnClickMeanColorAll(object sender, EventArgs e) diff --git a/UoFiddler.Controls/UserControls/SoundsControl.cs b/UoFiddler.Controls/UserControls/SoundsControl.cs index 81dfafd5..90b1da31 100644 --- a/UoFiddler.Controls/UserControls/SoundsControl.cs +++ b/UoFiddler.Controls/UserControls/SoundsControl.cs @@ -474,8 +474,7 @@ private void OnClickExportSoundListCsv(object sender, EventArgs e) Sounds.SaveSoundListToCsv(fileName, _soundIdOffset); - MessageBox.Show($"SoundList saved to {fileName}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, - MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "SoundList saved successfully."); } public bool SearchId(int id) diff --git a/UoFiddler.Controls/UserControls/SpeechControl.cs b/UoFiddler.Controls/UserControls/SpeechControl.cs index 07a2c58f..f25b67bf 100644 --- a/UoFiddler.Controls/UserControls/SpeechControl.cs +++ b/UoFiddler.Controls/UserControls/SpeechControl.cs @@ -352,8 +352,7 @@ private void OnClickExport(object sender, EventArgs e) SpeechList.ExportToCsv(fileName); - MessageBox.Show($"Speech saved to {fileName}", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, - MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "Speech saved successfully."); } private void OnClickImport(object sender, EventArgs e) diff --git a/UoFiddler.Plugin.Compare/UserControls/CompareGumpControl.cs b/UoFiddler.Plugin.Compare/UserControls/CompareGumpControl.cs index ec66eeac..7708e66b 100644 --- a/UoFiddler.Plugin.Compare/UserControls/CompareGumpControl.cs +++ b/UoFiddler.Plugin.Compare/UserControls/CompareGumpControl.cs @@ -18,6 +18,7 @@ using System.Windows.Forms; using Ultima; using UoFiddler.Controls.Classes; +using UoFiddler.Controls.Forms; using UoFiddler.Controls.UserControls.TileView; using UoFiddler.Plugin.Compare.Classes; @@ -326,8 +327,8 @@ private void Export_Bmp(object sender, EventArgs e) string path = Options.OutputPath; string fileName = Path.Combine(path, $"Gump(Sec) 0x{i:X}.bmp"); SecondGump.GetGump(i).Save(fileName, ImageFormat.Bmp); - MessageBox.Show($"Gump saved to {fileName}", "Saved", - MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + + FileSavedDialog.Show(FindForm(), fileName, "Gump saved successfully."); } private void Export_Tiff(object sender, EventArgs e) @@ -347,8 +348,8 @@ private void Export_Tiff(object sender, EventArgs e) string path = Options.OutputPath; string fileName = Path.Combine(path, $"Gump(Sec) 0x{i:X}.tiff"); SecondGump.GetGump(i).Save(fileName, ImageFormat.Tiff); - MessageBox.Show($"Gump saved to {fileName}", "Saved", - MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + + FileSavedDialog.Show(FindForm(), fileName, "Gump saved successfully."); } private void OnClickCopy(object sender, EventArgs e) diff --git a/UoFiddler.Plugin.Compare/UserControls/CompareItemControl.cs b/UoFiddler.Plugin.Compare/UserControls/CompareItemControl.cs index 2a002612..45bdc16f 100644 --- a/UoFiddler.Plugin.Compare/UserControls/CompareItemControl.cs +++ b/UoFiddler.Plugin.Compare/UserControls/CompareItemControl.cs @@ -18,6 +18,7 @@ using System.Windows.Forms; using Ultima; using UoFiddler.Controls.Classes; +using UoFiddler.Controls.Forms; using UoFiddler.Controls.UserControls.TileView; using UoFiddler.Plugin.Compare.Classes; @@ -298,8 +299,8 @@ private void ExportAsBmp(object sender, EventArgs e) string fileName = Path.Combine(Options.OutputPath, $"Item(Sec) 0x{i:X}.bmp"); SecondArt.GetStatic(i).Save(fileName, ImageFormat.Bmp); - MessageBox.Show($"Item saved to {fileName}", "Saved", - MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + + FileSavedDialog.Show(FindForm(), fileName, "Item saved successfully."); } private void ExportAsTiff(object sender, EventArgs e) @@ -318,8 +319,7 @@ private void ExportAsTiff(object sender, EventArgs e) string fileName = Path.Combine(Options.OutputPath, $"Item(Sec) 0x{i:X}.tiff"); SecondArt.GetStatic(i).Save(fileName, ImageFormat.Tiff); - MessageBox.Show($"Item saved to {fileName}", "Saved", - MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "Item saved successfully."); } private void OnClickCopy(object sender, EventArgs e) diff --git a/UoFiddler.Plugin.Compare/UserControls/CompareLandControl.cs b/UoFiddler.Plugin.Compare/UserControls/CompareLandControl.cs index 961172d1..f3cd8c73 100644 --- a/UoFiddler.Plugin.Compare/UserControls/CompareLandControl.cs +++ b/UoFiddler.Plugin.Compare/UserControls/CompareLandControl.cs @@ -18,6 +18,7 @@ using System.Windows.Forms; using Ultima; using UoFiddler.Controls.Classes; +using UoFiddler.Controls.Forms; using UoFiddler.Controls.UserControls.TileView; using UoFiddler.Plugin.Compare.Classes; @@ -263,8 +264,8 @@ private void ExportAsBmp(object sender, EventArgs e) string fileName = Path.Combine(Options.OutputPath, $"Landtile(Sec) 0x{i:X}.bmp"); SecondArt.GetLand(i).Save(fileName, ImageFormat.Bmp); - MessageBox.Show($"Landtile saved to {fileName}", "Saved", - MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + + FileSavedDialog.Show(FindForm(), fileName, "Landtile saved successfully."); } private void ExportAsTiff(object sender, EventArgs e) @@ -283,8 +284,7 @@ private void ExportAsTiff(object sender, EventArgs e) string fileName = Path.Combine(Options.OutputPath, $"Landtile(Sec) 0x{i:X}.tiff"); SecondArt.GetLand(i).Save(fileName, ImageFormat.Tiff); - MessageBox.Show($"Landtile saved to {fileName}", "Saved", - MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "Landtile saved successfully."); } private void BrowseOnClick(object sender, EventArgs e) diff --git a/UoFiddler.Plugin.Compare/UserControls/CompareTextureControl.cs b/UoFiddler.Plugin.Compare/UserControls/CompareTextureControl.cs index fcf70b5b..922493fb 100644 --- a/UoFiddler.Plugin.Compare/UserControls/CompareTextureControl.cs +++ b/UoFiddler.Plugin.Compare/UserControls/CompareTextureControl.cs @@ -18,6 +18,7 @@ using System.Windows.Forms; using Ultima; using UoFiddler.Controls.Classes; +using UoFiddler.Controls.Forms; using UoFiddler.Controls.UserControls.TileView; using UoFiddler.Plugin.Compare.Classes; @@ -252,8 +253,7 @@ private void ExportAsBmp(object sender, EventArgs e) string fileName = Path.Combine(Options.OutputPath, $"Texture(Sec) 0x{i:X}.bmp"); SecondTexture.GetTexture(i).Save(fileName, ImageFormat.Bmp); - MessageBox.Show($"Texture saved to {fileName}", "Saved", - MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "Texture saved successfully."); } private void ExportAsTiff(object sender, EventArgs e) @@ -272,8 +272,7 @@ private void ExportAsTiff(object sender, EventArgs e) string fileName = Path.Combine(Options.OutputPath, $"Texture(Sec) 0x{i:X}.tiff"); SecondTexture.GetTexture(i).Save(fileName, ImageFormat.Tiff); - MessageBox.Show($"Texture saved to {fileName}", "Saved", - MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "Texture saved successfully."); } private void BrowseOnClick(object sender, EventArgs e) diff --git a/UoFiddler.Plugin.MassImport/Forms/MassImportForm.cs b/UoFiddler.Plugin.MassImport/Forms/MassImportForm.cs index 1e573761..16f7dfb2 100644 --- a/UoFiddler.Plugin.MassImport/Forms/MassImportForm.cs +++ b/UoFiddler.Plugin.MassImport/Forms/MassImportForm.cs @@ -16,6 +16,7 @@ using System.Windows.Forms; using System.Xml; using UoFiddler.Controls.Classes; +using UoFiddler.Controls.Forms; using UoFiddler.Plugin.MassImport.Imports; namespace UoFiddler.Plugin.MassImport.Forms @@ -121,8 +122,8 @@ private void DefaultXMLOnClick(object sender, EventArgs e) dom.AppendChild(sr); dom.Save(fileName); - MessageBox.Show($"Default xml saved to {fileName}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + + FileSavedDialog.Show(FindForm(), fileName, "Default xml saved successfully."); } private readonly List _importList; @@ -254,7 +255,6 @@ private void LoadXMLOnClick(object sender, EventArgs e) { button3.Enabled = true; } - } private void StartOnClick(object sender, EventArgs e) diff --git a/UoFiddler.Plugin.MultiEditor/UserControls/MultiEditorControl.cs b/UoFiddler.Plugin.MultiEditor/UserControls/MultiEditorControl.cs index d9b17111..0c37556a 100644 --- a/UoFiddler.Plugin.MultiEditor/UserControls/MultiEditorControl.cs +++ b/UoFiddler.Plugin.MultiEditor/UserControls/MultiEditorControl.cs @@ -18,6 +18,7 @@ using System.Xml; using Ultima; using UoFiddler.Controls.Classes; +using UoFiddler.Controls.Forms; using UoFiddler.Plugin.MultiEditor.Classes; using UoFiddler.Plugin.MultiEditor.Forms; @@ -265,8 +266,7 @@ private void DoExport(Multis.ImportType type) break; } - MessageBox.Show($"Multi design saved to {fileName}", "Saved", MessageBoxButtons.OK, - MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); + FileSavedDialog.Show(FindForm(), fileName, "Multi design saved successfully."); } private void BTN_Export_TXT_OnClick(object sender, EventArgs e) From e4392277b216b9e033e099cf95507f716c3f0616 Mon Sep 17 00:00:00 2001 From: AsY!um- <377468+AsYlum-@users.noreply.github.com> Date: Fri, 24 Apr 2026 18:55:30 +0200 Subject: [PATCH 4/6] Remeber selected file type for `Add frame` in AnimationEditForm. #82 --- UoFiddler.Controls/Forms/AnimationEditForm.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/UoFiddler.Controls/Forms/AnimationEditForm.cs b/UoFiddler.Controls/Forms/AnimationEditForm.cs index f2fc4994..22b2e650 100644 --- a/UoFiddler.Controls/Forms/AnimationEditForm.cs +++ b/UoFiddler.Controls/Forms/AnimationEditForm.cs @@ -34,6 +34,7 @@ public partial class AnimationEditForm : Form private bool _showOnlyValid; private static bool _drawEmpty; private static bool _drawFull; + private static int _lastAddFilterIndex = 1; private static readonly Color _whiteConvert = Color.FromArgb(255, 255, 255, 255); private static readonly Pen _blackUnDrawTransparent = new Pen(Color.FromArgb(0, 0, 0, 0), 1); @@ -846,9 +847,11 @@ private void OnClickAdd(object sender, EventArgs e) dialog.Title = "Choose image file to add"; dialog.CheckFileExists = true; dialog.Filter = "Gif files (*.gif;)|*.gif; |Bitmap files (*.bmp;)|*.bmp; |Tiff files (*.tif;*.tiff)|*.tif;*.tiff; |Png files (*.png;)|*.png; |Jpeg files (*.jpeg;*.jpg;)|*.jpeg;*.jpg;"; + dialog.FilterIndex = _lastAddFilterIndex; if (dialog.ShowDialog() == DialogResult.OK) { + _lastAddFilterIndex = dialog.FilterIndex; FramesListView.BeginUpdate(); try { From 3e6159655902b6ab7f6de5ec7638990f489421f2 Mon Sep 17 00:00:00 2001 From: AsY!um- <377468+AsYlum-@users.noreply.github.com> Date: Fri, 24 Apr 2026 22:46:45 +0200 Subject: [PATCH 5/6] UopPacker improvements - MultiCollection.uop save and UI updates. --- .../Classes/LegacyMulFileConverter.cs | 126 +++++++- .../UserControls/UopPackerControl.Designer.cs | 290 ++++++++++-------- .../UserControls/UopPackerControl.cs | 275 +++++++++++++---- 3 files changed, 501 insertions(+), 190 deletions(-) diff --git a/UoFiddler.Plugin.UopPacker/Classes/LegacyMulFileConverter.cs b/UoFiddler.Plugin.UopPacker/Classes/LegacyMulFileConverter.cs index 91e6aad8..21e437e2 100644 --- a/UoFiddler.Plugin.UopPacker/Classes/LegacyMulFileConverter.cs +++ b/UoFiddler.Plugin.UopPacker/Classes/LegacyMulFileConverter.cs @@ -47,10 +47,16 @@ private static BinaryWriter OpenOutput(string path) : new BinaryWriter(new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None)); } + // Identifier for "build/multicollection/housing.bin" inside MultiCollection.uop. + private const ulong _housingBinIdentifier = 0x126D1E99DDEDEE0A; + + // Sentinel Id used to mark a synthetic entry that should be written from housing.bin. + private const int _housingBinSentinelId = -1; + // // MUL -> UOP // - public static void ToUop(string inFile, string inFileIdx, string outFile, FileType type, int typeIndex, CompressionFlag compressionFlag = CompressionFlag.None) + public static void ToUop(string inFile, string inFileIdx, string outFile, FileType type, int typeIndex, CompressionFlag compressionFlag = CompressionFlag.None, string housingBinFile = "") { // Same for all UOP files const long firstTable = 0x200; @@ -121,6 +127,17 @@ public static void ToUop(string inFile, string inFileIdx, string outFile, FileTy } } + if (type == FileType.MultiCollection && !string.IsNullOrWhiteSpace(housingBinFile) && File.Exists(housingBinFile)) + { + idxEntries.Add(new IdxEntry + { + Id = _housingBinSentinelId, + Offset = 0, + Size = 0, + Extra = 0 + }); + } + // File header writer.Write(0x50594D); // MYP writer.Write(type == FileType.GumpartLegacyMul ? 4 : 5); // version @@ -163,8 +180,17 @@ public static void ToUop(string inFile, string inFileIdx, string outFile, FileTy for (int j = idxStart; j < idxEnd; ++j, ++tableIdx) { - reader.BaseStream.Seek(idxEntries[j].Offset, SeekOrigin.Begin); - byte[] data = reader.ReadBytes(idxEntries[j].Size); + byte[] data; + + if (type == FileType.MultiCollection && idxEntries[j].Id == _housingBinSentinelId) + { + data = File.ReadAllBytes(housingBinFile); + } + else + { + reader.BaseStream.Seek(idxEntries[j].Offset, SeekOrigin.Begin); + data = reader.ReadBytes(idxEntries[j].Size); + } tableEntries[tableIdx].Offset = writer.BaseStream.Position; tableEntries[tableIdx].DecompressedSize = data.Length; @@ -177,12 +203,37 @@ public static void ToUop(string inFile, string inFileIdx, string outFile, FileTy { tableEntries[tableIdx].Identifier = HashLittle2(string.Format(hashFormat[1], idxEntries[j].Id)); } + else if (type == FileType.MultiCollection && idxEntries[j].Id == _housingBinSentinelId) + { + tableEntries[tableIdx].Identifier = _housingBinIdentifier; + } else { tableEntries[tableIdx].Identifier = HashLittle2(string.Format(hashFormat[0], idxEntries[j].Id)); } - if (type == FileType.GumpartLegacyMul) + if (type == FileType.MultiCollection && idxEntries[j].Id != _housingBinSentinelId) + { + byte[] multiData = BuildMultiUopEntryFromMul(data, idxEntries[j].Id); + + tableEntries[tableIdx].DecompressedSize = multiData.Length; + tableEntries[tableIdx].Size = multiData.Length; + + if (compressionFlag >= CompressionFlag.Zlib) + { + var result = UopUtils.Compress(multiData); + if (!result.success) + { + return; + } + multiData = result.compressedData; + tableEntries[tableIdx].Size = multiData.Length; + } + + tableEntries[tableIdx].Hash = HashAdler32(multiData); + writer.Write(multiData); + } + else if (type == FileType.GumpartLegacyMul) { byte[] gumpArtData = new byte[data.Length + 8]; using (MemoryStream ms = new MemoryStream(gumpArtData)) @@ -231,6 +282,26 @@ public static void ToUop(string inFile, string inFileIdx, string outFile, FileTy tableEntries[tableIdx].Hash = HashAdler32(gumpArtData); writer.Write(gumpArtData); } + else if (type == FileType.MultiCollection && idxEntries[j].Id == _housingBinSentinelId) + { + byte[] binData = data; + tableEntries[tableIdx].DecompressedSize = binData.Length; + tableEntries[tableIdx].Size = binData.Length; + + if (compressionFlag >= CompressionFlag.Zlib) + { + var result = UopUtils.Compress(binData); + if (!result.success) + { + return; + } + binData = result.compressedData; + tableEntries[tableIdx].Size = binData.Length; + } + + tableEntries[tableIdx].Hash = HashAdler32(binData); + writer.Write(binData); + } else { tableEntries[tableIdx].Size = data.Length; @@ -311,7 +382,7 @@ public void FromUop(string inFile, string outFile, string outFileIdx, FileType t { if (reader.ReadInt32() != 0x50594D) // MYP { - throw new ArgumentException("inFile is not a UOP file."); + throw new ArgumentException("Input file is not a UOP file."); } Stream stream = reader.BaseStream; @@ -582,7 +653,7 @@ private static string[] GetHashFormat(FileType type, int typeIndex, out int maxI } case FileType.MultiCollection: { - maxId = 0x2200; // seems like this is reasonable limit for multis + maxId = 0x2710; // newer clients add multis past 0x2200 (e.g. 9000); keep generous for future entries return ["build/multicollection/{0:000000}.bin", string.Empty]; } default: @@ -704,5 +775,48 @@ private static void WriteMultiUopEntryToMul(BinaryWriter mulWriter, byte[] chunk mulWriter.Write(0); } } + + // MUL row layout: [itemId:2][x:2][y:2][z:2][flag:4][extra:4] = 16 bytes + // UOP component: [itemId:2][x:2][y:2][z:2][flag:2][clilocsCount:4] = 14 bytes + private static byte[] BuildMultiUopEntryFromMul(byte[] mulData, int multiId) + { + const int mulRowSize = 16; + const int uopComponentSize = 14; + + int componentCount = mulData.Length / mulRowSize; + byte[] result = new byte[8 + componentCount * uopComponentSize]; + + Span dst = result.AsSpan(); + BinaryPrimitives.WriteUInt32LittleEndian(dst, (uint)multiId); + BinaryPrimitives.WriteUInt32LittleEndian(dst[4..], (uint)componentCount); + dst = dst[8..]; + + ReadOnlySpan src = mulData.AsSpan(); + + for (int i = 0; i < componentCount; i++) + { + ushort itemId = BinaryPrimitives.ReadUInt16LittleEndian(src); + short x = BinaryPrimitives.ReadInt16LittleEndian(src[2..]); + short y = BinaryPrimitives.ReadInt16LittleEndian(src[4..]); + short z = BinaryPrimitives.ReadInt16LittleEndian(src[6..]); + int mulFlag = BinaryPrimitives.ReadInt32LittleEndian(src[8..]); + // extra int32 at src[12..16] is discarded + + // Inverse of WriteMultiUopEntryToMul: mul==1 -> visible (uop flag 0), otherwise invisible (uop flag 1). + ushort uopFlag = (ushort)(mulFlag == 1 ? 0 : 1); + + BinaryPrimitives.WriteUInt16LittleEndian(dst, itemId); + BinaryPrimitives.WriteInt16LittleEndian(dst[2..], x); + BinaryPrimitives.WriteInt16LittleEndian(dst[4..], y); + BinaryPrimitives.WriteInt16LittleEndian(dst[6..], z); + BinaryPrimitives.WriteUInt16LittleEndian(dst[8..], uopFlag); + BinaryPrimitives.WriteUInt32LittleEndian(dst[10..], 0u); // clilocsCount + + src = src[mulRowSize..]; + dst = dst[uopComponentSize..]; + } + + return result; + } } } diff --git a/UoFiddler.Plugin.UopPacker/UserControls/UopPackerControl.Designer.cs b/UoFiddler.Plugin.UopPacker/UserControls/UopPackerControl.Designer.cs index ab82e360..806c13f1 100644 --- a/UoFiddler.Plugin.UopPacker/UserControls/UopPackerControl.Designer.cs +++ b/UoFiddler.Plugin.UopPacker/UserControls/UopPackerControl.Designer.cs @@ -46,15 +46,19 @@ private void InitializeComponent() label3 = new System.Windows.Forms.Label(); inmulbtn = new System.Windows.Forms.Button(); inidxbtn = new System.Windows.Forms.Button(); + inhousingbin = new System.Windows.Forms.TextBox(); + inhousingbinbtn = new System.Windows.Forms.Button(); + labelHousingBin = new System.Windows.Forms.Label(); multouop = new System.Windows.Forms.Button(); FileDialog = new System.Windows.Forms.OpenFileDialog(); - outuop = new System.Windows.Forms.TextBox(); + outuopfolder = new System.Windows.Forms.TextBox(); + outputUopFileLabel = new System.Windows.Forms.Label(); label7 = new System.Windows.Forms.Label(); multype = new System.Windows.Forms.ComboBox(); label4 = new System.Windows.Forms.Label(); label5 = new System.Windows.Forms.Label(); mulMapIndex = new System.Windows.Forms.NumericUpDown(); - outuopbtn = new System.Windows.Forms.Button(); + outuopfolderbtn = new System.Windows.Forms.Button(); inuopbtn = new System.Windows.Forms.Button(); uopMapIndex = new System.Windows.Forms.NumericUpDown(); label6 = new System.Windows.Forms.Label(); @@ -63,11 +67,9 @@ private void InitializeComponent() inuop = new System.Windows.Forms.TextBox(); label9 = new System.Windows.Forms.Label(); uoptomul = new System.Windows.Forms.Button(); - outidxbtn = new System.Windows.Forms.Button(); - outmulbtn = new System.Windows.Forms.Button(); - outidx = new System.Windows.Forms.TextBox(); - label10 = new System.Windows.Forms.Label(); - outmul = new System.Windows.Forms.TextBox(); + outfolderbtn = new System.Windows.Forms.Button(); + outputFilesLabel = new System.Windows.Forms.Label(); + outfolder = new System.Windows.Forms.TextBox(); label11 = new System.Windows.Forms.Label(); label12 = new System.Windows.Forms.Label(); OperationTypeTabControl = new System.Windows.Forms.TabControl(); @@ -115,7 +117,7 @@ private void InitializeComponent() // label2 // label2.AutoSize = true; - label2.Location = new System.Drawing.Point(35, 42); + label2.Location = new System.Drawing.Point(47, 72); label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); label2.Name = "label2"; label2.Size = new System.Drawing.Size(63, 15); @@ -125,25 +127,25 @@ private void InitializeComponent() // inmul // inmul.BackColor = System.Drawing.Color.White; - inmul.Location = new System.Drawing.Point(118, 38); + inmul.Location = new System.Drawing.Point(118, 68); inmul.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); inmul.Name = "inmul"; inmul.Size = new System.Drawing.Size(241, 23); - inmul.TabIndex = 2; + inmul.TabIndex = 1; // // inidx // inidx.BackColor = System.Drawing.Color.White; - inidx.Location = new System.Drawing.Point(118, 68); + inidx.Location = new System.Drawing.Point(118, 98); inidx.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); inidx.Name = "inidx"; inidx.Size = new System.Drawing.Size(241, 23); - inidx.TabIndex = 4; + inidx.TabIndex = 3; // // label3 // label3.AutoSize = true; - label3.Location = new System.Drawing.Point(35, 72); + label3.Location = new System.Drawing.Point(54, 102); label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); label3.Name = "label3"; label3.Size = new System.Drawing.Size(56, 15); @@ -152,33 +154,63 @@ private void InitializeComponent() // // inmulbtn // - inmulbtn.Location = new System.Drawing.Point(366, 38); + inmulbtn.Location = new System.Drawing.Point(366, 68); inmulbtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); inmulbtn.Name = "inmulbtn"; inmulbtn.Size = new System.Drawing.Size(31, 23); - inmulbtn.TabIndex = 5; + inmulbtn.TabIndex = 2; inmulbtn.Text = "..."; inmulbtn.UseVisualStyleBackColor = true; inmulbtn.Click += InputMulSelect; // // inidxbtn // - inidxbtn.Location = new System.Drawing.Point(366, 68); + inidxbtn.Location = new System.Drawing.Point(366, 98); inidxbtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); inidxbtn.Name = "inidxbtn"; inidxbtn.Size = new System.Drawing.Size(31, 23); - inidxbtn.TabIndex = 6; + inidxbtn.TabIndex = 4; inidxbtn.Text = "..."; inidxbtn.UseVisualStyleBackColor = true; inidxbtn.Click += InputIdxSelect; // + // inhousingbin + // + inhousingbin.BackColor = System.Drawing.Color.White; + inhousingbin.Location = new System.Drawing.Point(118, 128); + inhousingbin.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + inhousingbin.Name = "inhousingbin"; + inhousingbin.Size = new System.Drawing.Size(241, 23); + inhousingbin.TabIndex = 5; + // + // inhousingbinbtn + // + inhousingbinbtn.Location = new System.Drawing.Point(366, 128); + inhousingbinbtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + inhousingbinbtn.Name = "inhousingbinbtn"; + inhousingbinbtn.Size = new System.Drawing.Size(31, 23); + inhousingbinbtn.TabIndex = 6; + inhousingbinbtn.Text = "..."; + inhousingbinbtn.UseVisualStyleBackColor = true; + inhousingbinbtn.Click += InputHousingBinSelect; + // + // labelHousingBin + // + labelHousingBin.AutoSize = true; + labelHousingBin.Location = new System.Drawing.Point(9, 132); + labelHousingBin.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + labelHousingBin.Name = "labelHousingBin"; + labelHousingBin.Size = new System.Drawing.Size(101, 15); + labelHousingBin.TabIndex = 43; + labelHousingBin.Text = "Input housing.bin"; + // // multouop // multouop.Location = new System.Drawing.Point(405, 38); multouop.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); multouop.Name = "multouop"; - multouop.Size = new System.Drawing.Size(102, 150); - multouop.TabIndex = 7; + multouop.Size = new System.Drawing.Size(102, 173); + multouop.TabIndex = 11; multouop.Text = "Convert"; multouop.UseVisualStyleBackColor = true; multouop.Click += ToUop; @@ -186,41 +218,51 @@ private void InitializeComponent() // FileDialog // FileDialog.CheckFileExists = false; - FileDialog.Filter = "MUL|*.mul|UOP|*.uop|IDX|*.idx"; + FileDialog.Filter = "MUL|*.mul|UOP|*.uop|IDX|*.idx|BIN|*.bin"; + // + // outuopfolder // - // outuop + outuopfolder.BackColor = System.Drawing.Color.White; + outuopfolder.Location = new System.Drawing.Point(118, 188); + outuopfolder.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + outuopfolder.Name = "outuopfolder"; + outuopfolder.Size = new System.Drawing.Size(241, 23); + outuopfolder.TabIndex = 9; // - outuop.BackColor = System.Drawing.Color.White; - outuop.Location = new System.Drawing.Point(118, 165); - outuop.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - outuop.Name = "outuop"; - outuop.Size = new System.Drawing.Size(241, 23); - outuop.TabIndex = 17; + // outputUopFileLabel + // + outputUopFileLabel.AutoSize = true; + outputUopFileLabel.ForeColor = System.Drawing.SystemColors.GrayText; + outputUopFileLabel.Location = new System.Drawing.Point(118, 215); + outputUopFileLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + outputUopFileLabel.Name = "outputUopFileLabel"; + outputUopFileLabel.Size = new System.Drawing.Size(0, 15); + outputUopFileLabel.TabIndex = 45; // // label7 // label7.AutoSize = true; - label7.Location = new System.Drawing.Point(35, 168); + label7.Location = new System.Drawing.Point(31, 192); label7.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); label7.Name = "label7"; - label7.Size = new System.Drawing.Size(72, 15); + label7.Size = new System.Drawing.Size(79, 15); label7.TabIndex = 16; - label7.Text = "Output UOP"; + label7.Text = "Output folder"; // // multype // multype.BackColor = System.Drawing.Color.White; - multype.Location = new System.Drawing.Point(118, 99); + multype.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + multype.Location = new System.Drawing.Point(118, 38); multype.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); multype.Name = "multype"; multype.Size = new System.Drawing.Size(241, 23); - multype.TabIndex = 19; - multype.Text = "File Type"; + multype.TabIndex = 0; // // label4 // label4.AutoSize = true; - label4.Location = new System.Drawing.Point(35, 103); + label4.Location = new System.Drawing.Point(49, 41); label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); label4.Name = "label4"; label4.Size = new System.Drawing.Size(61, 15); @@ -230,7 +272,7 @@ private void InitializeComponent() // label5 // label5.AutoSize = true; - label5.Location = new System.Drawing.Point(35, 137); + label5.Location = new System.Drawing.Point(54, 161); label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); label5.Name = "label5"; label5.Size = new System.Drawing.Size(56, 15); @@ -240,32 +282,32 @@ private void InitializeComponent() // mulMapIndex // mulMapIndex.BackColor = System.Drawing.Color.White; - mulMapIndex.Location = new System.Drawing.Point(118, 135); + mulMapIndex.Location = new System.Drawing.Point(118, 158); mulMapIndex.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); mulMapIndex.Maximum = new decimal(new int[] { 5, 0, 0, 0 }); mulMapIndex.Name = "mulMapIndex"; mulMapIndex.ReadOnly = true; mulMapIndex.Size = new System.Drawing.Size(42, 23); - mulMapIndex.TabIndex = 22; + mulMapIndex.TabIndex = 7; // - // outuopbtn + // outuopfolderbtn // - outuopbtn.Location = new System.Drawing.Point(366, 165); - outuopbtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - outuopbtn.Name = "outuopbtn"; - outuopbtn.Size = new System.Drawing.Size(31, 23); - outuopbtn.TabIndex = 23; - outuopbtn.Text = "..."; - outuopbtn.UseVisualStyleBackColor = true; - outuopbtn.Click += OutputUopSelect; + outuopfolderbtn.Location = new System.Drawing.Point(366, 188); + outuopfolderbtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + outuopfolderbtn.Name = "outuopfolderbtn"; + outuopfolderbtn.Size = new System.Drawing.Size(31, 23); + outuopfolderbtn.TabIndex = 10; + outuopfolderbtn.Text = "..."; + outuopfolderbtn.UseVisualStyleBackColor = true; + outuopfolderbtn.Click += OutputUopFolderSelect; // // inuopbtn // - inuopbtn.Location = new System.Drawing.Point(366, 365); + inuopbtn.Location = new System.Drawing.Point(367, 326); inuopbtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); inuopbtn.Name = "inuopbtn"; inuopbtn.Size = new System.Drawing.Size(31, 23); - inuopbtn.TabIndex = 39; + inuopbtn.TabIndex = 14; inuopbtn.Text = "..."; inuopbtn.UseVisualStyleBackColor = true; inuopbtn.Click += InputUopSelect; @@ -273,18 +315,18 @@ private void InitializeComponent() // uopMapIndex // uopMapIndex.BackColor = System.Drawing.Color.White; - uopMapIndex.Location = new System.Drawing.Point(118, 335); + uopMapIndex.Location = new System.Drawing.Point(118, 297); uopMapIndex.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); uopMapIndex.Maximum = new decimal(new int[] { 5, 0, 0, 0 }); uopMapIndex.Name = "uopMapIndex"; uopMapIndex.ReadOnly = true; uopMapIndex.Size = new System.Drawing.Size(42, 23); - uopMapIndex.TabIndex = 38; + uopMapIndex.TabIndex = 17; // // label6 // label6.AutoSize = true; - label6.Location = new System.Drawing.Point(35, 337); + label6.Location = new System.Drawing.Point(54, 299); label6.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); label6.Name = "label6"; label6.Size = new System.Drawing.Size(56, 15); @@ -294,7 +336,7 @@ private void InitializeComponent() // label8 // label8.AutoSize = true; - label8.Location = new System.Drawing.Point(35, 302); + label8.Location = new System.Drawing.Point(49, 271); label8.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); label8.Name = "label8"; label8.Size = new System.Drawing.Size(61, 15); @@ -304,27 +346,27 @@ private void InitializeComponent() // uoptype // uoptype.BackColor = System.Drawing.Color.White; + uoptype.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; uoptype.FormattingEnabled = true; - uoptype.Location = new System.Drawing.Point(118, 299); + uoptype.Location = new System.Drawing.Point(118, 268); uoptype.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); uoptype.Name = "uoptype"; uoptype.Size = new System.Drawing.Size(241, 23); - uoptype.TabIndex = 35; - uoptype.Text = "File Type"; + uoptype.TabIndex = 12; // // inuop // inuop.BackColor = System.Drawing.Color.White; - inuop.Location = new System.Drawing.Point(118, 365); + inuop.Location = new System.Drawing.Point(118, 326); inuop.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); inuop.Name = "inuop"; inuop.Size = new System.Drawing.Size(241, 23); - inuop.TabIndex = 33; + inuop.TabIndex = 13; // // label9 // label9.AutoSize = true; - label9.Location = new System.Drawing.Point(35, 368); + label9.Location = new System.Drawing.Point(48, 329); label9.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); label9.Name = "label9"; label9.Size = new System.Drawing.Size(62, 15); @@ -333,79 +375,59 @@ private void InitializeComponent() // // uoptomul // - uoptomul.Location = new System.Drawing.Point(405, 238); + uoptomul.Location = new System.Drawing.Point(406, 268); uoptomul.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); uoptomul.Name = "uoptomul"; - uoptomul.Size = new System.Drawing.Size(102, 150); - uoptomul.TabIndex = 31; + uoptomul.Size = new System.Drawing.Size(102, 110); + uoptomul.TabIndex = 18; uoptomul.Text = "Convert"; uoptomul.UseVisualStyleBackColor = true; uoptomul.Click += ToMul; // - // outidxbtn - // - outidxbtn.Location = new System.Drawing.Point(366, 268); - outidxbtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - outidxbtn.Name = "outidxbtn"; - outidxbtn.Size = new System.Drawing.Size(31, 23); - outidxbtn.TabIndex = 30; - outidxbtn.Text = "..."; - outidxbtn.UseVisualStyleBackColor = true; - outidxbtn.Click += OutputIdxSelect; - // - // outmulbtn - // - outmulbtn.Location = new System.Drawing.Point(366, 238); - outmulbtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - outmulbtn.Name = "outmulbtn"; - outmulbtn.Size = new System.Drawing.Size(31, 23); - outmulbtn.TabIndex = 29; - outmulbtn.Text = "..."; - outmulbtn.UseVisualStyleBackColor = true; - outmulbtn.Click += OutMulSelect; - // - // outidx - // - outidx.BackColor = System.Drawing.Color.White; - outidx.Location = new System.Drawing.Point(118, 268); - outidx.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - outidx.Name = "outidx"; - outidx.Size = new System.Drawing.Size(241, 23); - outidx.TabIndex = 28; - // - // label10 - // - label10.AutoSize = true; - label10.Location = new System.Drawing.Point(35, 271); - label10.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - label10.Name = "label10"; - label10.Size = new System.Drawing.Size(66, 15); - label10.TabIndex = 27; - label10.Text = "Output IDX"; - // - // outmul - // - outmul.BackColor = System.Drawing.Color.White; - outmul.Location = new System.Drawing.Point(118, 238); - outmul.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - outmul.Name = "outmul"; - outmul.Size = new System.Drawing.Size(241, 23); - outmul.TabIndex = 26; + // outfolderbtn + // + outfolderbtn.Location = new System.Drawing.Point(367, 355); + outfolderbtn.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + outfolderbtn.Name = "outfolderbtn"; + outfolderbtn.Size = new System.Drawing.Size(31, 23); + outfolderbtn.TabIndex = 16; + outfolderbtn.Text = "..."; + outfolderbtn.UseVisualStyleBackColor = true; + outfolderbtn.Click += OutFolderSelect; + // + // outputFilesLabel + // + outputFilesLabel.AutoSize = true; + outputFilesLabel.ForeColor = System.Drawing.SystemColors.GrayText; + outputFilesLabel.Location = new System.Drawing.Point(118, 357); + outputFilesLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + outputFilesLabel.Name = "outputFilesLabel"; + outputFilesLabel.Size = new System.Drawing.Size(0, 15); + outputFilesLabel.TabIndex = 44; + // + // outfolder + // + outfolder.BackColor = System.Drawing.Color.White; + outfolder.Location = new System.Drawing.Point(118, 355); + outfolder.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + outfolder.Name = "outfolder"; + outfolder.Size = new System.Drawing.Size(241, 23); + outfolder.TabIndex = 15; // // label11 // label11.AutoSize = true; - label11.Location = new System.Drawing.Point(35, 241); + label11.Location = new System.Drawing.Point(31, 358); label11.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); label11.Name = "label11"; - label11.Size = new System.Drawing.Size(73, 15); + label11.Size = new System.Drawing.Size(79, 15); label11.TabIndex = 25; - label11.Text = "Output MUL"; + label11.Text = "Output folder"; // // label12 // label12.AutoSize = true; - label12.Location = new System.Drawing.Point(7, 203); + label12.Location = new System.Drawing.Point(7, 233); label12.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); label12.Name = "label12"; label12.Size = new System.Drawing.Size(147, 15); @@ -444,10 +466,10 @@ private void InitializeComponent() // // StartFolderButton // - StartFolderButton.Location = new System.Drawing.Point(10, 96); + StartFolderButton.Location = new System.Drawing.Point(56, 96); StartFolderButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); StartFolderButton.Name = "StartFolderButton"; - StartFolderButton.Size = new System.Drawing.Size(326, 27); + StartFolderButton.Size = new System.Drawing.Size(279, 27); StartFolderButton.TabIndex = 12; StartFolderButton.Text = "Start"; StartFolderButton.UseVisualStyleBackColor = true; @@ -538,6 +560,9 @@ private void InitializeComponent() ExtractSingleFileTabPage.Controls.Add(label1); ExtractSingleFileTabPage.Controls.Add(label2); ExtractSingleFileTabPage.Controls.Add(inmul); + ExtractSingleFileTabPage.Controls.Add(inhousingbin); + ExtractSingleFileTabPage.Controls.Add(inhousingbinbtn); + ExtractSingleFileTabPage.Controls.Add(labelHousingBin); ExtractSingleFileTabPage.Controls.Add(inuopbtn); ExtractSingleFileTabPage.Controls.Add(label3); ExtractSingleFileTabPage.Controls.Add(uopMapIndex); @@ -551,20 +576,19 @@ private void InitializeComponent() ExtractSingleFileTabPage.Controls.Add(inuop); ExtractSingleFileTabPage.Controls.Add(label7); ExtractSingleFileTabPage.Controls.Add(label9); - ExtractSingleFileTabPage.Controls.Add(outuop); + ExtractSingleFileTabPage.Controls.Add(outuopfolder); + ExtractSingleFileTabPage.Controls.Add(outputUopFileLabel); ExtractSingleFileTabPage.Controls.Add(uoptomul); ExtractSingleFileTabPage.Controls.Add(multype); - ExtractSingleFileTabPage.Controls.Add(outidxbtn); ExtractSingleFileTabPage.Controls.Add(label4); - ExtractSingleFileTabPage.Controls.Add(outmulbtn); + ExtractSingleFileTabPage.Controls.Add(outfolderbtn); ExtractSingleFileTabPage.Controls.Add(label5); - ExtractSingleFileTabPage.Controls.Add(outidx); ExtractSingleFileTabPage.Controls.Add(mulMapIndex); - ExtractSingleFileTabPage.Controls.Add(label10); - ExtractSingleFileTabPage.Controls.Add(outuopbtn); - ExtractSingleFileTabPage.Controls.Add(outmul); + ExtractSingleFileTabPage.Controls.Add(outuopfolderbtn); + ExtractSingleFileTabPage.Controls.Add(outfolder); ExtractSingleFileTabPage.Controls.Add(label12); ExtractSingleFileTabPage.Controls.Add(label11); + ExtractSingleFileTabPage.Controls.Add(outputFilesLabel); ExtractSingleFileTabPage.Location = new System.Drawing.Point(4, 24); ExtractSingleFileTabPage.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); ExtractSingleFileTabPage.Name = "ExtractSingleFileTabPage"; @@ -578,11 +602,11 @@ private void InitializeComponent() // compressionBox.BackColor = System.Drawing.Color.White; compressionBox.Items.AddRange(new object[] { "None", "Zlib", "Mythic" }); - compressionBox.Location = new System.Drawing.Point(168, 134); + compressionBox.Location = new System.Drawing.Point(168, 158); compressionBox.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); compressionBox.Name = "compressionBox"; compressionBox.Size = new System.Drawing.Size(191, 23); - compressionBox.TabIndex = 40; + compressionBox.TabIndex = 8; compressionBox.Text = "None"; // // MainStatusStrip @@ -678,7 +702,6 @@ private void InitializeComponent() private System.Windows.Forms.TextBox inuop; private System.Windows.Forms.Button inuopbtn; private System.Windows.Forms.Label label1; - private System.Windows.Forms.Label label10; private System.Windows.Forms.Label label11; private System.Windows.Forms.Label label12; private System.Windows.Forms.Label label13; @@ -693,12 +716,11 @@ private void InitializeComponent() private System.Windows.Forms.NumericUpDown mulMapIndex; private System.Windows.Forms.Button multouop; private System.Windows.Forms.ComboBox multype; - private System.Windows.Forms.TextBox outidx; - private System.Windows.Forms.Button outidxbtn; - private System.Windows.Forms.TextBox outmul; - private System.Windows.Forms.Button outmulbtn; - private System.Windows.Forms.TextBox outuop; - private System.Windows.Forms.Button outuopbtn; + private System.Windows.Forms.TextBox outfolder; + private System.Windows.Forms.Button outfolderbtn; + private System.Windows.Forms.TextBox outuopfolder; + private System.Windows.Forms.Label outputUopFileLabel; + private System.Windows.Forms.Button outuopfolderbtn; private System.Windows.Forms.RadioButton pack; private System.Windows.Forms.OpenFileDialog FileDialog; private System.Windows.Forms.FolderBrowserDialog FolderDialog; @@ -718,5 +740,9 @@ private void InitializeComponent() private System.Windows.Forms.ComboBox uoptype; private System.Windows.Forms.ToolStripStatusLabel VersionLabel; private System.Windows.Forms.ComboBox compressionBox; + private System.Windows.Forms.TextBox inhousingbin; + private System.Windows.Forms.Button inhousingbinbtn; + private System.Windows.Forms.Label labelHousingBin; + private System.Windows.Forms.Label outputFilesLabel; } } diff --git a/UoFiddler.Plugin.UopPacker/UserControls/UopPackerControl.cs b/UoFiddler.Plugin.UopPacker/UserControls/UopPackerControl.cs index 9b52c913..14b697f9 100644 --- a/UoFiddler.Plugin.UopPacker/UserControls/UopPackerControl.cs +++ b/UoFiddler.Plugin.UopPacker/UserControls/UopPackerControl.cs @@ -11,9 +11,11 @@ using System; using System.IO; -using System.Linq; using System.Windows.Forms; +using Serilog; using Ultima; +using UoFiddler.Controls.Classes; +using UoFiddler.Controls.Forms; using UoFiddler.Plugin.UopPacker.Classes; namespace UoFiddler.Plugin.UopPacker.UserControls @@ -30,14 +32,98 @@ private UopPackerControl() var fileTypes = Enum.GetNames(typeof(FileType)); - uoptype.DataSource = fileTypes; - multype.DataSource = fileTypes.SkipLast(1).ToArray(); // remove multi collection from ToUOP() conversion (not supported yet) + multype.SelectedIndexChanged += OnMulTypeChanged; + uoptype.SelectedIndexChanged += OnUopTypeChanged; + mulMapIndex.ValueChanged += OnMulTypeChanged; + uopMapIndex.ValueChanged += OnUopTypeChanged; + + uoptype.DataSource = new System.Collections.Generic.List(fileTypes); + multype.DataSource = new System.Collections.Generic.List(fileTypes); mulMapIndex.ReadOnly = uopMapIndex.ReadOnly = true; + // Single output folder for both directions; individual filenames are derived from the selected FileType. + outfolder.PlaceholderText = "folder where .mul/.idx will be written"; + outuopfolder.PlaceholderText = "folder where .uop will be written"; + + RefreshMulTypeUi(); + RefreshUopTypeUi(); + Dock = DockStyle.Fill; } + private static (string mul, string idx, string uop) GetConventionalNames(FileType type, int mapIndex) + { + return type switch + { + FileType.ArtLegacyMul => ("art.mul", "artidx.mul", "artLegacyMUL.uop"), + FileType.GumpartLegacyMul => ("gumpart.mul", "gumpidx.mul", "gumpartLegacyMUL.uop"), + FileType.MapLegacyMul => ($"map{mapIndex}.mul", null, $"map{mapIndex}LegacyMUL.uop"), + FileType.SoundLegacyMul => ("sound.mul", "soundidx.mul", "soundLegacyMUL.uop"), + FileType.MultiCollection => ("multi.mul", "multi.idx", "MultiCollection.uop"), + _ => ("", "", "") + }; + } + + private void OnMulTypeChanged(object sender, EventArgs e) => RefreshMulTypeUi(); + + private void OnUopTypeChanged(object sender, EventArgs e) => RefreshUopTypeUi(); + + private void RefreshMulTypeUi() + { + if (multype == null || !Enum.TryParse(multype.SelectedValue?.ToString() ?? string.Empty, out FileType type)) + { + return; + } + + bool isMap = type == FileType.MapLegacyMul; + bool isMulti = type == FileType.MultiCollection; + + inidx.Enabled = inidxbtn.Enabled = !isMap; + mulMapIndex.Enabled = isMap; + + inhousingbin.Visible = inhousingbinbtn.Visible = labelHousingBin.Visible = isMulti; + + // Previously-picked paths belong to the old type; clear them so the user can't accidentally + // run a conversion against the wrong file. + inmul.Text = string.Empty; + inidx.Text = string.Empty; + inhousingbin.Text = string.Empty; + + var (mulName, idxName, uopName) = GetConventionalNames(type, (int)mulMapIndex.Value); + inmul.PlaceholderText = mulName; + inidx.PlaceholderText = idxName ?? string.Empty; + inhousingbin.PlaceholderText = "housing.bin"; + + outputUopFileLabel.Text = string.IsNullOrEmpty(uopName) ? string.Empty : "Will create: " + uopName; + } + + private void RefreshUopTypeUi() + { + if (uoptype == null || !Enum.TryParse(uoptype.SelectedValue?.ToString() ?? string.Empty, out FileType type)) + { + return; + } + + bool isMap = type == FileType.MapLegacyMul; + bool isMulti = type == FileType.MultiCollection; + + uopMapIndex.Enabled = isMap; + + inuop.Text = string.Empty; + + var (mulName, idxName, uopName) = GetConventionalNames(type, (int)uopMapIndex.Value); + inuop.PlaceholderText = uopName; + + // Preview what will be written under the output folder. + string preview = idxName != null ? $"{mulName}, {idxName}" : mulName; + if (isMulti) + { + preview += ", housing.bin"; + } + outputFilesLabel.Text = "Will create: " + preview; + } + public UopPackerControl(string version) : this() { VersionLabel.Text = version; @@ -63,13 +149,11 @@ private void InputIdxSelect(object sender, EventArgs e) } } - private void OutputUopSelect(object sender, EventArgs e) + private void OutputUopFolderSelect(object sender, EventArgs e) { - FileDialog.FilterIndex = 2; - - if (FileDialog.ShowDialog() == DialogResult.OK) + if (FolderDialog.ShowDialog() == DialogResult.OK) { - outuop.Text = FileDialog.FileName; + outuopfolder.Text = FolderDialog.SelectedPath; } } @@ -88,71 +172,107 @@ private void ToUop(object sender, EventArgs e) return; } - if (inidx.Text.Length == 0) + if (!File.Exists(inmul.Text)) { - MessageBox.Show("You must specify the input idx"); + MessageBox.Show("The input mul does not exist"); return; } - if (outuop.Text.Length == 0) + if (inidx.Text.Length == 0 && fileType != FileType.MapLegacyMul) { - MessageBox.Show("You must specify the output uop"); + MessageBox.Show("You must specify the input idx"); return; } - if (!File.Exists(inmul.Text)) + if (fileType != FileType.MapLegacyMul && !File.Exists(inidx.Text)) { - MessageBox.Show("The input mul does not exists"); + MessageBox.Show("The input idx does not exist"); return; } - if (!File.Exists(inidx.Text)) + if (outuopfolder.Text.Length == 0) { - MessageBox.Show("The input idx does not exists"); + MessageBox.Show("You must specify the output folder"); return; } - if (File.Exists(outuop.Text)) + if (!Directory.Exists(outuopfolder.Text)) { - MessageBox.Show("Output file already exists"); + MessageBox.Show("The output folder does not exist"); return; } + + string housingBin = string.Empty; + if (fileType == FileType.MultiCollection) + { + housingBin = inhousingbin.Text; + if (!string.IsNullOrWhiteSpace(housingBin) && !File.Exists(housingBin)) + { + MessageBox.Show("The input housing.bin does not exist"); + return; + } + } + + var (_, _, uopName) = GetConventionalNames(fileType, (int)mulMapIndex.Value); + string outUopPath = Path.Combine(outuopfolder.Text, uopName); + + if (File.Exists(outUopPath)) + { + var prompt = MessageBox.Show( + $"{uopName} already exists in the output folder and will be overwritten.\n\nProceed?", + "Overwrite existing file", + MessageBoxButtons.YesNo, + MessageBoxIcon.Warning); + if (prompt != DialogResult.Yes) + { + return; + } + // ToUop opens output with FileMode.Create, which overwrites. + } + CompressionFlag selectedCompressionMethod = Enum.Parse(compressionBox.SelectedItem.ToString()); + + bool succeeded = false; try { multouop.Text = "Converting..."; multouop.Enabled = false; - LegacyMulFileConverter.ToUop(inmul.Text, inidx.Text, outuop.Text, fileType, (int)mulMapIndex.Value, selectedCompressionMethod); + LegacyMulFileConverter.ToUop(inmul.Text, inidx.Text, outUopPath, fileType, (int)mulMapIndex.Value, selectedCompressionMethod, housingBin); + succeeded = true; } - catch + catch (Exception ex) { - MessageBox.Show("An error occurred"); + LogConverterError(ex, nameof(ToUop), inmul.Text, outUopPath, fileType); + MessageBox.Show($"An error occurred.\r\n{ex.Message}"); } finally { multouop.Text = "Convert"; multouop.Enabled = true; } + + if (succeeded) + { + FileSavedDialog.Show(FindForm(), outUopPath, "UOP file saved successfully.", "Conversion complete"); + } } - private void OutMulSelect(object sender, EventArgs e) + private void InputHousingBinSelect(object sender, EventArgs e) { - FileDialog.FilterIndex = 1; + FileDialog.FilterIndex = 4; if (FileDialog.ShowDialog() == DialogResult.OK) { - outmul.Text = FileDialog.FileName; + inhousingbin.Text = FileDialog.FileName; } } - private void OutputIdxSelect(object sender, EventArgs e) + private void OutFolderSelect(object sender, EventArgs e) { - FileDialog.FilterIndex = 3; - - if (FileDialog.ShowDialog() == DialogResult.OK) + if (FolderDialog.ShowDialog() == DialogResult.OK) { - outidx.Text = FileDialog.FileName; + outfolder.Text = FolderDialog.SelectedPath; } } @@ -175,58 +295,88 @@ private void ToMul(object sender, EventArgs e) return; } - if (outmul.Text.Length == 0) + if (inuop.Text.Length == 0) { - MessageBox.Show("You must specify the output mul"); + MessageBox.Show("You must specify the input uop"); return; } - if (outidx.Text.Length == 0 && fileType != FileType.MapLegacyMul) + if (!File.Exists(inuop.Text)) { - MessageBox.Show("You must specify the output idx"); + MessageBox.Show("The input file does not exist"); return; } - if (inuop.Text.Length == 0) + if (outfolder.Text.Length == 0) { - MessageBox.Show("You must specify the input uop"); + MessageBox.Show("You must specify the output folder"); return; } - if (!File.Exists(inuop.Text)) + if (!Directory.Exists(outfolder.Text)) { - MessageBox.Show("The input file does not exists"); + MessageBox.Show("The output folder does not exist"); return; } - if (File.Exists(outmul.Text)) - { - MessageBox.Show("Output mul file already exists"); - return; - } + int mapIdx = (int)uopMapIndex.Value; + var (mulName, idxName, _) = GetConventionalNames(fileType, mapIdx); - if (File.Exists(outidx.Text) && fileType != FileType.MapLegacyMul) + string outMulPath = Path.Combine(outfolder.Text, mulName); + string outIdxPath = idxName != null ? Path.Combine(outfolder.Text, idxName) : null; + string housingBinPath = fileType == FileType.MultiCollection + ? Path.Combine(outfolder.Text, "housing.bin") + : string.Empty; + + var conflicts = new System.Collections.Generic.List(); + if (File.Exists(outMulPath)) conflicts.Add(mulName); + if (outIdxPath != null && File.Exists(outIdxPath)) conflicts.Add(idxName); + if (!string.IsNullOrEmpty(housingBinPath) && File.Exists(housingBinPath)) conflicts.Add("housing.bin"); + + if (conflicts.Count > 0) { - MessageBox.Show("Output index file already exists"); - return; + var prompt = MessageBox.Show( + $"These files already exist in the output folder and will be overwritten:\n\n {string.Join("\n ", conflicts)}\n\nProceed?", + "Overwrite existing files", + MessageBoxButtons.YesNo, + MessageBoxIcon.Warning); + if (prompt != DialogResult.Yes) + { + return; + } + // FromUop opens outputs with FileMode.Create, which overwrites. } + bool succeeded = false; try { uoptomul.Text = "Converting..."; uoptomul.Enabled = false; - _conv.FromUop(inuop.Text, outmul.Text, outidx.Text, fileType, (int)uopMapIndex.Value); + _conv.FromUop(inuop.Text, outMulPath, outIdxPath, fileType, mapIdx, housingBinPath); + succeeded = true; } - catch + catch (Exception ex) { - MessageBox.Show("An error occurred"); + LogConverterError(ex, nameof(ToMul), inuop.Text, outMulPath, fileType); + MessageBox.Show($"An error occurred.\r\n{ex.Message}"); } finally { uoptomul.Text = "Convert"; uoptomul.Enabled = true; } + + if (succeeded) + { + var written = new System.Collections.Generic.List { Path.GetFileName(outMulPath) }; + if (!string.IsNullOrEmpty(outIdxPath)) written.Add(Path.GetFileName(outIdxPath)); + if (!string.IsNullOrEmpty(housingBinPath)) written.Add(Path.GetFileName(housingBinPath)); + + FileSavedDialog.Show(FindForm(), outfolder.Text, + $"Saved: {string.Join(", ", written)}", + "Conversion complete"); + } } private void SelectFolder_Click(object sender, EventArgs e) @@ -281,11 +431,12 @@ private void Extract(string inFile, string outFile, string outIdx, FileType type } catch (Exception e) { + LogConverterError(e, nameof(Extract), inFile, outFile, type); MessageBox.Show($"An error occurred while performing the action.\r\n{e.Message}"); } } - private void Pack(string inFile, string inIdx, string outFile, FileType type, int typeIndex) + private void Pack(string inFile, string inIdx, string outFile, FileType type, int typeIndex, string housingBinFile = "") { try { @@ -308,19 +459,34 @@ private void Pack(string inFile, string inIdx, string outFile, FileType type, in } inIdx = FixPath(inIdx); + + if (!string.IsNullOrWhiteSpace(housingBinFile)) + { + housingBinFile = FixPath(housingBinFile); + } + ++_total; CompressionFlag selectedCompressionMethod = Enum.Parse(compressionBox.SelectedItem.ToString()); - LegacyMulFileConverter.ToUop(inFile, inIdx, outFile, type, typeIndex, selectedCompressionMethod); + LegacyMulFileConverter.ToUop(inFile, inIdx, outFile, type, typeIndex, selectedCompressionMethod, housingBinFile ?? string.Empty); ++_success; } catch (Exception e) { + LogConverterError(e, nameof(Pack), inFile, outFile, type); MessageBox.Show($"An error occurred while performing the action.\r\n{e.Message}"); } } + private static void LogConverterError(Exception ex, string operation, string input, string output, FileType type) + { + ILogger logger = Options.Logger; + + logger?.Error(ex, "UopPacker {Operation} failed (type={FileType}, input={Input}, output={Output})", + operation, type, input, output); + } + private string FixPath(string file) { return (file == null) ? null : Path.Combine(inputfolder.Text, file); @@ -351,7 +517,9 @@ private void StartFolderButtonClick(object sender, EventArgs e) Extract(map + "xLegacyMUL.uop", map + "x.mul", null, FileType.MapLegacyMul, i); } - statustext.Text = $"Done ({_success}/{_total} files extracted)"; + string extractMessage = $"Done ({_success}/{_total} files extracted)"; + statustext.Text = extractMessage; + FileSavedDialog.Show(FindForm(), inputfolder.Text, extractMessage, "Extraction complete"); } else if (pack.Checked) { @@ -360,6 +528,7 @@ private void StartFolderButtonClick(object sender, EventArgs e) Pack("art.mul", "artidx.mul", "artLegacyMUL.uop", FileType.ArtLegacyMul, 0); Pack("gumpart.mul", "gumpidx.mul", "gumpartLegacyMUL.uop", FileType.GumpartLegacyMul, 0); Pack("sound.mul", "soundidx.mul", "soundLegacyMUL.uop", FileType.SoundLegacyMul, 0); + Pack("multi-unpacked.mul", "multi-unpacked.idx", "MultiCollection.uop", FileType.MultiCollection, 0, "housing.bin"); for (int i = 0; i <= 5; ++i) { @@ -369,7 +538,9 @@ private void StartFolderButtonClick(object sender, EventArgs e) Pack(map + "x.mul", null, map + "xLegacyMUL.uop", FileType.MapLegacyMul, i); } - statustext.Text = $"Done ({_success}/{_total} files packed)"; + string packMessage = $"Done ({_success}/{_total} files packed)"; + statustext.Text = packMessage; + FileSavedDialog.Show(FindForm(), inputfolder.Text, packMessage, "Pack complete"); } else { From c0c29855d141ff92e6ce412080795366b5aa23ae Mon Sep 17 00:00:00 2001 From: AsY!um- <377468+AsYlum-@users.noreply.github.com> Date: Sun, 26 Apr 2026 21:41:35 +0200 Subject: [PATCH 6/6] Update change log and version. --- UoFiddler/Forms/AboutBoxForm.resx | 9 ++++++++- UoFiddler/UoFiddler.csproj | 6 +++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/UoFiddler/Forms/AboutBoxForm.resx b/UoFiddler/Forms/AboutBoxForm.resx index 15b32ccd..47a0bc6e 100644 --- a/UoFiddler/Forms/AboutBoxForm.resx +++ b/UoFiddler/Forms/AboutBoxForm.resx @@ -118,7 +118,14 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Version 4.19.0 + Version 4.19.1 +- UopPacker: added save support for MultiCollection.uop (including housing.bin) and refreshed the plugin UI. +- Map copy/replace dialog now supports UOP map files. #105 +- Added "Replace from folder" bulk action for Items and Land Tiles tabs. #102 +- More controls now use the unified File Saved dialog (with Open Folder shortcut) when saving. +- Animation editor remembers the selected file filter when adding new frames. #82 + +Version 4.19.0 - Added support for previewing contents of animations in anim6.mul and AnimationFrame1-6.uop (no export or edit option for uop yet). - Fixed possible crash and slowdown during tiledata CSV import from newer client to older client. - More preview boxes now support change background color and use background color set in Options. diff --git a/UoFiddler/UoFiddler.csproj b/UoFiddler/UoFiddler.csproj index ce5756bd..9ac78ff6 100644 --- a/UoFiddler/UoFiddler.csproj +++ b/UoFiddler/UoFiddler.csproj @@ -9,9 +9,9 @@ UoFiddler UoFiddler Copyright © 2026 - 4.19.0 - 4.19.0 - 4.19.0 + 4.19.1 + 4.19.1 + 4.19.1 true