Update to .NET 10 (#683)

This commit is contained in:
Kurt
2026-01-13 16:02:58 -06:00
committed by GitHub
parent 63bd5f643c
commit fa3f0e3cc8
316 changed files with 31897 additions and 32159 deletions

View File

@@ -3,30 +3,28 @@
using System.Windows.Forms;
using NHSE.Core;
namespace NHSE.WinForms
namespace NHSE.WinForms;
public partial class BuildingHelp : Form
{
public partial class BuildingHelp : Form
private static readonly IReadOnlyDictionary<string, string[]> HelpDictionary = StructureUtil.GetStructureHelpList();
public BuildingHelp()
{
private static readonly IReadOnlyDictionary<string, string[]> HelpDictionary = StructureUtil.GetStructureHelpList();
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
public BuildingHelp()
{
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
foreach (var entry in HelpDictionary)
CB_StructureType.Items.Add(entry.Key);
CB_StructureType.SelectedIndex = 0;
}
private void CB_StructureType_SelectedIndexChanged(object sender, EventArgs e)
{
var name = CB_StructureType.Text;
var values = HelpDictionary[name];
CB_StructureValues.Items.Clear();
foreach (var item in values)
CB_StructureValues.Items.Add(item);
CB_StructureValues.SelectedIndex = 0;
}
foreach (var entry in HelpDictionary)
CB_StructureType.Items.Add(entry.Key);
CB_StructureType.SelectedIndex = 0;
}
}
private void CB_StructureType_SelectedIndexChanged(object sender, EventArgs e)
{
var name = CB_StructureType.Text;
var values = HelpDictionary[name];
CB_StructureValues.Items.Clear();
CB_StructureValues.Items.AddRange(values);
CB_StructureValues.SelectedIndex = 0;
}
}

View File

