From ffa0d3612b7a73a22db770a48fe987b73110aac2 Mon Sep 17 00:00:00 2001 From: Kurt Date: Thu, 14 May 2020 09:12:38 -0700 Subject: [PATCH] Add island visitor editor Make daily NPCs show up reliably! --- NHSE.Core/Save/Files/MainSave.cs | 7 +++ NHSE.Core/Save/Offsets/MainSaveOffsets.cs | 1 + NHSE.Core/Save/Offsets/MainSaveOffsets10.cs | 1 + NHSE.Core/Save/Offsets/MainSaveOffsets11.cs | 1 + NHSE.Core/Save/Offsets/MainSaveOffsets12.cs | 1 + NHSE.Core/Structures/Misc/GSaveVisitorNpc.cs | 51 ++++++++++++++++++++ NHSE.Tests/FancyMarshalTests.cs | 1 + NHSE.WinForms/Editor.Designer.cs | 14 +++++- NHSE.WinForms/Editor.cs | 8 +++ 9 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 NHSE.Core/Structures/Misc/GSaveVisitorNpc.cs diff --git a/NHSE.Core/Save/Files/MainSave.cs b/NHSE.Core/Save/Files/MainSave.cs index ce9565c..a164447 100644 --- a/NHSE.Core/Save/Files/MainSave.cs +++ b/NHSE.Core/Save/Files/MainSave.cs @@ -264,6 +264,13 @@ public uint EventPlazaLeftUpZ set => BitConverter.GetBytes(value).CopyTo(Data, Offsets.OutsideField + AcreSizeAll + 8); } + + public GSaveVisitorNpc Visitor + { + get => Data.ToClass(Offsets.Visitor, GSaveVisitorNpc.SIZE); + set => value.ToBytesClass().CopyTo(Data, Offsets.Visitor); + } + public GSaveFg SaveFg { get => Data.ToClass(Offsets.SaveFg, GSaveFg.SIZE); diff --git a/NHSE.Core/Save/Offsets/MainSaveOffsets.cs b/NHSE.Core/Save/Offsets/MainSaveOffsets.cs index 8dfd25e..6040b42 100644 --- a/NHSE.Core/Save/Offsets/MainSaveOffsets.cs +++ b/NHSE.Core/Save/Offsets/MainSaveOffsets.cs @@ -34,6 +34,7 @@ public abstract class MainSaveOffsets public abstract int NpcHouseList { get; } public abstract int ShopKabu { get; } public abstract int Museum { get; } + public abstract int Visitor { get; } public abstract int SaveFg { get; } public abstract int BulletinBoard { get; } diff --git a/NHSE.Core/Save/Offsets/MainSaveOffsets10.cs b/NHSE.Core/Save/Offsets/MainSaveOffsets10.cs index 43806fe..f2d0ebc 100644 --- a/NHSE.Core/Save/Offsets/MainSaveOffsets10.cs +++ b/NHSE.Core/Save/Offsets/MainSaveOffsets10.cs @@ -33,6 +33,7 @@ public class MainSaveOffsets10 : MainSaveOffsets public const int GSaveShop = GSaveLandStart + 0x40ECE8; public override int ShopKabu => GSaveShop + 0x2AD0; // part of shop public override int Museum => GSaveLandStart + 0x411A80; + public override int Visitor => GSaveLandStart + 0x414E84; public override int SaveFg => GSaveLandStart + 0x4150B4; public override int BulletinBoard => GSaveLandStart + 0x4159F8; public override int AirportThemeColor => GSaveLandStart + 0x4F6600; diff --git a/NHSE.Core/Save/Offsets/MainSaveOffsets11.cs b/NHSE.Core/Save/Offsets/MainSaveOffsets11.cs index d5aad1d..cabd703 100644 --- a/NHSE.Core/Save/Offsets/MainSaveOffsets11.cs +++ b/NHSE.Core/Save/Offsets/MainSaveOffsets11.cs @@ -33,6 +33,7 @@ public class MainSaveOffsets11 : MainSaveOffsets public const int GSaveShop = GSaveLandStart + 0x40F480; public override int ShopKabu => GSaveShop + 0x2AD0; // part of shop public override int Museum => GSaveLandStart + 0x412218; + public override int Visitor => GSaveLandStart + 0x41561C; public override int SaveFg => GSaveLandStart + 0x41584C; public override int BulletinBoard => GSaveLandStart + 0x416190; public override int AirportThemeColor => GSaveLandStart + 0x4F6D98; diff --git a/NHSE.Core/Save/Offsets/MainSaveOffsets12.cs b/NHSE.Core/Save/Offsets/MainSaveOffsets12.cs index 6d08a1a..2d1a7e1 100644 --- a/NHSE.Core/Save/Offsets/MainSaveOffsets12.cs +++ b/NHSE.Core/Save/Offsets/MainSaveOffsets12.cs @@ -33,6 +33,7 @@ public class MainSaveOffsets12 : MainSaveOffsets public const int GSaveShop = GSaveLandStart + 0x40F480; public override int ShopKabu => GSaveShop + 0x2AD0; // part of shop public override int Museum => GSaveLandStart + 0x4124C4; + public override int Visitor => GSaveLandStart + 0x4158C8; public override int SaveFg => GSaveLandStart + 0x415AF8; public override int BulletinBoard => GSaveLandStart + 0x416440; public override int AirportThemeColor => GSaveLandStart + 0x4F7048; diff --git a/NHSE.Core/Structures/Misc/GSaveVisitorNpc.cs b/NHSE.Core/Structures/Misc/GSaveVisitorNpc.cs new file mode 100644 index 0000000..26127a3 --- /dev/null +++ b/NHSE.Core/Structures/Misc/GSaveVisitorNpc.cs @@ -0,0 +1,51 @@ +using System.ComponentModel; +using System.Runtime.InteropServices; + +#pragma warning disable CS8618, CA1815, CA1819, IDE1006 +namespace NHSE.Core +{ + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public class GSaveVisitorNpc + { + public const int SIZE = 0x78; + private const int Days = 7; + + [field: MarshalAs(UnmanagedType.ByValArray, SizeConst = Days)] + public int[] VisitorNPC { get; set; } + + public V3f CreatePos { get; set; } + public V3f _61e631dc { get; set; } + + [field: MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = Days)] + public bool[] IsNormalLive { get; set; } + + [field: MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = Days)] + public bool[] IsBirthdayLive { get; set; } + + [field: MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] gap_42; + + [field: MarshalAs(UnmanagedType.ByValArray, SizeConst = Days)] + public int[] InitSchedule { get; set; } + + [field: MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = Days * 2)] + public bool[] _437619d8 { get; set; } + + [field: MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] + public byte[] gap_6e; + + public int _e2484556 {get; set; } + public int _753479b1 { get; set; } + } + + // same as Vector3; not importing package + [TypeConverter(typeof(ValueTypeTypeConverter))] + public struct V3f + { + public float X { get; set; } + public float Y { get; set; } + public float Z { get; set; } + + public override string ToString() => $"({X},{Y},{Z})"; + } +} diff --git a/NHSE.Tests/FancyMarshalTests.cs b/NHSE.Tests/FancyMarshalTests.cs index ff68b3c..84a2ab5 100644 --- a/NHSE.Tests/FancyMarshalTests.cs +++ b/NHSE.Tests/FancyMarshalTests.cs @@ -22,6 +22,7 @@ public class FancyMarshalTests [Fact] public void MarshalGSaveManpu() => MarshalBytesTestS(GSavePlayerManpu.SIZE); [Fact] public void MarshalGSavePlayerHandleName() => MarshalBytesTestS(GSavePlayerHandleName.SIZE); [Fact] public void MarshalGSaveFg() => MarshalBytesTest(GSaveFg.SIZE); + [Fact] public void MarshalGSaveVisitorNpc() => MarshalBytesTest(GSaveVisitorNpc.SIZE); private static void MarshalBytesTestS(int size) where T : struct { diff --git a/NHSE.WinForms/Editor.Designer.cs b/NHSE.WinForms/Editor.Designer.cs index 22bde25..3acdfb1 100644 --- a/NHSE.WinForms/Editor.Designer.cs +++ b/NHSE.WinForms/Editor.Designer.cs @@ -95,6 +95,7 @@ private void InitializeComponent() this.PB_Player = new System.Windows.Forms.PictureBox(); this.TC_Editors = new System.Windows.Forms.TabControl(); this.B_EditMuseum_Click = new System.Windows.Forms.ToolStripMenuItem(); + this.B_EditVisitors = new System.Windows.Forms.ToolStripMenuItem(); this.Menu_Editor.SuspendLayout(); this.CM_Picture.SuspendLayout(); this.Tab_Map.SuspendLayout(); @@ -340,9 +341,10 @@ private void InitializeComponent() this.B_EditFieldItems, this.B_EditBulletin, this.B_EditFieldGoods, - this.B_EditMuseum_Click}); + this.B_EditMuseum_Click, + this.B_EditVisitors}); this.CM_EditMap.Name = "CM_EditMap"; - this.CM_EditMap.Size = new System.Drawing.Size(181, 136); + this.CM_EditMap.Size = new System.Drawing.Size(181, 158); // // B_EditLandFlags // @@ -774,6 +776,13 @@ private void InitializeComponent() this.B_EditMuseum_Click.Text = "Edit Museum"; this.B_EditMuseum_Click.Click += new System.EventHandler(this.B_EditMuseum_Click_Click); // + // B_EditVisitors + // + this.B_EditVisitors.Name = "B_EditVisitors"; + this.B_EditVisitors.Size = new System.Drawing.Size(180, 22); + this.B_EditVisitors.Text = "Edit Visitors"; + this.B_EditVisitors.Click += new System.EventHandler(this.B_EditVisitors_Click); + // // Editor // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -877,6 +886,7 @@ private void InitializeComponent() private System.Windows.Forms.Button B_EditDesignsTailor; private System.Windows.Forms.Button B_EditPatternFlag; private System.Windows.Forms.ToolStripMenuItem B_EditMuseum_Click; + private System.Windows.Forms.ToolStripMenuItem B_EditVisitors; } } diff --git a/NHSE.WinForms/Editor.cs b/NHSE.WinForms/Editor.cs index 446db9d..a269a99 100644 --- a/NHSE.WinForms/Editor.cs +++ b/NHSE.WinForms/Editor.cs @@ -482,5 +482,13 @@ private void B_EditMuseum_Click_Click(object sender, EventArgs e) if (editor.ShowDialog() == DialogResult.OK) SAV.Main.Museum = museum; } + + private void B_EditVisitors_Click(object sender, EventArgs e) + { + var boxed = SAV.Main.Visitor; + using var editor = new SingleObjectEditor(boxed, PropertySort.NoSort, false); + if (editor.ShowDialog() == DialogResult.OK) + SAV.Main.Visitor = boxed; + } } }