NHSE/NHSE.WinForms/Controls/VillagerEditor.cs
Kurt 345f3c3f1b Add howto hint for removing a villager
Closes #84

ty @PandaUnit-TWL
2020-04-19 16:56:03 -07:00

242 lines
8.4 KiB
C#

using System;
using System.IO;
using System.Windows.Forms;
using NHSE.Core;
using NHSE.Sprites;
namespace NHSE.WinForms
{
public partial class VillagerEditor : UserControl
{
public Villager[] Villagers;
public IVillagerOrigin Origin;
private readonly MainSave SAV;
private int VillagerIndex = -1;
private bool Loading;
public VillagerEditor(Villager[] villagers, IVillagerOrigin origin, MainSave sav, bool hasHouses)
{
Villagers = villagers;
Origin = origin;
SAV = sav;
InitializeComponent();
LoadVillagers();
if (!hasHouses)
B_DumpHouse.Visible = B_LoadHouse.Visible = false;
}
public void Save() => SaveVillager(VillagerIndex);
private void LoadVillagers()
{
CB_Personality.Items.Clear();
var personalities = Enum.GetNames(typeof(VillagerPersonality));
foreach (var p in personalities)
CB_Personality.Items.Add(p);
VillagerIndex = -1;
LoadVillager(0);
}
private void LoadVillager(object sender, EventArgs e) => LoadVillager((int)NUD_Villager.Value - 1);
private void LoadVillager(int index)
{
if (VillagerIndex >= 0)
SaveVillager(VillagerIndex);
if (index < 0)
return;
LoadVillager(Villagers[index]);
VillagerIndex = index;
}
private void LoadVillager(Villager v)
{
Loading = true;
NUD_Species.Value = v.Species;
NUD_Variant.Value = v.Variant;
CB_Personality.SelectedIndex = (int)v.Personality;
TB_Catchphrase.Text = v.CatchPhrase;
CHK_VillagerMovingOut.Checked = v.MovingOut;
Loading = false;
}
private void SaveVillager(int index)
{
var v = Villagers[index];
v.Species = (byte)NUD_Species.Value;
v.Variant = (byte)NUD_Variant.Value;
v.Personality = (VillagerPersonality)CB_Personality.SelectedIndex;
v.CatchPhrase = TB_Catchphrase.Text;
v.MovingOut = CHK_VillagerMovingOut.Checked;
}
private void CHK_VillagerMovingOut_CheckedChanged(object sender, EventArgs e)
{
if (Loading)
return;
if (!CHK_VillagerMovingOut.Checked)
return;
const string question = "Are you trying to make the Villager move out?";
const string reply = "If so, set the Event Flag (024 - ForceMoveOut) to 1 so that the Villager is removed by the game.";
WinFormsUtil.Alert(question, reply);
}
private void B_DumpVillager_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;
Villagers.DumpVillagers(fbd.SelectedPath);
return;
}
var name = L_ExternalName.Text;
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Villager (*.nhv)|*.nhv|All files (*.*)|*.*",
FileName = $"{name}.nhv",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
SaveVillager(VillagerIndex);
var v = Villagers[VillagerIndex];
File.WriteAllBytes(sfd.FileName, v.Data);
}
private void B_LoadVillager_Click(object sender, EventArgs e)
{
var name = L_ExternalName.Text;
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Villager (*.nhv)|*.nhv|All files (*.*)|*.*",
FileName = $"{name}.nhv",
};
if (ofd.ShowDialog() != DialogResult.OK)
return;
var file = ofd.FileName;
var original = Villagers[VillagerIndex];
var expectLength = original.Data.Length;
var fi = new FileInfo(file);
if (fi.Length != expectLength)
{
var msg = $"Imported villager's data length (0x{fi.Length:X}) does not match the required length (0x{expectLength:X}).";
WinFormsUtil.Error("Cancelling:", msg);
return;
}
var data = File.ReadAllBytes(ofd.FileName);
var v = new Villager(data);
var player0 = Origin;
if (!v.IsOriginatedFrom(player0))
{
const string msg = "Imported Villager did not originate from Resident Rep's data.";
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, msg, "Update values?");
if (result == DialogResult.Cancel)
return;
if (result == DialogResult.Yes)
v.ChangeOrigins(player0, v.Data);
}
LoadVillager(Villagers[VillagerIndex] = v);
}
private void B_EditFurniture_Click(object sender, EventArgs e)
{
var v = Villagers[VillagerIndex];
var items = v.Furniture;
using var editor = new PlayerItemEditor<VillagerItem>(items, 8, 2);
if (editor.ShowDialog() == DialogResult.OK)
v.Furniture = items;
}
private void B_EditVillagerFlags_Click(object sender, EventArgs e)
{
var v = Villagers[VillagerIndex];
var flags = v.GetEventFlagsSave();
using var editor = new VillagerFlagEditor(flags);
if (editor.ShowDialog() == DialogResult.OK)
v.SetEventFlagsSave(flags);
}
private string GetCurrentVillagerInternalName() => VillagerUtil.GetInternalVillagerName((VillagerSpecies)NUD_Species.Value, (int)NUD_Variant.Value);
private void ChangeVillager(object sender, EventArgs e) => ChangeVillager();
private void ChangeVillager()
{
var name = GetCurrentVillagerInternalName();
L_InternalName.Text = name;
L_ExternalName.Text = GameInfo.Strings.GetVillager(name);
PB_Villager.Image = VillagerSprite.GetVillagerSprite(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 name = L_ExternalName.Text;
using var sfd = new SaveFileDialog
{
Filter = "New Horizons Villager House (*.nhvh)|*.nhvh|All files (*.*)|*.*",
FileName = $"{name}.nhvh",
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
var h = SAV.GetVillagerHouse(VillagerIndex);
var data = h.ToBytesClass();
File.WriteAllBytes(sfd.FileName, data);
}
private void B_LoadHouse_Click(object sender, EventArgs e)
{
var name = L_ExternalName.Text;
using var ofd = new OpenFileDialog
{
Filter = "New Horizons Villager House (*.nhvh)|*.nhvh|All files (*.*)|*.*",
FileName = $"{name}.nhvh",
};
if (ofd.ShowDialog() != DialogResult.OK)
return;
var file = ofd.FileName;
var fi = new FileInfo(file);
const int expectLength = VillagerHouse.SIZE;
if (fi.Length != expectLength)
{
var msg = $"Imported villager house's data length (0x{fi.Length:X}) does not match the required length (0x{expectLength:X}).";
WinFormsUtil.Error("Cancelling:", msg);
return;
}
var data = File.ReadAllBytes(file);
var h = data.ToClass<VillagerHouse>();
SAV.SetVillagerHouse(h, VillagerIndex);
}
}
}