@@ -5,193 +5,190 @@
using System.Windows.Forms;
using NHSE.Core;
namespace NHSE.WinForms
namespace NHSE.WinForms;
public partial class BulkSpawn : Form
{
public partial class BulkSpawn : Form
private readonly IItemLayerEditor Editor;
private string NHIFilePath = "";
public BulkSpawn(IItemLayerEditor editor, int x = 0, int y = 0)
{
private readonly IItemLayerEditor Editor;
private string NHIFilePath = "";
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
public BulkSpawn(IItemLayerEditor editor, int x = 0, int y = 0)
Editor = editor;
CB_SpawnType.Items.AddRange(Enum.GetNames<SpawnType>());
CB_SpawnArrange.Items.AddRange(Enum.GetNames<SpawnArrangement>());
CB_SpawnType.SelectedIndex = 0;
CB_SpawnArrange.SelectedIndex = 0;
NUD_SpawnX.Value = x;
NUD_SpawnY.Value = y;
}
private void B_Apply_Click(object sender, EventArgs e)
{
var type = (SpawnType)CB_SpawnType.SelectedIndex;
var arrange = (SpawnArrangement)CB_SpawnArrange.SelectedIndex;
var x = (int)NUD_SpawnX.Value;
var y = (int)NUD_SpawnY.Value;
var count = (int)NUD_SpawnCount.Value;
IReadOnlyList<Item> items;
int sizeX;
int sizeY;
if (type is SpawnType.SequentialDIY or SpawnType.AlphabeticalDIY)
{
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
var min = (ushort)NUD_DIYStart.Value;
var max = (ushort)NUD_DIYStop.Value;
var diy = RecipeList.Recipes
.Where(z => z.Key is not (RecipeList.BridgeConstructionKit or RecipeList.CampsiteConstructionKit) && min <= z.Key && z.Key <= max)
.Select(z => z.Key)
.Select(z => new Item(Item.DIYRecipe) {FreeParam = z});
Editor = editor;
if (type == SpawnType.AlphabeticalDIY)
diy = diy.OrderBy(z => GameInfo.Strings.GetItemName(z));
CB_SpawnType.Items.AddRange(Enum.GetNames(typeof(SpawnType)));
CB_SpawnArrange.Items.AddRange(Enum.GetNames(typeof(SpawnArrangement)));
CB_SpawnType.SelectedIndex = 0;
CB_SpawnArrange.SelectedIndex = 0;
NUD_SpawnX.Value = x;
NUD_SpawnY.Value = y;
items = Enumerable.Repeat(diy, count).SelectMany(z => z).ToArray();
sizeX = sizeY = 2;
}
private void B_Apply_Click(object sender, EventArgs e)
else if (type == SpawnType.ItemsFromNHI)
{
var type = (SpawnType)CB_SpawnType.SelectedIndex;
var arrange = (SpawnArrangement)CB_SpawnArrange.SelectedIndex;
var x = (int)NUD_SpawnX.Value;
var y = (int)NUD_SpawnY.Value;
var count = (int)NUD_SpawnCount.Value;
IReadOnlyList<Item> items;
int sizeX;
int sizeY;
if (type is SpawnType.SequentialDIY or SpawnType.AlphabeticalDIY)
if (string.IsNullOrEmpty(NHIFilePath) || !File.Exists(NHIFilePath))
{
var min = (ushort)NUD_DIYStart.Value;
var max = (ushort)NUD_DIYStop.Value;
var diy = RecipeList.Recipes
.Where(z => z.Key is not RecipeList.BridgeConstructionKit or RecipeList.CampsiteConstructionKit && min <= z.Key && z.Key <= max)
.Select(z => z.Key)
.Select(z => new Item(Item.DIYRecipe) {FreeParam = z});
if (type == SpawnType.AlphabeticalDIY)
diy = diy.OrderBy(x => GameInfo.Strings.GetItemName(x));
items = Enumerable.Repeat(diy, count).SelectMany(z => z).ToArray();
sizeX = sizeY = 2;
}
else if (type == SpawnType.ItemsFromNHI)
{
if (string.IsNullOrEmpty(NHIFilePath) || !File.Exists(NHIFilePath))
{
WinFormsUtil.Alert(MessageStrings.MsgFieldItemNoNHI);
return;
}
// read non-empty slots into item array
var data = File.ReadAllBytes(this.NHIFilePath);
var array = data.GetArray<Item>(Item.SIZE).Where(item => !item.IsNone);
items = Enumerable.Repeat(array, count).SelectMany(z => z).ToArray();
// set flag0 = 0x20 for each item to ensure it gets dropped
// this also forces a 2x2 item size
foreach (Item item in items)
item.SystemParam = 0x20;
sizeX = sizeY = 2;
}
else
{
var item = Editor.ItemProvider.SetItem(new Item());
items = Enumerable.Repeat(item, count).ToArray();
var size = ItemInfo.GetItemSize(item);
sizeX = size.GetWidth();
sizeY = size.GetHeight();
}
if (sizeX % 2 == 1)
sizeX++;
if (sizeY % 2 == 1)
sizeY++;
var ctr = SpawnItems(Editor.SpawnLayer, items, x, y, arrange, sizeX, sizeY, true);
if (ctr == 0)
{
WinFormsUtil.Alert(MessageStrings.MsgFieldItemModifyNone);
WinFormsUtil.Alert(MessageStrings.MsgFieldItemNoNHI);
return;
}
Editor.ReloadItems();
WinFormsUtil.Alert(string.Format(MessageStrings.MsgFieldItemModifyCount, count));
// read non-empty slots into item array
var data = File.ReadAllBytes(NHIFilePath);
var array = data.GetArray<Item>(Item.SIZE).Where(item => !item.IsNone);
items = Enumerable.Repeat(array, count).SelectMany(z => z).ToArray();
// set flag0 = 0x20 for each item to ensure it gets dropped
// this also forces a 2x2 item size
foreach (var item in items)
item.SystemParam = 0x20;
sizeX = sizeY = 2;
}
else
{
var item = Editor.ItemProvider.SetItem(new Item());
items = Enumerable.Repeat(item, count).ToArray();
var size = ItemInfo.GetItemSize(item);
sizeX = size.Width;
sizeY = size.Height;
}
private static int SpawnItems(ItemLayer layer, IReadOnlyList<Item> items, int x, int y, SpawnArrangement arrange, int sizeX, int sizeY, bool noOverwrite)
if (sizeX % 2 == 1)
sizeX++;
if (sizeY % 2 == 1)
sizeY++;
var ctr = SpawnItems(Editor.SpawnLayer, items, x, y, arrange, sizeX, sizeY, true);
if (ctr == 0)
{
// every {setting} tiles, we jump down to the next available row of tiles.
int x0 = x;
var newline = arrange switch
WinFormsUtil.Alert(MessageStrings.MsgFieldItemModifyNone);
return;
}
Editor.ReloadItems();
WinFormsUtil.Alert(string.Format(MessageStrings.MsgFieldItemModifyCount, count));
}
private static int SpawnItems(ItemLayer layer, IReadOnlyList<Item> items, int x, int y, SpawnArrangement arrange, int sizeX, int sizeY, bool noOverwrite)
{
// every {setting} tiles, we jump down to the next available row of tiles.
int x0 = x;
var newline = arrange switch
{
SpawnArrangement.Square => (int)Math.Sqrt(items.Count * sizeX * sizeY),
SpawnArrangement.Vertical => 1 * sizeY,
_ => items.Count * sizeX // Horizontal
};
int ctr = 0;
for (var i = 0; i < items.Count; i++)
{
var item = items[i];
var permission = layer.IsOccupied(item, x, y);
switch (permission)
{
SpawnArrangement.Square => (int)Math.Sqrt(items.Count * sizeX * sizeY),
SpawnArrangement.Vertical => 1 * sizeY,
_ => items.Count * sizeX // Horizontal
};
case PlacedItemPermission.OutOfBounds when y >= layer.MaxHeight:
return ctr;
case PlacedItemPermission.OutOfBounds:
case PlacedItemPermission.Collision when noOverwrite:
i--;
break;
int ctr = 0;
for (var i = 0; i < items.Count; i++)
{
var item = items[i];
var permission = layer.IsOccupied(item, x, y);
switch (permission)
{
case PlacedItemPermission.OutOfBounds when y >= layer.MaxHeight:
return ctr;
case PlacedItemPermission.OutOfBounds:
case PlacedItemPermission.Collision when noOverwrite:
i--;
break;
default:
var exist = layer.GetTile(x, y);
layer.DeleteExtensionTiles(exist, x, y);
default:
var exist = layer.GetTile(x, y);
layer.DeleteExtensionTiles(exist, x, y);
// Set new placed data
layer.SetExtensionTiles(item, x, y);
exist.CopyFrom(item);
ctr++;
break;
}
x += sizeX;
if (x - x0 >= newline)
{
y += sizeY;
x = x0;
}
// Set new placed data
layer.SetExtensionTiles(item, x, y);
exist.CopyFrom(item);
ctr++;
break;
}
return ctr;
}
private void CB_SpawnType_SelectedIndexChanged(object sender, EventArgs e)
{
var index = (SpawnType)CB_SpawnType.SelectedIndex;
L_DIYStart.Visible = L_DIYStop.Visible = NUD_DIYStart.Visible = NUD_DIYStop.Visible = index is SpawnType.SequentialDIY or SpawnType.AlphabeticalDIY;
L_NHI.Visible = L_NHIFileName.Visible = index == SpawnType.ItemsFromNHI;
NUD_SpawnCount.Value = index switch
x += sizeX;
if (x - x0 >= newline)
{
SpawnType.SequentialDIY => 1,
SpawnType.AlphabeticalDIY => 1,
SpawnType.ItemsFromNHI => 1,
_ => 8,
};
if (index == SpawnType.ItemsFromNHI)
{
L_NHIFileName_Click(sender, e);
y += sizeY;
x = x0;
}
}
private void L_NHIFileName_Click(object sender, EventArgs e)
return ctr;
}
private void CB_SpawnType_SelectedIndexChanged(object sender, EventArgs e)
{
var index = (SpawnType)CB_SpawnType.SelectedIndex;
L_DIYStart.Visible = L_DIYStop.Visible = NUD_DIYStart.Visible = NUD_DIYStop.Visible = index is SpawnType.SequentialDIY or SpawnType.AlphabeticalDIY;
L_NHI.Visible = L_NHIFileName.Visible = index == SpawnType.ItemsFromNHI;
NUD_SpawnCount.Value = index switch
{
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Inventory (*.nhi)|*.nhi|All files (*.*)|*.*",
FileName = "items.nhi",
};
SpawnType.SequentialDIY => 1,
SpawnType.AlphabeticalDIY => 1,
SpawnType.ItemsFromNHI => 1,
_ => 8,
};
if (ofd.ShowDialog() != DialogResult.OK)
return;
L_NHIFileName.Text = ofd.SafeFileName;
this.NHIFilePath = ofd.FileName;
}
private enum SpawnType
if (index == SpawnType.ItemsFromNHI)
{
ItemFromEditor,
SequentialDIY,
AlphabeticalDIY,
ItemsFromNHI,
}
private enum SpawnArrangement
{
Square,
Horizontal,
Vertical,
L_NHIFileName_Click(sender, e);
}
}
}
private void L_NHIFileName_Click(object sender, EventArgs e)
{
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons Inventory (*.nhi)|*.nhi|All files (*.*)|*.*";
ofd.FileName = "items.nhi";
if (ofd.ShowDialog() != DialogResult.OK)
return;
L_NHIFileName.Text = ofd.SafeFileName;
this.NHIFilePath = ofd.FileName;
}
private enum SpawnType
{
ItemFromEditor,
SequentialDIY,
AlphabeticalDIY,
ItemsFromNHI,
}
private enum SpawnArrangement
{
Square,
Horizontal,
Vertical,
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,66 +1,65 @@
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using NHSE.Core;
namespace NHSE.WinForms
namespace NHSE.WinForms;
public partial class LandFlagEditor : Form
{
public partial class LandFlagEditor : Form
private readonly short[] Counts;
public LandFlagEditor(short[] counts)
{
private readonly short[] Counts;
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
public LandFlagEditor(short[] counts)
{
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
Counts = counts;
var str = GameInfo.Strings.InternalNameTranslation;
for (ushort i = 0; i < counts.Length; i++)
LB_Counts.Items.Add(EventFlagLand.GetName(i, counts[i], str));
DialogResult = DialogResult.Cancel;
LB_Counts.SelectedIndex = 0;
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_Save_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
private int Index;
private void NUD_Count_ValueChanged(object sender, EventArgs e)
{
if (Index < 0)
return;
Counts[Index] = (short) NUD_Count.Value;
LB_Counts.Items[Index] = EventFlagLand.GetName((ushort)Index, Counts[Index], GameInfo.Strings.InternalNameTranslation);
}
private void LB_Counts_SelectedIndexChanged(object sender, EventArgs e)
{
if (LB_Counts.SelectedIndex < 0)
return;
NUD_Count.Value = Counts[Index = LB_Counts.SelectedIndex];
}
private void B_Dump_Click(object sender, EventArgs e)
{
byte[] data = new byte[Counts.Length * 2];
Buffer.BlockCopy(Counts, 0, data, 0, data.Length);
MiscDumpHelper.DumpFlags(data, nameof(EventFlagLand));
}
private void B_Load_Click(object sender, EventArgs e)
{
var data = MiscDumpHelper.LoadFlags(Counts.Length * 2, nameof(EventFlagLand));
if (data.Length != 0)
Buffer.BlockCopy(data, 0, Counts, 0, data.Length);
LB_Counts.SelectedIndex = LB_Counts.SelectedIndex;
}
Counts = counts;
var str = GameInfo.Strings.InternalNameTranslation;
for (ushort i = 0; i < counts.Length; i++)
LB_Counts.Items.Add(EventFlagLand.GetName(i, counts[i], str));
DialogResult = DialogResult.Cancel;
LB_Counts.SelectedIndex = 0;
}
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_Save_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
private int Index;
private void NUD_Count_ValueChanged(object sender, EventArgs e)
{
if (Index < 0)
return;
Counts[Index] = (short) NUD_Count.Value;
LB_Counts.Items[Index] = EventFlagLand.GetName((ushort)Index, Counts[Index], GameInfo.Strings.InternalNameTranslation);
}
private void LB_Counts_SelectedIndexChanged(object sender, EventArgs e)
{
if (LB_Counts.SelectedIndex < 0)
return;
NUD_Count.Value = Counts[Index = LB_Counts.SelectedIndex];
}
private void B_Dump_Click(object sender, EventArgs e)
{
var data = MemoryMarshal.Cast<short, byte>(Counts);
MiscDumpHelper.DumpFlags(data, nameof(EventFlagLand));
}
private void B_Load_Click(object sender, EventArgs e)
{
var data = MiscDumpHelper.LoadFlags(Counts.Length * 2, nameof(EventFlagLand));
if (data.Length != 0)
Buffer.BlockCopy(data, 0, Counts, 0, data.Length);
LB_Counts.SelectedIndex = LB_Counts.SelectedIndex;
}
}

View File

@@ -1,252 +1,228 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using NHSE.Core;
namespace NHSE.WinForms
namespace NHSE.WinForms;
public static class MapDumpHelper
{
public static class MapDumpHelper
public static bool ImportToLayerAcreSingle(FieldItemLayer layer, int acreIndex, string acre, int layerIndex)
{
public static bool ImportToLayerAcreSingle(FieldItemLayer layer, int acreIndex, string acre, int layerIndex)
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons Field Item Layer (*.nhl)|*.nhl|All files (*.*)|*.*";
ofd.FileName = $"{acre}-{layerIndex}.nhl";
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var fi = new FileInfo(path);
int expect = layer.GridTileCount * Item.SIZE;
if (fi.Length != expect)
{
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Field Item Layer (*.nhl)|*.nhl|All files (*.*)|*.*",
FileName = $"{acre}-{layerIndex}.nhl",
};
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var fi = new FileInfo(path);
int expect = layer.GridTileCount * Item.SIZE;
if (fi.Length != expect)
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expect));
return false;
}
var data = File.ReadAllBytes(path);
layer.ImportAcre(acreIndex, data);
return true;
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expect));
return false;
}
public static bool ImportToLayerAcreAll(FieldItemLayer layer)
{
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Field Item Layer (*.nhl)|*.nhl|All files (*.*)|*.*",
FileName = "acres.nhl",
};
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var fi = new FileInfo(path);
int expect = layer.MaxTileCount * Item.SIZE;
if (fi.Length != expect)
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expect));
return false;
}
var data = File.ReadAllBytes(path);
layer.ImportAll(data);
return true;
}
public static void DumpLayerAcreSingle(FieldItemLayer layer, int acreIndex, string acre, int layerIndex)
{
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Field Item Layer (*.nhl)|*.nhl|All files (*.*)|*.*",
FileName = $"{acre}-{layerIndex}.nhl",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
var path = sfd.FileName;
var data = layer.DumpAcre(acreIndex);
File.WriteAllBytes(path, data);
}
public static void DumpLayerAcreAll(FieldItemLayer layer)
{
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Field Item Layer (*.nhl)|*.nhl|All files (*.*)|*.*",
FileName = "acres.nhl",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
var path = sfd.FileName;
var data = layer.DumpAll();
File.WriteAllBytes(path, data);
}
public static bool ImportTerrainAcre(TerrainLayer m, int acreIndex, string acre)
{
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Terrain (*.nht)|*.nht|All files (*.*)|*.*",
FileName = $"{acre}.nht",
};
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var fi = new FileInfo(path);
int expect = m.GridTileCount * TerrainTile.SIZE;
if (fi.Length != expect)
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expect));
return false;
}
var data = File.ReadAllBytes(path);
m.ImportAcre(acreIndex, data);
return true;
}
public static bool ImportTerrainAll(TerrainLayer m)
{
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Terrain (*.nht)|*.nht|All files (*.*)|*.*",
FileName = "terrainAcres.nht",
};
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var fi = new FileInfo(path);
int expect = m.MaxTileCount * TerrainTile.SIZE;
if (fi.Length != expect)
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expect));
return false;
}
var data = File.ReadAllBytes(path);
m.ImportAll(data);
return true;
}
public static void DumpTerrainAcre(TerrainLayer m, int acreIndex, string acre)
{
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Terrain (*.nht)|*.nht|All files (*.*)|*.*",
FileName = $"{acre}.nht",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
var path = sfd.FileName;
var data = m.DumpAcre(acreIndex);
File.WriteAllBytes(path, data);
}
public static void DumpTerrainAll(TerrainLayer m)
{
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Terrain (*.nht)|*.nht|All files (*.*)|*.*",
FileName = "terrainAcres.nht",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
var path = sfd.FileName;
var data = m.DumpAll();
File.WriteAllBytes(path, data);
}
public static void DumpBuildings(IReadOnlyList<Building> buildings)
{
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Building List (*.nhb)|*.nhb|All files (*.*)|*.*",
FileName = "buildings.nhb",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
var path = sfd.FileName;
byte[] data = Building.SetArray(buildings);
File.WriteAllBytes(path, data);
}
public static bool ImportBuildings(IReadOnlyList<Building> buildings)
{
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Building List (*.nhb)|*.nhb|All files (*.*)|*.*",
FileName = "buildings.nhb",
};
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var fi = new FileInfo(path);
const int expect = Building.SIZE * MainSaveOffsets.BuildingCount; // 46
const int oldSize = Building.SIZE * 40;
if (fi.Length != expect && fi.Length != oldSize)
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expect));
return false;
}
var data = File.ReadAllBytes(path);
var arr = Building.GetArray(data);
for (int i = 0; i < arr.Length; i++)
buildings[i].CopyFrom(arr[i]);
return true;
}
public static bool DumpMapAcresAll(byte[] data)
{
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Acres (*.nha)|*.nha|All files (*.*)|*.*",
FileName = "acres.nha",
};
if (sfd.ShowDialog() != DialogResult.OK)
return false;
File.WriteAllBytes(sfd.FileName, data);
return true;
}
public static bool ImportMapAcresAll(byte[] data)
{
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Acres (*.nha)|*.nha|All files (*.*)|*.*",
FileName = "acres.nha",
};
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var original = data;
var modified = File.ReadAllBytes(path);
if (original.Length != modified.Length)
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, modified.Length, original.Length), path);
return false;
}
modified.CopyTo(data, 0);
return true;
}
var data = File.ReadAllBytes(path);
layer.ImportAcre(acreIndex, data);
return true;
}
}
public static bool ImportToLayerAcreAll(FieldItemLayer layer)
{
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons Field Item Layer (*.nhl)|*.nhl|All files (*.*)|*.*";
ofd.FileName = "acres.nhl";
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var fi = new FileInfo(path);
int expect = layer.MaxTileCount * Item.SIZE;
if (fi.Length != expect)
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expect));
return false;
}
var data = File.ReadAllBytes(path);
layer.ImportAll(data);
return true;
}
public static void DumpLayerAcreSingle(FieldItemLayer layer, int acreIndex, string acre, int layerIndex)
{
using var sfd = new SaveFileDialog();
sfd.Filter = "New Horizons Field Item Layer (*.nhl)|*.nhl|All files (*.*)|*.*";
sfd.FileName = $"{acre}-{layerIndex}.nhl";
if (sfd.ShowDialog() != DialogResult.OK)
return;
var path = sfd.FileName;
var data = layer.DumpAcre(acreIndex);
File.WriteAllBytes(path, data);
}
public static void DumpLayerAcreAll(FieldItemLayer layer)
{
using var sfd = new SaveFileDialog();
sfd.Filter = "New Horizons Field Item Layer (*.nhl)|*.nhl|All files (*.*)|*.*";
sfd.FileName = "acres.nhl";
if (sfd.ShowDialog() != DialogResult.OK)
return;
var path = sfd.FileName;
var data = layer.DumpAll();
File.WriteAllBytes(path, data);
}
public static bool ImportTerrainAcre(TerrainLayer m, int acreIndex, string acre)
{
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons Terrain (*.nht)|*.nht|All files (*.*)|*.*";
ofd.FileName = $"{acre}.nht";
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var fi = new FileInfo(path);
int expect = m.GridTileCount * TerrainTile.SIZE;
if (fi.Length != expect)
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expect));
return false;
}
var data = File.ReadAllBytes(path);
m.ImportAcre(acreIndex, data);
return true;
}
public static bool ImportTerrainAll(TerrainLayer m)
{
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons Terrain (*.nht)|*.nht|All files (*.*)|*.*";
ofd.FileName = "terrainAcres.nht";
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var fi = new FileInfo(path);
int expect = m.MaxTileCount * TerrainTile.SIZE;
if (fi.Length != expect)
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expect));
return false;
}
var data = File.ReadAllBytes(path);
m.ImportAll(data);
return true;
}
public static void DumpTerrainAcre(TerrainLayer m, int acreIndex, string acre)
{
using var sfd = new SaveFileDialog();
sfd.Filter = "New Horizons Terrain (*.nht)|*.nht|All files (*.*)|*.*";
sfd.FileName = $"{acre}.nht";
if (sfd.ShowDialog() != DialogResult.OK)
return;
var path = sfd.FileName;
var data = m.DumpAcre(acreIndex);
File.WriteAllBytes(path, data);
}
public static void DumpTerrainAll(TerrainLayer m)
{
using var sfd = new SaveFileDialog();
sfd.Filter = "New Horizons Terrain (*.nht)|*.nht|All files (*.*)|*.*";
sfd.FileName = "terrainAcres.nht";
if (sfd.ShowDialog() != DialogResult.OK)
return;
var path = sfd.FileName;
var data = m.DumpAll();
File.WriteAllBytes(path, data);
}
public static void DumpBuildings(IReadOnlyList<Building> buildings)
{
using var sfd = new SaveFileDialog();
sfd.Filter = "New Horizons Building List (*.nhb)|*.nhb|All files (*.*)|*.*";
sfd.FileName = "buildings.nhb";
if (sfd.ShowDialog() != DialogResult.OK)
return;
var path = sfd.FileName;
byte[] data = Building.SetArray(buildings);
File.WriteAllBytes(path, data);
}
public static bool ImportBuildings(IReadOnlyList<Building> buildings)
{
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons Building List (*.nhb)|*.nhb|All files (*.*)|*.*";
ofd.FileName = "buildings.nhb";
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var fi = new FileInfo(path);
const int expect = Building.SIZE * MainSaveOffsets.BuildingCount; // 46
const int oldSize = Building.SIZE * 40;
if (fi.Length != expect && fi.Length != oldSize)
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expect));
return false;
}
var data = File.ReadAllBytes(path);
var arr = Building.GetArray(data);
for (int i = 0; i < arr.Length; i++)
buildings[i].CopyFrom(arr[i]);
return true;
}
public static bool DumpMapAcresAll(ReadOnlySpan<byte> data)
{
using var sfd = new SaveFileDialog();
sfd.Filter = "New Horizons Acres (*.nha)|*.nha|All files (*.*)|*.*";
sfd.FileName = "acres.nha";
if (sfd.ShowDialog() != DialogResult.OK)
return false;
File.WriteAllBytes(sfd.FileName, data);
return true;
}
public static bool ImportMapAcresAll(Span<byte> data)
{
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons Acres (*.nha)|*.nha|All files (*.*)|*.*";
ofd.FileName = "acres.nha";
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var original = data;
var modified = File.ReadAllBytes(path);
if (original.Length != modified.Length)
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, modified.Length, original.Length), path);
return false;
}
modified.CopyTo(data);
return true;
}
}

