From 8e4e0a92f8578f37624648d3dcd6df6f5cf5d4d1 Mon Sep 17 00:00:00 2001 From: Kurt Date: Thu, 7 May 2020 22:13:31 -0700 Subject: [PATCH] Add reaction list editor #167 If you're adding reactions, you should probably set FillReactionList in player flags to 44 so that the game knows to not give you more reactions...? --- NHSE.Core/Structures/Misc/GSavePlayerManpu.cs | 29 ++++- NHSE.WinForms/Editor.Designer.cs | 60 +++++---- NHSE.WinForms/Editor.cs | 7 + NHSE.WinForms/NHSE.WinForms.csproj | 3 + .../Player/ReactionEditor.Designer.cs | 109 ++++++++++++++++ .../Subforms/Player/ReactionEditor.cs | 41 ++++++ .../Subforms/Player/ReactionEditor.resx | 120 ++++++++++++++++++ 7 files changed, 343 insertions(+), 26 deletions(-) create mode 100644 NHSE.WinForms/Subforms/Player/ReactionEditor.Designer.cs create mode 100644 NHSE.WinForms/Subforms/Player/ReactionEditor.cs create mode 100644 NHSE.WinForms/Subforms/Player/ReactionEditor.resx diff --git a/NHSE.Core/Structures/Misc/GSavePlayerManpu.cs b/NHSE.Core/Structures/Misc/GSavePlayerManpu.cs index 1996c29..abb03c4 100644 --- a/NHSE.Core/Structures/Misc/GSavePlayerManpu.cs +++ b/NHSE.Core/Structures/Misc/GSavePlayerManpu.cs @@ -1,4 +1,5 @@ -using System.Runtime.InteropServices; +using System; +using System.Runtime.InteropServices; #pragma warning disable CS8618, CA1815, CA1819, IDE1006 namespace NHSE.Core @@ -27,5 +28,31 @@ public struct GSavePlayerManpu /// [field: MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = MaxCount)] public bool[] NewFlag { get; set; } + + public void AddMissingReactions() + { + var all = (Reaction[])Enum.GetValues(typeof(Reaction)); + foreach (var react in all) + AddReaction(react); + } + + // returns true if failed + public bool AddReaction(Reaction react) + { + if (react.ToString().StartsWith("UNUSED")) + return true; + + var index = Array.IndexOf(ManpuBit, react); + if (index >= 0) + return false; + + var empty = EmptyIndex; + if (empty < 0) + return true; + ManpuBit[empty] = react; + return false; + } + + private int EmptyIndex => Array.FindIndex(ManpuBit, z => z == 0); } } diff --git a/NHSE.WinForms/Editor.Designer.cs b/NHSE.WinForms/Editor.Designer.cs index 61c3cac..fc0ea1e 100644 --- a/NHSE.WinForms/Editor.Designer.cs +++ b/NHSE.WinForms/Editor.Designer.cs @@ -44,6 +44,8 @@ private void InitializeComponent() this.CM_Picture = new System.Windows.Forms.ContextMenuStrip(this.components); this.Menu_SavePNG = new System.Windows.Forms.ToolStripMenuItem(); this.Tab_Map = new System.Windows.Forms.TabPage(); + this.L_Hemisphere = new System.Windows.Forms.Label(); + this.CB_Hemisphere = new System.Windows.Forms.ComboBox(); this.B_EditPlayerHouses = new System.Windows.Forms.Button(); this.B_EditMap = new System.Windows.Forms.Button(); this.CM_EditMap = new System.Windows.Forms.ContextMenuStrip(this.components); @@ -88,8 +90,7 @@ private void InitializeComponent() this.CB_Players = new System.Windows.Forms.ComboBox(); this.PB_Player = new System.Windows.Forms.PictureBox(); this.TC_Editors = new System.Windows.Forms.TabControl(); - this.CB_Hemisphere = new System.Windows.Forms.ComboBox(); - this.L_Hemisphere = new System.Windows.Forms.Label(); + this.B_EditPlayerReactions = new System.Windows.Forms.ToolStripMenuItem(); this.Menu_Editor.SuspendLayout(); this.CM_Picture.SuspendLayout(); this.Tab_Map.SuspendLayout(); @@ -247,6 +248,24 @@ private void InitializeComponent() this.Tab_Map.Text = "Map"; this.Tab_Map.UseVisualStyleBackColor = true; // + // L_Hemisphere + // + this.L_Hemisphere.AutoSize = true; + this.L_Hemisphere.Location = new System.Drawing.Point(300, 9); + this.L_Hemisphere.Name = "L_Hemisphere"; + this.L_Hemisphere.Size = new System.Drawing.Size(63, 13); + this.L_Hemisphere.TabIndex = 58; + this.L_Hemisphere.Text = "Hemisphere"; + // + // CB_Hemisphere + // + this.CB_Hemisphere.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.CB_Hemisphere.FormattingEnabled = true; + this.CB_Hemisphere.Location = new System.Drawing.Point(202, 6); + this.CB_Hemisphere.Name = "CB_Hemisphere"; + this.CB_Hemisphere.Size = new System.Drawing.Size(92, 21); + this.CB_Hemisphere.TabIndex = 57; + // // B_EditPlayerHouses // this.B_EditPlayerHouses.Location = new System.Drawing.Point(6, 168); @@ -526,42 +545,43 @@ private void InitializeComponent() this.B_EditPlayerReceivedItems, this.B_EditAchievements, this.B_EditPlayerRecipes, - this.B_EditPlayerFlags}); + this.B_EditPlayerFlags, + this.B_EditPlayerReactions}); this.CM_EditPlayer.Name = "CM_EditPlayer"; - this.CM_EditPlayer.Size = new System.Drawing.Size(177, 114); + this.CM_EditPlayer.Size = new System.Drawing.Size(181, 158); // // B_EditPlayerStorage // this.B_EditPlayerStorage.Name = "B_EditPlayerStorage"; - this.B_EditPlayerStorage.Size = new System.Drawing.Size(176, 22); + this.B_EditPlayerStorage.Size = new System.Drawing.Size(180, 22); this.B_EditPlayerStorage.Text = "Edit Storage"; this.B_EditPlayerStorage.Click += new System.EventHandler(this.B_Storage_Click); // // B_EditPlayerReceivedItems // this.B_EditPlayerReceivedItems.Name = "B_EditPlayerReceivedItems"; - this.B_EditPlayerReceivedItems.Size = new System.Drawing.Size(176, 22); + this.B_EditPlayerReceivedItems.Size = new System.Drawing.Size(180, 22); this.B_EditPlayerReceivedItems.Text = "Edit Received Items"; this.B_EditPlayerReceivedItems.Click += new System.EventHandler(this.B_EditPlayerReceivedItems_Click); // // B_EditAchievements // this.B_EditAchievements.Name = "B_EditAchievements"; - this.B_EditAchievements.Size = new System.Drawing.Size(176, 22); + this.B_EditAchievements.Size = new System.Drawing.Size(180, 22); this.B_EditAchievements.Text = "Edit Achievements"; this.B_EditAchievements.Click += new System.EventHandler(this.B_EditAchievements_Click); // // B_EditPlayerRecipes // this.B_EditPlayerRecipes.Name = "B_EditPlayerRecipes"; - this.B_EditPlayerRecipes.Size = new System.Drawing.Size(176, 22); + this.B_EditPlayerRecipes.Size = new System.Drawing.Size(180, 22); this.B_EditPlayerRecipes.Text = "Edit Recipes"; this.B_EditPlayerRecipes.Click += new System.EventHandler(this.B_EditPlayerRecipes_Click); // // B_EditPlayerFlags // this.B_EditPlayerFlags.Name = "B_EditPlayerFlags"; - this.B_EditPlayerFlags.Size = new System.Drawing.Size(176, 22); + this.B_EditPlayerFlags.Size = new System.Drawing.Size(180, 22); this.B_EditPlayerFlags.Text = "Edit Flags"; this.B_EditPlayerFlags.Click += new System.EventHandler(this.B_EditPlayerFlags_Click); // @@ -703,23 +723,12 @@ private void InitializeComponent() this.TC_Editors.Size = new System.Drawing.Size(404, 237); this.TC_Editors.TabIndex = 1; // - // CB_Hemisphere + // B_EditPlayerReactions // - this.CB_Hemisphere.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.CB_Hemisphere.FormattingEnabled = true; - this.CB_Hemisphere.Location = new System.Drawing.Point(202, 6); - this.CB_Hemisphere.Name = "CB_Hemisphere"; - this.CB_Hemisphere.Size = new System.Drawing.Size(92, 21); - this.CB_Hemisphere.TabIndex = 57; - // - // L_Hemisphere - // - this.L_Hemisphere.AutoSize = true; - this.L_Hemisphere.Location = new System.Drawing.Point(300, 9); - this.L_Hemisphere.Name = "L_Hemisphere"; - this.L_Hemisphere.Size = new System.Drawing.Size(63, 13); - this.L_Hemisphere.TabIndex = 58; - this.L_Hemisphere.Text = "Hemisphere"; + this.B_EditPlayerReactions.Name = "B_EditPlayerReactions"; + this.B_EditPlayerReactions.Size = new System.Drawing.Size(180, 22); + this.B_EditPlayerReactions.Text = "Edit Reactions"; + this.B_EditPlayerReactions.Click += new System.EventHandler(this.B_EditPlayerReactions_Click); // // Editor // @@ -819,6 +828,7 @@ private void InitializeComponent() private System.Windows.Forms.NumericUpDown NUD_TotalNookMiles; private System.Windows.Forms.Label L_Hemisphere; private System.Windows.Forms.ComboBox CB_Hemisphere; + private System.Windows.Forms.ToolStripMenuItem B_EditPlayerReactions; } } diff --git a/NHSE.WinForms/Editor.cs b/NHSE.WinForms/Editor.cs index 8021641..3cf093a 100644 --- a/NHSE.WinForms/Editor.cs +++ b/NHSE.WinForms/Editor.cs @@ -245,6 +245,13 @@ private void B_EditPlayerReceivedItems_Click(object sender, EventArgs e) editor.ShowDialog(); } + private void B_EditPlayerReactions_Click(object sender, EventArgs e) + { + var player = SAV.Players[PlayerIndex].Personal; + using var editor = new ReactionEditor(player); + editor.ShowDialog(); + } + private void LoadPlayer(int index) { if (PlayerIndex >= 0) diff --git a/NHSE.WinForms/NHSE.WinForms.csproj b/NHSE.WinForms/NHSE.WinForms.csproj index 4b0fffa..1501af6 100644 --- a/NHSE.WinForms/NHSE.WinForms.csproj +++ b/NHSE.WinForms/NHSE.WinForms.csproj @@ -58,6 +58,9 @@ Form + + Form + Form diff --git a/NHSE.WinForms/Subforms/Player/ReactionEditor.Designer.cs b/NHSE.WinForms/Subforms/Player/ReactionEditor.Designer.cs new file mode 100644 index 0000000..6f73fc8 --- /dev/null +++ b/NHSE.WinForms/Subforms/Player/ReactionEditor.Designer.cs @@ -0,0 +1,109 @@ +namespace NHSE.WinForms +{ + partial class ReactionEditor + { + /// + /// 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_Cancel = new System.Windows.Forms.Button(); + this.B_Save = new System.Windows.Forms.Button(); + this.PG_Manpu = new System.Windows.Forms.PropertyGrid(); + this.B_GiveAll = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // 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(169, 252); + this.B_Cancel.Name = "B_Cancel"; + this.B_Cancel.Size = new System.Drawing.Size(72, 23); + this.B_Cancel.TabIndex = 7; + this.B_Cancel.Text = "Cancel"; + this.B_Cancel.UseVisualStyleBackColor = true; + this.B_Cancel.Click += new System.EventHandler(this.B_Cancel_Click); + // + // 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(247, 252); + this.B_Save.Name = "B_Save"; + this.B_Save.Size = new System.Drawing.Size(72, 23); + this.B_Save.TabIndex = 6; + this.B_Save.Text = "Save"; + this.B_Save.UseVisualStyleBackColor = true; + this.B_Save.Click += new System.EventHandler(this.B_Save_Click); + // + // PG_Manpu + // + this.PG_Manpu.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_Manpu.HelpVisible = false; + this.PG_Manpu.Location = new System.Drawing.Point(12, 12); + this.PG_Manpu.Name = "PG_Manpu"; + this.PG_Manpu.PropertySort = System.Windows.Forms.PropertySort.NoSort; + this.PG_Manpu.Size = new System.Drawing.Size(307, 234); + this.PG_Manpu.TabIndex = 8; + this.PG_Manpu.ToolbarVisible = false; + // + // B_GiveAll + // + this.B_GiveAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.B_GiveAll.Location = new System.Drawing.Point(12, 252); + this.B_GiveAll.Name = "B_GiveAll"; + this.B_GiveAll.Size = new System.Drawing.Size(96, 23); + this.B_GiveAll.TabIndex = 9; + this.B_GiveAll.Text = "Give All"; + this.B_GiveAll.UseVisualStyleBackColor = true; + this.B_GiveAll.Click += new System.EventHandler(this.B_GiveAll_Click); + // + // ReactionEditor + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(331, 287); + this.Controls.Add(this.B_GiveAll); + this.Controls.Add(this.PG_Manpu); + 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 = "ReactionEditor"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Reaction List Editor"; + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button B_Cancel; + private System.Windows.Forms.Button B_Save; + private System.Windows.Forms.PropertyGrid PG_Manpu; + private System.Windows.Forms.Button B_GiveAll; + } +} \ No newline at end of file diff --git a/NHSE.WinForms/Subforms/Player/ReactionEditor.cs b/NHSE.WinForms/Subforms/Player/ReactionEditor.cs new file mode 100644 index 0000000..a228ff6 --- /dev/null +++ b/NHSE.WinForms/Subforms/Player/ReactionEditor.cs @@ -0,0 +1,41 @@ +using System; +using System.Windows.Forms; +using NHSE.Core; + +namespace NHSE.WinForms +{ + public partial class ReactionEditor : Form + { + private readonly Personal Personal; + + public ReactionEditor(Personal p) + { + InitializeComponent(); + this.TranslateInterface(GameInfo.CurrentLanguage); + + Personal = p; + var manpu = p.Data.Slice(p.Offsets.Manpu, GSavePlayerManpu.SIZE).ToStructure(); + + PG_Manpu.SelectedObject = manpu; + } + + private void B_Cancel_Click(object sender, EventArgs e) => Close(); + + private void B_Save_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.OK; + var val = (GSavePlayerManpu) PG_Manpu.SelectedObject; + var bytes = val.ToBytes(); + bytes.CopyTo(Personal.Data, Personal.Offsets.Manpu); + Close(); + } + + private void B_GiveAll_Click(object sender, EventArgs e) + { + var val = (GSavePlayerManpu)PG_Manpu.SelectedObject; + val.AddMissingReactions(); + PG_Manpu.SelectedObject = val; + System.Media.SystemSounds.Asterisk.Play(); + } + } +} diff --git a/NHSE.WinForms/Subforms/Player/ReactionEditor.resx b/NHSE.WinForms/Subforms/Player/ReactionEditor.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/NHSE.WinForms/Subforms/Player/ReactionEditor.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