mirror of
https://github.com/kwsch/NHSE.git
synced 2026-09-29 13:26:51 -05:00
Update to .NET 10 (#683)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user