View File

@@ -1,261 +1,241 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using NHSE.Core;
namespace NHSE.WinForms
namespace NHSE.WinForms;
public static class MiscDumpHelper
{
public static class MiscDumpHelper
public static void DumpVillagerMemoryPlayer(IVillager v, GSaveMemory memory)
{
public static void DumpVillagerMemoryPlayer(IVillager v, GSaveMemory memory)
{
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Villager Player Memory (*.nhvpm)|*.nhvpm|All files (*.*)|*.*",
FileName = $"{v.InternalName}.nhvpm",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
using var sfd = new SaveFileDialog();
sfd.Filter = "New Horizons Villager Player Memory (*.nhvpm)|*.nhvpm|All files (*.*)|*.*";
sfd.FileName = $"{v.InternalName}.nhvpm";
if (sfd.ShowDialog() != DialogResult.OK)
return;
var data = memory.Data;
File.WriteAllBytes(sfd.FileName, data);
}
public static bool LoadVillagerMemoryPlayer(IVillager v, GSaveMemory[] memories, int index)
{
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Villager Player Memory (*.nhvpm)|*.nhvpm|All files (*.*)|*.*",
FileName = $"{v.InternalName}.nhvpm",
};
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var file = ofd.FileName;
var fi = new FileInfo(file);
const int expectLength = GSaveMemory.SIZE;
if (fi.Length != expectLength)
{
WinFormsUtil.Error(MessageStrings.MsgCanceling, string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength));
return false;
}
var data = File.ReadAllBytes(file);
var memory = new GSaveMemory(data);
var old = memories[index];
if (!memory.IsOriginatedFrom(old))
{
string msg = string.Format(MessageStrings.MsgDataDidNotOriginateFromHost_0, old.PlayerName);
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, msg, MessageStrings.MsgAskUpdateValues);
if (result == DialogResult.Cancel)
return false;
if (result == DialogResult.Yes)
memory.ChangeOrigins(old, memory.Data);
}
memories[index] = memory;
return true;
}
public static void DumpMuseum(Museum museum)
{
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Museum (*.nhm)|*.nhm|All files (*.*)|*.*",
FileName = "museum.nhm",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
var data = museum.Data;
File.WriteAllBytes(sfd.FileName, data);
}
public static bool LoadMuseum(Museum museum)
{
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Museum (*.nhm)|*.nhm|All files (*.*)|*.*",
FileName = "museum.nhm",
};
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var file = ofd.FileName;
var fi = new FileInfo(file);
const int expectLength = Museum.SIZE;
if (fi.Length != expectLength)
{
WinFormsUtil.Error(MessageStrings.MsgCanceling, string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength));
return false;
}
var data = File.ReadAllBytes(file);
data.CopyTo(museum.Data);
return true;
}
public static void DumpHouse(IReadOnlyList<Player> players, IReadOnlyList<IPlayerHouse> houses, int index, bool dumpAll)
{
if (dumpAll)
DumpAllPlayerHouses(houses, players);
else
DumpPlayerHouse(players, houses, index);
}
private static void DumpPlayerHouse(IReadOnlyList<Player> players, IReadOnlyList<IPlayerHouse> houses, int index)
{
var house = houses[index];
var name = PlayerHouseEditor.GetHouseSummary(players, house, index);
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Player House (*.nhph)|*.nhph|" +
"New Horizons Player House (*.nhph2)|*.nhph2|" +
"All files (*.*)|*.*",
FileName = $"{name}.{house.Extension}",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
var data = house.Write();
File.WriteAllBytes(sfd.FileName, data);
}
private static void DumpAllPlayerHouses(IReadOnlyList<IPlayerHouse> houses, IReadOnlyList<Player> players)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
var dir = Path.GetDirectoryName(fbd.SelectedPath);
if (dir == null || !Directory.Exists(dir))
return;
houses.DumpPlayerHouses(players, fbd.SelectedPath);
}
public static bool LoadHouse(MainSaveOffsets offsets, IReadOnlyList<Player> players, IPlayerHouse[] houses, int index)
{
var h = houses[index];
var name = PlayerHouseEditor.GetHouseSummary(players, houses[index], index);
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Player House (*.nhph)|*.nhph|" +
"New Horizons Player House (*.nhph2)|*.nhph2|" +
"All files (*.*)|*.*",
FileName = $"{name}.{h.Extension}",
};
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var expectLength = offsets.PlayerHouseSize;
var fi = new FileInfo(path);
if (!PlayerHouseConverter.IsCompatible((int)fi.Length, expectLength))
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength), path);
return false;
}
var data = File.ReadAllBytes(ofd.FileName);
data = PlayerHouseConverter.GetCompatible(data, expectLength);
if (data.Length != expectLength)
{
WinFormsUtil.Error(MessageStrings.MsgCanceling, string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength), path);
return false;
}
h = offsets.ReadPlayerHouse(data);
var current = houses[index];
h.NPC1 = current.NPC1;
houses[index] = h;
return true;
}
public static void DumpRoom(IPlayerRoom room, int index)
{
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Player House Room (*.nhpr)|*.nhpr|" +
"New Horizons Player House Room (*.nhpr2)|*.nhpr2|" +
"All files (*.*)|*.*",
FileName = $"Room {index + 1}.{room.Extension}",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
var data = room.Write();
File.WriteAllBytes(sfd.FileName, data);
}
public static bool LoadRoom(MainSaveOffsets offsets, ref IPlayerRoom room, int index)
{
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Player House Room (*.nhpr)|*.nhpr|" +
"New Horizons Player House Room (*.nhpr2)|*.nhpr2|" +
"All files (*.*)|*.*",
FileName = $"Room {index + 1}.{room.Extension}",
};
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var expectLength = offsets.PlayerRoomSize;
var fi = new FileInfo(path);
if (!PlayerRoomConverter.IsCompatible((int)fi.Length, expectLength))
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength), path);
return false;
}
var data = File.ReadAllBytes(ofd.FileName);
data = PlayerRoomConverter.GetCompatible(data, offsets.PlayerRoomSize);
if (data.Length != expectLength)
{
WinFormsUtil.Error(MessageStrings.MsgCanceling, string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength), path);
return false;
}
room = offsets.ReadPlayerRoom(data);
return true;
}
public static void DumpFlags(byte[] data, string name)
{
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Flag List (*.nhfl)|*.nhfl|All files (*.*)|*.*",
FileName = $"{name}.nhfl",
};
if (sfd.ShowDialog() == DialogResult.OK)
File.WriteAllBytes(sfd.FileName, data);
}
public static void DumpFlagsToClipboard(string data)
{
Clipboard.SetData(DataFormats.Text, data);
}
public static byte[] LoadFlags(int size, string name)
{
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Flag List (*.nhfl)|*.nhfl|All files (*.*)|*.*",
FileName = $"{name}.nhfl",
};
if (ofd.ShowDialog() != DialogResult.OK)
return System.Array.Empty<byte>();
var file = ofd.FileName;
var fi = new FileInfo(file);
int expectLength = size;
if (fi.Length != expectLength)
{
WinFormsUtil.Error(MessageStrings.MsgCanceling, string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength));
return System.Array.Empty<byte>();
}
return File.ReadAllBytes(file);
}
var data = memory.Data;
File.WriteAllBytes(sfd.FileName, data);
}
}
public static bool LoadVillagerMemoryPlayer(IVillager v, GSaveMemory[] memories, int index)
{
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons Villager Player Memory (*.nhvpm)|*.nhvpm|All files (*.*)|*.*";
ofd.FileName = $"{v.InternalName}.nhvpm";
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var file = ofd.FileName;
var fi = new FileInfo(file);
const int expectLength = GSaveMemory.SIZE;
if (fi.Length != expectLength)
{
WinFormsUtil.Error(MessageStrings.MsgCanceling, string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength));
return false;
}
var data = File.ReadAllBytes(file);
var memory = new GSaveMemory(data);
var old = memories[index];
if (!memory.IsOriginatedFrom(old))
{
string msg = string.Format(MessageStrings.MsgDataDidNotOriginateFromHost_0, old.PlayerName);
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, msg, MessageStrings.MsgAskUpdateValues);
if (result == DialogResult.Cancel)
return false;
if (result == DialogResult.Yes)
memory.ChangeOrigins(old, memory.Data);
}
memories[index] = memory;
return true;
}
public static void DumpMuseum(Museum museum)
{
using var sfd = new SaveFileDialog();
sfd.Filter = "New Horizons Museum (*.nhm)|*.nhm|All files (*.*)|*.*";
sfd.FileName = "museum.nhm";
if (sfd.ShowDialog() != DialogResult.OK)
return;
var data = museum.Data;
File.WriteAllBytes(sfd.FileName, data);
}
public static bool LoadMuseum(Museum museum)
{
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons Museum (*.nhm)|*.nhm|All files (*.*)|*.*";
ofd.FileName = "museum.nhm";
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var file = ofd.FileName;
var fi = new FileInfo(file);
const int expectLength = Museum.SIZE;
if (fi.Length != expectLength)
{
WinFormsUtil.Error(MessageStrings.MsgCanceling, string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength));
return false;
}
var data = File.ReadAllBytes(file);
data.AsSpan().CopyTo(museum.Data);
return true;
}
public static void DumpHouse(IReadOnlyList<Player> players, IReadOnlyList<IPlayerHouse> houses, int index, bool dumpAll)
{
if (dumpAll)
DumpAllPlayerHouses(houses, players);
else
DumpPlayerHouse(players, houses, index);
}
private static void DumpPlayerHouse(IReadOnlyList<Player> players, IReadOnlyList<IPlayerHouse> houses, int index)
{
var house = houses[index];
var name = PlayerHouseEditor.GetHouseSummary(players, house, index);
using var sfd = new SaveFileDialog();
sfd.Filter = "New Horizons Player House (*.nhph)|*.nhph|" +
"New Horizons Player House (*.nhph2)|*.nhph2|" +
"All files (*.*)|*.*";
sfd.FileName = $"{name}.{house.Extension}";
if (sfd.ShowDialog() != DialogResult.OK)
return;
var data = house.Write();
File.WriteAllBytes(sfd.FileName, data);
}
private static void DumpAllPlayerHouses(IReadOnlyList<IPlayerHouse> houses, IReadOnlyList<Player> players)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
var dir = Path.GetDirectoryName(fbd.SelectedPath);
if (dir == null || !Directory.Exists(dir))
return;
houses.DumpPlayerHouses(players, fbd.SelectedPath);
}
public static bool LoadHouse(MainSaveOffsets offsets, IReadOnlyList<Player> players, IPlayerHouse[] houses, int index)
{
var h = houses[index];
var name = PlayerHouseEditor.GetHouseSummary(players, houses[index], index);
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons Player House (*.nhph)|*.nhph|" +
"New Horizons Player House (*.nhph2)|*.nhph2|" +
"All files (*.*)|*.*";
ofd.FileName = $"{name}.{h.Extension}";
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var expectLength = offsets.PlayerHouseSize;
var fi = new FileInfo(path);
if (!PlayerHouseConverter.IsCompatible((int)fi.Length, expectLength))
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength), path);
return false;
}
var data = File.ReadAllBytes(ofd.FileName);
data = PlayerHouseConverter.GetCompatible(data, expectLength);
if (data.Length != expectLength)
{
WinFormsUtil.Error(MessageStrings.MsgCanceling, string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength), path);
return false;
}
h = offsets.ReadPlayerHouse(data);
var current = houses[index];
h.NPC1 = current.NPC1;
houses[index] = h;
return true;
}
public static void DumpRoom(IPlayerRoom room, int index)
{
using var sfd = new SaveFileDialog();
sfd.Filter = "New Horizons Player House Room (*.nhpr)|*.nhpr|" +
"New Horizons Player House Room (*.nhpr2)|*.nhpr2|" +
"All files (*.*)|*.*";
sfd.FileName = $"Room {index + 1}.{room.Extension}";
if (sfd.ShowDialog() != DialogResult.OK)
return;
var data = room.Write();
File.WriteAllBytes(sfd.FileName, data);
}
public static bool LoadRoom(MainSaveOffsets offsets, ref IPlayerRoom room, int index)
{
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons Player House Room (*.nhpr)|*.nhpr|" +
"New Horizons Player House Room (*.nhpr2)|*.nhpr2|" +
"All files (*.*)|*.*";
ofd.FileName = $"Room {index + 1}.{room.Extension}";
if (ofd.ShowDialog() != DialogResult.OK)
return false;
var path = ofd.FileName;
var expectLength = offsets.PlayerRoomSize;
var fi = new FileInfo(path);
if (!PlayerRoomConverter.IsCompatible((int)fi.Length, expectLength))
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength), path);
return false;
}
var data = File.ReadAllBytes(ofd.FileName);
data = PlayerRoomConverter.GetCompatible(data, offsets.PlayerRoomSize);
if (data.Length != expectLength)
{
WinFormsUtil.Error(MessageStrings.MsgCanceling, string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength), path);
return false;
}
room = offsets.ReadPlayerRoom(data);
return true;
}
public static void DumpFlags(ReadOnlySpan<byte> data, string name)
{
using var sfd = new SaveFileDialog();
sfd.Filter = "New Horizons Flag List (*.nhfl)|*.nhfl|All files (*.*)|*.*";
sfd.FileName = $"{name}.nhfl";
if (sfd.ShowDialog() == DialogResult.OK)
File.WriteAllBytes(sfd.FileName, data);
}
public static void DumpFlagsToClipboard(string data)
{
Clipboard.SetData(DataFormats.Text, data);
}
public static byte[] LoadFlags(int size, string name)
{
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons Flag List (*.nhfl)|*.nhfl|All files (*.*)|*.*";
ofd.FileName = $"{name}.nhfl";
if (ofd.ShowDialog() != DialogResult.OK)
return [];
var file = ofd.FileName;
var fi = new FileInfo(file);
int expectLength = size;
if (fi.Length != expectLength)
{
WinFormsUtil.Error(MessageStrings.MsgCanceling, string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength));
return [];
}
return File.ReadAllBytes(file);
}
}

