Add house editor

only some surface appearance properties; interior item layout nope
use enum values for house info interface

Closes #95
Closes #96

Changes the displayed villager indexes from 1-indexed to 0-indexed to match the game's references.
This commit is contained in:
Kurt 2020-04-22 21:55:24 -07:00
parent f9d397004a
commit de48c037f9
11 changed files with 435 additions and 112 deletions

View File

@ -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<VillagerHouse> houses)
{
for (int i = 0; i < houses.Count; i++)
SetVillagerHouse(houses[i], i);
}
private const int EventFlagsSaveCount = 0x400;
public short[] GetEventFlagLand()

View File

@ -1,6 +1,6 @@
namespace NHSE.Core
{
public enum DoorKind
public enum DoorKind : ushort
{
HouseDoorStandardAR = 0x00,
HouseDoorStandardAS = 0x02,

View File

@ -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; }
}

View File

@ -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; }

View File

@ -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; }

View File

@ -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;
}
}

View File

@ -22,8 +22,7 @@ public VillagerEditor(Villager[] villagers, IVillagerOrigin origin, MainSave 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<VillagerHouse>();
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);
}
}
}

View File

@ -43,6 +43,9 @@
<Compile Update="Subforms\Map\LandFlagEditor.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="Subforms\Map\VillagerHouseEditor.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="Subforms\Player\FlagEditor.cs">
<SubType>Form</SubType>
</Compile>

View File

@ -0,0 +1,137 @@
namespace NHSE.WinForms
{
partial class VillagerHouseEditor
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
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;
}
}

View File

@ -0,0 +1,121 @@
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<Villager> Villagers;
private int Index;
public VillagerHouseEditor(VillagerHouse[] houses, IReadOnlyList<Villager> 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<VillagerHouse>();
var current = Houses[Index];
h.NPC1 = current.NPC1;
Houses[Index] = h;
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>