diff --git a/NHSE.Core/Save/Files/MainSave.cs b/NHSE.Core/Save/Files/MainSave.cs index 35b59de..8e006a0 100644 --- a/NHSE.Core/Save/Files/MainSave.cs +++ b/NHSE.Core/Save/Files/MainSave.cs @@ -72,6 +72,20 @@ public void SetVillagerHouse(VillagerHouse h, int index) h.ToBytesClass().CopyTo(Data, Offsets.NpcHouseList + (index * VillagerHouse.SIZE)); } + public VillagerHouse[] GetVillagerHouses() + { + var villagers = new VillagerHouse[VillagerCount]; + for (int i = 0; i < villagers.Length; i++) + villagers[i] = GetVillagerHouse(i); + return villagers; + } + + public void SetVillagerHouses(IReadOnlyList houses) + { + for (int i = 0; i < houses.Count; i++) + SetVillagerHouse(houses[i], i); + } + private const int EventFlagsSaveCount = 0x400; public short[] GetEventFlagLand() diff --git a/NHSE.Core/Structures/Building/DoorKind.cs b/NHSE.Core/Structures/Building/DoorKind.cs index 2be2b3b..d7101e7 100644 --- a/NHSE.Core/Structures/Building/DoorKind.cs +++ b/NHSE.Core/Structures/Building/DoorKind.cs @@ -1,6 +1,6 @@ namespace NHSE.Core { - public enum DoorKind + public enum DoorKind : ushort { HouseDoorStandardAR = 0x00, HouseDoorStandardAS = 0x02, diff --git a/NHSE.Core/Structures/Villager/IHouseInfo.cs b/NHSE.Core/Structures/Villager/IHouseInfo.cs index a7af586..6eb23c9 100644 --- a/NHSE.Core/Structures/Villager/IHouseInfo.cs +++ b/NHSE.Core/Structures/Villager/IHouseInfo.cs @@ -3,12 +3,12 @@ public interface IHouseInfo { uint HouseLevel { get; set; } - ushort WallUniqueID { get; set; } - ushort RoofUniqueID { get; set; } - ushort DoorUniqueID { get; set; } - ushort OrderWallUniqueID { get; set; } - ushort OrderRoofUniqueID { get; set; } - ushort OrderDoorUniqueID { get; set; } + WallType WallUniqueID { get; set; } + RoofType RoofUniqueID { get; set; } + DoorKind DoorUniqueID { get; set; } + WallType OrderWallUniqueID { get; set; } + RoofType OrderRoofUniqueID { get; set; } + DoorKind OrderDoorUniqueID { get; set; } GSaveItemName DoorDecoItemName { get; set; } } diff --git a/NHSE.Core/Structures/Villager/PlayerHouse.cs b/NHSE.Core/Structures/Villager/PlayerHouse.cs index 05a4e82..0372d4f 100644 --- a/NHSE.Core/Structures/Villager/PlayerHouse.cs +++ b/NHSE.Core/Structures/Villager/PlayerHouse.cs @@ -8,12 +8,12 @@ public class PlayerHouse : IHouseInfo public const int SIZE = 0x26400; [field: FieldOffset(0x000)] public uint HouseLevel { get; set; } - [field: FieldOffset(0x004)] public ushort WallUniqueID { get; set; } - [field: FieldOffset(0x006)] public ushort RoofUniqueID { get; set; } - [field: FieldOffset(0x008)] public ushort DoorUniqueID { get; set; } - [field: FieldOffset(0x00A)] public ushort OrderWallUniqueID { get; set; } - [field: FieldOffset(0x00C)] public ushort OrderRoofUniqueID { get; set; } - [field: FieldOffset(0x00E)] public ushort OrderDoorUniqueID { get; set; } + [field: FieldOffset(0x004)] public WallType WallUniqueID { get; set; } + [field: FieldOffset(0x006)] public RoofType RoofUniqueID { get; set; } + [field: FieldOffset(0x008)] public DoorKind DoorUniqueID { get; set; } + [field: FieldOffset(0x00A)] public WallType OrderWallUniqueID { get; set; } + [field: FieldOffset(0x00C)] public RoofType OrderRoofUniqueID { get; set; } + [field: FieldOffset(0x00E)] public DoorKind OrderDoorUniqueID { get; set; } [field: FieldOffset(0x263D4)] public GSaveItemName DoorDecoItemName { get; set; } diff --git a/NHSE.Core/Structures/Villager/VillagerHouse.cs b/NHSE.Core/Structures/Villager/VillagerHouse.cs index 1509dd1..714c87b 100644 --- a/NHSE.Core/Structures/Villager/VillagerHouse.cs +++ b/NHSE.Core/Structures/Villager/VillagerHouse.cs @@ -10,12 +10,12 @@ public class VillagerHouse : IHouseInfo [field: FieldOffset(0x000)] public uint HouseLevel { get; set; } [field: FieldOffset(0x004)] public uint HouseStatus { get; set; } - [field: FieldOffset(0x008)] public ushort WallUniqueID { get; set; } - [field: FieldOffset(0x00A)] public ushort RoofUniqueID { get; set; } - [field: FieldOffset(0x00C)] public ushort DoorUniqueID { get; set; } - [field: FieldOffset(0x00E)] public ushort OrderWallUniqueID { get; set; } - [field: FieldOffset(0x010)] public ushort OrderRoofUniqueID { get; set; } - [field: FieldOffset(0x012)] public ushort OrderDoorUniqueID { get; set; } + [field: FieldOffset(0x008)] public WallType WallUniqueID { get; set; } + [field: FieldOffset(0x00A)] public RoofType RoofUniqueID { get; set; } + [field: FieldOffset(0x00C)] public DoorKind DoorUniqueID { get; set; } + [field: FieldOffset(0x00E)] public WallType OrderWallUniqueID { get; set; } + [field: FieldOffset(0x010)] public RoofType OrderRoofUniqueID { get; set; } + [field: FieldOffset(0x012)] public DoorKind OrderDoorUniqueID { get; set; } [field: FieldOffset(0x1C4)] public sbyte NPC1 { get; set; } [field: FieldOffset(0x1C5)] public sbyte NPC2 { get; set; } diff --git a/NHSE.WinForms/Controls/VillagerEditor.Designer.cs b/NHSE.WinForms/Controls/VillagerEditor.Designer.cs index 96c38fc..d8d564e 100644 --- a/NHSE.WinForms/Controls/VillagerEditor.Designer.cs +++ b/NHSE.WinForms/Controls/VillagerEditor.Designer.cs @@ -46,8 +46,7 @@ private void InitializeComponent() this.PB_Villager = new System.Windows.Forms.PictureBox(); this.L_VillagerID = new System.Windows.Forms.Label(); this.NUD_Villager = new System.Windows.Forms.NumericUpDown(); - this.B_LoadHouse = new System.Windows.Forms.Button(); - this.B_DumpHouse = new System.Windows.Forms.Button(); + this.B_EditHouses = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.NUD_Variant)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.NUD_Species)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.PB_Villager)).BeginInit(); @@ -77,7 +76,7 @@ private void InitializeComponent() // // B_EditFurniture // - this.B_EditFurniture.Location = new System.Drawing.Point(199, 119); + this.B_EditFurniture.Location = new System.Drawing.Point(297, 165); this.B_EditFurniture.Name = "B_EditFurniture"; this.B_EditFurniture.Size = new System.Drawing.Size(92, 40); this.B_EditFurniture.TabIndex = 44; @@ -226,51 +225,30 @@ private void InitializeComponent() // this.NUD_Villager.Location = new System.Drawing.Point(96, 3); this.NUD_Villager.Maximum = new decimal(new int[] { - 10, - 0, - 0, - 0}); - this.NUD_Villager.Minimum = new decimal(new int[] { - 1, + 9, 0, 0, 0}); this.NUD_Villager.Name = "NUD_Villager"; this.NUD_Villager.Size = new System.Drawing.Size(37, 20); this.NUD_Villager.TabIndex = 29; - this.NUD_Villager.Value = new decimal(new int[] { - 1, - 0, - 0, - 0}); this.NUD_Villager.ValueChanged += new System.EventHandler(this.LoadVillager); // - // B_LoadHouse + // B_EditHouses // - this.B_LoadHouse.Location = new System.Drawing.Point(297, 165); - this.B_LoadHouse.Name = "B_LoadHouse"; - this.B_LoadHouse.Size = new System.Drawing.Size(92, 40); - this.B_LoadHouse.TabIndex = 48; - this.B_LoadHouse.Text = "Load House"; - this.B_LoadHouse.UseVisualStyleBackColor = true; - this.B_LoadHouse.Click += new System.EventHandler(this.B_LoadHouse_Click); - // - // B_DumpHouse - // - this.B_DumpHouse.Location = new System.Drawing.Point(199, 165); - this.B_DumpHouse.Name = "B_DumpHouse"; - this.B_DumpHouse.Size = new System.Drawing.Size(92, 40); - this.B_DumpHouse.TabIndex = 47; - this.B_DumpHouse.Text = "Dump House"; - this.B_DumpHouse.UseVisualStyleBackColor = true; - this.B_DumpHouse.Click += new System.EventHandler(this.B_DumpHouse_Click); + this.B_EditHouses.Location = new System.Drawing.Point(199, 165); + this.B_EditHouses.Name = "B_EditHouses"; + this.B_EditHouses.Size = new System.Drawing.Size(92, 40); + this.B_EditHouses.TabIndex = 47; + this.B_EditHouses.Text = "Edit House"; + this.B_EditHouses.UseVisualStyleBackColor = true; + this.B_EditHouses.Click += new System.EventHandler(this.B_EditHouse_Click); // // VillagerEditor // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.B_LoadHouse); - this.Controls.Add(this.B_DumpHouse); + this.Controls.Add(this.B_EditHouses); this.Controls.Add(this.B_EditVillagerFlags); this.Controls.Add(this.CHK_VillagerMovingOut); this.Controls.Add(this.B_EditFurniture); @@ -320,7 +298,6 @@ private void InitializeComponent() private System.Windows.Forms.PictureBox PB_Villager; private System.Windows.Forms.Label L_VillagerID; private System.Windows.Forms.NumericUpDown NUD_Villager; - private System.Windows.Forms.Button B_LoadHouse; - private System.Windows.Forms.Button B_DumpHouse; + private System.Windows.Forms.Button B_EditHouses; } } diff --git a/NHSE.WinForms/Controls/VillagerEditor.cs b/NHSE.WinForms/Controls/VillagerEditor.cs index 18dfbc6..454c56d 100644 --- a/NHSE.WinForms/Controls/VillagerEditor.cs +++ b/NHSE.WinForms/Controls/VillagerEditor.cs @@ -16,14 +16,13 @@ public partial class VillagerEditor : UserControl public VillagerEditor(Villager[] villagers, IVillagerOrigin origin, MainSave sav, bool hasHouses) { + InitializeComponent(); Villagers = villagers; Origin = origin; SAV = sav; - InitializeComponent(); LoadVillagers(); - if (!hasHouses) - B_DumpHouse.Visible = B_LoadHouse.Visible = false; + B_EditHouses.Visible = hasHouses; } public void Save() => SaveVillager(VillagerIndex); @@ -39,7 +38,7 @@ private void LoadVillagers() LoadVillager(0); } - private void LoadVillager(object sender, EventArgs e) => LoadVillager((int)NUD_Villager.Value - 1); + private void LoadVillager(object sender, EventArgs e) => LoadVillager((int)NUD_Villager.Value); private void LoadVillager(int index) { @@ -180,61 +179,13 @@ private void ChangeVillager() PB_Villager.Image = VillagerSprite.GetVillagerSprite(name); } - private void B_DumpHouse_Click(object sender, EventArgs e) + private void B_EditHouse_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(MessageStrings.MsgCanceling, msg); - return; - } - - var data = File.ReadAllBytes(file); - var h = data.ToClass(); - var current = SAV.GetVillagerHouse(VillagerIndex); - h.NPC1 = current.NPC1; - SAV.SetVillagerHouse(h, VillagerIndex); + var villagers = SAV.GetVillagers(); + var houses = SAV.GetVillagerHouses(); + using var editor = new VillagerHouseEditor(houses, villagers, SAV, VillagerIndex); + if (editor.ShowDialog() == DialogResult.OK) + SAV.SetVillagerHouses(houses); } } } diff --git a/NHSE.WinForms/Editor.cs b/NHSE.WinForms/Editor.cs index 13f1760..61a92a2 100644 --- a/NHSE.WinForms/Editor.cs +++ b/NHSE.WinForms/Editor.cs @@ -19,15 +19,15 @@ public Editor(HorizonSave file) { InitializeComponent(); - Menu_Language.SelectedIndex = 0; // en -- triggers translation - // this.TranslateInterface(GameInfo.CurrentLanguage); - SAV = file; LoadPlayers(); LoadMain(); Villagers = LoadVillagers(); + Menu_Language.SelectedIndex = 0; // en -- triggers translation + // this.TranslateInterface(GameInfo.CurrentLanguage); + Text = SAV.GetSaveTitle("NHSE"); } @@ -240,9 +240,16 @@ private void LoadPlayer(int index) NUD_NookMiles.Value = Math.Min(int.MaxValue, pers.NookMiles.Value); NUD_Wallet.Value = Math.Min(int.MaxValue, pers.Wallet.Value); - var photo = pers.GetPhotoData(); - var bmp = new Bitmap(new MemoryStream(photo)); - PB_Player.Image = bmp; + try + { + var photo = pers.GetPhotoData(); + PB_Player.Image = new Bitmap(new MemoryStream(photo)); + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } PlayerIndex = index; } diff --git a/NHSE.WinForms/NHSE.WinForms.csproj b/NHSE.WinForms/NHSE.WinForms.csproj index 7a07efc..e6d8f30 100644 --- a/NHSE.WinForms/NHSE.WinForms.csproj +++ b/NHSE.WinForms/NHSE.WinForms.csproj @@ -43,6 +43,9 @@ Form + + Form + Form diff --git a/NHSE.WinForms/Resources/text/lang_en.txt b/NHSE.WinForms/Resources/text/lang_en.txt index 590653e..6cbc46c 100644 --- a/NHSE.WinForms/Resources/text/lang_en.txt +++ b/NHSE.WinForms/Resources/text/lang_en.txt @@ -8,6 +8,7 @@ SimpleHexEditor=RAM Edit SysBotRAMEdit=SysBotUI SysBotUI=SysBotUI TerrainEditor=Terrain Editor +VillagerHouseEditor=Villager House Editor AcreEditor.B_Cancel=Cancel AcreEditor.B_Export=Export AcreEditor.B_Import=Import @@ -37,10 +38,13 @@ BuildingEditor.L_StructureType=Structure Type: BuildingEditor.L_StructureValues=Values: Editor.B_DumpDesign=Dump Design Editor.B_DumpHouse=Dump House +Editor.B_DumpVillager=Dump Villager Editor.B_EditAchievements=Edit Achievements Editor.B_EditAcres=Edit Acres Editor.B_EditBuildings=Edit Buildings Editor.B_EditFieldItems=Edit Field Items +Editor.B_EditFurniture=Edit Furniture +Editor.B_EditHouses=Edit House Editor.B_EditLandFlags=Edit Flags Editor.B_EditPlayerFlags=Edit Flags Editor.B_EditPlayerItems=Edit Items @@ -49,16 +53,24 @@ Editor.B_EditPlayerRecipes=Edit Recipes Editor.B_EditPlayerStorage=Edit Storage Editor.B_EditTerrain=Edit Terrain Editor.B_EditTurnipExchange=Edit Turnip Exchange +Editor.B_EditVillagerFlags=Edit Flags Editor.B_LoadDesign=Load Design Editor.B_LoadHouse=Load House +Editor.B_LoadVillager=Load Villager Editor.B_RecycleBin=Edit Recycle Bin +Editor.CHK_VillagerMovingOut=Moving Out Editor.L_BankBells=Bank Bells: +Editor.L_Catchphrase=Catchphrase: Editor.L_NookMiles=Nook Miles: Editor.L_PatternIndex=Design Index: Editor.L_PatternName=*PatternName +Editor.L_Personality=Personality: Editor.L_PlayerHouse=Player House: Editor.L_PlayerName=Player Name: +Editor.L_Species=Species: Editor.L_TownName=Town Name: +Editor.L_Variant=Variant: +Editor.L_VillagerID=Villager Index: Editor.L_Wallet=Wallet: Editor.Menu_DumpDecrypted=Dump Decrypted Editor.Menu_File=File @@ -140,3 +152,7 @@ TerrainEditor.B_ZeroElevation=Zero All Elevation TerrainEditor.CHK_SnapToAcre=Snap to nearest Acre on Click TerrainEditor.L_Acre=Acre: TerrainEditor.Menu_SavePNG=Save .png +VillagerHouseEditor.B_Cancel=Cancel +VillagerHouseEditor.B_DumpHouse=Dump +VillagerHouseEditor.B_LoadHouse=Load +VillagerHouseEditor.B_Save=Save diff --git a/NHSE.WinForms/Resources/text/lang_jp.txt b/NHSE.WinForms/Resources/text/lang_jp.txt index 590653e..6cbc46c 100644 --- a/NHSE.WinForms/Resources/text/lang_jp.txt +++ b/NHSE.WinForms/Resources/text/lang_jp.txt @@ -8,6 +8,7 @@ SimpleHexEditor=RAM Edit SysBotRAMEdit=SysBotUI SysBotUI=SysBotUI TerrainEditor=Terrain Editor +VillagerHouseEditor=Villager House Editor AcreEditor.B_Cancel=Cancel AcreEditor.B_Export=Export AcreEditor.B_Import=Import @@ -37,10 +38,13 @@ BuildingEditor.L_StructureType=Structure Type: BuildingEditor.L_StructureValues=Values: Editor.B_DumpDesign=Dump Design Editor.B_DumpHouse=Dump House +Editor.B_DumpVillager=Dump Villager Editor.B_EditAchievements=Edit Achievements Editor.B_EditAcres=Edit Acres Editor.B_EditBuildings=Edit Buildings Editor.B_EditFieldItems=Edit Field Items +Editor.B_EditFurniture=Edit Furniture +Editor.B_EditHouses=Edit House Editor.B_EditLandFlags=Edit Flags Editor.B_EditPlayerFlags=Edit Flags Editor.B_EditPlayerItems=Edit Items @@ -49,16 +53,24 @@ Editor.B_EditPlayerRecipes=Edit Recipes Editor.B_EditPlayerStorage=Edit Storage Editor.B_EditTerrain=Edit Terrain Editor.B_EditTurnipExchange=Edit Turnip Exchange +Editor.B_EditVillagerFlags=Edit Flags Editor.B_LoadDesign=Load Design Editor.B_LoadHouse=Load House +Editor.B_LoadVillager=Load Villager Editor.B_RecycleBin=Edit Recycle Bin +Editor.CHK_VillagerMovingOut=Moving Out Editor.L_BankBells=Bank Bells: +Editor.L_Catchphrase=Catchphrase: Editor.L_NookMiles=Nook Miles: Editor.L_PatternIndex=Design Index: Editor.L_PatternName=*PatternName +Editor.L_Personality=Personality: Editor.L_PlayerHouse=Player House: Editor.L_PlayerName=Player Name: +Editor.L_Species=Species: Editor.L_TownName=Town Name: +Editor.L_Variant=Variant: +Editor.L_VillagerID=Villager Index: Editor.L_Wallet=Wallet: Editor.Menu_DumpDecrypted=Dump Decrypted Editor.Menu_File=File @@ -140,3 +152,7 @@ TerrainEditor.B_ZeroElevation=Zero All Elevation TerrainEditor.CHK_SnapToAcre=Snap to nearest Acre on Click TerrainEditor.L_Acre=Acre: TerrainEditor.Menu_SavePNG=Save .png +VillagerHouseEditor.B_Cancel=Cancel +VillagerHouseEditor.B_DumpHouse=Dump +VillagerHouseEditor.B_LoadHouse=Load +VillagerHouseEditor.B_Save=Save diff --git a/NHSE.WinForms/Resources/text/lang_zh.txt b/NHSE.WinForms/Resources/text/lang_zh.txt index 590653e..6cbc46c 100644 --- a/NHSE.WinForms/Resources/text/lang_zh.txt +++ b/NHSE.WinForms/Resources/text/lang_zh.txt @@ -8,6 +8,7 @@ SimpleHexEditor=RAM Edit SysBotRAMEdit=SysBotUI SysBotUI=SysBotUI TerrainEditor=Terrain Editor +VillagerHouseEditor=Villager House Editor AcreEditor.B_Cancel=Cancel AcreEditor.B_Export=Export AcreEditor.B_Import=Import @@ -37,10 +38,13 @@ BuildingEditor.L_StructureType=Structure Type: BuildingEditor.L_StructureValues=Values: Editor.B_DumpDesign=Dump Design Editor.B_DumpHouse=Dump House +Editor.B_DumpVillager=Dump Villager Editor.B_EditAchievements=Edit Achievements Editor.B_EditAcres=Edit Acres Editor.B_EditBuildings=Edit Buildings Editor.B_EditFieldItems=Edit Field Items +Editor.B_EditFurniture=Edit Furniture +Editor.B_EditHouses=Edit House Editor.B_EditLandFlags=Edit Flags Editor.B_EditPlayerFlags=Edit Flags Editor.B_EditPlayerItems=Edit Items @@ -49,16 +53,24 @@ Editor.B_EditPlayerRecipes=Edit Recipes Editor.B_EditPlayerStorage=Edit Storage Editor.B_EditTerrain=Edit Terrain Editor.B_EditTurnipExchange=Edit Turnip Exchange +Editor.B_EditVillagerFlags=Edit Flags Editor.B_LoadDesign=Load Design Editor.B_LoadHouse=Load House +Editor.B_LoadVillager=Load Villager Editor.B_RecycleBin=Edit Recycle Bin +Editor.CHK_VillagerMovingOut=Moving Out Editor.L_BankBells=Bank Bells: +Editor.L_Catchphrase=Catchphrase: Editor.L_NookMiles=Nook Miles: Editor.L_PatternIndex=Design Index: Editor.L_PatternName=*PatternName +Editor.L_Personality=Personality: Editor.L_PlayerHouse=Player House: Editor.L_PlayerName=Player Name: +Editor.L_Species=Species: Editor.L_TownName=Town Name: +Editor.L_Variant=Variant: +Editor.L_VillagerID=Villager Index: Editor.L_Wallet=Wallet: Editor.Menu_DumpDecrypted=Dump Decrypted Editor.Menu_File=File @@ -140,3 +152,7 @@ TerrainEditor.B_ZeroElevation=Zero All Elevation TerrainEditor.CHK_SnapToAcre=Snap to nearest Acre on Click TerrainEditor.L_Acre=Acre: TerrainEditor.Menu_SavePNG=Save .png +VillagerHouseEditor.B_Cancel=Cancel +VillagerHouseEditor.B_DumpHouse=Dump +VillagerHouseEditor.B_LoadHouse=Load +VillagerHouseEditor.B_Save=Save diff --git a/NHSE.WinForms/Subforms/Map/VillagerHouseEditor.Designer.cs b/NHSE.WinForms/Subforms/Map/VillagerHouseEditor.Designer.cs new file mode 100644 index 0000000..597c3b8 --- /dev/null +++ b/NHSE.WinForms/Subforms/Map/VillagerHouseEditor.Designer.cs @@ -0,0 +1,137 @@ +namespace NHSE.WinForms +{ + partial class VillagerHouseEditor + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.B_Save = new System.Windows.Forms.Button(); + this.B_Cancel = new System.Windows.Forms.Button(); + this.LB_Items = new System.Windows.Forms.ListBox(); + this.PG_Item = new System.Windows.Forms.PropertyGrid(); + this.B_DumpHouse = new System.Windows.Forms.Button(); + this.B_LoadHouse = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // B_Save + // + this.B_Save.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.B_Save.Location = new System.Drawing.Point(397, 240); + this.B_Save.Name = "B_Save"; + this.B_Save.Size = new System.Drawing.Size(75, 31); + this.B_Save.TabIndex = 1; + this.B_Save.Text = "Save"; + this.B_Save.UseVisualStyleBackColor = true; + this.B_Save.Click += new System.EventHandler(this.B_Save_Click); + // + // B_Cancel + // + this.B_Cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.B_Cancel.Location = new System.Drawing.Point(316, 240); + this.B_Cancel.Name = "B_Cancel"; + this.B_Cancel.Size = new System.Drawing.Size(75, 31); + this.B_Cancel.TabIndex = 2; + this.B_Cancel.Text = "Cancel"; + this.B_Cancel.UseVisualStyleBackColor = true; + this.B_Cancel.Click += new System.EventHandler(this.B_Cancel_Click); + // + // LB_Items + // + this.LB_Items.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.LB_Items.FormattingEnabled = true; + this.LB_Items.Location = new System.Drawing.Point(12, 12); + this.LB_Items.Name = "LB_Items"; + this.LB_Items.Size = new System.Drawing.Size(149, 251); + this.LB_Items.TabIndex = 3; + this.LB_Items.SelectedIndexChanged += new System.EventHandler(this.LB_Items_SelectedIndexChanged); + // + // PG_Item + // + this.PG_Item.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.PG_Item.HelpVisible = false; + this.PG_Item.Location = new System.Drawing.Point(167, 12); + this.PG_Item.Name = "PG_Item"; + this.PG_Item.PropertySort = System.Windows.Forms.PropertySort.NoSort; + this.PG_Item.Size = new System.Drawing.Size(305, 221); + this.PG_Item.TabIndex = 4; + this.PG_Item.ToolbarVisible = false; + this.PG_Item.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.PG_Item_PropertyValueChanged); + // + // B_DumpHouse + // + this.B_DumpHouse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.B_DumpHouse.Location = new System.Drawing.Point(168, 239); + this.B_DumpHouse.Name = "B_DumpHouse"; + this.B_DumpHouse.Size = new System.Drawing.Size(65, 31); + this.B_DumpHouse.TabIndex = 5; + this.B_DumpHouse.Text = "Dump"; + this.B_DumpHouse.UseVisualStyleBackColor = true; + this.B_DumpHouse.Click += new System.EventHandler(this.B_DumpHouse_Click); + // + // B_LoadHouse + // + this.B_LoadHouse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.B_LoadHouse.Location = new System.Drawing.Point(238, 240); + this.B_LoadHouse.Name = "B_LoadHouse"; + this.B_LoadHouse.Size = new System.Drawing.Size(65, 31); + this.B_LoadHouse.TabIndex = 6; + this.B_LoadHouse.Text = "Load"; + this.B_LoadHouse.UseVisualStyleBackColor = true; + this.B_LoadHouse.Click += new System.EventHandler(this.B_LoadHouse_Click); + // + // VillagerHouseEditor + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(484, 283); + this.Controls.Add(this.B_LoadHouse); + this.Controls.Add(this.B_DumpHouse); + this.Controls.Add(this.PG_Item); + this.Controls.Add(this.LB_Items); + this.Controls.Add(this.B_Cancel); + this.Controls.Add(this.B_Save); + this.Icon = global::NHSE.WinForms.Properties.Resources.icon; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "VillagerHouseEditor"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Villager House Editor"; + this.ResumeLayout(false); + + } + + #endregion + private System.Windows.Forms.Button B_Save; + private System.Windows.Forms.Button B_Cancel; + private System.Windows.Forms.ListBox LB_Items; + private System.Windows.Forms.PropertyGrid PG_Item; + private System.Windows.Forms.Button B_DumpHouse; + private System.Windows.Forms.Button B_LoadHouse; + } +} \ No newline at end of file diff --git a/NHSE.WinForms/Subforms/Map/VillagerHouseEditor.cs b/NHSE.WinForms/Subforms/Map/VillagerHouseEditor.cs new file mode 100644 index 0000000..f9ec9e1 --- /dev/null +++ b/NHSE.WinForms/Subforms/Map/VillagerHouseEditor.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Windows.Forms; +using NHSE.Core; + +namespace NHSE.WinForms +{ + public partial class VillagerHouseEditor : Form + { + private readonly MainSave SAV; + public readonly VillagerHouse[] Houses; + private readonly IReadOnlyList Villagers; + + private int Index; + + public VillagerHouseEditor(VillagerHouse[] houses, IReadOnlyList 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(VillagerHouse house) + { + var villagerIndex = house.NPC1; + var v = (uint) villagerIndex >= Villagers.Count ? "???" : Villagers[villagerIndex].InternalName; + var name = GameInfo.Strings.GetVillager(v); + return $"{name}'s House"; + } + + 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 v = (uint)Index >= Villagers.Count ? "???" : Villagers[Index].InternalName; + var name = GameInfo.Strings.GetVillager(v); + 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 = Houses[Index]; + var data = h.ToBytesClass(); + File.WriteAllBytes(sfd.FileName, data); + } + + private void B_LoadHouse_Click(object sender, EventArgs e) + { + var v = (uint)Index >= Villagers.Count ? "???" : Villagers[Index].InternalName; + var name = GameInfo.Strings.GetVillager(v); + 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(MessageStrings.MsgCanceling, msg); + return; + } + + var data = File.ReadAllBytes(file); + var h = data.ToClass(); + var current = Houses[Index]; + h.NPC1 = current.NPC1; + Houses[Index] = h; + } + } +} diff --git a/NHSE.WinForms/Subforms/Map/VillagerHouseEditor.resx b/NHSE.WinForms/Subforms/Map/VillagerHouseEditor.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/NHSE.WinForms/Subforms/Map/VillagerHouseEditor.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/NHSE.WinForms/Util/DevUtil.cs b/NHSE.WinForms/Util/DevUtil.cs index 97d8847..2f16af5 100644 --- a/NHSE.WinForms/Util/DevUtil.cs +++ b/NHSE.WinForms/Util/DevUtil.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Windows.Forms; using NHSE.Core; +using NHSE.WinForms.Properties; namespace NHSE.WinForms { @@ -29,6 +30,7 @@ public static void UpdateAll() private static void UpdateTranslations() { + WinFormsTranslator.LoadSpecialForms = LoadSpecialForms; WinFormsTranslator.SetRemovalMode(false); // add mode WinFormsTranslator.LoadAllForms(LoadBanlist); // populate with every possible control WinFormsTranslator.UpdateAll(DefaultLanguage, Languages); // propagate to others @@ -57,9 +59,18 @@ private static void UpdateTranslations() Application.Exit(); } + private static void LoadSpecialForms() + { + // For forms that require more complete initialization (dynamically added user controls) + var path = Settings.Default.LastFilePath; + var sav = new HorizonSave(path); + using var editor = new Editor(sav); + } + private static readonly string[] LoadBanlist = { nameof(SettingsEditor), + nameof(Editor), // special handling above }; private static readonly string[] Banlist = diff --git a/NHSE.WinForms/Util/WinFormsTranslator.cs b/NHSE.WinForms/Util/WinFormsTranslator.cs index dd58d65..1ce69f5 100644 --- a/NHSE.WinForms/Util/WinFormsTranslator.cs +++ b/NHSE.WinForms/Util/WinFormsTranslator.cs @@ -15,6 +15,8 @@ public static class WinFormsTranslator private static string GetTranslationFileNameInternal(string lang) => $"lang_{lang}"; private static string GetTranslationFileNameExternal(string lang) => $"lang_{lang}.txt"; + internal static Action LoadSpecialForms = () => { }; + private static TranslationContext GetContext(string lang) { if (Context.TryGetValue(lang, out var context)) @@ -173,6 +175,8 @@ public static void DumpAll(params string[] banlist) public static void LoadAllForms(params string[] banlist) { + LoadSpecialForms(); + var q = from t in System.Reflection.Assembly.GetExecutingAssembly().GetTypes() where t.BaseType == typeof(Form) && !banlist.Contains(t.Name) select t;