View File

@@ -2,123 +2,122 @@
using System.Windows.Forms;
using NHSE.Core;
namespace NHSE.WinForms
namespace NHSE.WinForms;
public partial class MuseumEditor : Form
{
public partial class MuseumEditor : Form
private readonly Core.MuseumEditor Editor;
private int Index = -1;
public MuseumEditor(Museum museum)
{
private readonly Core.MuseumEditor Editor;
private int Index = -1;
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
public MuseumEditor(Museum museum)
{
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
Editor = new Core.MuseumEditor(museum);
CAL_Date.MinDate = DateTime.MinValue;
Editor = new Core.MuseumEditor(museum);
CAL_Date.MinDate = DateTime.MinValue;
var str = GameInfo.Strings;
ItemEdit.Initialize(str.ItemDataSource);
for (int i = 0; i < Editor.Dates.Length; i++)
LB_Donations.Items.Add(Editor.GetDonationText(str, i));
var str = GameInfo.Strings;
ItemEdit.Initialize(str.ItemDataSource);
for (int i = 0; i < Editor.Dates.Length; i++)
LB_Donations.Items.Add(Editor.GetDonationText(str, i));
DialogResult = DialogResult.Cancel;
LB_Donations.SelectedIndex = 0;
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_Save_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Editor.Save();
Close();
}
private void LB_Counts_SelectedIndexChanged(object sender, EventArgs e)
{
if (LB_Donations.SelectedIndex < 0 || Changing)
return;
SaveIndex(Index);
Index = LB_Donations.SelectedIndex;
LoadIndex(Index);
}
private void LoadIndex(in int index)
{
if (index < 0)
return;
var date = (DateTime)Editor.Dates[index];
if (date < CAL_Date.MinDate)
date = CAL_Date.MinDate;
CAL_Date.Value = date;
NUD_Player.Value = Editor.Players[index];
ItemEdit.LoadItem(Editor.Items[index]);
}
private void SaveIndex(in int index)
{
if (index < 0)
return;
var date = CAL_Date.Value;
if (date == CAL_Date.MinDate)
date = DateTime.MinValue;
Editor.Dates[index] = date;
Editor.Players[index] = (byte)NUD_Player.Value;
ItemEdit.SetItem(Editor.Items[index]);
SetNameForIndex(index);
}
private bool Changing;
private void SetNameForIndex(in int index)
{
Changing = true;
LB_Donations.Items[index] = Editor.GetDonationText(GameInfo.Strings, index);
Changing = false;
}
private void B_Dump_Click(object sender, EventArgs e)
{
Editor.Save();
MiscDumpHelper.DumpMuseum(Editor.Museum);
}
private void B_Load_Click(object sender, EventArgs e)
{
if (!MiscDumpHelper.LoadMuseum(Editor.Museum))
return;
// data imported, mark as saved and close
DialogResult = DialogResult.OK;
Close();
}
private void B_GiveAll_Click(object sender, EventArgs e)
{
SaveIndex(Index);
Editor.GiveAll(GameInfo.GetStrings("en").itemlist, 1000);
Editor.Save();
System.Media.SystemSounds.Asterisk.Play();
DialogResult = DialogResult.OK;
Close();
}
private void B_SortDate_Click(object sender, EventArgs e)
{
SaveIndex(Index);
Editor.SortAll();
Editor.Save();
System.Media.SystemSounds.Asterisk.Play();
DialogResult = DialogResult.OK;
Close();
}
private static void ShowContextMenuBelow(ToolStripDropDown c, Control n) => c.Show(n.PointToScreen(new System.Drawing.Point(0, n.Height)));
private void B_Tools_Click(object sender, EventArgs e) => ShowContextMenuBelow(CM_Tools, B_Tools);
DialogResult = DialogResult.Cancel;
LB_Donations.SelectedIndex = 0;
}
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_Save_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Editor.Save();
Close();
}
private void LB_Counts_SelectedIndexChanged(object sender, EventArgs e)
{
if (LB_Donations.SelectedIndex < 0 || Changing)
return;
SaveIndex(Index);
Index = LB_Donations.SelectedIndex;
LoadIndex(Index);
}
private void LoadIndex(in int index)
{
if (index < 0)
return;
var date = (DateTime)Editor.Dates[index];
if (date < CAL_Date.MinDate)
date = CAL_Date.MinDate;
CAL_Date.Value = date;
NUD_Player.Value = Editor.Players[index];
ItemEdit.LoadItem(Editor.Items[index]);
}
private void SaveIndex(in int index)
{
if (index < 0)
return;
var date = CAL_Date.Value;
if (date == CAL_Date.MinDate)
date = DateTime.MinValue;
Editor.Dates[index] = date;
Editor.Players[index] = (byte)NUD_Player.Value;
ItemEdit.SetItem(Editor.Items[index]);
SetNameForIndex(index);
}
private bool Changing;
private void SetNameForIndex(in int index)
{
Changing = true;
LB_Donations.Items[index] = Editor.GetDonationText(GameInfo.Strings, index);
Changing = false;
}
private void B_Dump_Click(object sender, EventArgs e)
{
Editor.Save();
MiscDumpHelper.DumpMuseum(Editor.Museum);
}
private void B_Load_Click(object sender, EventArgs e)
{
if (!MiscDumpHelper.LoadMuseum(Editor.Museum))
return;
// data imported, mark as saved and close
DialogResult = DialogResult.OK;
Close();
}
private void B_GiveAll_Click(object sender, EventArgs e)
{
SaveIndex(Index);
Editor.GiveAll(GameInfo.GetStrings("en").itemlist, 1000);
Editor.Save();
System.Media.SystemSounds.Asterisk.Play();
DialogResult = DialogResult.OK;
Close();
}
private void B_SortDate_Click(object sender, EventArgs e)
{
SaveIndex(Index);
Editor.SortAll();
Editor.Save();
System.Media.SystemSounds.Asterisk.Play();
DialogResult = DialogResult.OK;
Close();
}
private static void ShowContextMenuBelow(ToolStripDropDown c, Control n) => c.Show(n.PointToScreen(new System.Drawing.Point(0, n.Height)));
private void B_Tools_Click(object sender, EventArgs e) => ShowContextMenuBelow(CM_Tools, B_Tools);
}

View File

