Add villager item editing

Furniture array is inside the villager's item list; there's another list of a different format in the offsets below

probably just a struct within another struct, like

struct villagerItem {
item; (0x08 bytes)
metadata; (0x24 bytes)
}
This commit is contained in:
Kurt 2020-03-29 17:12:41 -07:00
parent 39398b4f66
commit da4b292588
5 changed files with 61 additions and 16 deletions

View File

@ -4,7 +4,7 @@
namespace NHSE.Core
{
[StructLayout(LayoutKind.Sequential)]
public sealed class Item
public class Item
{
public static readonly Item NO_ITEM = new Item {ItemId = NONE};
public const ushort NONE = 0xFFFE;
@ -55,21 +55,8 @@ public void CopyFrom(Item item)
UseCount = item.UseCount;
}
public static Item[] GetArray(byte[] data)
{
var result = new Item[data.Length / SIZE];
for (int i = 0; i < result.Length; i++)
result[i] = data.Slice(i * SIZE, SIZE).ToClass<Item>();
return result;
}
public static byte[] SetArray(IReadOnlyList<Item> data)
{
var result = new byte[data.Count * SIZE];
for (int i = 0; i < data.Count; i++)
data[i].ToBytesClass().CopyTo(result, i * SIZE);
return result;
}
public static Item[] GetArray(byte[] data) => data.GetArray<Item>(SIZE);
public static byte[] SetArray(IReadOnlyList<Item> data) => data.SetArray(SIZE);
public ushort GetInventoryNameFromFlags()
{
@ -85,4 +72,13 @@ public ushort GetInventoryNameFromFlags()
};
}
}
[StructLayout(LayoutKind.Sequential)]
public sealed class VillagerItem : Item
{
public new const int SIZE = 0x2C;
public uint U08, U0C, U10, U14, U18, U1C, U20, U24, U28;
public new static VillagerItem[] GetArray(byte[] data) => data.GetArray<VillagerItem>(SIZE);
public static byte[] SetArray(IReadOnlyList<VillagerItem> data) => data.SetArray(SIZE);
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace NHSE.Core
@ -65,6 +66,12 @@ public string CatchPhrase
set => GetBytes(value, 2 * 12).CopyTo(Data, 0x10014);
}
public IReadOnlyList<VillagerItem> Furniture
{
get => VillagerItem.GetArray(Data.Slice(0x105EC, 16 * VillagerItem.SIZE));
set => VillagerItem.SetArray(value).CopyTo(Data, 0x105EC);
}
public override string ToString() => InternalName;
public string InternalName => VillagerUtil.GetInternalVillagerName((VillagerSpecies) Species, Variant);
public int Gender => ((int)Personality / 4) & 1; // 0 = M, 1 = F

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace NHSE.Core
@ -45,5 +46,21 @@ internal static class StructConverter
Marshal.FreeHGlobal(ptr);
return arr;
}
public static T[] GetArray<T>(this byte[] data, int size) where T : class
{
var result = new T[data.Length / size];
for (int i = 0; i < result.Length; i++)
result[i] = data.Slice(i * size, size).ToClass<T>();
return result;
}
public static byte[] SetArray<T>(this IReadOnlyList<T> data, int size) where T : class
{
var result = new byte[data.Count * size];
for (int i = 0; i < data.Count; i++)
data[i].ToBytesClass().CopyTo(result, i * size);
return result;
}
}
}

View File

@ -74,6 +74,7 @@ private void InitializeComponent()
this.B_RecycleBin = new System.Windows.Forms.Button();
this.Menu_LoadDecrypted = new System.Windows.Forms.ToolStripMenuItem();
this.B_LoadVillager = new System.Windows.Forms.Button();
this.B_EditFurniture = new System.Windows.Forms.Button();
this.Menu_Editor.SuspendLayout();
this.TC_Editors.SuspendLayout();
this.Tab_Players.SuspendLayout();
@ -353,6 +354,7 @@ private void InitializeComponent()
//
// Tab_Villagers
//
this.Tab_Villagers.Controls.Add(this.B_EditFurniture);
this.Tab_Villagers.Controls.Add(this.B_LoadVillager);
this.Tab_Villagers.Controls.Add(this.B_DumpVillager);
this.Tab_Villagers.Controls.Add(this.L_ExternalName);
@ -566,6 +568,16 @@ private void InitializeComponent()
this.B_LoadVillager.UseVisualStyleBackColor = true;
this.B_LoadVillager.Click += new System.EventHandler(this.B_LoadVillager_Click);
//
// B_EditFurniture
//
this.B_EditFurniture.Location = new System.Drawing.Point(218, 168);
this.B_EditFurniture.Name = "B_EditFurniture";
this.B_EditFurniture.Size = new System.Drawing.Size(100, 40);
this.B_EditFurniture.TabIndex = 26;
this.B_EditFurniture.Text = "Edit Furniture";
this.B_EditFurniture.UseVisualStyleBackColor = true;
this.B_EditFurniture.Click += new System.EventHandler(this.B_EditFurniture_Click);
//
// Editor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -648,6 +660,7 @@ private void InitializeComponent()
private System.Windows.Forms.Button B_EditPlayerStorage;
private System.Windows.Forms.ToolStripMenuItem Menu_LoadDecrypted;
private System.Windows.Forms.Button B_LoadVillager;
private System.Windows.Forms.Button B_EditFurniture;
}
}

View File

@ -351,5 +351,17 @@ private void B_LoadVillager_Click(object sender, EventArgs e)
SAV.Main.SetVillager(v, VillagerIndex);
}
private void B_EditFurniture_Click(object sender, EventArgs e)
{
var v = SAV.Main.GetVillager(VillagerIndex);
var items = v.Furniture;
using var editor = new PlayerItemEditor(items, 8, 2);
if (editor.ShowDialog() != DialogResult.OK)
return;
v.Furniture = items;
SAV.Main.SetVillager(v, VillagerIndex);
}
}
}