diff --git a/NHSE.Core/Structures/Item/IGridItem.cs b/NHSE.Core/Structures/Item/IGridItem.cs
new file mode 100644
index 0000000..8eb11e9
--- /dev/null
+++ b/NHSE.Core/Structures/Item/IGridItem.cs
@@ -0,0 +1,8 @@
+namespace NHSE.Core
+{
+ public interface IGridItem
+ {
+ int Width { get; }
+ int Height { get; }
+ }
+}
\ No newline at end of file
diff --git a/NHSE.Core/Structures/Item/Item.cs b/NHSE.Core/Structures/Item/Item.cs
index 05ffb9c..0d34e25 100644
--- a/NHSE.Core/Structures/Item/Item.cs
+++ b/NHSE.Core/Structures/Item/Item.cs
@@ -38,6 +38,23 @@ public Item(ushort itemId = NONE, byte flags0 = 0, byte flags1 = 0, byte count =
UseCount = useCount;
}
+ public void Delete()
+ {
+ ItemId = NONE;
+ Flags0 = Flags1 = Flags2 = Count = 0;
+ UseCount = 0;
+ }
+
+ public void CopyFrom(Item item)
+ {
+ ItemId = item.ItemId;
+ Flags0 = item.Flags0;
+ Flags1 = item.Flags1;
+ Flags2 = item.Flags2;
+ Count = item.Count;
+ UseCount = item.UseCount;
+ }
+
public static Item[] GetArray(byte[] data)
{
var result = new Item[data.Length / SIZE];
diff --git a/NHSE.Sprites/ItemSprite.cs b/NHSE.Sprites/ItemSprite.cs
new file mode 100644
index 0000000..49cb989
--- /dev/null
+++ b/NHSE.Sprites/ItemSprite.cs
@@ -0,0 +1,47 @@
+using System.Drawing;
+using NHSE.Core;
+using NHSE.Sprites.Properties;
+
+namespace NHSE.Sprites
+{
+ public class ItemSpriteDrawer : IGridItem
+ {
+ public int Width { get; set; } = 32;
+ public int Height { get; set; } = 32;
+
+ public Image HoverBackground = Resources.itemHover;
+
+ public Image? GetImage(Item item, Font font)
+ {
+ if (item.ItemId == Item.NONE)
+ return null;
+
+ return CreateFake(item, font);
+ }
+
+ public Image CreateFake(Item item, Font font)
+ {
+ var scramble = item.ItemId * 17;
+ var b = scramble & 0xFF;
+ var g = (scramble >> 8) & 0xFF;
+ var color = Color.FromArgb(b, g, b);
+
+ var bmp = new Bitmap(Width, Height);
+ using Graphics gfx = Graphics.FromImage(bmp);
+ using SolidBrush brush = new SolidBrush(color);
+ gfx.FillRectangle(brush, 0, 0, bmp.Width, bmp.Height);
+
+ if (item.Count != 0)
+ gfx.DrawString(item.Count.ToString(), font, Brushes.Black, 0, 0);
+ if (item.UseCount != 0)
+ gfx.DrawString(item.UseCount.ToString(), font, Brushes.Black, 10, 10);
+ if (item.Flags0 != 0)
+ gfx.DrawString(item.Flags0.ToString(), font, Brushes.Black, 20, 0);
+ if (item.Flags1 != 0)
+ gfx.DrawString(item.Flags1.ToString(), font, Brushes.Black, 0, 20);
+ if (item.Flags2 != 0)
+ gfx.DrawString(item.Flags2.ToString(), font, Brushes.Black, 20, 20);
+ return bmp;
+ }
+ }
+}
diff --git a/NHSE.Sprites/Misc/itemHover.png b/NHSE.Sprites/Misc/itemHover.png
new file mode 100644
index 0000000..1281386
Binary files /dev/null and b/NHSE.Sprites/Misc/itemHover.png differ
diff --git a/NHSE.Sprites/Properties/Resources.Designer.cs b/NHSE.Sprites/Properties/Resources.Designer.cs
index 4c737d8..ac143c5 100644
--- a/NHSE.Sprites/Properties/Resources.Designer.cs
+++ b/NHSE.Sprites/Properties/Resources.Designer.cs
@@ -2280,6 +2280,16 @@ internal class Resources {
}
}
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap itemHover {
+ get {
+ object obj = ResourceManager.GetObject("itemHover", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
diff --git a/NHSE.Sprites/Properties/Resources.resx b/NHSE.Sprites/Properties/Resources.resx
index 51776c5..644cfa3 100644
--- a/NHSE.Sprites/Properties/Resources.resx
+++ b/NHSE.Sprites/Properties/Resources.resx
@@ -784,6 +784,9 @@
..\Villagers\hrs16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Misc\itemHover.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
..\Villagers\kal00.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
diff --git a/NHSE.Sprites/SpriteUtil.cs b/NHSE.Sprites/SpriteUtil.cs
new file mode 100644
index 0000000..1777ef5
--- /dev/null
+++ b/NHSE.Sprites/SpriteUtil.cs
@@ -0,0 +1,7 @@
+namespace NHSE.Sprites
+{
+ public static class SpriteUtil
+ {
+ public static readonly ItemSpriteDrawer Items = new ItemSpriteDrawer();
+ }
+}
\ No newline at end of file
diff --git a/NHSE.WinForms/Controls/ItemEditor.Designer.cs b/NHSE.WinForms/Controls/ItemEditor.Designer.cs
new file mode 100644
index 0000000..07eee19
--- /dev/null
+++ b/NHSE.WinForms/Controls/ItemEditor.Designer.cs
@@ -0,0 +1,242 @@
+namespace NHSE.WinForms
+{
+ partial class ItemEditor
+ {
+ ///
+ /// 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 Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.CB_ItemID = new System.Windows.Forms.ComboBox();
+ this.NUD_Count = new System.Windows.Forms.NumericUpDown();
+ this.L_Count = new System.Windows.Forms.Label();
+ this.L_Uses = new System.Windows.Forms.Label();
+ this.NUD_Uses = new System.Windows.Forms.NumericUpDown();
+ this.L_Flag0 = new System.Windows.Forms.Label();
+ this.NUD_Flag0 = new System.Windows.Forms.NumericUpDown();
+ this.L_Flag1 = new System.Windows.Forms.Label();
+ this.NUD_Flag1 = new System.Windows.Forms.NumericUpDown();
+ this.L_Flag2 = new System.Windows.Forms.Label();
+ this.NUD_Flag2 = new System.Windows.Forms.NumericUpDown();
+ this.CM_Hand = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.Menu_View = new System.Windows.Forms.ToolStripMenuItem();
+ this.Menu_Set = new System.Windows.Forms.ToolStripMenuItem();
+ this.Menu_Delete = new System.Windows.Forms.ToolStripMenuItem();
+ ((System.ComponentModel.ISupportInitialize)(this.NUD_Count)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.NUD_Uses)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.NUD_Flag0)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.NUD_Flag1)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.NUD_Flag2)).BeginInit();
+ this.CM_Hand.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // CB_ItemID
+ //
+ this.CB_ItemID.FormattingEnabled = true;
+ this.CB_ItemID.Location = new System.Drawing.Point(3, 3);
+ this.CB_ItemID.Name = "CB_ItemID";
+ this.CB_ItemID.Size = new System.Drawing.Size(141, 21);
+ this.CB_ItemID.TabIndex = 1;
+ //
+ // NUD_Count
+ //
+ this.NUD_Count.Location = new System.Drawing.Point(88, 28);
+ this.NUD_Count.Maximum = new decimal(new int[] {
+ 255,
+ 0,
+ 0,
+ 0});
+ this.NUD_Count.Name = "NUD_Count";
+ this.NUD_Count.Size = new System.Drawing.Size(56, 20);
+ this.NUD_Count.TabIndex = 2;
+ //
+ // L_Count
+ //
+ this.L_Count.Location = new System.Drawing.Point(3, 27);
+ this.L_Count.Name = "L_Count";
+ this.L_Count.Size = new System.Drawing.Size(79, 20);
+ this.L_Count.TabIndex = 7;
+ this.L_Count.Text = "Count:";
+ this.L_Count.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+ //
+ // L_Uses
+ //
+ this.L_Uses.Location = new System.Drawing.Point(3, 50);
+ this.L_Uses.Name = "L_Uses";
+ this.L_Uses.Size = new System.Drawing.Size(79, 20);
+ this.L_Uses.TabIndex = 9;
+ this.L_Uses.Text = "Uses:";
+ this.L_Uses.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+ //
+ // NUD_Uses
+ //
+ this.NUD_Uses.Location = new System.Drawing.Point(88, 51);
+ this.NUD_Uses.Maximum = new decimal(new int[] {
+ 255,
+ 0,
+ 0,
+ 0});
+ this.NUD_Uses.Name = "NUD_Uses";
+ this.NUD_Uses.Size = new System.Drawing.Size(56, 20);
+ this.NUD_Uses.TabIndex = 8;
+ //
+ // L_Flag0
+ //
+ this.L_Flag0.Location = new System.Drawing.Point(3, 73);
+ this.L_Flag0.Name = "L_Flag0";
+ this.L_Flag0.Size = new System.Drawing.Size(79, 20);
+ this.L_Flag0.TabIndex = 11;
+ this.L_Flag0.Text = "Flag0:";
+ this.L_Flag0.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+ //
+ // NUD_Flag0
+ //
+ this.NUD_Flag0.Hexadecimal = true;
+ this.NUD_Flag0.Location = new System.Drawing.Point(88, 74);
+ this.NUD_Flag0.Maximum = new decimal(new int[] {
+ 255,
+ 0,
+ 0,
+ 0});
+ this.NUD_Flag0.Name = "NUD_Flag0";
+ this.NUD_Flag0.Size = new System.Drawing.Size(56, 20);
+ this.NUD_Flag0.TabIndex = 10;
+ //
+ // L_Flag1
+ //
+ this.L_Flag1.Location = new System.Drawing.Point(3, 96);
+ this.L_Flag1.Name = "L_Flag1";
+ this.L_Flag1.Size = new System.Drawing.Size(79, 20);
+ this.L_Flag1.TabIndex = 13;
+ this.L_Flag1.Text = "Flag1:";
+ this.L_Flag1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+ //
+ // NUD_Flag1
+ //
+ this.NUD_Flag1.Hexadecimal = true;
+ this.NUD_Flag1.Location = new System.Drawing.Point(88, 97);
+ this.NUD_Flag1.Maximum = new decimal(new int[] {
+ 255,
+ 0,
+ 0,
+ 0});
+ this.NUD_Flag1.Name = "NUD_Flag1";
+ this.NUD_Flag1.Size = new System.Drawing.Size(56, 20);
+ this.NUD_Flag1.TabIndex = 12;
+ //
+ // L_Flag2
+ //
+ this.L_Flag2.Location = new System.Drawing.Point(3, 119);
+ this.L_Flag2.Name = "L_Flag2";
+ this.L_Flag2.Size = new System.Drawing.Size(79, 20);
+ this.L_Flag2.TabIndex = 15;
+ this.L_Flag2.Text = "Flag2:";
+ this.L_Flag2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+ //
+ // NUD_Flag2
+ //
+ this.NUD_Flag2.Hexadecimal = true;
+ this.NUD_Flag2.Location = new System.Drawing.Point(88, 120);
+ this.NUD_Flag2.Maximum = new decimal(new int[] {
+ 255,
+ 0,
+ 0,
+ 0});
+ this.NUD_Flag2.Name = "NUD_Flag2";
+ this.NUD_Flag2.Size = new System.Drawing.Size(56, 20);
+ this.NUD_Flag2.TabIndex = 14;
+ //
+ // CM_Hand
+ //
+ this.CM_Hand.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.Menu_View,
+ this.Menu_Set,
+ this.Menu_Delete});
+ this.CM_Hand.Name = "CM_Hand";
+ this.CM_Hand.Size = new System.Drawing.Size(108, 70);
+ //
+ // Menu_View
+ //
+ this.Menu_View.Name = "Menu_View";
+ this.Menu_View.Size = new System.Drawing.Size(107, 22);
+ this.Menu_View.Text = "View";
+ //
+ // Menu_Set
+ //
+ this.Menu_Set.Name = "Menu_Set";
+ this.Menu_Set.Size = new System.Drawing.Size(107, 22);
+ this.Menu_Set.Text = "Set";
+ //
+ // Menu_Delete
+ //
+ this.Menu_Delete.Name = "Menu_Delete";
+ this.Menu_Delete.Size = new System.Drawing.Size(107, 22);
+ this.Menu_Delete.Text = "Delete";
+ //
+ // ItemEditor
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.L_Flag2);
+ this.Controls.Add(this.NUD_Flag2);
+ this.Controls.Add(this.L_Flag1);
+ this.Controls.Add(this.NUD_Flag1);
+ this.Controls.Add(this.L_Flag0);
+ this.Controls.Add(this.NUD_Flag0);
+ this.Controls.Add(this.L_Uses);
+ this.Controls.Add(this.NUD_Uses);
+ this.Controls.Add(this.L_Count);
+ this.Controls.Add(this.NUD_Count);
+ this.Controls.Add(this.CB_ItemID);
+ this.Name = "ItemEditor";
+ this.Size = new System.Drawing.Size(148, 144);
+ ((System.ComponentModel.ISupportInitialize)(this.NUD_Count)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.NUD_Uses)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.NUD_Flag0)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.NUD_Flag1)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.NUD_Flag2)).EndInit();
+ this.CM_Hand.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+ private System.Windows.Forms.ComboBox CB_ItemID;
+ private System.Windows.Forms.NumericUpDown NUD_Count;
+ private System.Windows.Forms.Label L_Count;
+ private System.Windows.Forms.Label L_Uses;
+ private System.Windows.Forms.NumericUpDown NUD_Uses;
+ private System.Windows.Forms.Label L_Flag0;
+ private System.Windows.Forms.NumericUpDown NUD_Flag0;
+ private System.Windows.Forms.Label L_Flag1;
+ private System.Windows.Forms.NumericUpDown NUD_Flag1;
+ private System.Windows.Forms.Label L_Flag2;
+ private System.Windows.Forms.NumericUpDown NUD_Flag2;
+ private System.Windows.Forms.ContextMenuStrip CM_Hand;
+ private System.Windows.Forms.ToolStripMenuItem Menu_View;
+ private System.Windows.Forms.ToolStripMenuItem Menu_Set;
+ private System.Windows.Forms.ToolStripMenuItem Menu_Delete;
+ }
+}
diff --git a/NHSE.WinForms/Controls/ItemEditor.cs b/NHSE.WinForms/Controls/ItemEditor.cs
new file mode 100644
index 0000000..5d8c1d6
--- /dev/null
+++ b/NHSE.WinForms/Controls/ItemEditor.cs
@@ -0,0 +1,43 @@
+using System.Windows.Forms;
+using NHSE.Core;
+
+namespace NHSE.WinForms
+{
+ public partial class ItemEditor : UserControl
+ {
+ public ItemEditor()
+ {
+ InitializeComponent();
+ }
+
+ public void Initialize(string[] itemnames)
+ {
+ foreach (var item in itemnames)
+ CB_ItemID.Items.Add(item);
+
+ LoadItem(Item.NO_ITEM);
+ }
+
+ public Item LoadItem(Item item)
+ {
+ CB_ItemID.SelectedIndex = item.ItemId;
+ NUD_Count.Value = item.Count;
+ NUD_Uses.Value = item.UseCount;
+ NUD_Flag0.Value = item.Flags0;
+ NUD_Flag1.Value = item.Flags1;
+ NUD_Flag2.Value = item.Flags2;
+ return item;
+ }
+
+ public Item SetItem(Item item)
+ {
+ item.ItemId = (ushort) CB_ItemID.SelectedIndex;
+ item.Count = (byte) NUD_Count.Value;
+ item.UseCount = (ushort) NUD_Uses.Value;
+ item.Flags0 = (byte) NUD_Flag0.Value;
+ item.Flags1 = (byte) NUD_Flag1.Value;
+ item.Flags2 = (byte) NUD_Flag2.Value;
+ return item;
+ }
+ }
+}
diff --git a/NHSE.WinForms/Controls/ItemEditor.resx b/NHSE.WinForms/Controls/ItemEditor.resx
new file mode 100644
index 0000000..5c621e7
--- /dev/null
+++ b/NHSE.WinForms/Controls/ItemEditor.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/NHSE.WinForms/Controls/ItemGrid.Designer.cs b/NHSE.WinForms/Controls/ItemGrid.Designer.cs
new file mode 100644
index 0000000..8712efa
--- /dev/null
+++ b/NHSE.WinForms/Controls/ItemGrid.Designer.cs
@@ -0,0 +1,44 @@
+namespace NHSE.WinForms
+{
+ partial class ItemGrid
+ {
+ ///
+ /// 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 Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.SuspendLayout();
+ //
+ // ItemGrid
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Name = "ItemGrid";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+ }
+}
diff --git a/NHSE.WinForms/Controls/ItemGrid.cs b/NHSE.WinForms/Controls/ItemGrid.cs
new file mode 100644
index 0000000..98f239f
--- /dev/null
+++ b/NHSE.WinForms/Controls/ItemGrid.cs
@@ -0,0 +1,80 @@
+using System.Collections.Generic;
+using System.Drawing;
+using System.Diagnostics;
+using System.Windows.Forms;
+using NHSE.Core;
+
+namespace NHSE.WinForms
+{
+ public partial class ItemGrid : UserControl
+ {
+ public ItemGrid()
+ {
+ InitializeComponent();
+ }
+
+ public readonly List Entries = new List();
+ public int Slots { get; private set; }
+
+ private int sizeW = 32;
+ private int sizeH = 32;
+
+ public void InitializeGrid(int width, int height, IGridItem info)
+ {
+ sizeW = info.Width;
+ sizeH = info.Height;
+ Generate(width, height);
+ Slots = width * height;
+ }
+
+ private const int padEdge = 0; // edges
+ private const int border = 1; // between
+
+ private void Generate(int width, int height)
+ {
+ SuspendLayout();
+ Controls.Clear();
+ Entries.Clear();
+
+ int colWidth = sizeW;
+ int rowHeight = sizeH;
+
+ Location = new Point(0, Location.Y); // prevent auto-expanding parent if position changes (centered)
+ for (int row = 0; row < height; row++)
+ {
+ var y = padEdge + (row * (rowHeight + border));
+ for (int column = 0; column < width; column++)
+ {
+ var x = padEdge + (column * (colWidth + border));
+ var pb = GetControl(sizeW, sizeH);
+ pb.SuspendLayout();
+ Controls.Add(pb);
+ pb.Location = new Point(x, y);
+ Entries.Add(pb);
+ }
+ }
+
+ Width = (2 * padEdge) + border + (width * (colWidth + border)) + 2;
+ Height = (2 * padEdge) + border + (height * (rowHeight + border)) + 2;
+ Debug.WriteLine($"{Name} -- Width: {Width}, Height: {Height}");
+ ResumeLayout();
+ }
+
+ public void SetBackground(Image img) => BackgroundImage = img;
+
+ public static PictureBox GetControl(int width, int height)
+ {
+ return new PictureBox
+ {
+ AutoSize = false,
+ SizeMode = PictureBoxSizeMode.CenterImage,
+ BackColor = Color.Transparent,
+ Width = width + (2 * 1),
+ Height = height + (2 * 1),
+ Padding = Padding.Empty,
+ Margin = Padding.Empty,
+ BorderStyle = BorderStyle.FixedSingle,
+ };
+ }
+ }
+}
diff --git a/NHSE.WinForms/Controls/ItemGrid.resx b/NHSE.WinForms/Controls/ItemGrid.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/NHSE.WinForms/Controls/ItemGrid.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/Controls/ItemGridEditor.Designer.cs b/NHSE.WinForms/Controls/ItemGridEditor.Designer.cs
new file mode 100644
index 0000000..0d04f7b
--- /dev/null
+++ b/NHSE.WinForms/Controls/ItemGridEditor.Designer.cs
@@ -0,0 +1,153 @@
+namespace NHSE.WinForms
+{
+ partial class ItemGridEditor
+ {
+ ///
+ /// 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 Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.itemGrid1 = new NHSE.WinForms.ItemGrid();
+ this.B_Up = new System.Windows.Forms.Button();
+ this.B_Down = new System.Windows.Forms.Button();
+ this.L_Page = new System.Windows.Forms.Label();
+ this.L_ItemName = new System.Windows.Forms.Label();
+ this.CM_Hand = new System.Windows.Forms.ContextMenuStrip(this.components);
+ this.Menu_View = new System.Windows.Forms.ToolStripMenuItem();
+ this.Menu_Set = new System.Windows.Forms.ToolStripMenuItem();
+ this.Menu_Delete = new System.Windows.Forms.ToolStripMenuItem();
+ this.CM_Hand.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // itemGrid1
+ //
+ this.itemGrid1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.itemGrid1.Location = new System.Drawing.Point(1, 27);
+ this.itemGrid1.Margin = new System.Windows.Forms.Padding(0);
+ this.itemGrid1.Name = "itemGrid1";
+ this.itemGrid1.Size = new System.Drawing.Size(170, 142);
+ this.itemGrid1.TabIndex = 0;
+ //
+ // B_Up
+ //
+ this.B_Up.Location = new System.Drawing.Point(176, 53);
+ this.B_Up.Name = "B_Up";
+ this.B_Up.Size = new System.Drawing.Size(41, 30);
+ this.B_Up.TabIndex = 3;
+ this.B_Up.Text = "↑\t";
+ this.B_Up.UseVisualStyleBackColor = true;
+ this.B_Up.Visible = false;
+ this.B_Up.Click += new System.EventHandler(this.B_Up_Click);
+ //
+ // B_Down
+ //
+ this.B_Down.Location = new System.Drawing.Point(176, 106);
+ this.B_Down.Name = "B_Down";
+ this.B_Down.Size = new System.Drawing.Size(42, 29);
+ this.B_Down.TabIndex = 4;
+ this.B_Down.Text = "↓";
+ this.B_Down.UseVisualStyleBackColor = true;
+ this.B_Down.Visible = false;
+ this.B_Down.Click += new System.EventHandler(this.B_Down_Click);
+ //
+ // L_Page
+ //
+ this.L_Page.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.L_Page.Location = new System.Drawing.Point(169, 84);
+ this.L_Page.Name = "L_Page";
+ this.L_Page.Size = new System.Drawing.Size(56, 20);
+ this.L_Page.TabIndex = 5;
+ this.L_Page.Text = "250/250";
+ this.L_Page.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ //
+ // L_ItemName
+ //
+ this.L_ItemName.AutoSize = true;
+ this.L_ItemName.Location = new System.Drawing.Point(3, 9);
+ this.L_ItemName.Name = "L_ItemName";
+ this.L_ItemName.Size = new System.Drawing.Size(39, 13);
+ this.L_ItemName.TabIndex = 6;
+ this.L_ItemName.Text = "(None)";
+ //
+ // CM_Hand
+ //
+ this.CM_Hand.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.Menu_View,
+ this.Menu_Set,
+ this.Menu_Delete});
+ this.CM_Hand.Name = "CM_Hand";
+ this.CM_Hand.Size = new System.Drawing.Size(108, 70);
+ //
+ // Menu_View
+ //
+ this.Menu_View.Name = "Menu_View";
+ this.Menu_View.Size = new System.Drawing.Size(107, 22);
+ this.Menu_View.Text = "View";
+ this.Menu_View.Click += new System.EventHandler(this.ClickView);
+ //
+ // Menu_Set
+ //
+ this.Menu_Set.Name = "Menu_Set";
+ this.Menu_Set.Size = new System.Drawing.Size(107, 22);
+ this.Menu_Set.Text = "Set";
+ this.Menu_Set.Click += new System.EventHandler(this.ClickSet);
+ //
+ // Menu_Delete
+ //
+ this.Menu_Delete.Name = "Menu_Delete";
+ this.Menu_Delete.Size = new System.Drawing.Size(107, 22);
+ this.Menu_Delete.Text = "Delete";
+ this.Menu_Delete.Click += new System.EventHandler(this.ClickDelete);
+ //
+ // ItemGridEditor
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.L_ItemName);
+ this.Controls.Add(this.B_Down);
+ this.Controls.Add(this.B_Up);
+ this.Controls.Add(this.itemGrid1);
+ this.Controls.Add(this.L_Page);
+ this.Name = "ItemGridEditor";
+ this.Size = new System.Drawing.Size(224, 170);
+ this.CM_Hand.ResumeLayout(false);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private ItemGrid itemGrid1;
+ private System.Windows.Forms.Button B_Up;
+ private System.Windows.Forms.Button B_Down;
+ private System.Windows.Forms.Label L_Page;
+ private System.Windows.Forms.Label L_ItemName;
+ private System.Windows.Forms.ContextMenuStrip CM_Hand;
+ private System.Windows.Forms.ToolStripMenuItem Menu_View;
+ private System.Windows.Forms.ToolStripMenuItem Menu_Set;
+ private System.Windows.Forms.ToolStripMenuItem Menu_Delete;
+ }
+}
diff --git a/NHSE.WinForms/Controls/ItemGridEditor.cs b/NHSE.WinForms/Controls/ItemGridEditor.cs
new file mode 100644
index 0000000..5388330
--- /dev/null
+++ b/NHSE.WinForms/Controls/ItemGridEditor.cs
@@ -0,0 +1,195 @@
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+using NHSE.Core;
+using NHSE.Sprites;
+
+namespace NHSE.WinForms
+{
+ public partial class ItemGridEditor : UserControl
+ {
+ private static readonly ItemSpriteDrawer Sprites = SpriteUtil.Items;
+ private readonly ItemEditor Editor;
+ private readonly IReadOnlyList- Items;
+ private readonly string[] ItemNames;
+
+ private IList SlotPictureBoxes = Array.Empty();
+ private int Count => Items.Count;
+ private int Page;
+ private int ItemsPerPage;
+
+ public ItemGridEditor(ItemEditor editor, IReadOnlyList
- items, string[] itemnames)
+ {
+ Editor = editor;
+ Items = items;
+ ItemNames = itemnames;
+ InitializeComponent();
+
+ HoverItem(Item.NO_ITEM);
+ }
+
+ public void InitializeGrid(int width, int height)
+ {
+ ItemsPerPage = width * height;
+ itemGrid1.InitializeGrid(width, height, Sprites);
+ InitializeSlots();
+ }
+
+ private void InitializeSlots()
+ {
+ SlotPictureBoxes = itemGrid1.Entries;
+ foreach (var pb in SlotPictureBoxes)
+ {
+ pb.MouseEnter += Slot_MouseEnter;
+ pb.MouseLeave += Slot_MouseLeave;
+ pb.MouseClick += Slot_MouseClick;
+ pb.ContextMenuStrip = CM_Hand;
+ }
+ ChangePage();
+ }
+
+ public void Slot_MouseEnter(object? sender, EventArgs e)
+ {
+ if (!(sender is PictureBox pb))
+ return;
+ var index = SlotPictureBoxes.IndexOf(pb);
+ HoverItem(index);
+ pb.Image = Sprites.HoverBackground;
+ }
+
+ public void Slot_MouseLeave(object? sender, EventArgs e)
+ {
+ if (!(sender is PictureBox pb))
+ return;
+ pb.Image = null;
+ }
+
+ public void Slot_MouseClick(object sender, MouseEventArgs e)
+ {
+ switch (ModifierKeys)
+ {
+ case Keys.Control | Keys.Alt: ClickClone(sender, e); break;
+ case Keys.Control: ClickView(sender, e); break;
+ case Keys.Shift: ClickSet(sender, e); break;
+ case Keys.Alt: ClickDelete(sender, e); break;
+ default:
+ return;
+ }
+ // restart hovering since the mouse event isn't fired
+ Slot_MouseEnter(sender, e);
+ }
+
+ public Item HoverItem(int index) => HoverItem(GetItem(index));
+ public Item LoadItem(int index) => Editor.LoadItem(GetItem(index));
+ public Item SetItem(int index) => Editor.SetItem(GetItem(index));
+
+ private Item HoverItem(Item item)
+ {
+ L_ItemName.Text = ItemNames[item.ItemId == Item.NONE ? 0 : item.ItemId];
+ return item;
+ }
+
+ private Item GetItem(int index)
+ {
+ index += Page * ItemsPerPage;
+ return Items[index];
+ }
+
+ private void ClickView(object sender, EventArgs e)
+ {
+ var pb = WinFormsUtil.GetUnderlyingControl(sender);
+ if (pb == null)
+ return;
+ var index = SlotPictureBoxes.IndexOf(pb);
+ LoadItem(index);
+ }
+
+ private void ClickSet(object sender, EventArgs e)
+ {
+ var pb = WinFormsUtil.GetUnderlyingControl(sender);
+ if (pb == null)
+ return;
+ var index = SlotPictureBoxes.IndexOf(pb);
+ var item = SetItem(index);
+ pb.BackgroundImage = Sprites.GetImage(item, L_ItemName.Font);
+ }
+
+ private void ClickDelete(object sender, EventArgs e)
+ {
+ var pb = WinFormsUtil.GetUnderlyingControl(sender);
+ if (pb == null)
+ return;
+ var index = SlotPictureBoxes.IndexOf(pb);
+ var item = GetItem(index);
+ item.Delete();
+ pb.BackgroundImage = Sprites.GetImage(item, L_ItemName.Font);
+ }
+
+ private void ClickClone(object sender, EventArgs e)
+ {
+ var pb = WinFormsUtil.GetUnderlyingControl(sender);
+ if (pb == null)
+ return;
+ var index = SlotPictureBoxes.IndexOf(pb);
+ var item = GetItem(index);
+ for (int i = 0; i < SlotPictureBoxes.Count; i++)
+ {
+ if (i == index)
+ continue;
+ var dest = GetItem(i);
+ dest.CopyFrom(item);
+ SlotPictureBoxes[i].BackgroundImage = Sprites.GetImage(item, L_ItemName.Font);
+ }
+ System.Media.SystemSounds.Asterisk.Play();
+ }
+
+ private int GetPageJump()
+ {
+ return ModifierKeys switch
+ {
+ Keys.Control => 10,
+ Keys.Alt => 25,
+ Keys.Shift => 1000,
+ _ => 1
+ };
+ }
+
+ private void B_Up_Click(object sender, EventArgs e)
+ {
+ if (Page == 0)
+ return;
+ Page = Math.Max(0, Page - GetPageJump());
+ ChangePage();
+ }
+
+ private void B_Down_Click(object sender, EventArgs e)
+ {
+ if (ItemsPerPage * (Page + 1) == Count)
+ return;
+ Page = Math.Min(PageCount - 1, Page + GetPageJump());
+ ChangePage();
+ }
+
+ private int PageCount => Count / ItemsPerPage;
+
+ private void ChangePage()
+ {
+ bool hasPages = Count > ItemsPerPage;
+ B_Up.Visible = hasPages && Page > 0;
+ B_Down.Visible = hasPages && Page < PageCount;
+ L_Page.Visible = hasPages;
+
+ L_Page.Text = $"{Page + 1}/{Count / ItemsPerPage}";
+ LoadItems();
+ }
+
+ public void LoadItems()
+ {
+ for (int i = 0; i < SlotPictureBoxes.Count; i++)
+ {
+ var item = GetItem(i);
+ SlotPictureBoxes[i].BackgroundImage = Sprites.GetImage(item, L_ItemName.Font);
+ }
+ }
+ }
+}
diff --git a/NHSE.WinForms/Controls/ItemGridEditor.resx b/NHSE.WinForms/Controls/ItemGridEditor.resx
new file mode 100644
index 0000000..5c621e7
--- /dev/null
+++ b/NHSE.WinForms/Controls/ItemGridEditor.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 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
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/NHSE.WinForms/Editor.cs b/NHSE.WinForms/Editor.cs
index 1f3dfd6..15f4aae 100644
--- a/NHSE.WinForms/Editor.cs
+++ b/NHSE.WinForms/Editor.cs
@@ -93,8 +93,17 @@ private void LoadVillagers()
private void B_EditPlayerItems_Click(object sender, EventArgs e)
{
- using var editor = new InventoryEditor(SAV.Players[PlayerIndex]);
- editor.ShowDialog();
+ var player = SAV.Players[PlayerIndex];
+ if (ModifierKeys == Keys.Control)
+ {
+ using var editor = new InventoryEditor(player);
+ editor.ShowDialog();
+ }
+ else
+ {
+ using var editor = new PlayerItemEditor(player);
+ editor.ShowDialog();
+ }
}
private void LoadPlayer(int index)
diff --git a/NHSE.WinForms/NHSE.WinForms.csproj b/NHSE.WinForms/NHSE.WinForms.csproj
index a8a2550..988f6ab 100644
--- a/NHSE.WinForms/NHSE.WinForms.csproj
+++ b/NHSE.WinForms/NHSE.WinForms.csproj
@@ -20,6 +20,12 @@
+
+ UserControl
+
+
+ ItemEditor.cs
+
Form
diff --git a/NHSE.WinForms/Subforms/PlayerItemEditor.Designer.cs b/NHSE.WinForms/Subforms/PlayerItemEditor.Designer.cs
new file mode 100644
index 0000000..50feb71
--- /dev/null
+++ b/NHSE.WinForms/Subforms/PlayerItemEditor.Designer.cs
@@ -0,0 +1,107 @@
+namespace NHSE.WinForms
+{
+ partial class PlayerItemEditor
+ {
+ ///
+ /// 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.TC_Groups = new System.Windows.Forms.TabControl();
+ this.ItemEditor = new NHSE.WinForms.ItemEditor();
+ 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(244, 234);
+ this.B_Cancel.Name = "B_Cancel";
+ this.B_Cancel.Size = new System.Drawing.Size(72, 23);
+ this.B_Cancel.TabIndex = 5;
+ 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(322, 234);
+ this.B_Save.Name = "B_Save";
+ this.B_Save.Size = new System.Drawing.Size(72, 23);
+ this.B_Save.TabIndex = 4;
+ this.B_Save.Text = "Save";
+ this.B_Save.UseVisualStyleBackColor = true;
+ this.B_Save.Click += new System.EventHandler(this.B_Save_Click);
+ //
+ // TC_Groups
+ //
+ this.TC_Groups.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.TC_Groups.Location = new System.Drawing.Point(9, 9);
+ this.TC_Groups.Name = "TC_Groups";
+ this.TC_Groups.Padding = new System.Drawing.Point(9, 9);
+ this.TC_Groups.SelectedIndex = 0;
+ this.TC_Groups.Size = new System.Drawing.Size(233, 219);
+ this.TC_Groups.TabIndex = 3;
+ //
+ // ItemEditor
+ //
+ this.ItemEditor.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.ItemEditor.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.ItemEditor.Location = new System.Drawing.Point(244, 12);
+ this.ItemEditor.Name = "ItemEditor";
+ this.ItemEditor.Size = new System.Drawing.Size(150, 216);
+ this.ItemEditor.TabIndex = 6;
+ //
+ // PlayerItemEditor
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(406, 267);
+ this.Controls.Add(this.ItemEditor);
+ this.Controls.Add(this.B_Cancel);
+ this.Controls.Add(this.B_Save);
+ this.Controls.Add(this.TC_Groups);
+ this.Icon = global::NHSE.WinForms.Properties.Resources.icon;
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "PlayerItemEditor";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "Inventory Editor";
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Button B_Cancel;
+ private System.Windows.Forms.Button B_Save;
+ private System.Windows.Forms.TabControl TC_Groups;
+ private ItemEditor ItemEditor;
+ }
+}
\ No newline at end of file
diff --git a/NHSE.WinForms/Subforms/PlayerItemEditor.cs b/NHSE.WinForms/Subforms/PlayerItemEditor.cs
new file mode 100644
index 0000000..055362f
--- /dev/null
+++ b/NHSE.WinForms/Subforms/PlayerItemEditor.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using NHSE.Core;
+
+namespace NHSE.WinForms
+{
+ public partial class PlayerItemEditor : Form
+ {
+ private readonly Player Player;
+ private readonly InventorySet[] Inventory;
+ private readonly string[] items;
+
+ public PlayerItemEditor(Player player)
+ {
+ InitializeComponent();
+
+ Player = player;
+ Inventory = GetInventory(player);
+ items = GameInfo.Strings.itemlist.ToArray(); // simple copy, we're gonna mutate
+
+ var set = new HashSet();
+ for (int i = 0; i < items.Length; i++)
+ {
+ var item = items[i];
+ if (string.IsNullOrEmpty(item))
+ items[i] = $"(Item #{i:000})";
+ else if (set.Contains(item))
+ items[i] += $" (#{i:000})";
+ else
+ set.Add(item);
+ }
+
+ ItemEditor.Initialize(items);
+ CreateTabs();
+ }
+
+ private void CreateTabs()
+ {
+ var i = items;
+ foreach (var p in Inventory)
+ {
+ var tab = new TabPage { Name = $"Tab_{p.Type}", Text = p.Type.ToString() };
+ var grid = new ItemGridEditor(ItemEditor, p.Items, i) { Dock = DockStyle.Fill };
+ grid.InitializeGrid(5, 4);
+ tab.Controls.Add(grid);
+ TC_Groups.TabPages.Add(tab);
+ TC_Groups.ShowToolTips = true;
+ tab.ToolTipText = p.Type.ToString();
+ }
+ }
+
+ private static InventorySet[] GetInventory(Player player)
+ {
+ return new[]
+ {
+ new InventorySet(InventoryType.Pocket1, player.Personal.Pocket2),
+ new InventorySet(InventoryType.Pocket2, player.Personal.Pocket1),
+ new InventorySet(InventoryType.Storage, player.Personal.Storage),
+ };
+ }
+
+ private void SetInventory(Player player)
+ {
+ player.Personal.Pocket2 = Inventory[0].Items;
+ player.Personal.Pocket1 = Inventory[1].Items;
+ player.Personal.Storage = Inventory[2].Items;
+ }
+
+ private void B_Cancel_Click(object sender, EventArgs e) => Close();
+
+ private void B_Save_Click(object sender, EventArgs e)
+ {
+ SetInventory(Player);
+ Close();
+ }
+ }
+}
diff --git a/NHSE.WinForms/Subforms/PlayerItemEditor.resx b/NHSE.WinForms/Subforms/PlayerItemEditor.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/NHSE.WinForms/Subforms/PlayerItemEditor.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