@@ -6,182 +6,174 @@
using NHSE.Core;
using NHSE.Sprites;
namespace NHSE.WinForms
namespace NHSE.WinForms;
public partial class PatternEditor : Form
{
public partial class PatternEditor : Form
private readonly DesignPattern[] Patterns;
private int Index;
private const int scale = 8;
public PatternEditor(DesignPattern[] patterns)
{
private readonly DesignPattern[] Patterns;
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
Patterns = patterns;
DialogResult = DialogResult.Cancel;
private int Index;
private const int scale = 8;
foreach (var p in patterns)
LB_Items.Items.Add(GetPatternSummary(p));
public PatternEditor(DesignPattern[] patterns)
{
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
Patterns = patterns;
DialogResult = DialogResult.Cancel;
foreach (var p in patterns)
LB_Items.Items.Add(GetPatternSummary(p));
LB_Items.SelectedIndex = 0;
SetCM_DLDesign();
}
private void SetCM_DLDesign()
{
var arr = LB_Items.Items.Count == 0
? new ToolStripItem[] { B_DumpDesign, B_LoadDesign }
: new ToolStripItem[] { B_DumpDesign, B_DumpDesignAll, B_LoadDesign, B_LoadDesignAll };
CM_DLDesign.Items.AddRange(arr);
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_Save_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
private void LB_Items_SelectedIndexChanged(object sender, EventArgs e)
{
if (LB_Items.SelectedIndex < 0)
return;
LoadPattern(Patterns[Index = LB_Items.SelectedIndex]);
}
private static string GetPatternSummary(DesignPattern p) => p.DesignName;
private static void ShowContextMenuBelow(ToolStripDropDown c, Control n) => c.Show(n.PointToScreen(new Point(0, n.Height)));
private void B_DumpLoadDesign_Click(object sender, EventArgs e) => ShowContextMenuBelow(CM_DLDesign, B_DumpLoadDesign);
private void B_DumpDesign_Click(object sender, EventArgs e)
{
if (sender == B_DumpDesignAll)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
var dir = Path.GetDirectoryName(fbd.SelectedPath);
if (dir == null || !Directory.Exists(dir))
return;
bool indexed = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MessageStrings.MsgAskExportResultsWithFileIndex) == DialogResult.Yes;
Patterns.Dump(fbd.SelectedPath, indexed);
return;
}
var original = Patterns[Index];
var name = original.DesignName;
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Design Pattern (*.nhd)|*.nhd|All files (*.*)|*.*",
FileName = $"{name}.nhd",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
var d = original;
File.WriteAllBytes(sfd.FileName, d.Data);
}
private void B_LoadDesign_Click(object sender, EventArgs e)
{
if (sender == B_LoadDesignAll)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
var dir = Path.GetDirectoryName(fbd.SelectedPath);
if (dir == null || !Directory.Exists(dir))
return;
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, MessageStrings.MsgAskUpdateValues);
Patterns.Load(fbd.SelectedPath, result == DialogResult.Yes);
LoadPattern(Patterns[Index]);
RepopulateList(Index);
return;
}
var original = Patterns[Index];
var name = original.DesignName;
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Design Pattern (*.nhd)|*.nhd|All files (*.*)|*.*",
FileName = $"{name}.nhd",
};
if (ofd.ShowDialog() != DialogResult.OK)
return;
var file = ofd.FileName;
var expectLength = original.Data.Length;
var fi = new FileInfo(file);
if (fi.Length != expectLength)
{
var msg = string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength);
WinFormsUtil.Error(MessageStrings.MsgCanceling, msg);
return;
}
var data = File.ReadAllBytes(ofd.FileName);
var d = new DesignPattern(data);
var player0 = original;
if (!d.IsOriginatedFrom(player0))
{
var notHost = string.Format(MessageStrings.MsgDataDidNotOriginateFromHost_0, player0.PlayerName);
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, notHost, MessageStrings.MsgAskUpdateValues);
if (result == DialogResult.Cancel)
return;
if (result == DialogResult.Yes)
d.ChangeOrigins(player0, d.Data);
}
Patterns[Index] = d;
LoadPattern(d);
RepopulateList(Index);
}
private void RepopulateList(int index)
{
LB_Items.Items.Clear();
foreach (var p in Patterns)
LB_Items.Items.Add(GetPatternSummary(p));
LB_Items.SelectedIndex = index;
}
private void LoadPattern(DesignPattern designPattern)
{
PB_Pattern.Image = ImageUtil.ResizeImage(designPattern.GetImage(), DesignPattern.Width * scale, DesignPattern.Height * scale);
PB_Palette.Image = ImageUtil.ResizeImage(designPattern.GetPalette(), 150, 10);
L_PatternName.Text = designPattern.DesignName + Environment.NewLine +
designPattern.TownName + Environment.NewLine +
designPattern.PlayerName;
}
private void PB_Pattern_MouseEnter(object sender, EventArgs e) => PB_Pattern.BackColor = Color.GreenYellow;
private void PB_Pattern_MouseLeave(object sender, EventArgs e) => PB_Pattern.BackColor = Color.Transparent;
private void Menu_SavePNG_Click(object sender, EventArgs e)
{
var pb = WinFormsUtil.GetUnderlyingControl<PictureBox>(sender);
if (pb?.Image == null)
{
WinFormsUtil.Alert(MessageStrings.MsgNoPictureLoaded);
return;
}
var name = Patterns[Index].DesignName;
using var sfd = new SaveFileDialog
{
Filter = "png file (*.png)|*.png|All files (*.*)|*.*",
FileName = $"{name}.png",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
var bmp = pb.Image;
bmp.Save(sfd.FileName, ImageFormat.Png);
}
LB_Items.SelectedIndex = 0;
SetCM_DLDesign();
}
}
private void SetCM_DLDesign()
{
var arr = LB_Items.Items.Count == 0
? new ToolStripItem[] { B_DumpDesign, B_LoadDesign }
: new ToolStripItem[] { B_DumpDesign, B_DumpDesignAll, B_LoadDesign, B_LoadDesignAll };
CM_DLDesign.Items.AddRange(arr);
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_Save_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
private void LB_Items_SelectedIndexChanged(object sender, EventArgs e)
{
if (LB_Items.SelectedIndex < 0)
return;
LoadPattern(Patterns[Index = LB_Items.SelectedIndex]);
}
private static string GetPatternSummary(DesignPattern p) => p.DesignName;
private static void ShowContextMenuBelow(ToolStripDropDown c, Control n) => c.Show(n.PointToScreen(new Point(0, n.Height)));
private void B_DumpLoadDesign_Click(object sender, EventArgs e) => ShowContextMenuBelow(CM_DLDesign, B_DumpLoadDesign);
private void B_DumpDesign_Click(object sender, EventArgs e)
{
if (sender == B_DumpDesignAll)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
var dir = Path.GetDirectoryName(fbd.SelectedPath);
if (dir == null || !Directory.Exists(dir))
return;
bool indexed = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MessageStrings.MsgAskExportResultsWithFileIndex) == DialogResult.Yes;
Patterns.Dump(fbd.SelectedPath, indexed);
return;
}
var original = Patterns[Index];
var name = original.DesignName;
using var sfd = new SaveFileDialog();
sfd.Filter = "New Horizons Design Pattern (*.nhd)|*.nhd|All files (*.*)|*.*";
sfd.FileName = $"{name}.nhd";
if (sfd.ShowDialog() != DialogResult.OK)
return;
var d = original;
File.WriteAllBytes(sfd.FileName, d.Data);
}
private void B_LoadDesign_Click(object sender, EventArgs e)
{
if (sender == B_LoadDesignAll)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
var dir = Path.GetDirectoryName(fbd.SelectedPath);
if (dir == null || !Directory.Exists(dir))
return;
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, MessageStrings.MsgAskUpdateValues);
Patterns.Load(fbd.SelectedPath, result == DialogResult.Yes);
LoadPattern(Patterns[Index]);
RepopulateList(Index);
return;
}
var original = Patterns[Index];
var name = original.DesignName;
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons Design Pattern (*.nhd)|*.nhd|All files (*.*)|*.*";
ofd.FileName = $"{name}.nhd";
if (ofd.ShowDialog() != DialogResult.OK)
return;
var file = ofd.FileName;
var expectLength = original.Data.Length;
var fi = new FileInfo(file);
if (fi.Length != expectLength)
{
var msg = string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength);
WinFormsUtil.Error(MessageStrings.MsgCanceling, msg);
return;
}
var data = File.ReadAllBytes(ofd.FileName);
var d = new DesignPattern(data);
var player0 = original;
if (!d.IsOriginatedFrom(player0))
{
var notHost = string.Format(MessageStrings.MsgDataDidNotOriginateFromHost_0, player0.PlayerName);
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, notHost, MessageStrings.MsgAskUpdateValues);
if (result == DialogResult.Cancel)
return;
if (result == DialogResult.Yes)
d.ChangeOrigins(player0, d.Data);
}
Patterns[Index] = d;
LoadPattern(d);
RepopulateList(Index);
}
private void RepopulateList(int index)
{
LB_Items.Items.Clear();
foreach (var p in Patterns)
LB_Items.Items.Add(GetPatternSummary(p));
LB_Items.SelectedIndex = index;
}
private void LoadPattern(DesignPattern designPattern)
{
PB_Pattern.Image = ImageUtil.ResizeImage(designPattern.GetImage(), DesignPattern.Width * scale, DesignPattern.Height * scale);
PB_Palette.Image = ImageUtil.ResizeImage(designPattern.GetPalette(), 150, 10);
L_PatternName.Text = designPattern.DesignName + Environment.NewLine +
designPattern.TownName + Environment.NewLine +
designPattern.PlayerName;
}
private void PB_Pattern_MouseEnter(object sender, EventArgs e) => PB_Pattern.BackColor = Color.GreenYellow;
private void PB_Pattern_MouseLeave(object sender, EventArgs e) => PB_Pattern.BackColor = Color.Transparent;
private void Menu_SavePNG_Click(object sender, EventArgs e)
{
if (!WinFormsUtil.TryGetUnderlying<PictureBox>(sender, out var pb) || pb.Image is null)
{
WinFormsUtil.Alert(MessageStrings.MsgNoPictureLoaded);
return;
}
var name = Patterns[Index].DesignName;
using var sfd = new SaveFileDialog();
sfd.Filter = "png file (*.png)|*.png|All files (*.*)|*.*";
sfd.FileName = $"{name}.png";
if (sfd.ShowDialog() != DialogResult.OK)
return;
var bmp = pb.Image;
bmp.Save(sfd.FileName, ImageFormat.Png);
}
}

View File

@@ -6,187 +6,179 @@
using NHSE.Core;
using NHSE.Sprites;
namespace NHSE.WinForms
namespace NHSE.WinForms;
public partial class PatternEditorPRO : Form
{
public partial class PatternEditorPRO : Form
private readonly DesignPatternPRO[] Patterns;
private int Index;
private const int scale = 4;
public PatternEditorPRO(DesignPatternPRO[] patterns)
{
private readonly DesignPatternPRO[] Patterns;
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
Patterns = patterns;
DialogResult = DialogResult.Cancel;
private int Index;
private const int scale = 4;
foreach (var p in patterns)
LB_Items.Items.Add(GetPatternSummary(p));
public PatternEditorPRO(DesignPatternPRO[] patterns)
{
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
Patterns = patterns;
DialogResult = DialogResult.Cancel;
foreach (var p in patterns)
LB_Items.Items.Add(GetPatternSummary(p));
LB_Items.SelectedIndex = 0;
SetCM_DLDesign();
}
private void SetCM_DLDesign()
{
var arr = LB_Items.Items.Count == 0
? new ToolStripItem[] { B_DumpDesign, B_LoadDesign }
: new ToolStripItem[] { B_DumpDesign, B_DumpDesignAll, B_LoadDesign, B_LoadDesignAll };
CM_DLDesign.Items.AddRange(arr);
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_Save_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
private void LB_Items_SelectedIndexChanged(object sender, EventArgs e)
{
if (LB_Items.SelectedIndex < 0)
return;
LoadPattern(Patterns[Index = LB_Items.SelectedIndex]);
}
private static string GetPatternSummary(DesignPatternPRO p) => p.DesignName;
private static void ShowContextMenuBelow(ToolStripDropDown c, Control n) => c.Show(n.PointToScreen(new Point(0, n.Height)));
private void B_DumpLoadDesign_Click(object sender, EventArgs e) => ShowContextMenuBelow(CM_DLDesign, B_DumpLoadDesign);
private void B_DumpDesign_Click(object sender, EventArgs e)
{
if (sender == B_DumpDesignAll)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
var dir = Path.GetDirectoryName(fbd.SelectedPath);
if (dir == null || !Directory.Exists(dir))
return;
bool indexed = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MessageStrings.MsgAskExportResultsWithFileIndex) == DialogResult.Yes;
Patterns.Dump(fbd.SelectedPath, indexed);
return;
}
var original = Patterns[Index];
var name = original.DesignName;
using var sfd = new SaveFileDialog
{
Filter = "New Horizons PRO Design (*.nhpd)|*.nhpd|All files (*.*)|*.*",
FileName = $"{name}.nhpd",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
var d = original;
File.WriteAllBytes(sfd.FileName, d.Data);
}
private void B_LoadDesign_Click(object sender, EventArgs e)
{
if (sender == B_LoadDesignAll)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
var dir = Path.GetDirectoryName(fbd.SelectedPath);
if (dir == null || !Directory.Exists(dir))
return;
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, MessageStrings.MsgAskUpdateValues);
Patterns.Load(fbd.SelectedPath, result == DialogResult.Yes);
LoadPattern(Patterns[Index]);
RepopulateList(Index);
return;
}
var original = Patterns[Index];
var name = original.DesignName;
using var ofd = new OpenFileDialog
{
Filter = "New Horizons PRO Design (*.nhpd)|*.nhpd|All files (*.*)|*.*",
FileName = $"{name}.nhpd",
};
if (ofd.ShowDialog() != DialogResult.OK)
return;
var file = ofd.FileName;
var expectLength = original.Data.Length;
var fi = new FileInfo(file);
if (fi.Length != expectLength)
{
var msg = string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength);
WinFormsUtil.Error(MessageStrings.MsgCanceling, msg);
return;
}
var data = File.ReadAllBytes(ofd.FileName);
var d = new DesignPatternPRO(data);
var player0 = original;
if (!d.IsOriginatedFrom(player0))
{
var notHost = string.Format(MessageStrings.MsgDataDidNotOriginateFromHost_0, player0.PlayerName);
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, notHost, MessageStrings.MsgAskUpdateValues);
if (result == DialogResult.Cancel)
return;
if (result == DialogResult.Yes)
d.ChangeOrigins(player0, d.Data);
}
Patterns[Index] = d;
LoadPattern(d);
RepopulateList(Index);
}
private void RepopulateList(int index)
{
LB_Items.Items.Clear();
foreach (var p in Patterns)
LB_Items.Items.Add(GetPatternSummary(p));
LB_Items.SelectedIndex = index;
}
private void LoadPattern(DesignPatternPRO dp)
{
const int w = DesignPatternPRO.Width * scale;
const int h = DesignPatternPRO.Height * scale;
PB_Sheet0.Image = ImageUtil.ResizeImage(dp.GetImage(0), w, h);
PB_Sheet1.Image = ImageUtil.ResizeImage(dp.GetImage(1), w, h);
PB_Sheet2.Image = ImageUtil.ResizeImage(dp.GetImage(2), w, h);
PB_Sheet3.Image = ImageUtil.ResizeImage(dp.GetImage(3), w, h);
PB_Palette.Image = ImageUtil.ResizeImage(dp.GetPalette(), 150, 10);
L_PatternName.Text = dp.DesignName + Environment.NewLine +
dp.TownName + Environment.NewLine +
dp.PlayerName;
}
private void PB_Pattern_MouseEnter(object sender, EventArgs e) => PB_Sheet0.BackColor = Color.GreenYellow;
private void PB_Pattern_MouseLeave(object sender, EventArgs e) => PB_Sheet0.BackColor = Color.Transparent;
private void Menu_SavePNG_Click(object sender, EventArgs e)
{
var pb = WinFormsUtil.GetUnderlyingControl<PictureBox>(sender);
if (pb?.Image == null)
{
WinFormsUtil.Alert(MessageStrings.MsgNoPictureLoaded);
return;
}
var name = Patterns[Index].DesignName;
using var sfd = new SaveFileDialog
{
Filter = "png file (*.png)|*.png|All files (*.*)|*.*",
FileName = $"{name}.png",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
var bmp = pb.Image;
bmp.Save(sfd.FileName, ImageFormat.Png);
}
LB_Items.SelectedIndex = 0;
SetCM_DLDesign();
}
}
private void SetCM_DLDesign()
{
var arr = LB_Items.Items.Count == 0
? new ToolStripItem[] { B_DumpDesign, B_LoadDesign }
: new ToolStripItem[] { B_DumpDesign, B_DumpDesignAll, B_LoadDesign, B_LoadDesignAll };
CM_DLDesign.Items.AddRange(arr);
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_Save_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
private void LB_Items_SelectedIndexChanged(object sender, EventArgs e)
{
if (LB_Items.SelectedIndex < 0)
return;
LoadPattern(Patterns[Index = LB_Items.SelectedIndex]);
}
private static string GetPatternSummary(DesignPatternPRO p) => p.DesignName;
private static void ShowContextMenuBelow(ToolStripDropDown c, Control n) => c.Show(n.PointToScreen(new Point(0, n.Height)));
private void B_DumpLoadDesign_Click(object sender, EventArgs e) => ShowContextMenuBelow(CM_DLDesign, B_DumpLoadDesign);
private void B_DumpDesign_Click(object sender, EventArgs e)
{
if (sender == B_DumpDesignAll)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
var dir = Path.GetDirectoryName(fbd.SelectedPath);
if (dir == null || !Directory.Exists(dir))
return;
bool indexed = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MessageStrings.MsgAskExportResultsWithFileIndex) == DialogResult.Yes;
Patterns.Dump(fbd.SelectedPath, indexed);
return;
}
var original = Patterns[Index];
var name = original.DesignName;
using var sfd = new SaveFileDialog();
sfd.Filter = "New Horizons PRO Design (*.nhpd)|*.nhpd|All files (*.*)|*.*";
sfd.FileName = $"{name}.nhpd";
if (sfd.ShowDialog() != DialogResult.OK)
return;
var d = original;
File.WriteAllBytes(sfd.FileName, d.Data);
}
private void B_LoadDesign_Click(object sender, EventArgs e)
{
if (sender == B_LoadDesignAll)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
var dir = Path.GetDirectoryName(fbd.SelectedPath);
if (dir == null || !Directory.Exists(dir))
return;
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, MessageStrings.MsgAskUpdateValues);
Patterns.Load(fbd.SelectedPath, result == DialogResult.Yes);
LoadPattern(Patterns[Index]);
RepopulateList(Index);
return;
}
var original = Patterns[Index];
var name = original.DesignName;
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons PRO Design (*.nhpd)|*.nhpd|All files (*.*)|*.*";
ofd.FileName = $"{name}.nhpd";
if (ofd.ShowDialog() != DialogResult.OK)
return;
var file = ofd.FileName;
var expectLength = original.Data.Length;
var fi = new FileInfo(file);
if (fi.Length != expectLength)
{
var msg = string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength);
WinFormsUtil.Error(MessageStrings.MsgCanceling, msg);
return;
}
var data = File.ReadAllBytes(ofd.FileName);
var d = new DesignPatternPRO(data);
var player0 = original;
if (!d.IsOriginatedFrom(player0))
{
var notHost = string.Format(MessageStrings.MsgDataDidNotOriginateFromHost_0, player0.PlayerName);
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, notHost, MessageStrings.MsgAskUpdateValues);
if (result == DialogResult.Cancel)
return;
if (result == DialogResult.Yes)
d.ChangeOrigins(player0, d.Data);
}
Patterns[Index] = d;
LoadPattern(d);
RepopulateList(Index);
}
private void RepopulateList(int index)
{
LB_Items.Items.Clear();
foreach (var p in Patterns)
LB_Items.Items.Add(GetPatternSummary(p));
LB_Items.SelectedIndex = index;
}
private void LoadPattern(DesignPatternPRO dp)
{
const int w = DesignPatternPRO.Width * scale;
const int h = DesignPatternPRO.Height * scale;
PB_Sheet0.Image = ImageUtil.ResizeImage(dp.GetImage(0), w, h);
PB_Sheet1.Image = ImageUtil.ResizeImage(dp.GetImage(1), w, h);
PB_Sheet2.Image = ImageUtil.ResizeImage(dp.GetImage(2), w, h);
PB_Sheet3.Image = ImageUtil.ResizeImage(dp.GetImage(3), w, h);
PB_Palette.Image = ImageUtil.ResizeImage(dp.GetPalette(), 150, 10);
L_PatternName.Text = dp.DesignName + Environment.NewLine +
dp.TownName + Environment.NewLine +
dp.PlayerName;
}
private void PB_Pattern_MouseEnter(object sender, EventArgs e) => PB_Sheet0.BackColor = Color.GreenYellow;
private void PB_Pattern_MouseLeave(object sender, EventArgs e) => PB_Sheet0.BackColor = Color.Transparent;
private void Menu_SavePNG_Click(object sender, EventArgs e)
{
if (!WinFormsUtil.TryGetUnderlying<PictureBox>(sender, out var pb) || pb.Image is null)
{
WinFormsUtil.Alert(MessageStrings.MsgNoPictureLoaded);
return;
}
var name = Patterns[Index].DesignName;
using var sfd = new SaveFileDialog();
sfd.Filter = "png file (*.png)|*.png|All files (*.*)|*.*";
sfd.FileName = $"{name}.png";
if (sfd.ShowDialog() != DialogResult.OK)
return;
var bmp = pb.Image;
bmp.Save(sfd.FileName, ImageFormat.Png);
}
}

