Rough draft area editor

This commit is contained in:
Kurt
2022-02-19 14:20:00 -08:00
parent d27891407a
commit a14c203ff3
18 changed files with 660 additions and 94 deletions

View File

@@ -98,6 +98,7 @@ private void ReadPack(BinaryReader br)
}
public int GetIndexFull(ulong hash) => Array.FindIndex(HashAbsolute, z => z.HashFnv1aPathFull == hash);
public int GetIndexFull(string path) => GetIndexFull(FnvHash.HashFnv1a_64(path));
public int GetIndexFileName(ulong hash)
{

View File

@@ -68,7 +68,7 @@ public string Field_22_Value
public IEnumerable<PlacementLocation8a> GetIntersectingLocations(IReadOnlyList<PlacementLocation8a> locations, float bias)
{
var c = Parameters.Coordinates;
return GetIntersectingLocations(locations, bias, c, Scalar + bias);
return GetIntersectingLocations(locations, bias, c, Scalar);
}
private static IEnumerable<PlacementLocation8a> GetIntersectingLocations(IReadOnlyList<PlacementLocation8a> locations, float bias, PlacementV3f8a c, float scalar)
@@ -78,7 +78,7 @@ private static IEnumerable<PlacementLocation8a> GetIntersectingLocations(IReadOn
{
if (!loc.IsNamedPlace)
continue;
if (loc.IntersectsSphere(c.X, c.Y, c.Z, scalar))
if (loc.IntersectsSphere(c.X, c.Y, c.Z, scalar + bias))
result.Add(loc);
}
@@ -141,24 +141,23 @@ public IEnumerable<PlacementLocation8a> GetContainingLocations(IReadOnlyList<Pla
result[FnvHash.HashFnv1a_64($"ex_trs_{i:00}")] = $"ex_trs_{i:00}";
}
result[FnvHash.HashFnv1a_64($"ha_area01_s01_ev001")] = $"ha_area01_s01_ev001";
result[FnvHash.HashFnv1a_64($"ha_area02_s02_ev001")] = $"ha_area02_s02_ev001";
result[FnvHash.HashFnv1a_64($"ha_area02_s02_ev002")] = $"ha_area02_s02_ev002";
result[FnvHash.HashFnv1a_64($"ha_area03_s03_ev001")] = $"ha_area03_s03_ev001";
result[FnvHash.HashFnv1a_64($"ha_area04_ev001")] = $"ha_area04_ev001";
result[FnvHash.HashFnv1a_64($"ha_area05_s03_ev001")] = $"ha_area05_s03_ev001";
result[FnvHash.HashFnv1a_64("ha_area01_s01_ev001")] = "ha_area01_s01_ev001";
result[FnvHash.HashFnv1a_64("ha_area02_s02_ev001")] = "ha_area02_s02_ev001";
result[FnvHash.HashFnv1a_64("ha_area02_s02_ev002")] = "ha_area02_s02_ev002";
result[FnvHash.HashFnv1a_64("ha_area03_s03_ev001")] = "ha_area03_s03_ev001";
result[FnvHash.HashFnv1a_64("ha_area04_ev001")] = "ha_area04_ev001";
result[FnvHash.HashFnv1a_64("ha_area05_s03_ev001")] = "ha_area05_s03_ev001";
result[FnvHash.HashFnv1a_64($"area03_s04_ev001")] = $"area03_s04_ev001";
result[FnvHash.HashFnv1a_64($"area03_s04_ev002")] = $"area03_s04_ev002";
result[FnvHash.HashFnv1a_64($"area03_s04_ev003")] = $"area03_s04_ev003";
result[FnvHash.HashFnv1a_64($"area03_s04_ev004")] = $"area03_s04_ev004";
result[FnvHash.HashFnv1a_64($"area03_s04_ev005")] = $"area03_s04_ev005";
result[FnvHash.HashFnv1a_64("area03_s04_ev001")] = "area03_s04_ev001";
result[FnvHash.HashFnv1a_64("area03_s04_ev002")] = "area03_s04_ev002";
result[FnvHash.HashFnv1a_64("area03_s04_ev003")] = "area03_s04_ev003";
result[FnvHash.HashFnv1a_64("area03_s04_ev004")] = "area03_s04_ev004";
result[FnvHash.HashFnv1a_64("area03_s04_ev005")] = "area03_s04_ev005";
// 1.0.2
result[FnvHash.HashFnv1a_64($"ha_area01_s01_1000")] = $"ha_area01_s01_1000";
result[FnvHash.HashFnv1a_64($"ha_area02_s02_1000")] = $"ha_area02_s02_1000";
result[FnvHash.HashFnv1a_64($"ha_area05_s03_1000")] = $"ha_area05_s03_1000";
result[FnvHash.HashFnv1a_64("ha_area01_s01_1000")] = "ha_area01_s01_1000";
result[FnvHash.HashFnv1a_64("ha_area02_s02_1000")] = "ha_area02_s02_1000";
result[FnvHash.HashFnv1a_64("ha_area05_s03_1000")] = "ha_area05_s03_1000";
for (var wh = 1; wh < 8; wh++)
{

View File

@@ -40,7 +40,7 @@ public PlacementParameters8a Parameters
public IEnumerable<PlacementLocation8a> GetIntersectingLocations(IReadOnlyList<PlacementLocation8a> locations, float bias)
{
var c = Parameters.Coordinates;
return GetIntersectingLocations(locations, bias, c, 0 + bias);
return GetIntersectingLocations(locations, bias, c, 0);
}
private static IEnumerable<PlacementLocation8a> GetIntersectingLocations(IReadOnlyList<PlacementLocation8a> locations, float bias, PlacementV3f8a c, float scalar)
@@ -50,7 +50,7 @@ private static IEnumerable<PlacementLocation8a> GetIntersectingLocations(IReadOn
{
if (!loc.IsNamedPlace)
continue;
if (loc.IntersectsSphere(c.X, c.Y, c.Z, scalar))
if (loc.IntersectsSphere(c.X, c.Y, c.Z, scalar + bias))
result.Add(loc);
}

View File

@@ -1,5 +1,4 @@
using System;
using pkNX.Containers;
using pkNX.Containers;
using System.Collections.Generic;
namespace pkNX.Structures.FlatBuffers;
@@ -8,77 +7,34 @@ namespace pkNX.Structures.FlatBuffers;
public sealed class AreaInstance8a
{
// Area Info
private readonly ResidentArea8a Area;
public readonly AreaInstance8a? ParentArea;
private readonly List<AreaInstance8a> Children = new();
private readonly AreaSettings8a Settings;
private readonly GFPack Resident;
public string AreaName => Settings.Name;
public bool IsSubArea => ParentArea != null;
public IReadOnlyList<AreaInstance8a> SubAreas => Children;
public string AreaName => Area.AreaName;
// Encount
public EncounterTable8a[] Encounters { get; private set; } = Array.Empty<EncounterTable8a>();
public EncounterTable8a[] Encounters => Area.Encounters;
// Placement
public PlacementLocation8a[] Locations { get; private set; } = Array.Empty<PlacementLocation8a>();
public PlacementSpawner8a[] Spawners { get; private set; } = Array.Empty<PlacementSpawner8a>();
public PlacementSpawner8a[] Wormholes { get; private set; } = Array.Empty<PlacementSpawner8a>();
public LandmarkItemSpawn8a[] LandItems { get; private set; } = Array.Empty<LandmarkItemSpawn8a>();
public LandmarkItem8a[] LandMarks { get; private set; } = Array.Empty<LandmarkItem8a>();
public PlacementUnnnEntry[] Unown { get; private set; } = Array.Empty<PlacementUnnnEntry>();
public PlacementMkrgEntry[] Mikaruge { get; private set; } = Array.Empty<PlacementMkrgEntry>();
public PlacementSearchItem[] SearchItem { get; private set; } = Array.Empty<PlacementSearchItem>();
public PlacementLocation8a[] Locations => Area.Locations;
public PlacementSpawner8a[] Spawners => Area.Spawners;
public PlacementSpawner8a[] Wormholes => Area.Wormholes;
public LandmarkItemSpawn8a[] LandItems => Area.LandItems;
public LandmarkItem8a[] LandMarks => Area.LandMarks;
public PlacementUnnnEntry[] Unown => Area.Unown;
public PlacementMkrgEntry[] Mikaruge => Area.Mikaruge;
public PlacementSearchItem[] SearchItem => Area.SearchItem;
private AreaInstance8a(GFPack resident, AreaSettings8a settings, AreaInstance8a? parentArea = null)
{
// General area properties
Resident = resident;
Settings = settings;
Area = new ResidentArea8a(resident, settings);
ParentArea = parentArea;
LoadInfo();
Area.LoadInfo();
}
private void LoadInfo()
{
// Load encount
var enc = Resident.GetDataFullPath(Settings.Encounters);
Encounters = FlatBufferConverter.DeserializeFrom<EncounterDataArchive8a>(enc).Table;
// Load placement
var locationf = Resident.GetDataFullPath(Settings.Locations);
var spawnerf = Resident.GetDataFullPath(Settings.Spawners);
var wh_spawnerf = Resident.GetDataFullPath(Settings.WormholeSpawners);
var l_spawnerf = Resident.GetDataFullPath(Settings.LandmarkItemSpawns);
var l_markf = Resident.GetDataFullPath(Settings.LandmarkItems);
var unnf = Resident.GetDataFullPath(Settings.UnownSpawners);
var mkrgf = Resident.GetDataFullPath(Settings.Mkrg);
var psif = Resident.GetDataFullPath(Settings.SearchItem);
Locations = FlatBufferConverter.DeserializeFrom<PlacementLocationArchive8a>(locationf).Table;
Spawners = FlatBufferConverter.DeserializeFrom<PlacementSpawnerArchive8a>(spawnerf).Table;
Wormholes = FlatBufferConverter.DeserializeFrom<PlacementSpawnerArchive8a>(wh_spawnerf).Table;
LandItems = FlatBufferConverter.DeserializeFrom<LandmarkItemSpawnTable8a>(l_spawnerf).Table;
LandMarks = FlatBufferConverter.DeserializeFrom<LandmarkItemTable8a>(l_markf).Table;
Unown = FlatBufferConverter.DeserializeFrom<PlacementUnnnTable>(unnf).Table;
Mikaruge = FlatBufferConverter.DeserializeFrom<PlacementMkrgTable>(mkrgf).Table;
SearchItem = FlatBufferConverter.DeserializeFrom<PlacementSearchItemTable>(psif).Table;
}
private void SaveInfo()
{
Resident.SetDataFullPath(Settings.Encounters, new EncounterDataArchive8a { Table = Encounters }.Write());
Resident.SetDataFullPath(Settings.Locations, new PlacementLocationArchive8a { Table = Locations }.Write());
Resident.SetDataFullPath(Settings.Spawners, new PlacementSpawnerArchive8a { Table = Spawners }.Write());
Resident.SetDataFullPath(Settings.WormholeSpawners, new PlacementSpawnerArchive8a { Table = Wormholes }.Write());
Resident.SetDataFullPath(Settings.LandmarkItemSpawns, new LandmarkItemSpawnTable8a { Table = LandItems }.Write());
Resident.SetDataFullPath(Settings.LandmarkItems, new LandmarkItemTable8a { Table = LandMarks }.Write());
Resident.SetDataFullPath(Settings.UnownSpawners, new PlacementUnnnTable { Table = Unown }.Write());
Resident.SetDataFullPath(Settings.Mkrg, new PlacementMkrgTable { Table = Mikaruge }.Write());
Resident.SetDataFullPath(Settings.SearchItem, new PlacementSearchItemTable { Table = SearchItem }.Write());
}
public static AreaInstance8a Create(GFPack resident, ResidentAreaSet areaNameList, AreaSettingsTable8a settingsTable)
{
var parentSettings = settingsTable.Find(areaNameList.ParentName);

View File

@@ -0,0 +1,81 @@
using System;
using pkNX.Containers;
namespace pkNX.Structures.FlatBuffers;
// Not a flatbuffer; wraps the fields into a single object.
public sealed class ResidentArea8a
{
public readonly AreaSettings8a Settings;
private readonly GFPack Resident;
public ResidentArea8a(GFPack resident, AreaSettings8a settings)
{
Resident = resident;
Settings = settings;
}
public string AreaName => Settings.Name;
// Encount
public EncounterTable8a[] Encounters { get; private set; } = Array.Empty<EncounterTable8a>();
// Placement
public PlacementLocation8a[] Locations { get; private set; } = Array.Empty<PlacementLocation8a>();
public PlacementSpawner8a[] Spawners { get; private set; } = Array.Empty<PlacementSpawner8a>();
public PlacementSpawner8a[] Wormholes { get; private set; } = Array.Empty<PlacementSpawner8a>();
public LandmarkItemSpawn8a[] LandItems { get; private set; } = Array.Empty<LandmarkItemSpawn8a>();
public LandmarkItem8a[] LandMarks { get; private set; } = Array.Empty<LandmarkItem8a>();
public PlacementUnnnEntry[] Unown { get; private set; } = Array.Empty<PlacementUnnnEntry>();
public PlacementMkrgEntry[] Mikaruge { get; private set; } = Array.Empty<PlacementMkrgEntry>();
public PlacementSearchItem[] SearchItem { get; private set; } = Array.Empty<PlacementSearchItem>();
private T2[] TryRead<T1, T2>(string path) where T1 : class, IFlatBufferArchive<T2> where T2 : class
{
var index = Resident.GetIndexFull(path);
if (index == -1)
return Array.Empty<T2>();
var data = Resident[index];
return FlatBufferConverter.DeserializeFrom<T1>(data).Table;
}
private void TryWrite(string path, byte[] obj)
{
var index = Resident.GetIndexFull(path);
if (index == -1)
return;
Resident[index] = obj;
}
private void TryWrite<T1>(string path, T1 obj) where T1 : class =>
TryWrite(path, FlatBufferConverter.SerializeFrom(obj));
public void LoadInfo()
{
// Load encount
Encounters = TryRead<EncounterDataArchive8a , EncounterTable8a >(Settings.Encounters);
Locations = TryRead<PlacementLocationArchive8a, PlacementLocation8a >(Settings.Locations);
Spawners = TryRead<PlacementSpawnerArchive8a , PlacementSpawner8a >(Settings.Spawners);
Wormholes = TryRead<PlacementSpawnerArchive8a , PlacementSpawner8a >(Settings.WormholeSpawners);
LandItems = TryRead<LandmarkItemSpawnTable8a , LandmarkItemSpawn8a >(Settings.LandmarkItemSpawns);
LandMarks = TryRead<LandmarkItemTable8a , LandmarkItem8a >(Settings.LandmarkItems);
Unown = TryRead<PlacementUnnnTable , PlacementUnnnEntry >(Settings.UnownSpawners);
Mikaruge = TryRead<PlacementMkrgTable , PlacementMkrgEntry >(Settings.Mkrg);
SearchItem = TryRead<PlacementSearchItemTable , PlacementSearchItem >(Settings.SearchItem);
}
public void SaveInfo()
{
TryWrite(Settings.Encounters, new EncounterDataArchive8a { Table = Encounters }.Write());
TryWrite(Settings.Locations, new PlacementLocationArchive8a { Table = Locations }.Write());
TryWrite(Settings.Spawners, new PlacementSpawnerArchive8a { Table = Spawners }.Write());
TryWrite(Settings.WormholeSpawners, new PlacementSpawnerArchive8a { Table = Wormholes }.Write());
TryWrite(Settings.LandmarkItemSpawns, new LandmarkItemSpawnTable8a { Table = LandItems }.Write());
TryWrite(Settings.LandmarkItems, new LandmarkItemTable8a { Table = LandMarks }.Write());
TryWrite(Settings.UnownSpawners, new PlacementUnnnTable { Table = Unown }.Write());
TryWrite(Settings.Mkrg, new PlacementMkrgTable { Table = Mikaruge }.Write());
TryWrite(Settings.SearchItem, new PlacementSearchItemTable { Table = SearchItem }.Write());
}
}

View File

@@ -6,7 +6,7 @@ namespace pkNX.Structures.FlatBuffers;
/// <summary>
/// Manually entered metadata about the interesting areas.
/// </summary>
public class ResidentAreaSet
public sealed class ResidentAreaSet
{
public readonly string ParentName;
public readonly IReadOnlyList<string> SubAreas;

View File

@@ -27,9 +27,10 @@ public class EncounterTable8a
private static Dictionary<ulong, string> GenerateTableMap()
{
var result = new Dictionary<ulong, string>();
result[0xCBF29CE484222645] = "";
var result = new Dictionary<ulong, string>
{
[0xCBF29CE484222645] = "",
};
var prefixes = new[] { "eve", "fly", "gmk", "lnd", "mas", "oyb", "swm", "whl" };
var kinds = new[] { "ex", "no", "ra" };

View File

@@ -7,7 +7,6 @@
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
#pragma warning disable CA1819 // Properties should not return arrays
namespace pkNX.Structures.FlatBuffers
{

View File

@@ -0,0 +1,100 @@
namespace pkNX.WinForms.Controls
{
partial class EncounterTableEditor8a
{
/// <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 Component 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_NoShinyLocks = new System.Windows.Forms.Button();
this.PG_Encounters = new System.Windows.Forms.PropertyGrid();
this.CB_Encounters = new System.Windows.Forms.ComboBox();
this.L_EncTableName = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// B_NoShinyLocks
//
this.B_NoShinyLocks.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.B_NoShinyLocks.Location = new System.Drawing.Point(614, 0);
this.B_NoShinyLocks.Name = "B_NoShinyLocks";
this.B_NoShinyLocks.Size = new System.Drawing.Size(148, 23);
this.B_NoShinyLocks.TabIndex = 8;
this.B_NoShinyLocks.Text = "Remove All Shiny Locks";
this.B_NoShinyLocks.UseVisualStyleBackColor = true;
this.B_NoShinyLocks.Click += new System.EventHandler(this.B_NoShinyLocks_Click);
//
// PG_Encounters
//
this.PG_Encounters.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_Encounters.Location = new System.Drawing.Point(3, 38);
this.PG_Encounters.Name = "PG_Encounters";
this.PG_Encounters.Size = new System.Drawing.Size(759, 548);
this.PG_Encounters.TabIndex = 7;
//
// CB_Encounters
//
this.CB_Encounters.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
this.CB_Encounters.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
this.CB_Encounters.FormattingEnabled = true;
this.CB_Encounters.Location = new System.Drawing.Point(3, 15);
this.CB_Encounters.Name = "CB_Encounters";
this.CB_Encounters.Size = new System.Drawing.Size(174, 21);
this.CB_Encounters.TabIndex = 6;
this.CB_Encounters.SelectedIndexChanged += new System.EventHandler(this.CB_Encounters_SelectedIndexChanged);
//
// L_EncTableName
//
this.L_EncTableName.AutoSize = true;
this.L_EncTableName.Location = new System.Drawing.Point(3, 1);
this.L_EncTableName.Name = "L_EncTableName";
this.L_EncTableName.Size = new System.Drawing.Size(35, 13);
this.L_EncTableName.TabIndex = 9;
this.L_EncTableName.Text = "label1";
//
// EncounterTableEditor8a
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.L_EncTableName);
this.Controls.Add(this.B_NoShinyLocks);
this.Controls.Add(this.PG_Encounters);
this.Controls.Add(this.CB_Encounters);
this.Name = "EncounterTableEditor8a";
this.Size = new System.Drawing.Size(765, 589);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button B_NoShinyLocks;
private System.Windows.Forms.PropertyGrid PG_Encounters;
private System.Windows.Forms.ComboBox CB_Encounters;
private System.Windows.Forms.Label L_EncTableName;
}
}

View File

@@ -0,0 +1,61 @@
using System;
using System.Linq;
using System.Windows.Forms;
using pkNX.Structures.FlatBuffers;
namespace pkNX.WinForms.Controls;
public partial class EncounterTableEditor8a : UserControl
{
public EncounterTable8a[] Tables = Array.Empty<EncounterTable8a>();
public EncounterTableEditor8a() => InitializeComponent();
public void LoadTable(EncounterTable8a[] table, string path)
{
Tables = table;
L_EncTableName.Text = path;
var items = table.Select(z => new ComboItem(z.TableName.Replace("\"", ""), z)).ToArray();
CB_Encounters.DisplayMember = nameof(ComboItem.Text);
CB_Encounters.ValueMember = nameof(ComboItem.Value);
CB_Encounters.DataSource = new BindingSource(items, null);
CB_Encounters.SelectedIndex = 0;
}
private class ComboItem
{
public ComboItem(string text, EncounterTable8a value)
{
Text = text;
Value = value;
}
public string Text { get; }
public EncounterTable8a Value { get; }
}
private void CB_Encounters_SelectedIndexChanged(object sender, EventArgs e)
{
PG_Encounters.SelectedObject = (EncounterTable8a)CB_Encounters.SelectedValue;
}
private void B_NoShinyLocks_Click(object sender, EventArgs e)
{
int ctr = 0;
foreach (var table in Tables)
{
foreach (var slot in table.Table)
{
if (slot.ShinyLock != ShinyType8a.Never)
continue;
slot.ShinyLock = ShinyType8a.Random;
ctr++;
}
}
WinFormsUtil.Alert($"Removed {ctr} locked slots.");
CB_Encounters_SelectedIndexChanged(sender, e);
}
}

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>

View File

@@ -375,7 +375,8 @@ public void DumpWilds()
var residentpak = ROM.GetFile(GameFile.Resident)[0];
var resident = new GFPack(residentpak);
var settings = FlatBufferConverter.DeserializeFrom<AreaSettingsTable8a>(resident[2042]);
var bin_settings = resident.GetDataFullPath("bin/field/resident/AreaSettings.bin");
var settings = FlatBufferConverter.DeserializeFrom<AreaSettingsTable8a>(bin_settings);
const string wild = "wild";
Directory.CreateDirectory(GetPath(wild));
@@ -466,7 +467,8 @@ public void DumpResident()
{
var residentpak = ROM.GetFile(GameFile.Resident)[0];
var resident = new GFPack(residentpak);
var settings = FlatBufferConverter.DeserializeFrom<AreaSettingsTable8a>(resident[2042]);
var bin_settings = resident.GetDataFullPath("bin/field/resident/AreaSettings.bin");
var settings = FlatBufferConverter.DeserializeFrom<AreaSettingsTable8a>(bin_settings);
var dir = GetPath("Resident");
var props = typeof(AreaSettings8a).GetProperties();
foreach (var x in settings.Table)
@@ -504,7 +506,8 @@ public void DumpPlacement()
{
var residentpak = ROM.GetFile(GameFile.Resident)[0];
var resident = new GFPack(residentpak);
var settings = FlatBufferConverter.DeserializeFrom<AreaSettingsTable8a>(resident[2042]);
var bin_settings = resident.GetDataFullPath("bin/field/resident/AreaSettings.bin");
var settings = FlatBufferConverter.DeserializeFrom<AreaSettingsTable8a>(bin_settings);
Dictionary<string, (string Name, int Index)> map = GetPlaceNameMap();

View File

@@ -357,7 +357,7 @@ void Randomize()
else
{
var table = shop.Shop2;
var names = table.Select((z, i) => $"{(z.LGPE.TryGetValue(z.Hash, out var shopName) ? shopName : z.Hash.ToString("X"))}").ToArray();
var names = table.Select((z, _) => $"{(z.LGPE.TryGetValue(z.Hash, out var shopName) ? shopName : z.Hash.ToString("X"))}").ToArray();
var cache = new DirectCache<Shop2>(table);
using var form = new GenericEditor<Shop2>(cache, names, $"{nameof(Shop2)} Editor", Randomize);
form.ShowDialog();

View File

@@ -233,6 +233,12 @@ public void EditSpawns()
form.ShowDialog();
}
public void EditAreas()
{
using var form = new AreaEditor8a((GameManagerPLA)ROM);
form.ShowDialog();
}
public void EditMoves()
{
var obj = ROM[GameFile.MoveStats]; // folder

View File

@@ -0,0 +1,162 @@
namespace pkNX.WinForms.Subforms
{
partial class AreaEditor8a
{
/// <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.CB_Area = new System.Windows.Forms.ComboBox();
this.TC_Editor = new System.Windows.Forms.TabControl();
this.Tab_Encounters = new System.Windows.Forms.TabPage();
this.Tab_Regular = new System.Windows.Forms.TabPage();
this.Tab_Wormhole = new System.Windows.Forms.TabPage();
this.Tab_Landmarks = new System.Windows.Forms.TabPage();
this.Edit_Encounters = new pkNX.WinForms.Controls.EncounterTableEditor8a();
this.Tab_Randomize = new System.Windows.Forms.TabPage();
this.B_Save = new System.Windows.Forms.Button();
this.TC_Editor.SuspendLayout();
this.Tab_Encounters.SuspendLayout();
this.SuspendLayout();
//
// CB_Area
//
this.CB_Area.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
this.CB_Area.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
this.CB_Area.FormattingEnabled = true;
this.CB_Area.Location = new System.Drawing.Point(12, 12);
this.CB_Area.Name = "CB_Area";
this.CB_Area.Size = new System.Drawing.Size(212, 21);
this.CB_Area.TabIndex = 1;
this.CB_Area.SelectedIndexChanged += new System.EventHandler(this.CB_Map_SelectedIndexChanged);
//
// TC_Editor
//
this.TC_Editor.Controls.Add(this.Tab_Encounters);
this.TC_Editor.Controls.Add(this.Tab_Regular);
this.TC_Editor.Controls.Add(this.Tab_Wormhole);
this.TC_Editor.Controls.Add(this.Tab_Landmarks);
this.TC_Editor.Controls.Add(this.Tab_Randomize);
this.TC_Editor.Location = new System.Drawing.Point(12, 39);
this.TC_Editor.Name = "TC_Editor";
this.TC_Editor.SelectedIndex = 0;
this.TC_Editor.Size = new System.Drawing.Size(685, 481);
this.TC_Editor.TabIndex = 2;
//
// Tab_Encounters
//
this.Tab_Encounters.Controls.Add(this.Edit_Encounters);
this.Tab_Encounters.Location = new System.Drawing.Point(4, 22);
this.Tab_Encounters.Name = "Tab_Encounters";
this.Tab_Encounters.Padding = new System.Windows.Forms.Padding(3);
this.Tab_Encounters.Size = new System.Drawing.Size(677, 455);
this.Tab_Encounters.TabIndex = 0;
this.Tab_Encounters.Text = "Encounters";
this.Tab_Encounters.UseVisualStyleBackColor = true;
//
// Tab_Regular
//
this.Tab_Regular.Location = new System.Drawing.Point(4, 22);
this.Tab_Regular.Name = "Tab_Regular";
this.Tab_Regular.Padding = new System.Windows.Forms.Padding(3);
this.Tab_Regular.Size = new System.Drawing.Size(677, 455);
this.Tab_Regular.TabIndex = 1;
this.Tab_Regular.Text = "*Regular";
this.Tab_Regular.UseVisualStyleBackColor = true;
//
// Tab_Wormhole
//
this.Tab_Wormhole.Location = new System.Drawing.Point(4, 22);
this.Tab_Wormhole.Name = "Tab_Wormhole";
this.Tab_Wormhole.Size = new System.Drawing.Size(677, 455);
this.Tab_Wormhole.TabIndex = 2;
this.Tab_Wormhole.Text = "*Wormhole";
this.Tab_Wormhole.UseVisualStyleBackColor = true;
//
// Tab_Landmarks
//
this.Tab_Landmarks.Location = new System.Drawing.Point(4, 22);
this.Tab_Landmarks.Name = "Tab_Landmarks";
this.Tab_Landmarks.Size = new System.Drawing.Size(677, 455);
this.Tab_Landmarks.TabIndex = 3;
this.Tab_Landmarks.Text = "*Landmarks";
this.Tab_Landmarks.UseVisualStyleBackColor = true;
//
// Edit_Encounters
//
this.Edit_Encounters.Dock = System.Windows.Forms.DockStyle.Fill;
this.Edit_Encounters.Location = new System.Drawing.Point(3, 3);
this.Edit_Encounters.Name = "Edit_Encounters";
this.Edit_Encounters.Size = new System.Drawing.Size(671, 449);
this.Edit_Encounters.TabIndex = 0;
//
// Tab_Randomize
//
this.Tab_Randomize.Location = new System.Drawing.Point(4, 22);
this.Tab_Randomize.Name = "Tab_Randomize";
this.Tab_Randomize.Padding = new System.Windows.Forms.Padding(3);
this.Tab_Randomize.Size = new System.Drawing.Size(677, 455);
this.Tab_Randomize.TabIndex = 4;
this.Tab_Randomize.Text = "Randomize";
this.Tab_Randomize.UseVisualStyleBackColor = true;
//
// B_Save
//
this.B_Save.Location = new System.Drawing.Point(633, 1);
this.B_Save.Name = "B_Save";
this.B_Save.Size = new System.Drawing.Size(75, 23);
this.B_Save.TabIndex = 3;
this.B_Save.Text = "Save All";
this.B_Save.UseVisualStyleBackColor = true;
this.B_Save.Click += new System.EventHandler(this.B_Save_Click);
//
// AreaEditor8a
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(709, 532);
this.Controls.Add(this.B_Save);
this.Controls.Add(this.TC_Editor);
this.Controls.Add(this.CB_Area);
this.Name = "AreaEditor8a";
this.Text = "Area Editor";
this.TC_Editor.ResumeLayout(false);
this.Tab_Encounters.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ComboBox CB_Area;
private System.Windows.Forms.TabControl TC_Editor;
private System.Windows.Forms.TabPage Tab_Encounters;
private System.Windows.Forms.TabPage Tab_Regular;
private System.Windows.Forms.TabPage Tab_Wormhole;
private System.Windows.Forms.TabPage Tab_Landmarks;
private Controls.EncounterTableEditor8a Edit_Encounters;
private System.Windows.Forms.TabPage Tab_Randomize;
private System.Windows.Forms.Button B_Save;
}
}

View File

@@ -0,0 +1,81 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
using pkNX.Containers;
using pkNX.Game;
using pkNX.Structures.FlatBuffers;
namespace pkNX.WinForms.Subforms;
public partial class AreaEditor8a : Form
{
private readonly GameManagerPLA ROM;
private readonly GFPack Resident;
private readonly AreaSettingsTable8a Settings;
private readonly string[] AreaNames;
private ResidentArea8a Area;
private int AreaIndex;
private readonly bool Loading;
public AreaEditor8a(GameManagerPLA rom)
{
ROM = rom;
var residentpak = ROM.GetFile(GameFile.Resident)[0];
Resident = new GFPack(residentpak);
var bin_settings = Resident.GetDataFullPath("bin/field/resident/AreaSettings.bin");
Settings = FlatBufferConverter.DeserializeFrom<AreaSettingsTable8a>(bin_settings);
AreaNames = Settings.Table.Select(z => z.Name).ToArray();
const string startingArea = "ha_area01";
(AreaIndex, Area) = LoadAreaByName(startingArea);
InitializeComponent();
Loading = true;
CB_Area.Items.AddRange(AreaNames);
CB_Area.SelectedIndex = AreaIndex;
LoadArea();
Loading = false;
}
private (int index, ResidentArea8a area) LoadAreaByName(string name)
{
var index = Array.IndexOf(AreaNames, name);
var area = new ResidentArea8a(Resident, Settings.Find(name));
area.LoadInfo();
return (index, area);
}
private void CB_Map_SelectedIndexChanged(object sender, EventArgs e)
{
if (Loading)
return;
SaveArea();
(AreaIndex, Area) = LoadAreaByName(AreaNames[CB_Area.SelectedIndex]);
LoadArea();
}
private void LoadArea()
{
Debug.WriteLine($"Loading Area {AreaIndex}");
Edit_Encounters.LoadTable(Area.Encounters, Area.Settings.Encounters);
}
private void SaveArea()
{
Debug.WriteLine($"Saving Area {AreaIndex}");
Area.SaveInfo();
}
private void B_Save_Click(object sender, EventArgs e)
{
SaveArea();
ROM.GetFile(GameFile.Resident)[0] = Resident.Write();
Close();
}
}

View File

@@ -22,7 +22,8 @@ public MapViewer8a(GameManagerPLA rom, GFPack resident)
{
ROM = rom;
Resident = resident;
Settings = FlatBufferConverter.DeserializeFrom<AreaSettingsTable8a>(resident[2042]);
var bin_settings = resident.GetDataFullPath("bin/field/resident/AreaSettings.bin");
Settings = FlatBufferConverter.DeserializeFrom<AreaSettingsTable8a>(bin_settings);
InitializeComponent();
@@ -52,7 +53,8 @@ public MapViewer8a(GameManagerPLA rom, GFPack resident)
Loading = false;
CB_Map.SelectedIndex = 0;
}
public class ComboItem
private class ComboItem
{
public ComboItem(string text, int value)
{

View File

@@ -154,9 +154,7 @@ private bool ImportTextFiles(string fileName)
for (int i = 0; i < TextData.Length; i++)
{
try { TextData[i] = textLines[i]; }
#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception e) { WinFormsUtil.Error($"The input Text File (# {i}) failed to convert:", e.ToString()); return false; }
#pragma warning restore CA1031 // Do not catch general exception types
}
return true;
@@ -171,9 +169,7 @@ private void ChangeEntry(object sender, EventArgs e)
{
TextData[entry] = GetCurrentDGLines();
}
#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception ex) { WinFormsUtil.Error(ex.ToString()); }
#pragma warning restore CA1031 // Do not catch general exception types
}
// Reset
@@ -235,9 +231,7 @@ private void B_AddLine_Click(object sender, EventArgs e)
{
int currentRow = 0;
try { currentRow = dgv.CurrentRow.Index; }
#pragma warning disable CA1031 // Do not catch general exception types
catch { dgv.Rows.Add(); }
#pragma warning restore CA1031 // Do not catch general exception types
if (dgv.Rows.Count != 1 && (currentRow < dgv.Rows.Count - 1 || currentRow == 0))
{
if (ModifierKeys != Keys.Control && currentRow != 0)