View File

@@ -5,316 +5,316 @@
using NHSE.Core;
using NHSE.Sprites;
namespace NHSE.WinForms
namespace NHSE.WinForms;
public partial class PlayerHouseEditor : Form
{
public partial class PlayerHouseEditor : Form
private readonly MainSave SAV;
private readonly IPlayerHouse[] Houses;
private readonly IReadOnlyList<Player> Players;
private RoomItemManager Manager;
private const int scale = 24;
private int Index = -1;
private int RoomIndex = -1;
public PlayerHouseEditor(IPlayerHouse[] houses, IReadOnlyList<Player> players, MainSave sav, int index)
{
private readonly MainSave SAV;
private readonly IPlayerHouse[] Houses;
private readonly IReadOnlyList<Player> Players;
private RoomItemManager Manager;
private const int scale = 24;
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
SAV = sav;
Houses = houses;
Players = players;
Manager = new RoomItemManager(houses[0].GetRoom(0));
private int Index = -1;
private int RoomIndex = -1;
var data = GameInfo.Strings.ItemDataSource;
ItemEdit.Initialize(data, true);
public PlayerHouseEditor(IPlayerHouse[] houses, IReadOnlyList<Player> players, MainSave sav, int index)
DialogResult = DialogResult.Cancel;
for (var i = 0; i < Houses.Length; i++)
{
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
SAV = sav;
Houses = houses;
Players = players;
Manager = new RoomItemManager(houses[0].GetRoom(0));
var data = GameInfo.Strings.ItemDataSource;
ItemEdit.Initialize(data, true);
DialogResult = DialogResult.Cancel;
for (var i = 0; i < Houses.Length; i++)
{
var obj = Houses[i];
LB_Items.Items.Add(GetHouseSummary(players, obj, i));
}
LB_Items.SelectedIndex = index;
var obj = Houses[i];
LB_Items.Items.Add(GetHouseSummary(players, obj, i));
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
LB_Items.SelectedIndex = index;
}
private void B_Save_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
SaveRoom();
Close();
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void SaveRoom()
private void B_Save_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
SaveRoom();
Close();
}
private void SaveRoom()
{
if (RoomIndex < 0)
return;
Manager.Save();
var house = Houses[Index];
house.SetRoom(RoomIndex, Manager.Room);
}
private void LB_Items_SelectedIndexChanged(object sender, EventArgs e)
{
if (LB_Items.SelectedIndex < 0)
return;
SaveRoom();
var house = Houses[Index = LB_Items.SelectedIndex];
PG_Item.SelectedObject = house;
ChangeRoom(house);
}
private void PG_Item_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
{
LB_Items.Items[Index] = GetHouseSummary(Players, Houses[Index], Index);
}
public static string GetHouseSummary(IReadOnlyList<Player> players, IPlayerHouse house, int index)
{
var houseName = index >= players.Count ? $"House {index}" : $"{players[index].Personal.PlayerName}'s House";
return $"{houseName} (lv {house.HouseLevel})";
}
private void B_DumpHouse_Click(object sender, EventArgs e)
{
MiscDumpHelper.DumpHouse(Players, Houses, Index, ModifierKeys == Keys.Shift);
}
private void B_LoadHouse_Click(object sender, EventArgs e)
{
if (!MiscDumpHelper.LoadHouse(SAV.Offsets, Players, Houses, Index))
return;
RoomIndex = -1;
var house = Houses[Index];
PG_Item.SelectedObject = house;
ChangeRoom(house);
}
private void B_EditFlags_Click(object sender, EventArgs e)
{
var flags = Houses[Index].EventFlags;
var edit = flags.ToArray();
using var editor = new PlayerHouseFlagEditor(edit);
if (editor.ShowDialog() == DialogResult.OK)
edit.CopyTo(flags);
}
private int HoverX;
private int HoverY;
private void PB_Room_MouseMove(object sender, MouseEventArgs e)
{
var l = CurrentLayer;
var oldTile = l.GetTile(HoverX, HoverY);
var tile = GetTile(l, e, out var x, out var y);
if (ReferenceEquals(tile, oldTile))
return;
var str = GameInfo.Strings;
var name = str.GetItemName(tile);
TT_Hover.SetToolTip(PB_Room, name);
SetCoordinateText(x, y, name);
}
private void SetCoordinateText(int x, int y, string name) => L_Coordinates.Text = $"({x:000},{y:000}) = {name}";
private Item GetTile(ItemLayer layer, MouseEventArgs e, out int x, out int y)
{
SetHoveredItem(e);
return layer.GetTile(x = HoverX, y = HoverY);
}
private void SetHoveredItem(MouseEventArgs e)
{
GetCoordinates(e, out HoverX, out HoverY);
// Mouse event may fire with a slightly too large x/y; clamp just in case.
Manager.Layers[0].ClampCoordinatesInsideGrid(ref HoverX, ref HoverY);
}
private static void GetCoordinates(MouseEventArgs e, out int x, out int y)
{
x = e.X / scale;
y = e.Y / scale;
}
private void ChangeRoom(IPlayerHouse house)
{
RoomIndex = (int) NUD_Room.Value - 1;
ReloadManager(house);
DrawLayer();
}
private void ReloadManager(IPlayerHouse house)
{
var unsupported = Manager.GetUnsupportedTiles();
if (unsupported.Count != 0)
WinFormsUtil.Alert(MessageStrings.MsgFieldItemUnsupportedLayer2Tile);
var room = house.GetRoom(RoomIndex);
Manager = new RoomItemManager(room);
}
private void DrawLayer() => DrawRoom(CurrentLayer);
private void DrawRoom(ItemLayer layer)
{
var w = layer.MaxWidth;
var h = layer.MaxHeight;
Span<int> scale1 = stackalloc int[w * h];
int[] scaleX = new int[scale * scale * scale1.Length];
var bmp = new Bitmap(scale * w, scale * h);
PB_Room.Image = ItemLayerSprite.GetBitmapItemLayerViewGrid(layer, 0, 0, scale, scale1, scaleX, bmp, gridlineColor: 0x7F000000);
}
private void NUD_Room_ValueChanged(object sender, EventArgs e)
{
ChangeRoom(Houses[Index]);
}
private void NUD_Layer_ValueChanged(object sender, EventArgs e)
{
DrawLayer();
}
#region Item Editing
private void PlayerHouseEditor_Click(object sender, MouseEventArgs e)
{
var tile = GetTile(CurrentLayer, e, out var x, out var y);
OmniTile(tile, x, y);
}
private void OmniTile(Item tile, int x, int y)
{
switch (ModifierKeys)
{
if (RoomIndex < 0)
default:
ViewTile(tile, x, y);
return;
Manager.Save();
var house = Houses[Index];
house.SetRoom(RoomIndex, Manager.Room);
}
private void LB_Items_SelectedIndexChanged(object sender, EventArgs e)
{
if (LB_Items.SelectedIndex < 0)
case Keys.Shift:
SetTile(tile, x, y);
return;
SaveRoom();
var house = Houses[Index = LB_Items.SelectedIndex];
PG_Item.SelectedObject = house;
ChangeRoom(house);
}
private void PG_Item_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
{
LB_Items.Items[Index] = GetHouseSummary(Players, Houses[Index], Index);
}
public static string GetHouseSummary(IReadOnlyList<Player> players, IPlayerHouse house, int index)
{
var houseName = index >= players.Count ? $"House {index}" : $"{players[index].Personal.PlayerName}'s House";
return $"{houseName} (lv {house.HouseLevel})";
}
private void B_DumpHouse_Click(object sender, EventArgs e)
{
MiscDumpHelper.DumpHouse(Players, Houses, Index, ModifierKeys == Keys.Shift);
}
private void B_LoadHouse_Click(object sender, EventArgs e)
{
if (!MiscDumpHelper.LoadHouse(SAV.Offsets, Players, Houses, Index))
case Keys.Alt:
DeleteTile(tile, x, y);
return;
RoomIndex = -1;
var house = Houses[Index];
PG_Item.SelectedObject = house;
ChangeRoom(house);
}
private void B_EditFlags_Click(object sender, EventArgs e)
{
var flags = Houses[Index].GetEventFlags();
using var editor = new PlayerHouseFlagEditor(flags);
if (editor.ShowDialog() == DialogResult.OK)
Houses[Index].SetEventFlags(flags);
}
private int HoverX;
private int HoverY;
private void PB_Room_MouseMove(object sender, MouseEventArgs e)
{
var l = CurrentLayer;
var oldTile = l.GetTile(HoverX, HoverY);
var tile = GetTile(l, e, out var x, out var y);
if (ReferenceEquals(tile, oldTile))
return;
var str = GameInfo.Strings;
var name = str.GetItemName(tile);
TT_Hover.SetToolTip(PB_Room, name);
SetCoordinateText(x, y, name);
}
private void SetCoordinateText(int x, int y, string name) => L_Coordinates.Text = $"({x:000},{y:000}) = {name}";
private Item GetTile(ItemLayer layer, MouseEventArgs e, out int x, out int y)
{
SetHoveredItem(e);
return layer.GetTile(x = HoverX, y = HoverY);
}
private void SetHoveredItem(MouseEventArgs e)
{
GetCoordinates(e, out HoverX, out HoverY);
// Mouse event may fire with a slightly too large x/y; clamp just in case.
Manager.Layers[0].ClampCoordinatesInsideGrid(ref HoverX, ref HoverY);
}
private static void GetCoordinates(MouseEventArgs e, out int x, out int y)
{
x = e.X / scale;
y = e.Y / scale;
}
private void ChangeRoom(IPlayerHouse house)
{
RoomIndex = (int) NUD_Room.Value - 1;
ReloadManager(house);
DrawLayer();
}
private void ReloadManager(IPlayerHouse house)
{
var unsupported = Manager.GetUnsupportedTiles();
if (unsupported.Count != 0)
WinFormsUtil.Alert(MessageStrings.MsgFieldItemUnsupportedLayer2Tile);
var room = house.GetRoom(RoomIndex);
Manager = new RoomItemManager(room);
}
private void DrawLayer() => DrawRoom(CurrentLayer);
private void DrawRoom(ItemLayer layer)
{
var w = layer.MaxWidth;
var h = layer.MaxHeight;
int[] scale1 = new int[w * h];
int[] scaleX = new int[scale * scale * scale1.Length];
var bmp = new Bitmap(scale * w, scale * h);
PB_Room.Image = ItemLayerSprite.GetBitmapItemLayerViewGrid(layer, 0, 0, scale, scale1, scaleX, bmp, gridlineColor: 0x7F000000);
}
private void NUD_Room_ValueChanged(object sender, EventArgs e)
{
ChangeRoom(Houses[Index]);
}
private void NUD_Layer_ValueChanged(object sender, EventArgs e)
{
DrawLayer();
}
#region Item Editing
private void PlayerHouseEditor_Click(object sender, MouseEventArgs e)
{
var tile = GetTile(CurrentLayer, e, out var x, out var y);
OmniTile(tile, x, y);
}
private void OmniTile(Item tile, int x, int y)
{
switch (ModifierKeys)
{
default:
ViewTile(tile, x, y);
return;
case Keys.Shift:
SetTile(tile, x, y);
return;
case Keys.Alt:
DeleteTile(tile, x, y);
return;
}
}
private void Menu_View_Click(object sender, EventArgs e)
{
var x = HoverX;
var y = HoverY;
var tile = CurrentLayer.GetTile(x, y);
ViewTile(tile, x, y);
}
private void Menu_Set_Click(object sender, EventArgs e)
{
var x = HoverX;
var y = HoverY;
var tile = CurrentLayer.GetTile(x, y);
SetTile(tile, x, y);
}
private void Menu_Reset_Click(object sender, EventArgs e)
{
var x = HoverX;
var y = HoverY;
var tile = CurrentLayer.GetTile(x, y);
DeleteTile(tile, x, y);
}
private ItemLayer CurrentLayer => Manager.Layers[(int)NUD_Layer.Value - 1];
private void ViewTile(Item tile, int x, int y)
{
if (CHK_RedirectExtensionLoad.Checked && tile.IsExtension)
{
var l = CurrentLayer;
var rx = Math.Max(0, Math.Min(l.MaxWidth - 1, x - tile.ExtensionX));
var ry = Math.Max(0, Math.Min(l.MaxHeight - 1, y - tile.ExtensionY));
var redir = l.GetTile(rx, ry);
if (redir.IsRoot && redir.ItemId == tile.ExtensionItemId)
tile = redir;
}
ViewTile(tile);
}
private void ViewTile(Item tile)
{
ItemEdit.LoadItem(tile);
}
private void SetTile(Item tile, int x, int y)
{
var l = CurrentLayer;
var pgt = new Item();
ItemEdit.SetItem(pgt);
var permission = l.IsOccupied(pgt, x, y);
switch (permission)
{
case PlacedItemPermission.OutOfBounds:
case PlacedItemPermission.Collision when CHK_NoOverwrite.Checked:
System.Media.SystemSounds.Asterisk.Play();
return;
}
// Clean up original placed data
if (tile.IsRoot && CHK_AutoExtension.Checked)
l.DeleteExtensionTiles(tile, x, y);
// Set new placed data
if (pgt.IsRoot && CHK_AutoExtension.Checked)
l.SetExtensionTiles(pgt, x, y);
tile.CopyFrom(pgt);
DrawLayer();
}
private void DeleteTile(Item tile, int x, int y)
{
if (CHK_AutoExtension.Checked)
{
if (!tile.IsRoot)
{
x -= tile.ExtensionX;
y -= tile.ExtensionY;
tile = CurrentLayer.GetTile(x, y);
}
CurrentLayer.DeleteExtensionTiles(tile, x, y);
}
tile.Delete();
DrawLayer();
}
#endregion
private void B_LoadRoom_Click(object sender, EventArgs e)
{
var room = Manager.Room;
MiscDumpHelper.LoadRoom(SAV.Offsets, ref room, RoomIndex);
var house = Houses[Index];
house.SetRoom(RoomIndex, room);
ReloadManager(house);
DrawLayer();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_DumpRoom_Click(object sender, EventArgs e)
{
SaveRoom();
MiscDumpHelper.DumpRoom(Manager.Room, RoomIndex);
}
}
}
private void Menu_View_Click(object sender, EventArgs e)
{
var x = HoverX;
var y = HoverY;
var tile = CurrentLayer.GetTile(x, y);
ViewTile(tile, x, y);
}
private void Menu_Set_Click(object sender, EventArgs e)
{
var x = HoverX;
var y = HoverY;
var tile = CurrentLayer.GetTile(x, y);
SetTile(tile, x, y);
}
private void Menu_Reset_Click(object sender, EventArgs e)
{
var x = HoverX;
var y = HoverY;
var tile = CurrentLayer.GetTile(x, y);
DeleteTile(tile, x, y);
}
private ItemLayer CurrentLayer => Manager.Layers[(int)NUD_Layer.Value - 1];
private void ViewTile(Item tile, int x, int y)
{
if (CHK_RedirectExtensionLoad.Checked && tile.IsExtension)
{
var l = CurrentLayer;
var rx = Math.Max(0, Math.Min(l.MaxWidth - 1, x - tile.ExtensionX));
var ry = Math.Max(0, Math.Min(l.MaxHeight - 1, y - tile.ExtensionY));
var redir = l.GetTile(rx, ry);
if (redir.IsRoot && redir.ItemId == tile.ExtensionItemId)
tile = redir;
}
ViewTile(tile);
}
private void ViewTile(Item tile)
{
ItemEdit.LoadItem(tile);
}
private void SetTile(Item tile, int x, int y)
{
var l = CurrentLayer;
var pgt = new Item();
ItemEdit.SetItem(pgt);
var permission = l.IsOccupied(pgt, x, y);
switch (permission)
{
case PlacedItemPermission.OutOfBounds:
case PlacedItemPermission.Collision when CHK_NoOverwrite.Checked:
System.Media.SystemSounds.Asterisk.Play();
return;
}
// Clean up original placed data
if (tile.IsRoot && CHK_AutoExtension.Checked)
l.DeleteExtensionTiles(tile, x, y);
// Set new placed data
if (pgt.IsRoot && CHK_AutoExtension.Checked)
l.SetExtensionTiles(pgt, x, y);
tile.CopyFrom(pgt);
DrawLayer();
}
private void DeleteTile(Item tile, int x, int y)
{
if (CHK_AutoExtension.Checked)
{
if (!tile.IsRoot)
{
x -= tile.ExtensionX;
y -= tile.ExtensionY;
tile = CurrentLayer.GetTile(x, y);
}
CurrentLayer.DeleteExtensionTiles(tile, x, y);
}
tile.Delete();
DrawLayer();
}
#endregion
private void B_LoadRoom_Click(object sender, EventArgs e)
{
var room = Manager.Room;
MiscDumpHelper.LoadRoom(SAV.Offsets, ref room, RoomIndex);
var house = Houses[Index];
house.SetRoom(RoomIndex, room);
ReloadManager(house);
DrawLayer();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_DumpRoom_Click(object sender, EventArgs e)
{
SaveRoom();
MiscDumpHelper.DumpRoom(Manager.Room, RoomIndex);
}
}

View File

@@ -2,64 +2,63 @@
using System.Windows.Forms;
using NHSE.Core;
namespace NHSE.WinForms
namespace NHSE.WinForms;
public partial class PlayerHouseFlagEditor : Form
{
public partial class PlayerHouseFlagEditor : Form
private readonly short[] Counts;
public PlayerHouseFlagEditor(short[] counts)
{
private readonly short[] Counts;
public PlayerHouseFlagEditor(short[] counts)
{
Counts = counts;
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
var str = GameInfo.Strings.InternalNameTranslation;
for (ushort i = 0; i < counts.Length; i++)
LB_Counts.Items.Add(EventFlagHouse.GetName(i, counts[i], str));
DialogResult = DialogResult.Cancel;
LB_Counts.SelectedIndex = 0;
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_Save_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
private int Index;
private void NUD_Count_ValueChanged(object sender, EventArgs e)
{
if (Index < 0)
return;
Counts[Index] = (short) NUD_Count.Value;
LB_Counts.Items[Index] = EventFlagHouse.GetName((ushort)Index, Counts[Index], GameInfo.Strings.InternalNameTranslation);
}
private void LB_Counts_SelectedIndexChanged(object sender, EventArgs e)
{
if (LB_Counts.SelectedIndex < 0)
return;
NUD_Count.Value = Counts[Index = LB_Counts.SelectedIndex];
}
private void B_Dump_Click(object sender, EventArgs e)
{
byte[] data = new byte[Counts.Length * 2];
Buffer.BlockCopy(Counts, 0, data, 0, data.Length);
MiscDumpHelper.DumpFlags(data, nameof(EventFlagHouse));
}
private void B_Load_Click(object sender, EventArgs e)
{
var data = MiscDumpHelper.LoadFlags(Counts.Length * 2, nameof(EventFlagHouse));
if (data.Length != 0)
Buffer.BlockCopy(data, 0, Counts, 0, data.Length);
LB_Counts.SelectedIndex = LB_Counts.SelectedIndex;
}
Counts = counts;
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
var str = GameInfo.Strings.InternalNameTranslation;
for (ushort i = 0; i < counts.Length; i++)
LB_Counts.Items.Add(EventFlagHouse.GetName(i, counts[i], str));
DialogResult = DialogResult.Cancel;
LB_Counts.SelectedIndex = 0;
}
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_Save_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
private int Index;
private void NUD_Count_ValueChanged(object sender, EventArgs e)
{
if (Index < 0)
return;
Counts[Index] = (short) NUD_Count.Value;
LB_Counts.Items[Index] = EventFlagHouse.GetName((ushort)Index, Counts[Index], GameInfo.Strings.InternalNameTranslation);
}
private void LB_Counts_SelectedIndexChanged(object sender, EventArgs e)
{
if (LB_Counts.SelectedIndex < 0)
return;
NUD_Count.Value = Counts[Index = LB_Counts.SelectedIndex];
}
private void B_Dump_Click(object sender, EventArgs e)
{
byte[] data = new byte[Counts.Length * 2];
Buffer.BlockCopy(Counts, 0, data, 0, data.Length);
MiscDumpHelper.DumpFlags(data, nameof(EventFlagHouse));
}
private void B_Load_Click(object sender, EventArgs e)
{
var data = MiscDumpHelper.LoadFlags(Counts.Length * 2, nameof(EventFlagHouse));
if (data.Length != 0)
Buffer.BlockCopy(data, 0, Counts, 0, data.Length);
LB_Counts.SelectedIndex = LB_Counts.SelectedIndex;
}
}

View File

@@ -1,309 +1,286 @@
using NHSE.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace NHSE.WinForms.Subforms.Map
namespace NHSE.WinForms.Subforms.Map;
public partial class TerrainBrushEditor : Form
{
public partial class TerrainBrushEditor : Form
public readonly PropertyGrid PG_TerrainTile;
private readonly FieldItemEditor FIEWindow;
public TrackBar Slider_thickness => slider_thickness;
public bool IsBrushSelected;
public bool RandomizeVariation;
public TerrainBrushEditor(PropertyGrid pG_TerrainTile, FieldItemEditor fieWindow)
{
public PropertyGrid PG_TerrainTile;
private FieldItemEditor FIEWindow;
public TrackBar Slider_thickness { get => slider_thickness; }
public bool brushSelected;
public bool randomizeVariation;
public TerrainBrushEditor(PropertyGrid pG_TerrainTile, FieldItemEditor fieWindow)
{
InitializeComponent();
PG_TerrainTile = pG_TerrainTile;
FIEWindow = fieWindow;
}
#region Tiles buttons
#region Dirt tiles
private void NW_Rounded_Tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3B,
LandMakingAngle = 0,
Elevation = (ushort)slider_elevation.Value,
};
private void N_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff5B,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void NE_rounded_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3B,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void W_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff5B,
LandMakingAngle = 0,
Elevation = (ushort)slider_elevation.Value,
};
private void Middle_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
Elevation = (ushort)slider_elevation.Value,
};
private void E_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff5B,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void SW_rounded_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3B,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
private void S_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff5B,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
private void SE_rounded_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3B,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void NW_angular_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3C,
Elevation = (ushort)slider_elevation.Value,
};
private void NE_angular_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3C,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void SW_angular_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3C,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
private void SE_angular_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3C,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void TR_dirt_inside_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff7A,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void DL_dirt_inside_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff7A,
Elevation = (ushort)slider_elevation.Value,
};
private void DR_dirt_inside_Click(object sender, EventArgs e)
{
PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff7A,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
}
#endregion Dirt tiles
#region Water tiles
private void NW_diagonal_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3B,
Elevation = (ushort)slider_elevation.Value,
};
private void N_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River5B,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void NE_diagonal_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3B,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void W_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River5B,
Elevation = (ushort)slider_elevation.Value,
};
private void Center_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River8A,
Elevation = (ushort)slider_elevation.Value,
};
private void e_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River5B,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void sw_diagonal_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3B,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
private void s_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River5B,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
private void SE_diagonal_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3B,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void NW_angular_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3C,
Elevation = (ushort)slider_elevation.Value,
};
private void NE_angular_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3C,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void SW_angular_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3C,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
private void SE_angular_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3C,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void TL_dirt_inside_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff7A,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void TL_water_inside_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River7A,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void TR_water_inside_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River7A,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void DL_water_inside_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River7A,
Elevation = (ushort)slider_elevation.Value,
};
private void DR_water_inside_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River7A,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
#endregion Water tiles
#endregion Tiles buttons
private void SliderThicknessValueChanged(object sender, EventArgs e)
{
lbl_size_count.Text = slider_thickness.Value.ToString();
}
private void SliderElevationValueChanged(object sender, EventArgs e)
{
lbl_elevation_count.Text = slider_elevation.Value.ToString();
TerrainTile currentTile = (TerrainTile)PG_TerrainTile.SelectedObject;
currentTile.Elevation = (ushort)slider_elevation.Value;
PG_TerrainTile.SelectedObject = currentTile;
}
private void B_Brush_Click(object sender, EventArgs e)
{
brushSelected = true;
}
private void TerrainBrushEditor_FormClosed(object sender, FormClosedEventArgs e)
{
brushSelected = false;
}
private void B_Normal_Click(object sender, EventArgs e)
{
brushSelected = false;
}
private void CB_TileVariation_CheckedChanged(object sender, EventArgs e)
{
randomizeVariation = cb_tileVariation.Checked;
}
PG_TerrainTile = pG_TerrainTile;
FIEWindow = fieWindow;
InitializeComponent();
}
#region Tiles buttons
#region Dirt tiles
private void NW_Rounded_Tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3B,
LandMakingAngle = 0,
Elevation = (ushort)slider_elevation.Value,
};
private void N_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff5B,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void NE_rounded_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3B,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void W_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff5B,
LandMakingAngle = 0,
Elevation = (ushort)slider_elevation.Value,
};
private void Middle_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
Elevation = (ushort)slider_elevation.Value,
};
private void E_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff5B,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void SW_rounded_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3B,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
private void S_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff5B,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
private void SE_rounded_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3B,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void NW_angular_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3C,
Elevation = (ushort)slider_elevation.Value,
};
private void NE_angular_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3C,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void SW_angular_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3C,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
private void SE_angular_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff3C,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void TR_dirt_inside_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff7A,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void DL_dirt_inside_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff7A,
Elevation = (ushort)slider_elevation.Value,
};
private void DR_dirt_inside_Click(object sender, EventArgs e)
{
PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff7A,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
}
#endregion Dirt tiles
#region Water tiles
private void NW_diagonal_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3B,
Elevation = (ushort)slider_elevation.Value,
};
private void N_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River5B,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void NE_diagonal_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3B,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void W_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River5B,
Elevation = (ushort)slider_elevation.Value,
};
private void Center_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River8A,
Elevation = (ushort)slider_elevation.Value,
};
private void e_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River5B,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void sw_diagonal_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3B,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
private void s_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River5B,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
private void SE_diagonal_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3B,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void NW_angular_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3C,
Elevation = (ushort)slider_elevation.Value,
};
private void NE_angular_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3C,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void SW_angular_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3C,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
private void SE_angular_water_tile_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River3C,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void TL_dirt_inside_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.Cliff7A,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void TL_water_inside_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River7A,
LandMakingAngle = 3,
Elevation = (ushort)slider_elevation.Value,
};
private void TR_water_inside_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River7A,
LandMakingAngle = 2,
Elevation = (ushort)slider_elevation.Value,
};
private void DL_water_inside_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River7A,
Elevation = (ushort)slider_elevation.Value,
};
private void DR_water_inside_Click(object sender, EventArgs e) => PG_TerrainTile.SelectedObject = new TerrainTile
{
UnitModel = TerrainUnitModel.River7A,
LandMakingAngle = 1,
Elevation = (ushort)slider_elevation.Value,
};
#endregion Water tiles
#endregion Tiles buttons
private void SliderThicknessValueChanged(object sender, EventArgs e)
{
lbl_size_count.Text = slider_thickness.Value.ToString();
}
private void SliderElevationValueChanged(object sender, EventArgs e)
{
lbl_elevation_count.Text = slider_elevation.Value.ToString();
TerrainTile currentTile = (TerrainTile)PG_TerrainTile.SelectedObject!;
currentTile.Elevation = (ushort)slider_elevation.Value;
PG_TerrainTile.SelectedObject = currentTile;
}
private void B_Brush_Click(object sender, EventArgs e) => IsBrushSelected = true;
private void TerrainBrushEditor_FormClosed(object sender, FormClosedEventArgs e) => IsBrushSelected = false;
private void B_Normal_Click(object sender, EventArgs e) => IsBrushSelected = false;
private void CB_TileVariation_CheckedChanged(object sender, EventArgs e) => RandomizeVariation = cb_tileVariation.Checked;
}

View File

@@ -4,133 +4,128 @@
using System.Windows.Forms;
using NHSE.Core;
namespace NHSE.WinForms
namespace NHSE.WinForms;
public partial class VillagerHouseEditor : Form
{
public partial class VillagerHouseEditor : Form
private readonly MainSave SAV;
private readonly IVillagerHouse[] Houses;
private readonly IReadOnlyList<IVillager> Villagers;
private int Index;
public VillagerHouseEditor(IVillagerHouse[] houses, IReadOnlyList<IVillager> villagers, MainSave sav, int index)
{
private readonly MainSave SAV;
private readonly IVillagerHouse[] Houses;
private readonly IReadOnlyList<IVillager> Villagers;
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
SAV = sav;
Houses = houses;
Villagers = villagers;
DialogResult = DialogResult.Cancel;
private int Index;
foreach (var obj in Houses)
LB_Items.Items.Add(GetHouseSummary(obj));
public VillagerHouseEditor(IVillagerHouse[] houses, IReadOnlyList<IVillager> villagers, MainSave sav, int index)
{
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
SAV = sav;
Houses = houses;
Villagers = villagers;
DialogResult = DialogResult.Cancel;
foreach (var obj in Houses)
LB_Items.Items.Add(GetHouseSummary(obj));
var hIndex = Array.FindIndex(houses, z => z.NPC1 == index);
if (hIndex < 0)
hIndex = 0;
LB_Items.SelectedIndex = hIndex;
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_Save_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
private void LB_Items_SelectedIndexChanged(object sender, EventArgs e)
{
if (LB_Items.SelectedIndex < 0)
return;
PG_Item.SelectedObject = Houses[Index = LB_Items.SelectedIndex];
}
private void PG_Item_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
{
LB_Items.Items[Index] = GetHouseSummary(Houses[Index]);
}
private string GetHouseSummary(IVillagerHouse house) => $"{GetVillagerName(house)}'s House";
private string GetVillagerName(IVillagerHouse house)
{
var villagerIndex = house.NPC1;
var v = (uint) villagerIndex >= Villagers.Count ? "???" : Villagers[villagerIndex].InternalName;
var name = GameInfo.Strings.GetVillager(v);
return name;
}
private void B_DumpHouse_Click(object sender, EventArgs e)
{
if (ModifierKeys == Keys.Shift)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
var dir = Path.GetDirectoryName(fbd.SelectedPath);
if (dir == null || !Directory.Exists(dir))
return;
SAV.DumpVillagerHouses(fbd.SelectedPath);
return;
}
var h = Houses[Index];
var name = GetVillagerName(h);
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Villager House (*.nhvh)|*.nhvh|" +
"New Horizons Villager House (*.nhvh2)|*.nhvh2|" +
"All files (*.*)|*.*",
FileName = $"{name}.{h.Extension}",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
var data = h.Write();
File.WriteAllBytes(sfd.FileName, data);
}
private void B_LoadHouse_Click(object sender, EventArgs e)
{
var h = Houses[Index];
var name = GetVillagerName(Houses[Index]);
if (name == "???")
name = "*";
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Villager House (*.nhvh)|*.nhvh|" +
"New Horizons Villager House (*.nhvh2)|*.nhvh2|" +
"All files (*.*)|*.*",
FileName = $"{name}.{h.Extension}",
};
if (ofd.ShowDialog() != DialogResult.OK)
return;
var path = ofd.FileName;
var expectLength = SAV.Offsets.VillagerHouseSize;
var fi = new FileInfo(path);
if (!VillagerHouseConverter.IsCompatible((int)fi.Length, expectLength))
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength), path);
return;
}
var data = File.ReadAllBytes(ofd.FileName);
data = VillagerHouseConverter.GetCompatible(data, expectLength);
if (data.Length != expectLength)
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength), path);
return;
}
h = SAV.Offsets.ReadVillagerHouse(data);
var current = Houses[Index];
h.NPC1 = current.NPC1;
Houses[Index] = h;
PG_Item.SelectedObject = h;
}
var hIndex = Array.FindIndex(houses, z => z.NPC1 == index);
if (hIndex < 0)
hIndex = 0;
LB_Items.SelectedIndex = hIndex;
}
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_Save_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
private void LB_Items_SelectedIndexChanged(object sender, EventArgs e)
{
if (LB_Items.SelectedIndex < 0)
return;
PG_Item.SelectedObject = Houses[Index = LB_Items.SelectedIndex];
}
private void PG_Item_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
{
LB_Items.Items[Index] = GetHouseSummary(Houses[Index]);
}
private string GetHouseSummary(IVillagerHouse house) => $"{GetVillagerName(house)}'s House";
private string GetVillagerName(IVillagerHouse house)
{
var villagerIndex = house.NPC1;
var v = (uint) villagerIndex >= Villagers.Count ? "???" : Villagers[villagerIndex].InternalName;
var name = GameInfo.Strings.GetVillager(v);
return name;
}
private void B_DumpHouse_Click(object sender, EventArgs e)
{
if (ModifierKeys == Keys.Shift)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
var dir = Path.GetDirectoryName(fbd.SelectedPath);
if (dir == null || !Directory.Exists(dir))
return;
SAV.DumpVillagerHouses(fbd.SelectedPath);
return;
}
var h = Houses[Index];
var name = GetVillagerName(h);
using var sfd = new SaveFileDialog();
sfd.Filter = "New Horizons Villager House (*.nhvh)|*.nhvh|" +
"New Horizons Villager House (*.nhvh2)|*.nhvh2|" +
"All files (*.*)|*.*";
sfd.FileName = $"{name}.{h.Extension}";
if (sfd.ShowDialog() != DialogResult.OK)
return;
var data = h.Write();
File.WriteAllBytes(sfd.FileName, data);
}
private void B_LoadHouse_Click(object sender, EventArgs e)
{
var h = Houses[Index];
var name = GetVillagerName(Houses[Index]);
if (name == "???")
name = "*";
using var ofd = new OpenFileDialog();
ofd.Filter = "New Horizons Villager House (*.nhvh)|*.nhvh|" +
"New Horizons Villager House (*.nhvh2)|*.nhvh2|" +
"All files (*.*)|*.*";
ofd.FileName = $"{name}.{h.Extension}";
if (ofd.ShowDialog() != DialogResult.OK)
return;
var path = ofd.FileName;
var expectLength = SAV.Offsets.VillagerHouseSize;
var fi = new FileInfo(path);
if (!VillagerHouseConverter.IsCompatible((int)fi.Length, expectLength))
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength), path);
return;
}
Memory<byte> data = File.ReadAllBytes(ofd.FileName);
data = VillagerHouseConverter.GetCompatible(data, expectLength);
if (data.Length != expectLength)
{
WinFormsUtil.Error(string.Format(MessageStrings.MsgDataSizeMismatchImport, fi.Length, expectLength), path);
return;
}
h = SAV.Offsets.ReadVillagerHouse(data);
var current = Houses[Index];
h.NPC1 = current.NPC1;
Houses[Index] = h;
PG_Item.SelectedObject = h;
}
}