Refactoring

File scoped namespaces
NET6 for GUI
handle nullable references
add editorconfig (mostly for newline at end of file)
This commit is contained in:
Kurt
2022-10-01 12:44:47 -07:00
parent b61ecb5cb4
commit 76b0b62ca3
40 changed files with 8608 additions and 8580 deletions

45
.editorconfig Normal file
View File

@@ -0,0 +1,45 @@
root = true
# All Files
[*]
charset = utf-8
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
# Solution Files
[*.sln]
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
# XML Project Files
[*.csproj]
indent_style = space
indent_size = 2
# Code Files
[*.cs]
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 4
tab_width = 4
end_of_line = crlf
csharp_prefer_braces = when_multiline:warning
dotnet_diagnostic.IDE0047.severity = none
dotnet_diagnostic.IDE0048.severity = none
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:suggest
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:suggest
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggest
dotnet_style_parentheses_in_other_operators = always_for_clarity:suggest
[*.{cs,vb}]
#### Naming styles ####
# Naming styles
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.capitalization = pascal_case

View File

@@ -1,150 +1,152 @@
using System;
using System;
using System.Windows.Forms;
using pkNX.Sprites;
using pkNX.Structures.FlatBuffers;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public partial class EncounterList : UserControl
{
public partial class EncounterList : UserControl
public EncounterList()
{
public EncounterList()
InitializeComponent();
}
public bool OverworldSpawn
{
set => NUD_Count.Visible = L_Count.Visible = value;
}
public bool ShowForm
{
set => dgv.Columns[FormColumn].Visible = value;
}
private const string FormColumn = nameof(FormColumn);
public void Initialize()
{
var dgvPicture = new DataGridViewImageColumn
{
InitializeComponent();
}
public bool OverworldSpawn
HeaderText = "Sprite",
DisplayIndex = 0,
Width = SpriteUtil.Spriter.Width + 2,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter },
ReadOnly = true,
};
var padding = SpriteUtil.Spriter.Height > 40
? new Padding(0, (SpriteUtil.Spriter.Height / 2) - 8, 0, 0)
: new Padding(0);
var dgvSpecies = new DataGridViewComboBoxColumn
{
set => NUD_Count.Visible = L_Count.Visible = value;
}
public bool ShowForm
HeaderText = "Species",
DisplayIndex = 1,
Width = 135,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter, Padding = padding },
FlatStyle = FlatStyle.Flat
};
var dgvForm = new DataGridViewTextBoxColumn
{
set => dgv.Columns[FormColumn].Visible = value;
}
private const string FormColumn = nameof(FormColumn);
public void Initialize()
Name = FormColumn,
HeaderText = "Form",
DisplayIndex = 2,
Width = 45,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter }
};
var dgvPercent = new DataGridViewTextBoxColumn
{
var dgvPicture = new DataGridViewImageColumn
{
HeaderText = "Sprite",
DisplayIndex = 0,
Width = SpriteUtil.Spriter.Width + 2,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter },
ReadOnly = true,
};
var padding = SpriteUtil.Spriter.Height > 40
? new Padding(0, (SpriteUtil.Spriter.Height / 2) - 8, 0, 0)
: new Padding(0);
var dgvSpecies = new DataGridViewComboBoxColumn
{
HeaderText = "Species",
DisplayIndex = 1,
Width = 135,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter, Padding = padding },
FlatStyle = FlatStyle.Flat
};
var dgvForm = new DataGridViewTextBoxColumn
{
Name = FormColumn,
HeaderText = "Form",
DisplayIndex = 2,
Width = 45,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter }
};
var dgvPercent = new DataGridViewTextBoxColumn
{
HeaderText = "Chance",
DisplayIndex = 3,
Width = 52,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter }
};
HeaderText = "Chance",
DisplayIndex = 3,
Width = 52,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter }
};
dgvSpecies.Items.AddRange(species);
dgvSpecies.Items.AddRange(SpeciesNames);
dgv.Columns.Add(dgvPicture);
dgv.Columns.Add(dgvSpecies);
dgv.Columns.Add(dgvForm);
dgv.Columns.Add(dgvPercent);
dgv.Columns.Add(dgvPicture);
dgv.Columns.Add(dgvSpecies);
dgv.Columns.Add(dgvForm);
dgv.Columns.Add(dgvPercent);
dgv.CellValueChanged += (s, e) =>
{
if (e.ColumnIndex == 0)
return;
UpdateRowImage(e.RowIndex);
};
dgv.Columns[0].DefaultCellStyle.SelectionBackColor = dgv.DefaultCellStyle.BackColor;
}
private void UpdateRowImage(int row)
dgv.CellValueChanged += (s, e) =>
{
int sp = Array.IndexOf(species, dgv.Rows[row].Cells[1].Value);
string formstr = (dgv.Rows[row].Cells[2].Value ?? 0).ToString();
if (!int.TryParse(formstr, out var form) || (uint) form > 100)
dgv.Rows[row].Cells[2].Value = 0;
if (!int.TryParse(dgv.Rows[row].Cells[2].Value?.ToString(), out var rate) || (uint)rate > 100)
dgv.Rows[row].Cells[3].Value = 0;
dgv.Rows[row].Cells[0].Value = SpriteUtil.GetSprite(sp, form, 0, 0, false, false, false);
}
private EncounterSlot7b[]? Slots;
public static string[] species = Array.Empty<string>();
public void LoadSlots(EncounterSlot7b[] slots)
{
Slots = slots;
dgv.Rows.Clear();
dgv.Rows.Add(slots.Length);
// Fill Entries
for (int i = 0; i < slots.Length; i++)
{
var row = dgv.Rows[i];
row.Cells[1].Value = species[slots[i].Species];
row.Cells[2].Value = slots[i].Form;
row.Cells[3].Value = slots[i].Probability;
row.Height = SpriteUtil.Spriter.Height + 2;
}
dgv.CancelEdit();
}
public void SaveCurrent()
{
if (Slots == null)
if (e.ColumnIndex == 0)
return;
for (int i = 0; i < Slots.Length; i++)
{
SaveRow(i, Slots[i]);
}
UpdateRowImage(e.RowIndex);
};
dgv.Columns[0].DefaultCellStyle.SelectionBackColor = dgv.DefaultCellStyle.BackColor;
}
private void UpdateRowImage(int row)
{
var r = dgv.Rows[row];
var cells = r.Cells;
int sp = Array.IndexOf(SpeciesNames, cells[1].Value);
var formstr = cells[2].Value?.ToString() ?? "0";
if (!int.TryParse(formstr, out var form) || (uint) form > 100)
cells[2].Value = 0;
if (!int.TryParse(cells[2].Value?.ToString(), out var rate) || (uint)rate > 100)
cells[3].Value = 0;
cells[0].Value = SpriteUtil.GetSprite(sp, form, 0, 0, false, false, false);
}
private EncounterSlot7b[]? Slots;
public static string[] SpeciesNames { private get; set; }= Array.Empty<string>();
public void LoadSlots(EncounterSlot7b[] slots)
{
Slots = slots;
dgv.Rows.Clear();
dgv.Rows.Add(slots.Length);
// Fill Entries
for (int i = 0; i < slots.Length; i++)
{
var row = dgv.Rows[i];
row.Cells[1].Value = SpeciesNames[slots[i].Species];
row.Cells[2].Value = slots[i].Form;
row.Cells[3].Value = slots[i].Probability;
row.Height = SpriteUtil.Spriter.Height + 2;
}
private void SaveRow(int row, EncounterSlot7b s)
dgv.CancelEdit();
}
public void SaveCurrent()
{
if (Slots == null)
return;
for (int i = 0; i < Slots.Length; i++)
{
int sp = Array.IndexOf(species, dgv.Rows[row].Cells[1].Value ?? species[0]);
string formstr = (dgv.Rows[row].Cells[2].Value ?? 0).ToString();
short.TryParse(formstr, out var form);
string probstr = (dgv.Rows[row].Cells[3].Value ?? 0).ToString();
int.TryParse(probstr, out var prob);
if (sp == 0)
{
s.Species = s.Probability = 0;
s.Form = 0;
return;
}
s.Species = sp;
s.Form = form;
s.Probability = prob;
}
private void CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgv.IsCurrentCellDirty)
dgv.CommitEdit(DataGridViewDataErrorContexts.Commit);
SaveRow(i, Slots[i]);
}
}
private void SaveRow(int row, EncounterSlot7b s)
{
var cells = dgv.Rows[row].Cells;
int sp = Array.IndexOf(SpeciesNames, cells[1].Value ?? SpeciesNames[0]);
string formstr = cells[2].Value?.ToString() ?? "0";
_ = short.TryParse(formstr, out var form);
string probstr = cells[3].Value?.ToString() ?? "0";
_ = int.TryParse(probstr, out var prob);
if (sp == 0)
{
s.Species = s.Probability = 0;
s.Form = 0;
return;
}
s.Species = sp;
s.Form = form;
s.Probability = prob;
}
private void CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgv.IsCurrentCellDirty)
dgv.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}

View File

@@ -1,139 +1,138 @@
using System;
using System;
using System.Windows.Forms;
using pkNX.Sprites;
using pkNX.Structures.FlatBuffers;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public partial class EncounterList8 : UserControl
{
public partial class EncounterList8 : UserControl
private EncounterSlot8[]? Slots;
public static string[] SpeciesNames { private get; set; } = Array.Empty<string>();
private const string FormColumn = nameof(FormColumn);
public EncounterList8() => InitializeComponent();
public void Initialize()
{
public EncounterList8()
var dgvPicture = new DataGridViewImageColumn
{
InitializeComponent();
}
private const string FormColumn = nameof(FormColumn);
public void Initialize()
HeaderText = "Sprite",
DisplayIndex = 0,
Width = SpriteUtil.Spriter.Width + 2,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter },
ReadOnly = true,
};
var padding = SpriteUtil.Spriter.Height > 40
? new Padding(0, (SpriteUtil.Spriter.Height / 2) - 8, 0, 0)
: new Padding(0);
var dgvSpecies = new DataGridViewComboBoxColumn
{
var dgvPicture = new DataGridViewImageColumn
{
HeaderText = "Sprite",
DisplayIndex = 0,
Width = SpriteUtil.Spriter.Width + 2,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter },
ReadOnly = true,
};
var padding = SpriteUtil.Spriter.Height > 40
? new Padding(0, (SpriteUtil.Spriter.Height / 2) - 8, 0, 0)
: new Padding(0);
var dgvSpecies = new DataGridViewComboBoxColumn
{
HeaderText = "Species",
DisplayIndex = 1,
Width = 135,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter, Padding = padding},
FlatStyle = FlatStyle.Flat
};
var dgvForm = new DataGridViewTextBoxColumn
{
Name = FormColumn,
HeaderText = "Form",
DisplayIndex = 2,
Width = 45,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter }
};
var dgvPercent = new DataGridViewTextBoxColumn
{
HeaderText = "Chance",
DisplayIndex = 3,
Width = 52,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter }
};
dgvSpecies.Items.AddRange(species);
dgv.Columns.Add(dgvPicture);
dgv.Columns.Add(dgvSpecies);
dgv.Columns.Add(dgvForm);
dgv.Columns.Add(dgvPercent);
dgv.CellValueChanged += (s, e) =>
{
if (e.ColumnIndex == 0)
return;
UpdateRowImage(e.RowIndex);
};
dgv.Columns[0].DefaultCellStyle.SelectionBackColor = dgv.DefaultCellStyle.BackColor;
}
private void UpdateRowImage(int row)
HeaderText = "Species",
DisplayIndex = 1,
Width = 135,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter, Padding = padding},
FlatStyle = FlatStyle.Flat
};
var dgvForm = new DataGridViewTextBoxColumn
{
int sp = Array.IndexOf(species, dgv.Rows[row].Cells[1].Value);
string formstr = (dgv.Rows[row].Cells[2].Value ?? 0).ToString();
if (!int.TryParse(formstr, out var form) || (uint) form > 100)
dgv.Rows[row].Cells[2].Value = 0;
if (!int.TryParse(dgv.Rows[row].Cells[2].Value?.ToString(), out var rate) || (uint)rate > 100)
dgv.Rows[row].Cells[3].Value = 0;
dgv.Rows[row].Cells[0].Value = SpriteUtil.GetSprite(sp, form, 0, 0, false, false, false);
}
private EncounterSlot8[]? Slots;
public static string[] species = Array.Empty<string>();
public void LoadSlots(EncounterSlot8[] slots)
Name = FormColumn,
HeaderText = "Form",
DisplayIndex = 2,
Width = 45,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter }
};
var dgvPercent = new DataGridViewTextBoxColumn
{
Slots = slots;
HeaderText = "Chance",
DisplayIndex = 3,
Width = 52,
DefaultCellStyle = { Alignment = DataGridViewContentAlignment.MiddleCenter }
};
dgv.Rows.Clear();
dgv.Rows.Add(slots.Length);
// Fill Entries
for (int i = 0; i < slots.Length; i++)
{
var row = dgv.Rows[i];
row.Cells[1].Value = species[slots[i].Species];
row.Cells[2].Value = slots[i].Form;
row.Cells[3].Value = slots[i].Probability;
row.Height = SpriteUtil.Spriter.Height + 2;
}
dgvSpecies.Items.AddRange(SpeciesNames);
dgv.CancelEdit();
}
dgv.Columns.Add(dgvPicture);
dgv.Columns.Add(dgvSpecies);
dgv.Columns.Add(dgvForm);
dgv.Columns.Add(dgvPercent);
public void SaveCurrent()
dgv.CellValueChanged += (s, e) =>
{
if (Slots == null)
if (e.ColumnIndex == 0)
return;
for (int i = 0; i < Slots.Length; i++)
{
SaveRow(i, Slots[i]);
}
UpdateRowImage(e.RowIndex);
};
dgv.Columns[0].DefaultCellStyle.SelectionBackColor = dgv.DefaultCellStyle.BackColor;
}
private void UpdateRowImage(int row)
{
var cells = dgv.Rows[row].Cells;
int sp = Array.IndexOf(SpeciesNames, cells[1].Value);
string formstr = cells[2].Value?.ToString() ?? "0";
if (!int.TryParse(formstr, out var form) || (uint) form > 100)
cells[2].Value = 0;
if (!int.TryParse(dgv.Rows[row].Cells[2].Value?.ToString(), out var rate) || (uint)rate > 100)
cells[3].Value = 0;
cells[0].Value = SpriteUtil.GetSprite(sp, form, 0, 0, false, false, false);
}
public void LoadSlots(EncounterSlot8[] slots)
{
Slots = slots;
dgv.Rows.Clear();
dgv.Rows.Add(slots.Length);
// Fill Entries
for (int i = 0; i < slots.Length; i++)
{
var row = dgv.Rows[i];
var cells = row.Cells;
cells[1].Value = SpeciesNames[slots[i].Species];
cells[2].Value = slots[i].Form;
cells[3].Value = slots[i].Probability;
row.Height = SpriteUtil.Spriter.Height + 2;
}
private void SaveRow(int row, EncounterSlot8 s)
dgv.CancelEdit();
}
public void SaveCurrent()
{
if (Slots == null)
return;
for (int i = 0; i < Slots.Length; i++)
{
int sp = Array.IndexOf(species, dgv.Rows[row].Cells[1].Value ?? species[0]);
string formstr = (dgv.Rows[row].Cells[2].Value ?? 0).ToString();
byte.TryParse(formstr, out var form);
string probstr = (dgv.Rows[row].Cells[3].Value ?? 0).ToString();
byte.TryParse(probstr, out var prob);
if (sp == 0)
{
s.Species = s.Form = s.Probability = 0;
return;
}
s.Species = sp;
s.Form = form;
s.Probability = prob;
}
private void CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgv.IsCurrentCellDirty)
dgv.CommitEdit(DataGridViewDataErrorContexts.Commit);
SaveRow(i, Slots[i]);
}
}
private void SaveRow(int row, EncounterSlot8 s)
{
var cells = dgv.Rows[row].Cells;
int sp = Array.IndexOf(SpeciesNames, cells[1].Value ?? SpeciesNames[0]);
string formstr = cells[2].Value?.ToString() ?? "0";
_ = byte.TryParse(formstr, out var form);
string probstr = cells[3].Value?.ToString() ?? "0";
_ = byte.TryParse(probstr, out var prob);
if (sp == 0)
{
s.Species = s.Form = s.Probability = 0;
return;
}
s.Species = sp;
s.Form = form;
s.Probability = prob;
}
private void CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgv.IsCurrentCellDirty)
dgv.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}

View File

@@ -1,8 +1,6 @@
using System;
using System.Diagnostics;
using System;
using System.Linq;
using System.Windows.Forms;
using pkNX.Structures;
using pkNX.Structures.FlatBuffers;
namespace pkNX.WinForms.Controls;
@@ -70,7 +68,7 @@ private void B_NoShinyLocks_Click(object sender, EventArgs e)
private void PG_Encounters_SelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e)
{
object obj = e.NewSelection.Value;
var obj = e.NewSelection.Value;
bool enable = obj is EncounterSlot8a;
B_CloneTableEntry.Enabled = enable;
B_ConfigureAsAlpha.Enabled = enable;
@@ -79,7 +77,7 @@ private void PG_Encounters_SelectedGridItemChanged(object sender, SelectedGridIt
private void B_CloneTableEntry_Click(object sender, EventArgs e)
{
object obj = PG_Encounters.SelectedGridItem.Value;
var obj = PG_Encounters.SelectedGridItem.Value;
if (obj is EncounterSlot8a slotToClone)
{
var encounterTable = (EncounterTable8a)PG_Encounters.SelectedObject;
@@ -90,7 +88,7 @@ private void B_CloneTableEntry_Click(object sender, EventArgs e)
private void B_ConfigureAsAlpha_Click(object sender, EventArgs e)
{
object obj = PG_Encounters.SelectedGridItem.Value;
var obj = PG_Encounters.SelectedGridItem.Value;
if (obj is EncounterSlot8a slotToEdit)
{
slotToEdit.BaseProbability = 1;
@@ -107,7 +105,7 @@ private void B_ConfigureAsAlpha_Click(object sender, EventArgs e)
private void B_RemoveCondition_Click(object sender, EventArgs e)
{
object obj = PG_Encounters.SelectedGridItem.Value;
var obj = PG_Encounters.SelectedGridItem.Value;
if (obj is EncounterSlot8a slotToEdit)
{
slotToEdit.Eligibility.ConditionID = Condition8a.None;

View File

@@ -1,96 +1,95 @@
using System;
using System;
using System.Linq;
using System.Windows.Forms;
using pkNX.Sprites;
using pkNX.Structures;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public partial class EvolutionRow : UserControl
{
public partial class EvolutionRow : UserControl
public EvolutionRow()
{
public EvolutionRow()
InitializeComponent();
CB_Method.Items.AddRange(EvoMethods);
CB_Species.Items.AddRange(species);
CB_Species.SelectedIndexChanged += (_, __) => ChangeSpecies(CB_Species.SelectedIndex, (int)NUD_Form.Value);
NUD_Form.ValueChanged += (_, __) => ChangeSpecies(CB_Species.SelectedIndex, (int)NUD_Form.Value);
CB_Arg.Items.AddRange(None);
CB_Method.SelectedIndexChanged += (s, e) =>
{
InitializeComponent();
CB_Method.Items.AddRange(EvoMethods);
CB_Species.Items.AddRange(species);
CB_Species.SelectedIndexChanged += (_, __) => ChangeSpecies(CB_Species.SelectedIndex, (int)NUD_Form.Value);
NUD_Form.ValueChanged += (_, __) => ChangeSpecies(CB_Species.SelectedIndex, (int)NUD_Form.Value);
CB_Arg.Items.AddRange(None);
CB_Method.SelectedIndexChanged += (s, e) =>
{
var index = (EvolutionType)CB_Method.SelectedIndex;
var type = index.GetArgType();
L_Method.Visible = L_Species.Visible = L_Arg.Visible = L_Form.Visible = L_Level.Visible = index > 0;
L_Arg.Visible = CB_Arg.Visible = type >= EvolutionTypeArgumentType.Items;
if (type == oldMethod)
return;
if (type < EvolutionTypeArgumentType.Items)
return;
CB_Arg.Visible = true;
oldMethod = type;
CB_Arg.Items.Clear();
var vals = GetArgs(type);
CB_Arg.Items.AddRange(vals);
CB_Arg.SelectedIndex = 0;
};
}
private void ChangeSpecies(int spec, int form) => PB_Preview.Image = SpriteUtil.GetSprite(spec, form, 0, 0, false, false, false);
private EvolutionMethod? current;
private EvolutionTypeArgumentType oldMethod;
public void LoadEvolution(EvolutionMethod s)
{
var evo = current = s;
CB_Species.SelectedIndex = evo.Species;
NUD_Form.Value = evo.Form;
NUD_Level.Value = evo.Level;
CB_Method.SelectedIndex = (int)evo.Method;
CB_Arg.SelectedIndex = evo.Argument;
}
public void SaveEvolution()
{
var evo = current;
if (evo == null)
var index = (EvolutionType)CB_Method.SelectedIndex;
var type = index.GetArgType();
L_Method.Visible = L_Species.Visible = L_Arg.Visible = L_Form.Visible = L_Level.Visible = index > 0;
L_Arg.Visible = CB_Arg.Visible = type >= EvolutionTypeArgumentType.Items;
if (type == oldMethod)
return;
evo.Species = (ushort)CB_Species.SelectedIndex;
evo.Form = (byte)NUD_Form.Value;
evo.Level = (byte)NUD_Level.Value;
evo.Method = (EvolutionType)CB_Method.SelectedIndex;
evo.Argument = (ushort)CB_Arg.SelectedIndex;
}
public static string[] items = Array.Empty<string>();
public static string[] movelist = Array.Empty<string>();
public static string[] species = Array.Empty<string>();
public static string[] types = Array.Empty<string>();
if (type < EvolutionTypeArgumentType.Items)
return;
private static readonly string[] EvoMethods = Enum.GetNames(typeof(EvolutionType));
private static readonly string[] Levels = Enumerable.Range(0, 100 + 1).Select(z => z.ToString()).ToArray();
private static readonly string[] Stats = Enumerable.Range(0, 255 + 1).Select(z => z.ToString()).ToArray();
private static readonly string[] None = { "" };
CB_Arg.Visible = true;
oldMethod = type;
CB_Arg.Items.Clear();
var vals = GetArgs(type);
CB_Arg.Items.AddRange(vals);
CB_Arg.SelectedIndex = 0;
};
}
private static string[] GetArgs(EvolutionTypeArgumentType type)
private void ChangeSpecies(int spec, int form) => PB_Preview.Image = SpriteUtil.GetSprite(spec, form, 0, 0, false, false, false);
private EvolutionMethod? current;
private EvolutionTypeArgumentType oldMethod;
public void LoadEvolution(EvolutionMethod s)
{
var evo = current = s;
CB_Species.SelectedIndex = evo.Species;
NUD_Form.Value = evo.Form;
NUD_Level.Value = evo.Level;
CB_Method.SelectedIndex = (int)evo.Method;
CB_Arg.SelectedIndex = evo.Argument;
}
public void SaveEvolution()
{
var evo = current;
if (evo == null)
return;
evo.Species = (ushort)CB_Species.SelectedIndex;
evo.Form = (byte)NUD_Form.Value;
evo.Level = (byte)NUD_Level.Value;
evo.Method = (EvolutionType)CB_Method.SelectedIndex;
evo.Argument = (ushort)CB_Arg.SelectedIndex;
}
public static string[] items = Array.Empty<string>();
public static string[] movelist = Array.Empty<string>();
public static string[] species = Array.Empty<string>();
public static string[] types = Array.Empty<string>();
private static readonly string[] EvoMethods = Enum.GetNames(typeof(EvolutionType));
private static readonly string[] Levels = Enumerable.Range(0, 100 + 1).Select(z => z.ToString()).ToArray();
private static readonly string[] Stats = Enumerable.Range(0, 255 + 1).Select(z => z.ToString()).ToArray();
private static readonly string[] None = { "" };
private static string[] GetArgs(EvolutionTypeArgumentType type)
{
return type switch
{
return type switch
{
EvolutionTypeArgumentType.NoArg => None,
EvolutionTypeArgumentType.Level => Levels,
EvolutionTypeArgumentType.Items => items,
EvolutionTypeArgumentType.Moves => movelist,
EvolutionTypeArgumentType.Species => species,
EvolutionTypeArgumentType.Stat => Stats,
EvolutionTypeArgumentType.Type => types,
EvolutionTypeArgumentType.Version => Stats,
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
};
}
EvolutionTypeArgumentType.NoArg => None,
EvolutionTypeArgumentType.Level => Levels,
EvolutionTypeArgumentType.Items => items,
EvolutionTypeArgumentType.Moves => movelist,
EvolutionTypeArgumentType.Species => species,
EvolutionTypeArgumentType.Stat => Stats,
EvolutionTypeArgumentType.Type => types,
EvolutionTypeArgumentType.Version => Stats,
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
};
}
}

View File

@@ -1,97 +1,96 @@
using System;
using System;
using System.Linq;
using System.Windows.Forms;
using pkNX.Sprites;
using pkNX.Structures;
using pkNX.Structures.FlatBuffers;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public partial class EvolutionRow8a : UserControl
{
public partial class EvolutionRow8a : UserControl
public static string[] items = Array.Empty<string>();
public static string[] movelist = Array.Empty<string>();
public static string[] species = Array.Empty<string>();
public static string[] types = Array.Empty<string>();
private static readonly string[] EvoMethods = Enum.GetNames(typeof(EvolutionType));
private static readonly string[] Levels = Enumerable.Range(0, 100 + 1).Select(z => z.ToString()).ToArray();
private static readonly string[] Stats = Enumerable.Range(0, 255 + 1).Select(z => z.ToString()).ToArray();
private static readonly string[] None = { "" };
private EvolutionEntry8a? current;
private EvolutionTypeArgumentType oldMethod;
public EvolutionRow8a()
{
public static string[] items = Array.Empty<string>();
public static string[] movelist = Array.Empty<string>();
public static string[] species = Array.Empty<string>();
public static string[] types = Array.Empty<string>();
InitializeComponent();
private static readonly string[] EvoMethods = Enum.GetNames(typeof(EvolutionType));
private static readonly string[] Levels = Enumerable.Range(0, 100 + 1).Select(z => z.ToString()).ToArray();
private static readonly string[] Stats = Enumerable.Range(0, 255 + 1).Select(z => z.ToString()).ToArray();
private static readonly string[] None = { "" };
CB_Method.Items.AddRange(EvoMethods);
CB_Species.Items.AddRange(species);
private EvolutionEntry8a? current;
private EvolutionTypeArgumentType oldMethod;
CB_Species.SelectedIndexChanged += (_, __) => ChangeSpecies(CB_Species.SelectedIndex, (int)NUD_Form.Value);
NUD_Form.ValueChanged += (_, __) => ChangeSpecies(CB_Species.SelectedIndex, (int)NUD_Form.Value);
public EvolutionRow8a()
CB_Arg.Items.AddRange(None);
CB_Method.SelectedIndexChanged += (s, e) =>
{
InitializeComponent();
CB_Method.Items.AddRange(EvoMethods);
CB_Species.Items.AddRange(species);
CB_Species.SelectedIndexChanged += (_, __) => ChangeSpecies(CB_Species.SelectedIndex, (int)NUD_Form.Value);
NUD_Form.ValueChanged += (_, __) => ChangeSpecies(CB_Species.SelectedIndex, (int)NUD_Form.Value);
CB_Arg.Items.AddRange(None);
CB_Method.SelectedIndexChanged += (s, e) =>
{
var index = (EvolutionType)CB_Method.SelectedIndex;
var type = index.GetArgType();
L_Method.Visible = L_Species.Visible = L_Arg.Visible = L_Form.Visible = L_Level.Visible = index > 0;
L_Arg.Visible = CB_Arg.Visible = type >= EvolutionTypeArgumentType.Items;
if (type == oldMethod)
return;
if (type < EvolutionTypeArgumentType.Items)
return;
CB_Arg.Visible = true;
oldMethod = type;
CB_Arg.Items.Clear();
var vals = GetArgs(type);
CB_Arg.Items.AddRange(vals);
CB_Arg.SelectedIndex = 0;
};
}
private void ChangeSpecies(int spec, int form) => PB_Preview.Image = SpriteUtil.GetSprite(spec, form, 0, 0, false, false, false);
public void LoadEvolution(EvolutionEntry8a s)
{
var evo = current = s;
CB_Species.SelectedIndex = evo.Species;
NUD_Form.Value = evo.Form;
NUD_Level.Value = evo.Level;
CB_Method.SelectedIndex = evo.Method;
CB_Arg.SelectedIndex = evo.Argument;
}
public void SaveEvolution()
{
var evo = current;
if (evo == null)
var index = (EvolutionType)CB_Method.SelectedIndex;
var type = index.GetArgType();
L_Method.Visible = L_Species.Visible = L_Arg.Visible = L_Form.Visible = L_Level.Visible = index > 0;
L_Arg.Visible = CB_Arg.Visible = type >= EvolutionTypeArgumentType.Items;
if (type == oldMethod)
return;
evo.Species = (ushort)CB_Species.SelectedIndex;
evo.Form = (ushort)NUD_Form.Value;
evo.Level = (ushort)NUD_Level.Value;
evo.Method = (ushort)CB_Method.SelectedIndex;
evo.Argument = (ushort)CB_Arg.SelectedIndex;
}
private static string[] GetArgs(EvolutionTypeArgumentType type)
if (type < EvolutionTypeArgumentType.Items)
return;
CB_Arg.Visible = true;
oldMethod = type;
CB_Arg.Items.Clear();
var vals = GetArgs(type);
CB_Arg.Items.AddRange(vals);
CB_Arg.SelectedIndex = 0;
};
}
private void ChangeSpecies(int spec, int form) => PB_Preview.Image = SpriteUtil.GetSprite(spec, form, 0, 0, false, false, false);
public void LoadEvolution(EvolutionEntry8a s)
{
var evo = current = s;
CB_Species.SelectedIndex = evo.Species;
NUD_Form.Value = evo.Form;
NUD_Level.Value = evo.Level;
CB_Method.SelectedIndex = evo.Method;
CB_Arg.SelectedIndex = evo.Argument;
}
public void SaveEvolution()
{
var evo = current;
if (evo == null)
return;
evo.Species = (ushort)CB_Species.SelectedIndex;
evo.Form = (ushort)NUD_Form.Value;
evo.Level = (ushort)NUD_Level.Value;
evo.Method = (ushort)CB_Method.SelectedIndex;
evo.Argument = (ushort)CB_Arg.SelectedIndex;
}
private static string[] GetArgs(EvolutionTypeArgumentType type)
{
return type switch
{
return type switch
{
EvolutionTypeArgumentType.NoArg => None,
EvolutionTypeArgumentType.Level => Levels,
EvolutionTypeArgumentType.Items => items,
EvolutionTypeArgumentType.Moves => movelist,
EvolutionTypeArgumentType.Species => species,
EvolutionTypeArgumentType.Stat => Stats,
EvolutionTypeArgumentType.Type => types,
EvolutionTypeArgumentType.Version => Stats,
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
};
}
EvolutionTypeArgumentType.NoArg => None,
EvolutionTypeArgumentType.Level => Levels,
EvolutionTypeArgumentType.Items => items,
EvolutionTypeArgumentType.Moves => movelist,
EvolutionTypeArgumentType.Species => species,
EvolutionTypeArgumentType.Stat => Stats,
EvolutionTypeArgumentType.Type => types,
EvolutionTypeArgumentType.Version => Stats,
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
};
}
}

View File

@@ -1,65 +1,64 @@
using System;
using System;
using System.Windows.Forms;
using pkNX.Sprites;
using pkNX.Structures;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public partial class MegaEvoEntry : UserControl
{
public partial class MegaEvoEntry : UserControl
public static string[] items = Array.Empty<string>();
private static readonly string[] EvoMethods = Enum.GetNames(typeof(MegaEvolutionMethod));
public MegaEvoEntry()
{
public static string[] items = Array.Empty<string>();
InitializeComponent();
private static readonly string[] EvoMethods = Enum.GetNames(typeof(MegaEvolutionMethod));
CB_Method.Items.AddRange(EvoMethods);
CB_Arg.Items.AddRange(items);
public MegaEvoEntry()
NUD_Form.ValueChanged += (_, __) => ChangeSpecies((int)NUD_Form.Value);
CB_Method.SelectedIndexChanged += (s, e) =>
{
InitializeComponent();
CB_Method.Items.AddRange(EvoMethods);
CB_Arg.Items.AddRange(items);
NUD_Form.ValueChanged += (_, __) => ChangeSpecies((int)NUD_Form.Value);
CB_Method.SelectedIndexChanged += (s, e) =>
{
PB_Preview.Visible = PB_Base.Visible = L_Into.Visible = CB_Method.SelectedIndex > 0;
CB_Arg.Visible = CB_Method.SelectedIndex == (int)MegaEvolutionMethod.Item;
};
}
public int Species { private get; set; }
private MegaEvolutionSet? current;
private void ChangeSpecies(int form)
{
PB_Base.Image = SpriteUtil.GetSprite(Species, 0, 0, 0, false, false, false, 7);
PB_Preview.Image = SpriteUtil.GetSprite(Species, form, 0, 0, false, false, false, 7);
PB_Preview.Visible = PB_Base.Visible = L_Into.Visible = CB_Method.SelectedIndex > 0;
}
CB_Arg.Visible = CB_Method.SelectedIndex == (int)MegaEvolutionMethod.Item;
};
}
public void LoadEvolution(MegaEvolutionSet s, int species)
public int Species { private get; set; }
private MegaEvolutionSet? current;
private void ChangeSpecies(int form)
{
PB_Base.Image = SpriteUtil.GetSprite(Species, 0, 0, 0, false, false, false, 7);
PB_Preview.Image = SpriteUtil.GetSprite(Species, form, 0, 0, false, false, false, 7);
PB_Preview.Visible = PB_Base.Visible = L_Into.Visible = CB_Method.SelectedIndex > 0;
}
public void LoadEvolution(MegaEvolutionSet s, int species)
{
Species = species;
current = s;
CB_Method.SelectedIndex = s.Method;
NUD_Form.Value = s.ToForm;
}
public void SaveEvolution()
{
if (current == null)
return;
if (CB_Method.SelectedIndex <= 0)
{
Species = species;
current = s;
CB_Method.SelectedIndex = s.Method;
NUD_Form.Value = s.ToForm;
}
public void SaveEvolution()
{
if (current == null)
return;
if (CB_Method.SelectedIndex <= 0)
{
current.ToForm = 0;
current.Method = 0;
current.Argument = 0;
return;
}
current.Method = CB_Method.SelectedIndex;
current.Argument = CB_Arg.SelectedIndex;
current.ToForm = (int) NUD_Form.Value;
current.ToForm = 0;
current.Method = 0;
current.Argument = 0;
return;
}
current.Method = CB_Method.SelectedIndex;
current.Argument = CB_Arg.SelectedIndex;
current.ToForm = (int) NUD_Form.Value;
}
}

View File

@@ -1,171 +1,170 @@
using System;
using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using pkNX.Structures;
using Util = pkNX.Randomization.Util;
namespace pkNX.WinForms.Controls
namespace pkNX.WinForms.Controls;
public partial class StatEditor : UserControl
{
public partial class StatEditor : UserControl
public StatEditor()
{
public StatEditor()
InitializeComponent();
tb_iv = new[] { TB_HPIV, TB_ATKIV, TB_DEFIV, TB_SPEIV, TB_SPAIV, TB_SPDIV };
tb_ev = new[] { TB_HPEV, TB_ATKEV, TB_DEFEV, TB_SPEEV, TB_SPAEV, TB_SPDEV };
tb_av = new[] { TB_HPAV, TB_ATKAV, TB_DEFAV, TB_SPEAV, TB_SPAAV, TB_SPDAV };
labarray = new[] { Label_ATK, Label_DEF, Label_SPE, Label_SPA, Label_SPD };
}
public void Initialize(string[] types)
{
UpdatingFields = true;
foreach (var t in types.Skip(1))
CB_HPType.Items.Add(t);
UpdatingFields = false;
}
public IPersonalTable? Personal { private get; set; }
public bool UpdatingFields;
public StatPKM PKM { get; set; } = new TrainerPoke7b();
private readonly MaskedTextBox[] tb_iv;
private readonly MaskedTextBox[] tb_ev;
private readonly MaskedTextBox[] tb_av;
private readonly Label[] labarray;
public void UpdateStats()
{
if (UpdatingFields)
return;
UpdatingFields = true;
for (int i = 0; i < 6; i++)
{
InitializeComponent();
tb_iv = new[] { TB_HPIV, TB_ATKIV, TB_DEFIV, TB_SPEIV, TB_SPAIV, TB_SPDIV };
tb_ev = new[] { TB_HPEV, TB_ATKEV, TB_DEFEV, TB_SPEEV, TB_SPAEV, TB_SPDEV };
tb_av = new[] { TB_HPAV, TB_ATKAV, TB_DEFAV, TB_SPEAV, TB_SPAAV, TB_SPDAV };
labarray = new[] { Label_ATK, Label_DEF, Label_SPE, Label_SPA, Label_SPD };
if (Util.ToInt32(tb_iv[i].Text) > 31)
tb_iv[i].Text = "31";
if (Util.ToInt32(tb_ev[i].Text) > 255)
tb_ev[i].Text = "255";
if (Util.ToInt32(tb_av[i].Text) > 200)
tb_av[i].Text = "200";
}
UpdatingFields = false;
public void Initialize(string[] types)
var pt = Personal;
if (pt == null)
throw new NullReferenceException("Personal table hasn't been initialized.");
var pi = pt.GetFormEntry((ushort)PKM.Species, (byte)PKM.Form);
var stats = PKM.GetStats(pi);
Stat_HP.Text = stats[0].ToString();
Stat_ATK.Text = stats[1].ToString();
Stat_DEF.Text = stats[2].ToString();
Stat_SPA.Text = stats[4].ToString();
Stat_SPD.Text = stats[5].ToString();
Stat_SPE.Text = stats[3].ToString();
TB_IVTotal.Text = tb_iv.Select(z => Util.ToInt32(z.Text)).Sum().ToString();
TB_EVTotal.Text = tb_ev.Select(z => Util.ToInt32(z.Text)).Sum().ToString();
if (PKM is IAwakened s)
TB_AVTotal.Text = s.AwakeningSum().ToString();
var showAV = PKM is IAwakened;
Label_AVs.Visible = TB_AVTotal.Visible = FLP_HPType.Visible = showAV;
foreach (var mtb in tb_av)
mtb.Visible = showAV;
Label_EVs.Visible = TB_EVTotal.Visible = FLP_Dynamax.Visible = !showAV;
foreach (var mtb in tb_ev)
mtb.Visible = !showAV;
// Recolor the Stat Labels based on boosted stats.
RecolorStatLabels();
UpdatingFields = true;
CB_HPType.SelectedIndex = PKM.HiddenPowerType;
UpdatingFields = false;
}
private void RecolorStatLabels()
{
int incr = (PKM.Nature / 5);
int decr = (PKM.Nature % 5);
// Reset Label Colors
foreach (Label label in labarray)
label.ResetForeColor();
// Set Colored StatLabels only if Nature isn't Neutral
if (incr != decr)
{
UpdatingFields = true;
foreach (var t in types.Skip(1))
CB_HPType.Items.Add(t);
UpdatingFields = false;
}
public IPersonalTable? Personal { private get; set; }
public bool UpdatingFields;
public StatPKM PKM { get; set; } = new TrainerPoke7b();
private readonly MaskedTextBox[] tb_iv;
private readonly MaskedTextBox[] tb_ev;
private readonly MaskedTextBox[] tb_av;
private readonly Label[] labarray;
public void UpdateStats()
{
if (UpdatingFields)
return;
UpdatingFields = true;
for (int i = 0; i < 6; i++)
{
if (Util.ToInt32(tb_iv[i].Text) > 31)
tb_iv[i].Text = "31";
if (Util.ToInt32(tb_ev[i].Text) > 255)
tb_ev[i].Text = "255";
if (Util.ToInt32(tb_av[i].Text) > 200)
tb_av[i].Text = "200";
}
UpdatingFields = false;
var pt = Personal;
if (pt == null)
throw new NullReferenceException("Personal table hasn't been initialized.");
var pi = pt.GetFormEntry((ushort)PKM.Species, (byte)PKM.Form);
var stats = PKM.GetStats(pi);
Stat_HP.Text = stats[0].ToString();
Stat_ATK.Text = stats[1].ToString();
Stat_DEF.Text = stats[2].ToString();
Stat_SPA.Text = stats[4].ToString();
Stat_SPD.Text = stats[5].ToString();
Stat_SPE.Text = stats[3].ToString();
TB_IVTotal.Text = tb_iv.Select(z => Util.ToInt32(z.Text)).Sum().ToString();
TB_EVTotal.Text = tb_ev.Select(z => Util.ToInt32(z.Text)).Sum().ToString();
if (PKM is IAwakened s)
TB_AVTotal.Text = s.AwakeningSum().ToString();
var showAV = PKM is IAwakened;
Label_AVs.Visible = TB_AVTotal.Visible = FLP_HPType.Visible = showAV;
foreach (var mtb in tb_av)
mtb.Visible = showAV;
Label_EVs.Visible = TB_EVTotal.Visible = FLP_Dynamax.Visible = !showAV;
foreach (var mtb in tb_ev)
mtb.Visible = !showAV;
// Recolor the Stat Labels based on boosted stats.
RecolorStatLabels();
UpdatingFields = true;
CB_HPType.SelectedIndex = PKM.HiddenPowerType;
UpdatingFields = false;
}
private void RecolorStatLabels()
{
int incr = (PKM.Nature / 5);
int decr = (PKM.Nature % 5);
// Reset Label Colors
foreach (Label label in labarray)
label.ResetForeColor();
// Set Colored StatLabels only if Nature isn't Neutral
if (incr != decr)
{
labarray[incr].ForeColor = Color.Red;
labarray[decr].ForeColor = Color.Blue;
}
}
public void LoadStats(StatPKM pkm)
{
PKM = pkm;
UpdatingFields = true;
for (int i = 0; i < 6; i++)
tb_iv[i].Text = pkm.GetIV(i).ToString("00");
for (int i = 0; i < 6; i++)
tb_ev[i].Text = pkm.GetEV(i).ToString("00");
if (PKM is IAwakened a)
{
for (int i = 0; i < 6; i++)
tb_av[i].Text = a.GetAV(i).ToString("00");
}
CB_HPType.SelectedIndex = PKM.HiddenPowerType;
UpdatingFields = false;
UpdateStats();
}
private void UpdateIV(object sender, EventArgs e)
{
if (UpdatingFields || sender is not MaskedTextBox t)
return;
var index = Array.IndexOf(tb_iv, t);
if (index < 0)
return;
int value = Math.Min(31, Util.ToInt32(t.Text));
PKM.SetIV(index, value);
UpdatingFields = true;
CB_HPType.SelectedIndex = PKM.HiddenPowerType;
UpdatingFields = false;
UpdateStats();
}
private void UpdateEV(object sender, EventArgs e)
{
if (UpdatingFields || sender is not MaskedTextBox t)
return;
var index = Array.IndexOf(tb_ev, t);
if (index < 0)
return;
int value = Math.Min(252, Util.ToInt32(t.Text));
PKM.SetEV(index, value);
UpdateStats();
}
private void UpdateAV(object sender, EventArgs e)
{
if (UpdatingFields || sender is not MaskedTextBox t || PKM is not IAwakened a)
return;
var index = Array.IndexOf(tb_av, t);
if (index < 0)
return;
int value = Math.Min(200, Util.ToInt32(t.Text));
a.SetAV(index, value);
UpdateStats();
}
private void ChangeHPType(object sender, EventArgs e)
{
if (UpdatingFields)
return;
PKM.SetHPIVs(CB_HPType.SelectedIndex);
UpdateStats();
labarray[incr].ForeColor = Color.Red;
labarray[decr].ForeColor = Color.Blue;
}
}
public void LoadStats(StatPKM pkm)
{
PKM = pkm;
UpdatingFields = true;
for (int i = 0; i < 6; i++)
tb_iv[i].Text = pkm.GetIV(i).ToString("00");
for (int i = 0; i < 6; i++)
tb_ev[i].Text = pkm.GetEV(i).ToString("00");
if (PKM is IAwakened a)
{
for (int i = 0; i < 6; i++)
tb_av[i].Text = a.GetAV(i).ToString("00");
}
CB_HPType.SelectedIndex = PKM.HiddenPowerType;
UpdatingFields = false;
UpdateStats();
}
private void UpdateIV(object sender, EventArgs e)
{
if (UpdatingFields || sender is not MaskedTextBox t)
return;
var index = Array.IndexOf(tb_iv, t);
if (index < 0)
return;
int value = Math.Min(31, Util.ToInt32(t.Text));
PKM.SetIV(index, value);
UpdatingFields = true;
CB_HPType.SelectedIndex = PKM.HiddenPowerType;
UpdatingFields = false;
UpdateStats();
}
private void UpdateEV(object sender, EventArgs e)
{
if (UpdatingFields || sender is not MaskedTextBox t)
return;
var index = Array.IndexOf(tb_ev, t);
if (index < 0)
return;
int value = Math.Min(252, Util.ToInt32(t.Text));
PKM.SetEV(index, value);
UpdateStats();
}
private void UpdateAV(object sender, EventArgs e)
{
if (UpdatingFields || sender is not MaskedTextBox t || PKM is not IAwakened a)
return;
var index = Array.IndexOf(tb_av, t);
if (index < 0)
return;
int value = Math.Min(200, Util.ToInt32(t.Text));
a.SetAV(index, value);
UpdateStats();
}
private void ChangeHPType(object sender, EventArgs e)
{
if (UpdatingFields)
return;
PKM.SetHPIVs(CB_HPType.SelectedIndex);
UpdateStats();
}
}

View File

@@ -1,145 +1,144 @@
using System;
using System;
using System.Diagnostics;
using System.Windows.Forms;
using pkNX.Game;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public partial class DumperPLA : Form
{
public partial class DumperPLA : Form
private readonly GameDumperPLA Dumper;
public DumperPLA(GameManagerPLA rom)
{
private readonly GameDumperPLA Dumper;
public DumperPLA(GameManagerPLA rom)
{
InitializeComponent();
Dumper = new GameDumperPLA(rom);
}
private void B_OpenFolder_Click(object sender, EventArgs e) => Process.Start("explorer.exe", Dumper.DumpFolder);
#region Tab 1
private void B_ParsePersonal_Click(object sender, EventArgs e)
{
Dumper.DumpPersonal();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_ParsePKMDetails_Click(object sender, EventArgs e)
{
Dumper.DumpPokeInfo();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Wild_Click(object sender, EventArgs e)
{
Dumper.DumpWilds();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Static_Click(object sender, EventArgs e)
{
Dumper.DumpStatic();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Gift_Click(object sender, EventArgs e)
{
Dumper.DumpGifts();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PokeDrops_Click(object sender, EventArgs e)
{
Dumper.DumpDrops();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_ItemInfo_Click(object sender, EventArgs e)
{
Dumper.DumpItems();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Moves_Click(object sender, EventArgs e)
{
Dumper.DumpMoves();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Placement_Click(object sender, EventArgs e)
{
Dumper.DumpPlacement();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Resident_Click(object sender, EventArgs e)
{
Dumper.DumpResident();
System.Media.SystemSounds.Asterisk.Play();
}
#endregion
#region Tab 2
private void B_PKText_Click(object sender, EventArgs e)
{
Dumper.DumpStrings();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PKLearn_Click(object sender, EventArgs e)
{
Dumper.DumpLearnsetBinary();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PKEvo_Click(object sender, EventArgs e)
{
Dumper.DumpEvolutionBinary();
System.Media.SystemSounds.Asterisk.Play();
}
#endregion
#region Tab 3
private void B_GetOutbreak_Click(object sender, EventArgs e)
{
Dumper.DumpOutbreak();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_DumpScriptCommands(object sender, EventArgs e)
{
Dumper.DumpScriptID();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_EventTriggers_Click(object sender, EventArgs e)
{
Dumper.DumpEventTriggers();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_GetDex_Click(object sender, EventArgs e)
{
Dumper.DumpDex();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_MoveShop_Click(object sender, EventArgs e)
{
Dumper.DumpMoveShop();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_DumpHash_Click(object sender, EventArgs e)
{
Dumper.DumpAHTB();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_FlavorText_Click(object sender, EventArgs e)
{
Dumper.DumpFlavorText();
System.Media.SystemSounds.Asterisk.Play();
}
#endregion
InitializeComponent();
Dumper = new GameDumperPLA(rom);
}
private void B_OpenFolder_Click(object sender, EventArgs e) => Process.Start("explorer.exe", Dumper.DumpFolder);
#region Tab 1
private void B_ParsePersonal_Click(object sender, EventArgs e)
{
Dumper.DumpPersonal();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_ParsePKMDetails_Click(object sender, EventArgs e)
{
Dumper.DumpPokeInfo();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Wild_Click(object sender, EventArgs e)
{
Dumper.DumpWilds();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Static_Click(object sender, EventArgs e)
{
Dumper.DumpStatic();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Gift_Click(object sender, EventArgs e)
{
Dumper.DumpGifts();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PokeDrops_Click(object sender, EventArgs e)
{
Dumper.DumpDrops();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_ItemInfo_Click(object sender, EventArgs e)
{
Dumper.DumpItems();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Moves_Click(object sender, EventArgs e)
{
Dumper.DumpMoves();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Placement_Click(object sender, EventArgs e)
{
Dumper.DumpPlacement();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Resident_Click(object sender, EventArgs e)
{
Dumper.DumpResident();
System.Media.SystemSounds.Asterisk.Play();
}
#endregion
#region Tab 2
private void B_PKText_Click(object sender, EventArgs e)
{
Dumper.DumpStrings();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PKLearn_Click(object sender, EventArgs e)
{
Dumper.DumpLearnsetBinary();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PKEvo_Click(object sender, EventArgs e)
{
Dumper.DumpEvolutionBinary();
System.Media.SystemSounds.Asterisk.Play();
}
#endregion
#region Tab 3
private void B_GetOutbreak_Click(object sender, EventArgs e)
{
Dumper.DumpOutbreak();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_DumpScriptCommands(object sender, EventArgs e)
{
Dumper.DumpScriptID();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_EventTriggers_Click(object sender, EventArgs e)
{
Dumper.DumpEventTriggers();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_GetDex_Click(object sender, EventArgs e)
{
Dumper.DumpDex();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_MoveShop_Click(object sender, EventArgs e)
{
Dumper.DumpMoveShop();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_DumpHash_Click(object sender, EventArgs e)
{
Dumper.DumpAHTB();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_FlavorText_Click(object sender, EventArgs e)
{
Dumper.DumpFlavorText();
System.Media.SystemSounds.Asterisk.Play();
}
#endregion
}

View File

@@ -1,180 +1,179 @@
using System;
using System;
using System.Diagnostics;
using System.Windows.Forms;
using pkNX.Game;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public partial class DumperSWSH : Form
{
public partial class DumperSWSH : Form
private readonly GameDumperSWSH Dumper;
public DumperSWSH(GameManagerSWSH rom)
{
private readonly GameDumperSWSH Dumper;
public DumperSWSH(GameManagerSWSH rom)
{
InitializeComponent();
Dumper = new GameDumperSWSH(rom);
}
private void B_OpenFolder_Click(object sender, EventArgs e) => Process.Start("explorer.exe", Dumper.DumpFolder);
#region Tab 1
private void B_ParsePKMDetails_Click(object sender, EventArgs e)
{
Dumper.DumpPokeInfo();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_DumpTrainers_Click(object sender, EventArgs e)
{
Dumper.DumpTrainers();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Wild_Click(object sender, EventArgs e)
{
Dumper.DumpWilds();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Static_Click(object sender, EventArgs e)
{
Dumper.DumpStatic();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Placement_Click(object sender, EventArgs e)
{
Dumper.DumpPlacement();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Gift_Click(object sender, EventArgs e)
{
Dumper.DumpGifts();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Nest_Click(object sender, EventArgs e)
{
Dumper.DumpNestEntries();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Trade_Click(object sender, EventArgs e)
{
Dumper.DumpTrades();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_ItemInfo_Click(object sender, EventArgs e)
{
Dumper.DumpItems();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Moves_Click(object sender, EventArgs e)
{
Dumper.DumpMoves();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_BattleTower_Click(object sender, EventArgs e)
{
Dumper.DumpBattleTower();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Distribution_Nests_Click(object sender, EventArgs e)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
var path = fbd.SelectedPath;
Dumper.DumpDistributionNestEntries(path);
System.Media.SystemSounds.Asterisk.Play();
}
#endregion
#region Tab 2
private void B_PKText_Click(object sender, EventArgs e)
{
Dumper.DumpStrings();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PKLearn_Click(object sender, EventArgs e)
{
Dumper.DumpLearnsetBinary();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PKEggMove_Click(object sender, EventArgs e)
{
Dumper.DumpEggBinary();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PKEvo_Click(object sender, EventArgs e)
{
Dumper.DumpEvolutionBinary();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PKForms_Click(object sender, EventArgs e)
{
Dumper.DumpFormNames();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PKRibbon_Click(object sender, EventArgs e)
{
Dumper.DumpRibbonNames();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Memories_Click(object sender, EventArgs e)
{
Dumper.DumpMemoryStrings();
System.Media.SystemSounds.Asterisk.Play();
}
#endregion
#region Tab 3
private void B_GetDummiedMoveInfo_Click(object sender, EventArgs e)
{
Dumper.DumpDummiedMoves();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_DumpHash_Click(object sender, EventArgs e)
{
Dumper.DumpAHTB();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_GalarDex_Click(object sender, EventArgs e)
{
Dumper.DumpGalarDex();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_FlavorText_Click(object sender, EventArgs e)
{
Dumper.DumpFlavorText();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_EggMove_Click(object sender, EventArgs e)
{
Dumper.DumpEggEntries();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_MaxDens_Click(object sender, EventArgs e)
{
Dumper.DumpMaxDens();
System.Media.SystemSounds.Asterisk.Play();
}
#endregion
InitializeComponent();
Dumper = new GameDumperSWSH(rom);
}
private void B_OpenFolder_Click(object sender, EventArgs e) => Process.Start("explorer.exe", Dumper.DumpFolder);
#region Tab 1
private void B_ParsePKMDetails_Click(object sender, EventArgs e)
{
Dumper.DumpPokeInfo();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_DumpTrainers_Click(object sender, EventArgs e)
{
Dumper.DumpTrainers();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Wild_Click(object sender, EventArgs e)
{
Dumper.DumpWilds();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Static_Click(object sender, EventArgs e)
{
Dumper.DumpStatic();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Placement_Click(object sender, EventArgs e)
{
Dumper.DumpPlacement();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Gift_Click(object sender, EventArgs e)
{
Dumper.DumpGifts();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Nest_Click(object sender, EventArgs e)
{
Dumper.DumpNestEntries();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Trade_Click(object sender, EventArgs e)
{
Dumper.DumpTrades();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_ItemInfo_Click(object sender, EventArgs e)
{
Dumper.DumpItems();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Moves_Click(object sender, EventArgs e)
{
Dumper.DumpMoves();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_BattleTower_Click(object sender, EventArgs e)
{
Dumper.DumpBattleTower();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Distribution_Nests_Click(object sender, EventArgs e)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
var path = fbd.SelectedPath;
Dumper.DumpDistributionNestEntries(path);
System.Media.SystemSounds.Asterisk.Play();
}
#endregion
#region Tab 2
private void B_PKText_Click(object sender, EventArgs e)
{
Dumper.DumpStrings();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PKLearn_Click(object sender, EventArgs e)
{
Dumper.DumpLearnsetBinary();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PKEggMove_Click(object sender, EventArgs e)
{
Dumper.DumpEggBinary();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PKEvo_Click(object sender, EventArgs e)
{
Dumper.DumpEvolutionBinary();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PKForms_Click(object sender, EventArgs e)
{
Dumper.DumpFormNames();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_PKRibbon_Click(object sender, EventArgs e)
{
Dumper.DumpRibbonNames();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Memories_Click(object sender, EventArgs e)
{
Dumper.DumpMemoryStrings();
System.Media.SystemSounds.Asterisk.Play();
}
#endregion
#region Tab 3
private void B_GetDummiedMoveInfo_Click(object sender, EventArgs e)
{
Dumper.DumpDummiedMoves();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_DumpHash_Click(object sender, EventArgs e)
{
Dumper.DumpAHTB();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_GalarDex_Click(object sender, EventArgs e)
{
Dumper.DumpGalarDex();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_FlavorText_Click(object sender, EventArgs e)
{
Dumper.DumpFlavorText();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_EggMove_Click(object sender, EventArgs e)
{
Dumper.DumpEggEntries();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_MaxDens_Click(object sender, EventArgs e)
{
Dumper.DumpMaxDens();
System.Media.SystemSounds.Asterisk.Play();
}
#endregion
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
@@ -6,239 +6,238 @@
using pkNX.Structures.FlatBuffers;
#nullable disable // meh
namespace pkNX.WinForms
namespace pkNX.WinForms;
public class PersonalDumperPLA
{
public class PersonalDumperPLA
private void AddTRs(List<string> lines, IMovesInfo_1 pi, string specCode)
{
private void AddTRs(List<string> lines, IMovesInfo_1 pi, string specCode)
if (!(TMIndexes?.Count > 0))
return;
var tmhm = pi.TMHM;
int count = 0;
lines.Add("Legacy TRs:");
for (int i = 0; i < 100; i++)
{
if (!(TMIndexes?.Count > 0))
return;
var tmhm = pi.TMHM;
int count = 0;
lines.Add("Legacy TRs:");
for (int i = 0; i < 100; i++)
{
if (!tmhm[100 + i])
continue;
var move = TMIndexes[100 + i];
lines.Add($"- [TR{i:00}] {Moves[move]}");
count++;
if (!tmhm[100 + i])
continue;
var move = TMIndexes[100 + i];
lines.Add($"- [TR{i:00}] {Moves[move]}");
count++;
MoveSpeciesLearn[move].Add(specCode);
}
if (count == 0)
lines.Add("None!");
MoveSpeciesLearn[move].Add(specCode);
}
if (count == 0)
lines.Add("None!");
}
public bool HasAbilities { get; set; } = true;
public bool HasItems { get; set; } = true;
public bool HasAbilities { get; set; } = true;
public bool HasItems { get; set; } = true;
public IReadOnlyList<string> Abilities { private get; set; }
public IReadOnlyList<string> Types { private get; set; }
public IReadOnlyList<string> Items { private get; set; }
public IReadOnlyList<string> Colors { private get; set; }
public IReadOnlyList<string> EggGroups { private get; set; }
public IReadOnlyList<string> ExpGroups { private get; set; }
public IReadOnlyList<string> EntryNames { private get; set; }
public IReadOnlyList<string> Moves { protected get; set; }
public IReadOnlyList<string> Species { private get; set; }
public IReadOnlyList<string> ZukanA { private get; set; }
public IReadOnlyList<string> ZukanB { private get; set; }
public IReadOnlyList<string> Abilities { private get; set; }
public IReadOnlyList<string> Types { private get; set; }
public IReadOnlyList<string> Items { private get; set; }
public IReadOnlyList<string> Colors { private get; set; }
public IReadOnlyList<string> EggGroups { private get; set; }
public IReadOnlyList<string> ExpGroups { private get; set; }
public IReadOnlyList<string> EntryNames { private get; set; }
public IReadOnlyList<string> Moves { protected get; set; }
public IReadOnlyList<string> Species { private get; set; }
public IReadOnlyList<string> ZukanA { private get; set; }
public IReadOnlyList<string> ZukanB { private get; set; }
public Learnset8aMeta[] EntryLearnsets { private get; set; }
public IReadOnlyList<EggMoves> EntryEggMoves { private get; set; }
public EvolutionSet8a[] Evos { private get; set; }
public IReadOnlyList<ushort> TMIndexes { protected get; set; }
public Learnset8aMeta[] EntryLearnsets { private get; set; }
public IReadOnlyList<EggMoves> EntryEggMoves { private get; set; }
public EvolutionSet8a[] Evos { private get; set; }
public IReadOnlyList<ushort> TMIndexes { protected get; set; }
private static readonly string[] AbilitySuffix = { " (1)", " (2)", " (H)" };
private static readonly string[] ItemPrefix = { "Item 1 (50%)", "Item 2 (5%)", "Item 3 (1%)" };
private static readonly string[] AbilitySuffix = { " (1)", " (2)", " (H)" };
private static readonly string[] ItemPrefix = { "Item 1 (50%)", "Item 2 (5%)", "Item 3 (1%)" };
public IReadOnlyList<List<string>> MoveSpeciesLearn { get; private set; }
public IReadOnlyList<List<string>> MoveSpeciesLearn { get; private set; }
public PersonalDumperSettings Settings = new();
public PersonalDumperSettings Settings = new();
public List<string> Dump(IPersonalTable table)
public List<string> Dump(IPersonalTable table)
{
var lines = new List<string>();
var ml = new List<string>[Moves.Count];
for (int i = 0; i < ml.Length; i++)
ml[i] = new List<string>();
MoveSpeciesLearn = ml;
for (ushort species = 0; species <= table.MaxSpeciesID; species++)
{
var lines = new List<string>();
var ml = new List<string>[Moves.Count];
for (int i = 0; i < ml.Length; i++)
ml[i] = new List<string>();
MoveSpeciesLearn = ml;
for (ushort species = 0; species <= table.MaxSpeciesID; species++)
{
var spec = table[species];
for (byte form = 0; form < spec.FormCount; form++)
AddDump(lines, table, species, form);
}
return lines;
var spec = table[species];
for (byte form = 0; form < spec.FormCount; form++)
AddDump(lines, table, species, form);
}
return lines;
}
public void AddDump(List<string> lines, IPersonalTable table, ushort species, byte form)
public void AddDump(List<string> lines, IPersonalTable table, ushort species, byte form)
{
var index = table.GetFormIndex(species, form);
var entry = table[index];
string name = EntryNames[index];
AddDump(lines, entry, index, name, species, form);
lines.Add("");
}
private void AddDump(List<string> lines, IPersonalInfo pi, int entry, string name, int species, int form)
{
if (pi is IPersonalMisc_1 { IsPresentInGame: false })
return;
var specCode = pi.FormCount > 1 ? $"{Species[species]}-{form}" : $"{Species[species]}";
if (Settings.Stats)
AddPersonalLines(lines, pi, entry, name, specCode);
if (Settings.Learn)
{
var index = table.GetFormIndex(species, form);
var entry = table[index];
string name = EntryNames[index];
AddDump(lines, entry, index, name, species, form);
lines.Add("");
AddLearnsets(lines, specCode, species, form);
AddLearnsetsLegacy(lines, specCode, species, form);
}
if (Settings.Evo)
AddEvolutions(lines, species, form);
if (Settings.Dex)
AddZukan(lines, entry);
}
private void AddDump(List<string> lines, IPersonalInfo pi, int entry, string name, int species, int form)
private void AddZukan(List<string> lines, int entry)
{
if (entry >= Species.Count)
return;
lines.Add(ZukanA[entry].Replace("\\n", " "));
lines.Add(ZukanB[entry].Replace("\\n", " "));
}
protected virtual void AddTMs(List<string> lines, IMovesInfo_1 pi, string SpecCode)
{
var tmhm = pi.TMHM;
int count = 0;
lines.Add("Legacy TMs:");
for (int i = 0; i < 100; i++)
{
if (pi is IPersonalMisc_1 { IsPresentInGame: false })
return;
if (!tmhm[i])
continue;
var move = TMIndexes[i];
lines.Add($"- [TM{i:00}] {Moves[move]}");
count++;
var specCode = pi.FormCount > 1 ? $"{Species[species]}-{form}" : $"{Species[species]}";
if (Settings.Stats)
AddPersonalLines(lines, pi, entry, name, specCode);
if (Settings.Learn)
{
AddLearnsets(lines, specCode, species, form);
AddLearnsetsLegacy(lines, specCode, species, form);
}
if (Settings.Evo)
AddEvolutions(lines, species, form);
if (Settings.Dex)
AddZukan(lines, entry);
MoveSpeciesLearn[move].Add(SpecCode);
}
if (count == 0)
lines.Add("None!");
private void AddZukan(List<string> lines, int entry)
AddTRs(lines, pi, SpecCode);
}
protected virtual void AddArmorTutors(List<string> lines, IMovesInfo_2 pi, string SpecCode)
{
var shop = pi.SpecialTutors[0];
int count = 0;
lines.Add("Move Shop:");
for (int i = 0; i < Math.Min(shop.Length, Legal.MoveShop8_LA.Length); i++)
{
if (entry >= Species.Count)
return;
lines.Add(ZukanA[entry].Replace("\\n", " "));
lines.Add(ZukanB[entry].Replace("\\n", " "));
if (!shop[i])
continue;
var move = Legal.MoveShop8_LA[i];
lines.Add($"- {Moves[move]}");
count++;
MoveSpeciesLearn[move].Add(SpecCode);
}
if (count == 0)
lines.Add("None!");
}
protected virtual void AddTMs(List<string> lines, IMovesInfo_1 pi, string SpecCode)
private void AddLearnsetsLegacy(List<string> lines, string specCode, int species, int form)
{
var learn = Array.Find(EntryLearnsets, z => z.Species == species && z.Form == form);
if (learn is null)
return;
lines.Add("Legacy Level Up Moves:");
foreach (var x in learn.Mainline)
{
var tmhm = pi.TMHM;
int count = 0;
lines.Add("Legacy TMs:");
for (int i = 0; i < 100; i++)
{
if (!tmhm[i])
continue;
var move = TMIndexes[i];
lines.Add($"- [TM{i:00}] {Moves[move]}");
count++;
MoveSpeciesLearn[move].Add(SpecCode);
}
if (count == 0)
lines.Add("None!");
AddTRs(lines, pi, SpecCode);
}
protected virtual void AddArmorTutors(List<string> lines, IMovesInfo_2 pi, string SpecCode)
{
var shop = pi.SpecialTutors[0];
int count = 0;
lines.Add("Move Shop:");
for (int i = 0; i < Math.Min(shop.Length, Legal.MoveShop8_LA.Length); i++)
{
if (!shop[i])
continue;
var move = Legal.MoveShop8_LA[i];
lines.Add($"- {Moves[move]}");
count++;
MoveSpeciesLearn[move].Add(SpecCode);
}
if (count == 0)
lines.Add("None!");
}
private void AddLearnsetsLegacy(List<string> lines, string specCode, int species, int form)
{
var learn = Array.Find(EntryLearnsets, z => z.Species == species && z.Form == form);
if (learn is null)
return;
lines.Add("Legacy Level Up Moves:");
foreach (var x in learn.Mainline)
{
var move = x.Move;
var level = x.Level;
lines.Add($"- [{level:00}] {Moves[move]}");
MoveSpeciesLearn[move].Add(specCode);
}
}
private void AddLearnsets(List<string> lines, string specCode, int species, int form)
{
var learn = Array.Find(EntryLearnsets, z => z.Species == species && z.Form == form);
if (learn is null)
return;
lines.Add("Level Up Moves:");
foreach (var x in learn.Arceus)
{
var move = x.Move;
var level = x.Level;
var master = x.LevelMaster;
lines.Add($"- [{level:00}] [{master:00}] {Moves[move]}");
MoveSpeciesLearn[move].Add(specCode);
}
}
private void AddEvolutions(List<string> lines, int species, int form)
{
var evo = Array.Find(Evos, z => z.Species == species && z.Form == form);
if (evo?.Table is null)
return;
var evo2 = evo.Table.Where(z => z.Species != 0).ToArray();
if (evo2.Length == 0)
return;
var msg = evo2.Select(z => $"Evolves into {Species[z.Species]}-{z.Form} @ {z.Level} ({z.Method}) [{z.Argument}]");
lines.AddRange(msg);
}
private void AddPersonalLines(List<string> lines, IPersonalInfo pi, int entry, string name, string specCode)
{
Debug.WriteLine($"Dumping {specCode}");
lines.Add("======");
lines.Add($"{entry:000} - {name} (Stage: {pi.EvoStage})");
lines.Add("======");
if (pi is IPersonalMisc_1 { IsPresentInGame: false })
lines.Add("Present: No");
lines.Add($"Base Stats: {pi.HP}.{pi.ATK}.{pi.DEF}.{pi.SPA}.{pi.SPD}.{pi.SPE} (BST: {pi.GetBaseStatTotal()})");
lines.Add($"EV Yield: {pi.EV_HP}.{pi.EV_ATK}.{pi.EV_DEF}.{pi.EV_SPA}.{pi.EV_SPD}.{pi.EV_SPE}");
lines.Add($"Gender Ratio: {pi.Gender}");
lines.Add($"Catch Rate: {pi.CatchRate}");
if (HasAbilities)
{
var abils = new int[pi.GetNumAbilities()];
pi.GetAbilities(abils);
var msg = string.Join(" | ", abils.Select((z, j) => Abilities[z] + AbilitySuffix[j]));
lines.Add($"Abilities: {msg}");
}
lines.Add(string.Format(pi.Type1 != pi.Type2
? "Type: {0} / {1}"
: "Type: {0}", Types[(int)pi.Type1], Types[(int)pi.Type2]));
if (HasItems)
{
var items = new int[pi.GetNumItems()];
pi.GetItems(items);
if (items.Distinct().Count() == 1)
lines.Add($"Items: {Items[pi.Item1]}");
else
lines.AddRange(items.Select((z, j) => $"{ItemPrefix[j]}: {Items[z]}"));
}
lines.Add($"EXP Group: {ExpGroups[pi.EXPGrowth]}");
lines.Add(string.Format(pi.EggGroup1 != pi.EggGroup2
? "Egg Group: {0} / {1}"
: "Egg Group: {0}", EggGroups[pi.EggGroup1], EggGroups[pi.EggGroup2]));
lines.Add($"Height: {(decimal)pi.Height / 100:00.00}m, Weight: {(decimal)pi.Weight / 10:000.0}kg, Color: {Colors[pi.Color]}");
var move = x.Move;
var level = x.Level;
lines.Add($"- [{level:00}] {Moves[move]}");
MoveSpeciesLearn[move].Add(specCode);
}
}
}
private void AddLearnsets(List<string> lines, string specCode, int species, int form)
{
var learn = Array.Find(EntryLearnsets, z => z.Species == species && z.Form == form);
if (learn is null)
return;
lines.Add("Level Up Moves:");
foreach (var x in learn.Arceus)
{
var move = x.Move;
var level = x.Level;
var master = x.LevelMaster;
lines.Add($"- [{level:00}] [{master:00}] {Moves[move]}");
MoveSpeciesLearn[move].Add(specCode);
}
}
private void AddEvolutions(List<string> lines, int species, int form)
{
var evo = Array.Find(Evos, z => z.Species == species && z.Form == form);
if (evo?.Table is null)
return;
var evo2 = evo.Table.Where(z => z.Species != 0).ToArray();
if (evo2.Length == 0)
return;
var msg = evo2.Select(z => $"Evolves into {Species[z.Species]}-{z.Form} @ {z.Level} ({z.Method}) [{z.Argument}]");
lines.AddRange(msg);
}
private void AddPersonalLines(List<string> lines, IPersonalInfo pi, int entry, string name, string specCode)
{
Debug.WriteLine($"Dumping {specCode}");
lines.Add("======");
lines.Add($"{entry:000} - {name} (Stage: {pi.EvoStage})");
lines.Add("======");
if (pi is IPersonalMisc_1 { IsPresentInGame: false })
lines.Add("Present: No");
lines.Add($"Base Stats: {pi.HP}.{pi.ATK}.{pi.DEF}.{pi.SPA}.{pi.SPD}.{pi.SPE} (BST: {pi.GetBaseStatTotal()})");
lines.Add($"EV Yield: {pi.EV_HP}.{pi.EV_ATK}.{pi.EV_DEF}.{pi.EV_SPA}.{pi.EV_SPD}.{pi.EV_SPE}");
lines.Add($"Gender Ratio: {pi.Gender}");
lines.Add($"Catch Rate: {pi.CatchRate}");
if (HasAbilities)
{
var abils = new int[pi.GetNumAbilities()];
pi.GetAbilities(abils);
var msg = string.Join(" | ", abils.Select((z, j) => Abilities[z] + AbilitySuffix[j]));
lines.Add($"Abilities: {msg}");
}
lines.Add(string.Format(pi.Type1 != pi.Type2
? "Type: {0} / {1}"
: "Type: {0}", Types[(int)pi.Type1], Types[(int)pi.Type2]));
if (HasItems)
{
var items = new int[pi.GetNumItems()];
pi.GetItems(items);
if (items.Distinct().Count() == 1)
lines.Add($"Items: {Items[pi.Item1]}");
else
lines.AddRange(items.Select((z, j) => $"{ItemPrefix[j]}: {Items[z]}"));
}
lines.Add($"EXP Group: {ExpGroups[pi.EXPGrowth]}");
lines.Add(string.Format(pi.EggGroup1 != pi.EggGroup2
? "Egg Group: {0} / {1}"
: "Egg Group: {0}", EggGroups[pi.EggGroup1], EggGroups[pi.EggGroup2]));
lines.Add($"Height: {(decimal)pi.Height / 100:00.00}m, Weight: {(decimal)pi.Weight / 10:000.0}kg, Color: {Colors[pi.Color]}");
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
@@ -7,183 +7,197 @@
using System.Windows.Forms;
using pkNX.Sprites;
using pkNX.Structures;
using pkNX.WinForms.Properties;
using EditorBase = pkNX.WinForms.Controls.EditorBase;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public class ProgramSettings
{
public partial class Main : Form
public int Language { get; set; } = 2;
public string GamePath { get; set; } = string.Empty;
}
public partial class Main : Form
{
public static readonly string ProgramSettingsPath = Path.Combine(Application.StartupPath, "settings.json");
public ProgramSettings Settings { get; }
private int Language
{
private int Language
get => CB_Lang.SelectedIndex;
set => CB_Lang.SelectedIndex = value;
}
private EditorBase? Editor;
public Main()
{
InitializeComponent();
// Fix number values displaying incorrectly for certain cultures.
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
Settings = SettingsSerializer.GetSettings<ProgramSettings>(ProgramSettingsPath).Result;
CB_Lang.SelectedIndex = Settings.Language;
if (!string.IsNullOrWhiteSpace(Settings.GamePath))
OpenPath(Settings.GamePath);
DragDrop += (s, e) =>
{
get => CB_Lang.SelectedIndex;
set => CB_Lang.SelectedIndex = value;
}
private EditorBase? Editor;
public Main()
{
InitializeComponent();
// Fix number values displaying incorrectly for certain cultures.
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
CB_Lang.SelectedIndex = Settings.Default.Language;
if (!string.IsNullOrWhiteSpace(Settings.Default.GamePath))
OpenPath(Settings.Default.GamePath);
DragDrop += (s, e) =>
{
var files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (var f in files)
OpenPath(f);
};
DragEnter += (s, e) =>
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
};
}
private void ChangeLanguage(object sender, EventArgs e)
{
Menu_Options.DropDown.Close();
if (Editor == null)
var files = (string[]?)e.Data?.GetData(DataFormats.FileDrop);
if (files is null)
return;
foreach (var f in files)
OpenPath(f);
};
DragEnter += (s, e) =>
{
if (e.Data?.GetDataPresent(DataFormats.FileDrop) ?? false)
e.Effect = DragDropEffects.Copy;
};
}
if (Editor.Game.GetGeneration() < 7 && Language > 7)
{
WinFormsUtil.Alert("Selected Language is not available for this game", "Defaulting to English.");
CB_Lang.SelectedIndex = 2;
private void ChangeLanguage(object sender, EventArgs e)
{
Menu_Options.DropDown.Close();
if (Editor == null)
return;
if (Editor.Game.GetGeneration() < 7 && Language > 7)
{
WinFormsUtil.Alert("Selected Language is not available for this game", "Defaulting to English.");
CB_Lang.SelectedIndex = 2;
return;
}
Editor.Language = Language;
}
private void Menu_Open_Click(object sender, EventArgs e)
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() == DialogResult.OK)
OpenPath(fbd.SelectedPath);
}
private async void Main_FormClosing(object sender, FormClosingEventArgs e)
{
if (Editor == null)
return;
Editor.Close();
EditUtil.SaveSettings(Editor.Game);
Settings.Language = CB_Lang.SelectedIndex;
Settings.GamePath = TB_Path.Text;
await SettingsSerializer.SaveSettings(Settings, ProgramSettingsPath);
}
private void Menu_Exit_Click(object sender, EventArgs e)
{
if (ModifierKeys == Keys.Control) // triggered via hotkey
{
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, $"Quit {nameof(pkNX)}?"))
return;
}
Editor.Language = Language;
}
Close();
}
private void Menu_Open_Click(object sender, EventArgs e)
private void Menu_SetRNGSeed_Click(object sender, EventArgs e)
{
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Reseed RNG?",
"If yes, copy the 32 bit (not hex) integer seed to the clipboard before hitting Yes.");
if (DialogResult.Yes != result)
return;
string val = string.Empty;
try { val = Clipboard.GetText(); }
catch { }
if (int.TryParse(val, out int seed))
{
using var fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() == DialogResult.OK)
OpenPath(fbd.SelectedPath);
Util.Rand = new Random(seed);
WinFormsUtil.Alert($"Reseeded RNG to seed: {seed}");
return;
}
WinFormsUtil.Alert("Unable to set seed.");
}
private void Main_FormClosing(object sender, FormClosingEventArgs e)
private void OpenPath(string path)
{
try
{
if (Editor == null)
return;
Editor.Close();
EditUtil.SaveSettings(Editor.Game);
Settings.Default.Language = CB_Lang.SelectedIndex;
Settings.Default.GamePath = TB_Path.Text;
Settings.Default.Save();
if (Directory.Exists(path))
OpenFolder(path);
else
OpenFile(path);
}
private void Menu_Exit_Click(object sender, EventArgs e)
catch (Exception ex)
{
if (ModifierKeys == Keys.Control) // triggered via hotkey
{
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, $"Quit {nameof(pkNX)}?"))
return;
}
Close();
}
private void Menu_SetRNGSeed_Click(object sender, EventArgs e)
{
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Reseed RNG?",
"If yes, copy the 32 bit (not hex) integer seed to the clipboard before hitting Yes.");
if (DialogResult.Yes != result)
return;
string val = string.Empty;
try { val = Clipboard.GetText(); }
catch { }
if (int.TryParse(val, out int seed))
{
Util.Rand = new Random(seed);
WinFormsUtil.Alert($"Reseeded RNG to seed: {seed}");
return;
}
WinFormsUtil.Alert("Unable to set seed.");
}
private void OpenPath(string path)
{
try
{
if (Directory.Exists(path))
OpenFolder(path);
else
OpenFile(path);
}
catch (Exception ex)
{
WinFormsUtil.Error($"Failed to open -- {path}", ex.Message);
}
}
private static void OpenFile(string path)
{
var result = FileRipper.TryOpenFile(path);
if (result.Code != RipResultCode.Success)
{
WinFormsUtil.Alert("Invalid file loaded." + Environment.NewLine + $"Unable to recognize data: {result.Code}.", path);
return;
}
System.Media.SystemSounds.Asterisk.Play();
Process.Start("explorer.exe", result.ResultPath);
}
private void OpenFolder(string path)
{
var editor = EditorBase.GetEditor(path, Language);
if (editor == null)
{
WinFormsUtil.Alert("Invalid folder loaded." + Environment.NewLine + "Unable to recognize game data.", path);
return;
}
try
{
editor.Initialize();
LoadROM(editor);
}
catch (Exception ex)
{
WinFormsUtil.Error("Failed to initialize ROM data." + Environment.NewLine + "Please ensure your dump is correctly set up, with updated patches merged in (if applicable).", ex.Message, ex.StackTrace);
}
}
private void LoadROM(EditorBase editor)
{
Editor = editor;
var ctrl = Editor.GetControls(120, 35).OrderBy(x => x.Text);
FLP_Controls.Controls.Clear();
foreach (var c in ctrl)
FLP_Controls.Controls.Add(c);
Text = $"{nameof(pkNX)} - {Editor.Game}";
TB_Path.Text = Editor.Location;
Menu_Current.Enabled = true;
EditUtil.LoadSettings(Editor.Game);
EditUtil.SaveSettings(Editor.Game);
SpriteUtil.Initialize();
System.Media.SystemSounds.Asterisk.Play();
}
private void Menu_Current_Click(object sender, EventArgs e)
{
if (Directory.Exists(TB_Path.Text))
Process.Start("explorer.exe", TB_Path.Text);
}
private void Menu_Save_Click(object sender, EventArgs e)
{
Editor?.Save();
WinFormsUtil.Error($"Failed to open -- {path}", ex.Message);
}
}
private static void OpenFile(string path)
{
var result = FileRipper.TryOpenFile(path);
if (result.Code != RipResultCode.Success || result.ResultPath is not { } resultPath)
{
WinFormsUtil.Alert("Invalid file loaded." + Environment.NewLine + $"Unable to recognize data: {result.Code}.", path);
return;
}
System.Media.SystemSounds.Asterisk.Play();
Process.Start("explorer.exe", resultPath);
}
private void OpenFolder(string path)
{
var editor = EditorBase.GetEditor(path, Language);
if (editor == null)
{
var msg = "Invalid folder loaded." + Environment.NewLine + "Unable to recognize game data.";
WinFormsUtil.Alert(msg, path);
return;
}
try
{
editor.Initialize();
LoadROM(editor);
}
catch (Exception ex)
{
var msg = "Failed to initialize ROM data." + Environment.NewLine +
"Please ensure your dump is correctly set up, with updated patches merged in (if applicable).";
var stack = ex.StackTrace ?? string.Empty;
WinFormsUtil.Error(msg, ex.Message, stack);
}
}
private void LoadROM(EditorBase editor)
{
Editor = editor;
var ctrl = Editor.GetControls(120, 35).OrderBy(x => x.Text);
FLP_Controls.Controls.Clear();
foreach (var c in ctrl)
FLP_Controls.Controls.Add(c);
Text = $"{nameof(pkNX)} - {Editor.Game}";
TB_Path.Text = Editor.Location;
Menu_Current.Enabled = true;
EditUtil.LoadSettings(Editor.Game);
EditUtil.SaveSettings(Editor.Game);
SpriteUtil.Initialize();
System.Media.SystemSounds.Asterisk.Play();
}
private void Menu_Current_Click(object sender, EventArgs e)
{
if (Directory.Exists(TB_Path.Text))
Process.Start("explorer.exe", TB_Path.Text);
}
private void Menu_Save_Click(object sender, EventArgs e)
{
Editor?.Save();
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
@@ -6,66 +6,67 @@
using pkNX.Randomization;
using pkNX.Structures;
namespace pkNX.WinForms
namespace pkNX.WinForms;
[Serializable]
public class SharedSettings
{
[Serializable]
public class SharedSettings
public PersonalRandSettings Personal { get; set; } = new();
public SpeciesSettings Species { get; set; } = new();
public TrainerRandSettings Trainer { get; set; } = new();
public MovesetRandSettings Move { get; set; } = new();
public LearnSettings Learn { get; set; } = new();
}
public static class EditUtil
{
public static SharedSettings Settings { get; set; } = new();
public static void LoadSettings(GameVersion game)
{
public PersonalRandSettings Personal { get; set; } = new();
public SpeciesSettings Species { get; set; } = new();
public TrainerRandSettings Trainer { get; set; } = new();
public MovesetRandSettings Move { get; set; } = new();
public LearnSettings Learn { get; set; } = new();
string path = GetSettingsFileName(game);
if (!File.Exists(path))
{
Settings = new SharedSettings();
return;
}
using var file = File.OpenRead(path);
var reader = new XmlSerializer(typeof(SharedSettings));
try
{
Settings = (SharedSettings?) reader.Deserialize(file) ?? new SharedSettings();
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
public static class EditUtil
public static void SaveSettings(GameVersion game)
{
public static SharedSettings Settings { get; set; } = new();
public static void LoadSettings(GameVersion game)
string path = GetSettingsFileName(game);
using var file = File.Create(path);
var writer = new XmlSerializer(typeof(SharedSettings));
try
{
string path = GetSettingsFileName(game);
writer.Serialize(file, Settings);
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
if (!File.Exists(path))
{
Settings = new SharedSettings();
return;
}
using var file = File.OpenRead(path);
var reader = new XmlSerializer(typeof(SharedSettings));
try
{
Settings = (SharedSettings?) reader.Deserialize(file) ?? new SharedSettings();
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
file.Close();
File.Delete(path);
}
}
public static void SaveSettings(GameVersion game)
{
string path = GetSettingsFileName(game);
using var file = File.Create(path);
var writer = new XmlSerializer(typeof(SharedSettings));
try
{
writer.Serialize(file, Settings);
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
if (!File.Exists(path))
return;
file.Close();
File.Delete(path);
}
}
private static string GetSettingsFileName(GameVersion game)
{
var path = Path.GetDirectoryName(Application.ExecutablePath);
return Path.Combine(path, $"randsetting{game}.xml");
}
private static string GetSettingsFileName(GameVersion game)
{
var path = Path.GetDirectoryName(Application.StartupPath);
if (path is null)
throw new ArgumentNullException(nameof(path));
return Path.Combine(path, $"randsetting{game}.xml");
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.IO;
using System.Linq;
using System.Windows.Forms;
@@ -8,379 +8,378 @@
using pkNX.Structures;
using pkNX.Structures.FlatBuffers;
namespace pkNX.WinForms.Controls
namespace pkNX.WinForms.Controls;
internal class EditorGG : EditorBase
{
internal class EditorGG : EditorBase
private GameData Data => ((GameManagerGG)ROM).Data;
protected internal EditorGG(GameManagerGG rom) : base(rom) { }
public void EditCommon()
{
private GameData Data => ((GameManagerGG)ROM).Data;
protected internal EditorGG(GameManagerGG rom) : base(rom) { }
var text = ROM.GetFilteredFolder(GameFile.GameText, z => Path.GetExtension(z) == ".dat");
var config = new TextConfig(ROM.Game);
var tc = new TextContainer(text, config);
using var form = new TextEditor(tc, TextEditor.TextEditorMode.Common);
form.ShowDialog();
if (!form.Modified)
text.CancelEdits();
}
public void EditCommon()
public void EditScript()
{
var text = ROM.GetFilteredFolder(GameFile.StoryText, z => Path.GetExtension(z) == ".dat");
var config = new TextConfig(ROM.Game);
var tc = new TextContainer(text, config);
using var form = new TextEditor(tc, TextEditor.TextEditorMode.Script);
form.ShowDialog();
if (!form.Modified)
text.CancelEdits();
}
public void EditTrainers()
{
var editor = new TrainerEditor
{
var text = ROM.GetFilteredFolder(GameFile.GameText, z => Path.GetExtension(z) == ".dat");
var config = new TextConfig(ROM.Game);
var tc = new TextContainer(text, config);
using var form = new TextEditor(tc, TextEditor.TextEditorMode.Common);
form.ShowDialog();
if (!form.Modified)
text.CancelEdits();
}
ReadClass = data => new TrainerClass7b(data),
ReadPoke = data => new TrainerPoke7b(data),
ReadTrainer = data => new TrainerData7b(data),
ReadTeam = TrainerPoke7b.ReadTeam,
WriteTeam = TrainerPoke7b.WriteTeam,
TrainerData = ROM.GetFilteredFolder(GameFile.TrainerData),
TrainerPoke = ROM.GetFilteredFolder(GameFile.TrainerPoke),
TrainerClass = ROM.GetFilteredFolder(GameFile.TrainerClass),
};
editor.Initialize();
using var form = new BTTE(Data, editor, ROM);
form.ShowDialog();
if (!form.Modified)
editor.CancelEdits();
else
editor.Save();
}
public void EditScript()
public void EditPokémon()
{
var editor = new PokeEditor
{
var text = ROM.GetFilteredFolder(GameFile.StoryText, z => Path.GetExtension(z) == ".dat");
var config = new TextConfig(ROM.Game);
var tc = new TextContainer(text, config);
using var form = new TextEditor(tc, TextEditor.TextEditorMode.Script);
form.ShowDialog();
if (!form.Modified)
text.CancelEdits();
}
Evolve = Data.EvolutionData,
Learn = Data.LevelUpData,
Mega = Data.MegaEvolutionData,
Personal = Data.PersonalData,
TMHM = Legal.TMHM_GG,
};
using var form = new PokeDataUI(editor, ROM, Data);
form.ShowDialog();
if (!form.Modified)
editor.CancelEdits();
else
editor.Save();
}
public void EditTrainers()
public void EditItems()
{
var obj = ROM.GetFilteredFolder(GameFile.ItemStats, z => new FileInfo(z).Length == 36);
var cache = new DataCache<Item>(obj)
{
var editor = new TrainerEditor
{
ReadClass = data => new TrainerClass7b(data),
ReadPoke = data => new TrainerPoke7b(data),
ReadTrainer = data => new TrainerData7b(data),
ReadTeam = TrainerPoke7b.ReadTeam,
WriteTeam = TrainerPoke7b.WriteTeam,
TrainerData = ROM.GetFilteredFolder(GameFile.TrainerData),
TrainerPoke = ROM.GetFilteredFolder(GameFile.TrainerPoke),
TrainerClass = ROM.GetFilteredFolder(GameFile.TrainerClass),
};
editor.Initialize();
using var form = new BTTE(Data, editor, ROM);
form.ShowDialog();
if (!form.Modified)
editor.CancelEdits();
else
editor.Save();
}
public void EditPokémon()
{
var editor = new PokeEditor
{
Evolve = Data.EvolutionData,
Learn = Data.LevelUpData,
Mega = Data.MegaEvolutionData,
Personal = Data.PersonalData,
TMHM = Legal.TMHM_GG,
};
using var form = new PokeDataUI(editor, ROM, Data);
form.ShowDialog();
if (!form.Modified)
editor.CancelEdits();
else
editor.Save();
}
public void EditItems()
{
var obj = ROM.GetFilteredFolder(GameFile.ItemStats, z => new FileInfo(z).Length == 36);
var cache = new DataCache<Item>(obj)
{
Create = Item.FromBytes,
Write = item => item.Write(),
};
using var form = new GenericEditor<Item>(cache, ROM.GetStrings(TextName.ItemNames), "Item Editor");
form.ShowDialog();
if (!form.Modified)
cache.CancelEdits();
else
cache.Save();
}
public void EditMoves()
{
var obj = ROM[GameFile.MoveStats]; // mini
var cache = new DataCache<Move7>(obj)
{
Create = data => new Move7(data),
Write = move => move.Write(),
};
using var form = new GenericEditor<Move7>(cache, ROM.GetStrings(TextName.MoveNames), "Move Editor");
form.ShowDialog();
if (!form.Modified)
{
cache.CancelEdits();
return;
}
Create = Item.FromBytes,
Write = item => item.Write(),
};
using var form = new GenericEditor<Item>(cache, ROM.GetStrings(TextName.ItemNames), "Item Editor");
form.ShowDialog();
if (!form.Modified)
cache.CancelEdits();
else
cache.Save();
Data.MoveData.ClearAll(); // force reload if used again
}
public void EditMoves()
{
var obj = ROM[GameFile.MoveStats]; // mini
var cache = new DataCache<Move7>(obj)
{
Create = data => new Move7(data),
Write = move => move.Write(),
};
using var form = new GenericEditor<Move7>(cache, ROM.GetStrings(TextName.MoveNames), "Move Editor");
form.ShowDialog();
if (!form.Modified)
{
cache.CancelEdits();
return;
}
public void EditGift()
cache.Save();
Data.MoveData.ClearAll(); // force reload if used again
}
public void EditGift()
{
var file = ROM[GameFile.EncounterGift];
var data = file[0];
var objs = data.GetArray(z => new EncounterGift7b(z), EncounterGift7b.SIZE); // binary
var names = Enumerable.Range(0, objs.Length).Select(z => $"{z:000}").ToArray();
var cache = new DirectCache<EncounterGift7b>(objs);
void Randomize()
{
var file = ROM[GameFile.EncounterGift];
var data = file[0];
var objs = data.GetArray(z => new EncounterGift7b(z), EncounterGift7b.SIZE); // binary
var names = Enumerable.Range(0, objs.Length).Select(z => $"{z:000}").ToArray();
var cache = new DirectCache<EncounterGift7b>(objs);
var spec = EditUtil.Settings.Species;
spec.Gen2 = spec.Gen3 = spec.Gen4 = spec.Gen5 = spec.Gen6 = spec.Gen7 = false;
var srand = new SpeciesRandomizer(ROM.Info, Data.PersonalData);
var frand = new FormRandomizer(Data.PersonalData);
srand.Initialize(spec);
foreach (var t in objs)
{
t.Species = (Species)srand.GetRandomSpecies((int)t.Species);
t.Form = frand.GetRandomForme((int)t.Species, false, false, true, false, Data.PersonalData.Table);
t.Nature = Nature.Random25;
t.Gender = FixedGender.Random;
t.Shiny = Shiny.Random;
t.RelearnMoves = new[] { 0, 0, 0, 0 };
if (t.IV_HP != -4)
t.IVs = new[] { -1, -1, -1, -1, -1, -1 };
}
}
using var form = new GenericEditor<EncounterGift7b>(cache, names, "Gift Editor", Randomize);
form.ShowDialog();
if (!form.Modified)
file.CancelEdits();
else
file[0] = objs.SelectMany(z => z.Write()).ToArray();
}
public void EditTrade()
{
var file = ROM[GameFile.EncounterTrade];
var data = file[0];
var objs = data.GetArray(z => new EncounterTrade7b(z), EncounterTrade7b.SIZE); // binary
var names = Enumerable.Range(0, objs.Length).Select(z => $"{z:000}").ToArray();
var cache = new DirectCache<EncounterTrade7b>(objs);
void Randomize()
{
var spec = EditUtil.Settings.Species;
spec.Gen2 = spec.Gen3 = spec.Gen4 = spec.Gen5 = spec.Gen6 = spec.Gen7 = false;
var srand = new SpeciesRandomizer(ROM.Info, Data.PersonalData);
var frand = new FormRandomizer(Data.PersonalData);
srand.Initialize(spec, 808, 809); // can only catch 1-151 in wild
foreach (var t in objs)
{
t.Species = (Species)srand.GetRandomSpecies((int)t.Species);
t.RequiredSpecies = (Species)srand.GetRandomSpecies((int)t.Species);
t.Form = frand.GetRandomForme((int)t.Species, false, false, true, false, Data.PersonalData.Table);
t.RequiredForm = 0; // can't catch wild alolan forms
t.Nature = Nature.Random - 1;
t.Gender = FixedGender.Random;
t.Shiny = Shiny.Random;
t.RelearnMoves = new[] { 0, 0, 0, 0 };
if (t.IV_HP != -4)
t.IVs = new[] { -1, -1, -1, -1, -1, -1 };
}
}
using var form = new GenericEditor<EncounterTrade7b>(cache, names, "Trade Editor", Randomize);
form.ShowDialog();
if (!form.Modified)
file.CancelEdits();
else
file[0] = objs.SelectMany(z => z.Write()).ToArray();
}
public void EditStatic()
{
var file = ROM[GameFile.EncounterStatic];
var data = file[0];
var objs = data.GetArray(z => new EncounterStatic7b(z), EncounterStatic7b.SIZE); // binary
var names = Enumerable.Range(0, objs.Length).Select(z => $"{z:000}").ToArray();
var cache = new DirectCache<EncounterStatic7b>(objs);
void Randomize()
{
var spec = EditUtil.Settings.Species;
spec.Gen2 = spec.Gen3 = spec.Gen4 = spec.Gen5 = spec.Gen6 = spec.Gen7 = false;
var srand = new SpeciesRandomizer(ROM.Info, Data.PersonalData);
var frand = new FormRandomizer(Data.PersonalData);
srand.Initialize(spec);
for (int i = 2; i < objs.Length; i++) // skip starters
{
var t = objs[i];
t.Species = (Species)srand.GetRandomSpecies((int)t.Species);
t.Form = frand.GetRandomForme((int)t.Species, false, false, true, false, Data.PersonalData.Table);
t.Nature = Nature.Random25;
t.Gender = FixedGender.Random;
t.Shiny = Shiny.Random;
t.RelearnMoves = new[] { 0, 0, 0, 0 };
if (t.IV_HP != -4)
t.IVs = new[] { -1, -1, -1, -1, -1, -1 };
}
}
using var form = new GenericEditor<EncounterStatic7b>(cache, names, "Static Encounter Editor", Randomize);
form.ShowDialog();
if (!form.Modified)
file.CancelEdits();
else
file[0] = objs.SelectMany(z => z.Write()).ToArray();
}
public void EditWild() => PopWildEdit(ROM.Game == GameVersion.GP ? GameFile.WildData1 : GameFile.WildData2);
private void PopWildEdit(GameFile type)
{
var file = ROM.GetFile(type);
var data = file[0];
var obj = FlatBufferConverter.DeserializeFrom<EncounterArchive7b>(data);
using var form = new GGWE((GameManagerGG)ROM, obj);
if (form.ShowDialog() != DialogResult.OK)
return;
data = FlatBufferConverter.SerializeFrom(obj);
file[0] = data;
}
public void EditShinyRate()
{
var path = Path.Combine(ROM.PathExeFS, "main");
var data = FileMitm.ReadAllBytes(path);
var nso = new NSO(data);
var shiny = new ShinyRateGG(nso.DecompressedText);
if (!shiny.IsEditable)
{
WinFormsUtil.Alert("Not able to find shiny rate logic in ExeFS.");
return;
}
using var editor = new ShinyRate(shiny);
editor.ShowDialog();
if (!editor.Modified)
return;
nso.DecompressedText = shiny.Data;
FileMitm.WriteAllBytes(path, nso.Write());
}
public void EditTM()
{
var path = Path.Combine(ROM.PathExeFS, "main");
var data = FileMitm.ReadAllBytes(path);
var list = new TMEditorGG(data);
if (!list.Valid)
{
WinFormsUtil.Alert("Not able to find tm data in ExeFS.");
return;
}
var moves = list.GetMoves();
var allowed = Legal.GetAllowedMoves(ROM.Game, Data.MoveData.Length);
var names = ROM.GetStrings(TextName.MoveNames);
using var editor = new TMList(moves, allowed, names);
editor.ShowDialog();
if (!editor.Modified)
return;
list.SetMoves(editor.FinalMoves);
data = list.Write();
FileMitm.WriteAllBytes(path, data);
}
public void EditTypeChart()
{
var path = Path.Combine(ROM.PathExeFS, "main");
var data = FileMitm.ReadAllBytes(path);
var nso = new NSO(data);
byte[] pattern = // N2nn3pia9transport18UnreliableProtocolE
{
0x4E, 0x32, 0x6E, 0x6E, 0x33, 0x70, 0x69, 0x61, 0x39, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72,
0x74, 0x31, 0x38, 0x55, 0x6E, 0x72, 0x65, 0x6C, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x50, 0x72, 0x6F, 0x74,
0x6F, 0x63, 0x6F, 0x6C, 0x45, 0x00
};
int ofs = CodePattern.IndexOfBytes(nso.DecompressedRO, pattern);
if (ofs < 0)
{
WinFormsUtil.Alert("Not able to find type chart data in ExeFS.");
return;
}
ofs += pattern.Length + 0x24; // 0x5B4C0C in lgpe 1.0 RO
var cdata = new byte[18 * 18];
var types = ROM.GetStrings(TextName.Types);
Array.Copy(nso.DecompressedRO, ofs, cdata, 0, cdata.Length);
var chart = new TypeChartEditor(cdata);
using var editor = new TypeChart(chart, types);
editor.ShowDialog();
if (!editor.Modified)
return;
chart.Data.CopyTo(nso.DecompressedRO, ofs);
data = nso.Write();
FileMitm.WriteAllBytes(path, data);
}
public void EditShop1() => EditShop(false);
public void EditShop2() => EditShop(true);
private void EditShop(bool shop2)
{
var arc = ROM.GetFile(GameFile.Shops);
var data = arc[0];
int[] PossibleHeldItems = Legal.GetRandomItemList(ROM.Game);
var shop = FlatBufferConverter.DeserializeFrom<ShopInventory>(data);
if (!shop2)
{
var table = shop.Shop1;
var names = table.Select((z, _) => $"{(z.LGPE.TryGetValue(z.Hash, out var shopName) ? shopName : z.Hash.ToString("X"))}").ToArray();
var cache = new DirectCache<Shop1>(table);
using var form = new GenericEditor<Shop1>(cache, names, $"{nameof(Shop1)} Editor", Randomize);
form.ShowDialog();
if (!form.Modified)
{
arc.CancelEdits();
return;
}
void Randomize()
{
var spec = EditUtil.Settings.Species;
spec.Gen2 = spec.Gen3 = spec.Gen4 = spec.Gen5 = spec.Gen6 = spec.Gen7 = false;
var srand = new SpeciesRandomizer(ROM.Info, Data.PersonalData);
var frand = new FormRandomizer(Data.PersonalData);
srand.Initialize(spec);
foreach (var t in objs)
for (int s = 1; s < table.Length; s++) // skip first table with TMs (unobtainable otherwise)
{
t.Species = (Species)srand.GetRandomSpecies((int)t.Species);
t.Form = frand.GetRandomForme((int)t.Species, false, false, true, false, Data.PersonalData.Table);
t.Nature = Nature.Random25;
t.Gender = FixedGender.Random;
t.Shiny = Shiny.Random;
t.RelearnMoves = new[] { 0, 0, 0, 0 };
if (t.IV_HP != -4)
t.IVs = new[] { -1, -1, -1, -1, -1, -1 };
var shopDefinition = table[s];
var items = shopDefinition.Inventory.Items;
for (int i = 0; i < items.Length; i++)
items[i] = PossibleHeldItems[Randomization.Util.Random.Next(PossibleHeldItems.Length)];
}
}
using var form = new GenericEditor<EncounterGift7b>(cache, names, "Gift Editor", Randomize);
}
else
{
var table = shop.Shop2;
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();
if (!form.Modified)
file.CancelEdits();
else
file[0] = objs.SelectMany(z => z.Write()).ToArray();
}
public void EditTrade()
{
var file = ROM[GameFile.EncounterTrade];
var data = file[0];
var objs = data.GetArray(z => new EncounterTrade7b(z), EncounterTrade7b.SIZE); // binary
var names = Enumerable.Range(0, objs.Length).Select(z => $"{z:000}").ToArray();
var cache = new DirectCache<EncounterTrade7b>(objs);
{
arc.CancelEdits();
return;
}
void Randomize()
{
var spec = EditUtil.Settings.Species;
spec.Gen2 = spec.Gen3 = spec.Gen4 = spec.Gen5 = spec.Gen6 = spec.Gen7 = false;
var srand = new SpeciesRandomizer(ROM.Info, Data.PersonalData);
var frand = new FormRandomizer(Data.PersonalData);
srand.Initialize(spec, 808, 809); // can only catch 1-151 in wild
foreach (var t in objs)
foreach (var shopDefinition in table)
{
t.Species = (Species)srand.GetRandomSpecies((int)t.Species);
t.RequiredSpecies = (Species)srand.GetRandomSpecies((int)t.Species);
t.Form = frand.GetRandomForme((int)t.Species, false, false, true, false, Data.PersonalData.Table);
t.RequiredForm = 0; // can't catch wild alolan forms
t.Nature = Nature.Random - 1;
t.Gender = FixedGender.Random;
t.Shiny = Shiny.Random;
t.RelearnMoves = new[] { 0, 0, 0, 0 };
if (t.IV_HP != -4)
t.IVs = new[] { -1, -1, -1, -1, -1, -1 };
}
}
using var form = new GenericEditor<EncounterTrade7b>(cache, names, "Trade Editor", Randomize);
form.ShowDialog();
if (!form.Modified)
file.CancelEdits();
else
file[0] = objs.SelectMany(z => z.Write()).ToArray();
}
public void EditStatic()
{
var file = ROM[GameFile.EncounterStatic];
var data = file[0];
var objs = data.GetArray(z => new EncounterStatic7b(z), EncounterStatic7b.SIZE); // binary
var names = Enumerable.Range(0, objs.Length).Select(z => $"{z:000}").ToArray();
var cache = new DirectCache<EncounterStatic7b>(objs);
void Randomize()
{
var spec = EditUtil.Settings.Species;
spec.Gen2 = spec.Gen3 = spec.Gen4 = spec.Gen5 = spec.Gen6 = spec.Gen7 = false;
var srand = new SpeciesRandomizer(ROM.Info, Data.PersonalData);
var frand = new FormRandomizer(Data.PersonalData);
srand.Initialize(spec);
for (int i = 2; i < objs.Length; i++) // skip starters
{
var t = objs[i];
t.Species = (Species)srand.GetRandomSpecies((int)t.Species);
t.Form = frand.GetRandomForme((int)t.Species, false, false, true, false, Data.PersonalData.Table);
t.Nature = Nature.Random25;
t.Gender = FixedGender.Random;
t.Shiny = Shiny.Random;
t.RelearnMoves = new[] { 0, 0, 0, 0 };
if (t.IV_HP != -4)
t.IVs = new[] { -1, -1, -1, -1, -1, -1 };
}
}
using var form = new GenericEditor<EncounterStatic7b>(cache, names, "Static Encounter Editor", Randomize);
form.ShowDialog();
if (!form.Modified)
file.CancelEdits();
else
file[0] = objs.SelectMany(z => z.Write()).ToArray();
}
public void EditWild() => PopWildEdit(ROM.Game == GameVersion.GP ? GameFile.WildData1 : GameFile.WildData2);
private void PopWildEdit(GameFile type)
{
var file = ROM.GetFile(type);
var data = file[0];
var obj = FlatBufferConverter.DeserializeFrom<EncounterArchive7b>(data);
using var form = new GGWE((GameManagerGG)ROM, obj);
if (form.ShowDialog() != DialogResult.OK)
return;
data = FlatBufferConverter.SerializeFrom(obj);
file[0] = data;
}
public void EditShinyRate()
{
var path = Path.Combine(ROM.PathExeFS, "main");
var data = FileMitm.ReadAllBytes(path);
var nso = new NSO(data);
var shiny = new ShinyRateGG(nso.DecompressedText);
if (!shiny.IsEditable)
{
WinFormsUtil.Alert("Not able to find shiny rate logic in ExeFS.");
return;
}
using var editor = new ShinyRate(shiny);
editor.ShowDialog();
if (!editor.Modified)
return;
nso.DecompressedText = shiny.Data;
FileMitm.WriteAllBytes(path, nso.Write());
}
public void EditTM()
{
var path = Path.Combine(ROM.PathExeFS, "main");
var data = FileMitm.ReadAllBytes(path);
var list = new TMEditorGG(data);
if (!list.Valid)
{
WinFormsUtil.Alert("Not able to find tm data in ExeFS.");
return;
}
var moves = list.GetMoves();
var allowed = Legal.GetAllowedMoves(ROM.Game, Data.MoveData.Length);
var names = ROM.GetStrings(TextName.MoveNames);
using var editor = new TMList(moves, allowed, names);
editor.ShowDialog();
if (!editor.Modified)
return;
list.SetMoves(editor.FinalMoves);
data = list.Write();
FileMitm.WriteAllBytes(path, data);
}
public void EditTypeChart()
{
var path = Path.Combine(ROM.PathExeFS, "main");
var data = FileMitm.ReadAllBytes(path);
var nso = new NSO(data);
byte[] pattern = // N2nn3pia9transport18UnreliableProtocolE
{
0x4E, 0x32, 0x6E, 0x6E, 0x33, 0x70, 0x69, 0x61, 0x39, 0x74, 0x72, 0x61, 0x6E, 0x73, 0x70, 0x6F, 0x72,
0x74, 0x31, 0x38, 0x55, 0x6E, 0x72, 0x65, 0x6C, 0x69, 0x61, 0x62, 0x6C, 0x65, 0x50, 0x72, 0x6F, 0x74,
0x6F, 0x63, 0x6F, 0x6C, 0x45, 0x00
};
int ofs = CodePattern.IndexOfBytes(nso.DecompressedRO, pattern);
if (ofs < 0)
{
WinFormsUtil.Alert("Not able to find type chart data in ExeFS.");
return;
}
ofs += pattern.Length + 0x24; // 0x5B4C0C in lgpe 1.0 RO
var cdata = new byte[18 * 18];
var types = ROM.GetStrings(TextName.Types);
Array.Copy(nso.DecompressedRO, ofs, cdata, 0, cdata.Length);
var chart = new TypeChartEditor(cdata);
using var editor = new TypeChart(chart, types);
editor.ShowDialog();
if (!editor.Modified)
return;
chart.Data.CopyTo(nso.DecompressedRO, ofs);
data = nso.Write();
FileMitm.WriteAllBytes(path, data);
}
public void EditShop1() => EditShop(false);
public void EditShop2() => EditShop(true);
private void EditShop(bool shop2)
{
var arc = ROM.GetFile(GameFile.Shops);
var data = arc[0];
int[] PossibleHeldItems = Legal.GetRandomItemList(ROM.Game);
var shop = FlatBufferConverter.DeserializeFrom<ShopInventory>(data);
if (!shop2)
{
var table = shop.Shop1;
var names = table.Select((z, _) => $"{(z.LGPE.TryGetValue(z.Hash, out var shopName) ? shopName : z.Hash.ToString("X"))}").ToArray();
var cache = new DirectCache<Shop1>(table);
using var form = new GenericEditor<Shop1>(cache, names, $"{nameof(Shop1)} Editor", Randomize);
form.ShowDialog();
if (!form.Modified)
{
arc.CancelEdits();
return;
}
void Randomize()
{
for (int s = 1; s < table.Length; s++) // skip first table with TMs (unobtainable otherwise)
foreach (var inv in shopDefinition.Inventories)
{
var shopDefinition = table[s];
var items = shopDefinition.Inventory.Items;
var items = inv.Items;
for (int i = 0; i < items.Length; i++)
items[i] = PossibleHeldItems[Randomization.Util.Random.Next(PossibleHeldItems.Length)];
}
}
}
else
{
var table = shop.Shop2;
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();
if (!form.Modified)
{
arc.CancelEdits();
return;
}
void Randomize()
{
foreach (var shopDefinition in table)
{
foreach (var inv in shopDefinition.Inventories)
{
var items = inv.Items;
for (int i = 0; i < items.Length; i++)
items[i] = PossibleHeldItems[Randomization.Util.Random.Next(PossibleHeldItems.Length)];
}
}
}
}
arc[0] = FlatBufferConverter.SerializeFrom(shop);
}
arc[0] = FlatBufferConverter.SerializeFrom(shop);
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -57,7 +57,7 @@ public void EditTrainers()
Create = FlatBufferConverter.DeserializeFrom<TrData8a>,
Write = FlatBufferConverter.SerializeFrom,
};
var names = folder.GetPaths().Select(Path.GetFileNameWithoutExtension).ToArray();
var names = folder.GetPaths().Select(s => Path.GetFileNameWithoutExtension(s)!).ToArray();
using var form = new GenericEditor<TrData8a>(cache, names, "Trainers", Randomize, canSave: true);
form.ShowDialog();

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
@@ -6,117 +6,116 @@
using pkNX.Game;
using pkNX.Structures;
namespace pkNX.WinForms.Controls
namespace pkNX.WinForms.Controls;
public abstract class EditorBase
{
public abstract class EditorBase
protected readonly GameManager ROM;
public GameVersion Game => ROM.Game;
public int Language { get => ROM.Language; set => ROM.Language = value; }
protected EditorBase(GameManager rom) => ROM = rom;
public string? Location { get; internal set; }
public void Initialize() => ROM.Initialize();
private static string GetEditorName(string name)
{
protected readonly GameManager ROM;
var newName = name.Replace('_', ' ').ToCharArray();
var builder = new StringBuilder();
public GameVersion Game => ROM.Game;
public int Language { get => ROM.Language; set => ROM.Language = value; }
// Force first char to upper
newName[0] = char.ToUpper(newName[0]);
protected EditorBase(GameManager rom) => ROM = rom;
public string? Location { get; internal set; }
public void Initialize() => ROM.Initialize();
private static string GetEditorName(string name)
for (int i = 0; i < newName.Length; ++i)
{
var newName = name.Replace('_', ' ').ToCharArray();
var builder = new StringBuilder();
char c = newName[i];
builder.Append(c);
// Force first char to upper
newName[0] = char.ToUpper(newName[0]);
// Check the next char
if (i + 1 >= newName.Length)
continue;
char nextC = newName[i + 1];
for (int i = 0; i < newName.Length; ++i)
// If current is space, replace next with upper char
if (c == ' ')
{
char c = newName[i];
builder.Append(c);
// Check the next char
if (i + 1 >= newName.Length)
continue;
char nextC = newName[i + 1];
// If current is space, replace next with upper char
if (c == ' ')
{
newName[i + 1] = char.ToUpper(nextC);
}
// If current is lower and next is upper, add a space in between
else if (char.IsLower(c) && char.IsUpper(nextC))
{
builder.Append(' ');
}
// If previous is upper, current is upper and next is lower, add a space in between
else if (i + 2 < newName.Length && char.IsUpper(c) && char.IsUpper(nextC) && char.IsLower(newName[i + 2]))
{
builder.Append(' ');
}
newName[i + 1] = char.ToUpper(nextC);
}
return builder.ToString();
}
public IEnumerable<Button> GetControls(int width, int height)
{
var type = GetType();
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);
foreach (var m in methods)
// If current is lower and next is upper, add a space in between
else if (char.IsLower(c) && char.IsUpper(nextC))
{
const string prefix = "Edit";
if (!m.Name.StartsWith(prefix))
continue;
var name = m.Name[prefix.Length..];
var b = new Button
{
Width = width,
Height = height,
Name = $"B_{name}",
Text = GetEditorName(name),
};
b.Click += (s, e) =>
{
try
{
m.Invoke(this, null);
}
catch (Exception exception)
{
if (exception.InnerException is { } x)
exception = x;
Console.WriteLine(exception);
WinFormsUtil.Error(exception.Message, exception.StackTrace);
}
};
yield return b;
builder.Append(' ');
}
// If previous is upper, current is upper and next is lower, add a space in between
else if (i + 2 < newName.Length && char.IsUpper(c) && char.IsUpper(nextC) && char.IsLower(newName[i + 2]))
{
builder.Append(' ');
}
}
return builder.ToString();
}
public void Close() => ROM.SaveAll(true);
public void Save() => ROM.SaveAll(false);
private static EditorBase? GetEditor(GameManager ROM) => ROM switch
public IEnumerable<Button> GetControls(int width, int height)
{
var type = GetType();
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);
foreach (var m in methods)
{
GameManagerGG gg => new EditorGG(gg),
GameManagerSWSH swsh => new EditorSWSH(swsh),
GameManagerPLA pla => new EditorPLA(pla),
_ => null,
};
const string prefix = "Edit";
if (!m.Name.StartsWith(prefix))
continue;
public static EditorBase? GetEditor(string loc, int language)
{
var gl = GameLocation.GetGame(loc);
if (gl == null)
return null;
var gm = GameManager.GetManager(gl, language);
var editor = GetEditor(gm);
if (editor == null)
return null;
editor.Location = loc;
return editor;
var name = m.Name[prefix.Length..];
var b = new Button
{
Width = width,
Height = height,
Name = $"B_{name}",
Text = GetEditorName(name),
};
b.Click += (s, e) =>
{
try
{
m.Invoke(this, null);
}
catch (Exception exception)
{
if (exception.InnerException is { } x)
exception = x;
Console.WriteLine(exception);
WinFormsUtil.Error(exception.Message, exception.StackTrace ?? string.Empty);
}
};
yield return b;
}
}
public void Close() => ROM.SaveAll(true);
public void Save() => ROM.SaveAll(false);
private static EditorBase? GetEditor(GameManager ROM) => ROM switch
{
GameManagerGG gg => new EditorGG(gg),
GameManagerSWSH swsh => new EditorSWSH(swsh),
GameManagerPLA pla => new EditorPLA(pla),
_ => null,
};
public static EditorBase? GetEditor(string loc, int language)
{
var gl = GameLocation.GetGame(loc);
if (gl == null)
return null;
var gm = GameManager.GetManager(gl, language);
var editor = GetEditor(gm);
if (editor == null)
return null;
editor.Location = loc;
return editor;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +1,23 @@
using System;
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace pkNX.WinForms
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static void Main()
{
// Make FlatSharp build the serializers for our FlatBuffer objects now and take the startup penalty async
// Opening a FlatBuffer editor later won't be hit with a >5s delay assuming the user opens the editor no earlier than 10 seconds after program startup.
_ = Task.Run(() => _ = Structures.FlatBuffers.FlatBufferConverter.SerializeFrom(new Structures.FlatBuffers.Waza8()));
namespace pkNX.WinForms;
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Main());
}
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static void Main()
{
// Make FlatSharp build the serializers for our FlatBuffer objects now and take the startup penalty async
// Opening a FlatBuffer editor later won't be hit with a >5s delay assuming the user opens the editor no earlier than 10 seconds after program startup.
_ = Task.Run(() => _ = Structures.FlatBuffers.FlatBufferConverter.SerializeFrom(new Structures.FlatBuffers.Waza8()));
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Main());
}
}

View File

@@ -1,50 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace pkNX.WinForms.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.0.3.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("2")]
public int Language {
get {
return ((int)(this["Language"]));
}
set {
this["Language"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string GamePath {
get {
return ((string)(this["GamePath"]));
}
set {
this["GamePath"] = value;
}
}
}
}

View File

@@ -1,12 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="pkNX.WinForms.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="Language" Type="System.Int32" Scope="User">
<Value Profile="(Default)">2</Value>
</Setting>
<Setting Name="GamePath" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile>

View File

@@ -1,122 +1,125 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using pkNX.Containers;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public enum RipResultCode
{
public enum RipResultCode
UnknownFormat,
Success,
FileExist,
BadSize,
ReadError,
}
public static class FileRipper
{
public static ContainerHandler DefaultHandler { private get; set; } = new();
public static readonly List<Func<BinaryReader, uint, string, ContainerHandler, FileRipperResult>> Loaders =
new()
{
GFPackDump,
NSODump,
};
private static FileRipperResult NSODump(BinaryReader br, uint header, string path, ContainerHandler handler)
{
UnknownFormat,
Success,
FileExist,
BadSize,
ReadError,
if (header != NSOHeader.ExpectedMagic)
return new FileRipperResult(RipResultCode.UnknownFormat);
br.BaseStream.Position = 0;
var nso = new NSO(br);
var dir = Path.GetDirectoryName(path);
if (dir == null)
return new FileRipperResult(RipResultCode.FileExist);
var folder = Path.GetFileNameWithoutExtension(path);
var resultPath = Path.Combine(dir, folder);
if (resultPath == path)
resultPath += "_nso";
Directory.CreateDirectory(resultPath);
File.WriteAllBytes(Path.Combine(resultPath, "text.bin"), nso.DecompressedText);
File.WriteAllBytes(Path.Combine(resultPath, "data.bin"), nso.DecompressedData);
File.WriteAllBytes(Path.Combine(resultPath, "ro.bin"), nso.DecompressedRO);
return new FileRipperResult(RipResultCode.Success) { ResultPath = resultPath };
}
public static class FileRipper
private static FileRipperResult GFPackDump(BinaryReader br, uint header, string path, ContainerHandler handler)
{
public static ContainerHandler DefaultHandler { private get; set; } = new();
if (header != 0x584C_4647)
return new FileRipperResult(RipResultCode.UnknownFormat);
public static readonly List<Func<BinaryReader, uint, string, ContainerHandler, FileRipperResult>> Loaders =
new()
{
GFPackDump,
NSODump,
};
br.BaseStream.Position = 0;
var gfp = new GFPack(br);
private static FileRipperResult NSODump(BinaryReader br, uint header, string path, ContainerHandler handler)
var dir = Path.GetDirectoryName(path);
if (dir == null)
return new FileRipperResult(RipResultCode.FileExist);
var folder = Path.GetFileNameWithoutExtension(path);
var resultPath = Path.Combine(dir, folder);
Directory.CreateDirectory(resultPath);
gfp.Dump(resultPath, handler);
return new FileRipperResult(RipResultCode.Success) {ResultPath = resultPath};
}
public static FileRipperResult TryOpenFile(string path, ContainerHandler? handler = null)
{
if (!File.Exists(path))
return new FileRipperResult(RipResultCode.FileExist);
handler ??= DefaultHandler;
try
{
if (header != NSOHeader.ExpectedMagic)
return new FileRipperResult(RipResultCode.UnknownFormat);
br.BaseStream.Position = 0;
var nso = new NSO(br);
var dir = Path.GetDirectoryName(path);
var folder = Path.GetFileNameWithoutExtension(path);
var resultPath = Path.Combine(dir, folder);
if (resultPath == path)
resultPath += "_nso";
Directory.CreateDirectory(resultPath);
File.WriteAllBytes(Path.Combine(resultPath, "text.bin"), nso.DecompressedText);
File.WriteAllBytes(Path.Combine(resultPath, "data.bin"), nso.DecompressedData);
File.WriteAllBytes(Path.Combine(resultPath, "ro.bin"), nso.DecompressedRO);
return new FileRipperResult(RipResultCode.Success) { ResultPath = resultPath };
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read);
using var br = new BinaryReader(fs);
if (br.BaseStream.Length < 4)
return new FileRipperResult(RipResultCode.BadSize);
var header = br.ReadUInt32();
var result = TryLoadFile(br, header, path, handler);
if (result.Code == RipResultCode.Success)
return result;
}
private static FileRipperResult GFPackDump(BinaryReader br, uint header, string path, ContainerHandler handler)
catch (Exception e)
{
if (header != 0x584C_4647)
return new FileRipperResult(RipResultCode.UnknownFormat);
br.BaseStream.Position = 0;
var gfp = new GFPack(br);
var dir = Path.GetDirectoryName(path);
var folder = Path.GetFileNameWithoutExtension(path);
var resultPath = Path.Combine(dir, folder);
Directory.CreateDirectory(resultPath);
gfp.Dump(resultPath, handler);
return new FileRipperResult(RipResultCode.Success) {ResultPath = resultPath};
Debug.WriteLine(e.Message);
return new FileRipperResult(RipResultCode.ReadError);
}
return new FileRipperResult(RipResultCode.UnknownFormat);
}
public static FileRipperResult TryOpenFile(string path, ContainerHandler? handler = null)
private static FileRipperResult TryLoadFile(BinaryReader br, uint header, string path, ContainerHandler handler)
{
foreach (var method in Loaders)
{
if (!File.Exists(path))
return new FileRipperResult(RipResultCode.FileExist);
handler ??= DefaultHandler;
try
{
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read);
using var br = new BinaryReader(fs);
if (br.BaseStream.Length < 4)
return new FileRipperResult(RipResultCode.BadSize);
var header = br.ReadUInt32();
var result = TryLoadFile(br, header, path, handler);
var result = method(br, header, path, handler);
if (result.Code == RipResultCode.Success)
return result;
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
return new FileRipperResult(RipResultCode.ReadError);
}
return new FileRipperResult(RipResultCode.UnknownFormat);
}
private static FileRipperResult TryLoadFile(BinaryReader br, uint header, string path, ContainerHandler handler)
{
foreach (var method in Loaders)
{
try
{
var result = method(br, header, path, handler);
if (result.Code == RipResultCode.Success)
return result;
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}
return new FileRipperResult(RipResultCode.UnknownFormat);
}
}
public class FileRipperResult
{
public readonly RipResultCode Code;
public string? ResultPath;
public FileRipperResult(RipResultCode code) => Code = code;
return new FileRipperResult(RipResultCode.UnknownFormat);
}
}
public class FileRipperResult
{
public readonly RipResultCode Code;
public string? ResultPath;
public FileRipperResult(RipResultCode code) => Code = code;
}

View File

@@ -0,0 +1,40 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace pkNX.WinForms;
public static class SettingsSerializer
{
public static async Task<T> GetSettings<T>(string path) where T : new()
{
if (!File.Exists(path))
return new T();
try
{
var data = await File.ReadAllTextAsync(path);
return System.Text.Json.JsonSerializer.Deserialize<T>(data) ?? new T();
}
catch (Exception ex)
{
Debug.WriteLine($"Unable to load settings from {path}: {ex.Message}");
return new T();
}
}
public static async Task SaveSettings<T>(T settings, string path, CancellationToken token = default)
{
try
{
var json = System.Text.Json.JsonSerializer.Serialize(settings);
await File.WriteAllTextAsync(path, json, token);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,64 +1,4 @@
<?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.
-->
<root>
<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">

View File

@@ -8,436 +8,435 @@
using pkNX.Structures;
using pkNX.Structures.FlatBuffers;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public sealed partial class GGWE : Form
{
public sealed partial class GGWE : Form
private readonly EncounterArchive7b Tables;
private readonly GameManagerGG ROM;
private int entry = -1;
public GGWE(GameManagerGG rom, EncounterArchive7b obj)
{
private readonly EncounterArchive7b Tables;
private readonly GameManagerGG ROM;
private int entry = -1;
public GGWE(GameManagerGG rom, EncounterArchive7b obj)
InitializeComponent();
if (obj.EncounterTables.Length == 0 || obj.EncounterTables[0].GroundTable.Length == 0)
{
InitializeComponent();
if (obj.EncounterTables.Length == 0 || obj.EncounterTables[0].GroundTable.Length == 0)
{
WinFormsUtil.Error("Bad data provided.", $"Unable to parse to {nameof(EncounterArchive7b)} data.");
Close();
}
ROM = rom;
var spec = rom.GetStrings(TextName.SpeciesNames);
var species = (string[])spec.Clone();
species[0] = "";
EncounterList.species = species;
var locs = rom.GetStrings(TextName.metlist_00000);
EL_Ground.Initialize();
EL_Water.Initialize();
EL_Old.Initialize();
EL_Good.Initialize();
EL_Super.Initialize();
EL_Sky.Initialize();
TC_Tables.Controls.Remove(Tab_Old);
TC_Tables.Controls.Remove(Tab_Good);
TC_Tables.Controls.Remove(Tab_Super);
EL_Old.OverworldSpawn = EL_Good.OverworldSpawn = EL_Super.OverworldSpawn = false;
L_Rank.Visible = NUD_RankMin.Visible = NUD_RankMax.Visible = false;
PG_Species.SelectedObject = EditUtil.Settings.Species;
Tables = obj;
LoadFile(locs);
EL_Ground.ShowForm = false;
EL_Water.ShowForm = false;
EL_Old.ShowForm = false;
EL_Good.ShowForm = false;
EL_Super.ShowForm = false;
EL_Sky.ShowForm = false;
CB_Location.SelectedIndex = 0;
}
public void LoadFile(string[] locationNames)
{
var locs = Tables.EncounterTables.Select(z => z.ZoneID);
var names = GetNames(locs, locationNames);
var dupeNamed = GetScreenedNames(names);
CB_Location.Items.Clear();
CB_Location.Items.AddRange(dupeNamed.ToArray());
}
private static IEnumerable<string> GetNames(IEnumerable<ulong> locs, string[] locationNames)
{
return locs
.Select(z => DictHash[z]) // loc internal name
.Select(z => LocIDTable[z]) // loc ID
.Select(z => locationNames[z]); // loc external name (pkmdata)
}
private static IEnumerable<string> GetScreenedNames(IEnumerable<string> names)
{
int ctr = 0;
string? prev = null;
foreach (var name in names)
{
if (name != prev)
{
ctr = 1;
yield return name;
}
else
{
ctr++;
yield return $"{name} ({ctr})";
}
prev = name;
}
}
private static readonly Dictionary<string, int> LocIDTable = new()
{
["forest001"] = 39,
["r004d0101"] = 40,
["r004d0102"] = 40,
["r004d0103"] = 40,
["r010d0101"] = 41,
["r010d0102"] = 41,
["r010r0101"] = 42,
["r011d0101"] = 43,
["r020d0101"] = 44,
["r020d0102"] = 44,
["r020d0103"] = 44,
["r020d0104_1"] = 44,
["r020d0104_2"] = 44,
["r020d0105_1"] = 44,
["r020d0105_2"] = 44,
["r023d0101"] = 45,
["r023d0102"] = 45,
["r023d0103"] = 45,
["road001"] = 3,
["road002_1"] = 4,
["road002_2"] = 4,
["road003"] = 5,
["road004_1"] = 6,
["road004_2"] = 6,
["road005"] = 7,
["road006"] = 8,
["road007"] = 9,
["road008"] = 10,
["road009"] = 11,
["road010_1"] = 12,
["road010_2"] = 12,
["road011_1"] = 13,
["road011_2"] = 13,
["road012"] = 14,
["road013"] = 15,
["road014"] = 16,
["road015_1"] = 17,
["road015_2"] = 17,
["road016_1"] = 18,
["road016_2"] = 18,
["road017"] = 19,
["road018_1"] = 20,
["road018_2"] = 20,
["road019"] = 21,
["road020"] = 22,
["road020_2"] = 22,
["road021"] = 23,
["road022"] = 24,
["road023"] = 25,
["road024"] = 26,
["road025"] = 27,
["t004d0101"] = 46,
["t004d0102"] = 46,
["t004d0103"] = 46,
["t005r0303"] = 47,
["t005r0304"] = 47,
["t005r0305"] = 47,
["t005r0306"] = 47,
["t009r0201"] = 51,
["t009r0202"] = 51,
["t009r0203"] = 51,
["t009r0204"] = 51,
["town001"] = 28,
["town002"] = 29,
["town003"] = 30,
["town004"] = 31,
["town005"] = 32,
["town006"] = 33,
["town007"] = 34,
["town008"] = 35,
["town009"] = 36,
};
private static readonly Dictionary<ulong, string> DictHash = LocIDTable
.Select(z => new KeyValuePair<ulong, string>(FnvHash.HashFnv1a_64(z.Key), z.Key))
.ToDictionary(z => z.Key, z => z.Value);
private void CB_Location_SelectedIndexChanged(object sender, EventArgs e)
{
SaveEntry(entry);
entry = CB_Location.SelectedIndex;
var id = Tables.EncounterTables[entry].ZoneID;
var iname = LocIDTable.First(z => FnvHash.HashFnv1a_64(z.Key) == id).Key;
L_Hash.Text = Tables.EncounterTables[entry].ZoneID.ToString("X16") + " " + iname;
LoadEntry(entry);
}
private void LoadEntry(int i)
{
var arr = Tables.EncounterTables[i];
NUD_RankMin.Value = arr.TrainerRankMin;
NUD_RankMax.Value = arr.TrainerRankMax;
EL_Ground.LoadSlots(arr.GroundTable);
EL_Water.LoadSlots(arr.WaterTable);
EL_Old.LoadSlots(arr.OldRodTable);
EL_Good.LoadSlots(arr.GoodRodTable);
EL_Super.LoadSlots(arr.SuperRodTable);
EL_Sky.LoadSlots(arr.SkyTable);
EL_Ground.NUD_Min.Value = arr.GroundTableLevelMin;
EL_Ground.NUD_Max.Value = arr.GroundTableLevelMax;
EL_Ground.NUD_SpawnRate.Value = arr.GroundTableEncounterRate;
EL_Ground.NUD_Count.Value = arr.GroundSpawnCountMax;
EL_Ground.NUD_Duration.Value = arr.GroundSpawnDuration;
EL_Water.NUD_Min.Value = arr.WaterTableLevelMin;
EL_Water.NUD_Max.Value = arr.WaterTableLevelMax;
EL_Water.NUD_SpawnRate.Value = arr.WaterTableEncounterRate;
EL_Water.NUD_Count.Value = arr.WaterSpawnCountMax;
EL_Water.NUD_Duration.Value = arr.WaterSpawnDuration;
EL_Old.NUD_Min.Value = arr.OldRodTableLevelMin;
EL_Old.NUD_Max.Value = arr.OldRodTableLevelMax;
EL_Old.NUD_SpawnRate.Value = arr.OldRodTableEncounterRate;
EL_Good.NUD_Min.Value = arr.GoodRodTableLevelMin;
EL_Good.NUD_Max.Value = arr.GoodRodTableLevelMax;
EL_Good.NUD_SpawnRate.Value = arr.GoodRodTableEncounterRate;
EL_Super.NUD_Min.Value = arr.SuperRodTableLevelMin;
EL_Super.NUD_Max.Value = arr.SuperRodTableLevelMax;
EL_Super.NUD_SpawnRate.Value = arr.SuperRodTableEncounterRate;
EL_Sky.NUD_Min.Value = arr.SkyTableLevelMin;
EL_Sky.NUD_Max.Value = arr.SkyTableLevelMax;
EL_Sky.NUD_SpawnRate.Value = arr.SkyTableEncounterRate;
EL_Sky.NUD_Count.Value = arr.SkySpawnCountMax;
EL_Sky.NUD_Duration.Value = arr.SkySpawnDuration;
}
private void SaveEntry(int i)
{
if (i < 0)
return;
var arr = Tables.EncounterTables[i];
arr.TrainerRankMin = (int)NUD_RankMin.Value;
arr.TrainerRankMax = (int)NUD_RankMax.Value;
arr.GroundTableLevelMin = (int)EL_Ground.NUD_Min.Value;
arr.GroundTableLevelMax = (int)EL_Ground.NUD_Max.Value;
arr.GroundTableEncounterRate = (int)EL_Ground.NUD_SpawnRate.Value;
arr.GroundSpawnCountMax = (int)EL_Ground.NUD_Count.Value;
arr.GroundSpawnDuration = (int)EL_Ground.NUD_Duration.Value;
arr.WaterTableLevelMin = (int)EL_Water.NUD_Min.Value;
arr.WaterTableLevelMax = (int)EL_Water.NUD_Max.Value;
arr.WaterTableEncounterRate = (int)EL_Water.NUD_SpawnRate.Value;
arr.WaterSpawnCountMax = (int)EL_Water.NUD_Count.Value;
arr.WaterSpawnDuration = (int)EL_Water.NUD_Duration.Value;
arr.OldRodTableLevelMin = (int)EL_Old.NUD_Min.Value;
arr.OldRodTableLevelMax = (int)EL_Old.NUD_Max.Value;
arr.OldRodTableEncounterRate = (int)EL_Old.NUD_SpawnRate.Value;
arr.GoodRodTableLevelMin = (int)EL_Good.NUD_Min.Value;
arr.GoodRodTableLevelMax = (int)EL_Good.NUD_Max.Value;
arr.GoodRodTableEncounterRate = (int)EL_Good.NUD_SpawnRate.Value;
arr.SuperRodTableLevelMin = (int)EL_Super.NUD_Min.Value;
arr.SuperRodTableLevelMax = (int)EL_Super.NUD_Max.Value;
arr.SuperRodTableEncounterRate = (int)EL_Super.NUD_SpawnRate.Value;
arr.SkyTableLevelMin = (int)EL_Sky.NUD_Min.Value;
arr.SkyTableLevelMax = (int)EL_Sky.NUD_Max.Value;
arr.SkyTableEncounterRate = (int)EL_Sky.NUD_SpawnRate.Value;
arr.SkySpawnCountMax = (int)EL_Sky.NUD_Count.Value;
arr.SkySpawnDuration = (int)EL_Sky.NUD_Duration.Value;
EL_Ground.SaveCurrent();
EL_Water.SaveCurrent();
EL_Old.SaveCurrent();
EL_Good.SaveCurrent();
EL_Super.SaveCurrent();
EL_Sky.SaveCurrent();
}
private void B_Save_Click(object sender, EventArgs e)
{
SaveEntry(entry);
EL_Ground.SaveCurrent();
EL_Water.SaveCurrent();
EL_Old.SaveCurrent();
EL_Good.SaveCurrent();
EL_Super.SaveCurrent();
EL_Sky.SaveCurrent();
DialogResult = DialogResult.OK;
WinFormsUtil.Error("Bad data provided.", $"Unable to parse to {nameof(EncounterArchive7b)} data.");
Close();
}
private void B_ModCount_Click(object sender, EventArgs e)
ROM = rom;
var spec = rom.GetStrings(TextName.SpeciesNames);
var species = (string[])spec.Clone();
species[0] = "";
EncounterList.SpeciesNames = species;
var locs = rom.GetStrings(TextName.metlist_00000);
EL_Ground.Initialize();
EL_Water.Initialize();
EL_Old.Initialize();
EL_Good.Initialize();
EL_Super.Initialize();
EL_Sky.Initialize();
TC_Tables.Controls.Remove(Tab_Old);
TC_Tables.Controls.Remove(Tab_Good);
TC_Tables.Controls.Remove(Tab_Super);
EL_Old.OverworldSpawn = EL_Good.OverworldSpawn = EL_Super.OverworldSpawn = false;
L_Rank.Visible = NUD_RankMin.Visible = NUD_RankMax.Visible = false;
PG_Species.SelectedObject = EditUtil.Settings.Species;
Tables = obj;
LoadFile(locs);
EL_Ground.ShowForm = false;
EL_Water.ShowForm = false;
EL_Old.ShowForm = false;
EL_Good.ShowForm = false;
EL_Super.ShowForm = false;
EL_Sky.ShowForm = false;
CB_Location.SelectedIndex = 0;
}
public void LoadFile(string[] locationNames)
{
var locs = Tables.EncounterTables.Select(z => z.ZoneID);
var names = GetNames(locs, locationNames);
var dupeNamed = GetScreenedNames(names);
CB_Location.Items.Clear();
CB_Location.Items.AddRange(dupeNamed.ToArray());
}
private static IEnumerable<string> GetNames(IEnumerable<ulong> locs, string[] locationNames)
{
return locs
.Select(z => DictHash[z]) // loc internal name
.Select(z => LocIDTable[z]) // loc ID
.Select(z => locationNames[z]); // loc external name (pkmdata)
}
private static IEnumerable<string> GetScreenedNames(IEnumerable<string> names)
{
int ctr = 0;
string? prev = null;
foreach (var name in names)
{
SaveEntry(entry);
foreach (var area in Tables.EncounterTables)
if (name != prev)
{
if (area.GroundSpawnCountMax != 0)
area.GroundSpawnCountMax = (int)NUD_ModCount.Value;
if (area.WaterSpawnCountMax != 0)
area.WaterSpawnCountMax = (int)NUD_ModCount.Value;
if (area.SkySpawnCountMax != 0)
area.SkySpawnCountMax = (int)NUD_ModCount.Value;
ctr = 1;
yield return name;
}
LoadEntry(entry);
System.Media.SystemSounds.Asterisk.Play();
}
private void B_ModRate_Click(object sender, EventArgs e)
{
SaveEntry(entry);
foreach (var area in Tables.EncounterTables)
else
{
if (area.GroundTableEncounterRate != 0)
area.GroundTableEncounterRate = (int)NUD_ModCount.Value;
if (area.WaterTableEncounterRate != 0)
area.WaterTableEncounterRate = (int)NUD_ModCount.Value;
if (area.SkyTableEncounterRate != 0)
area.SkyTableEncounterRate = (int)NUD_ModCount.Value;
ctr++;
yield return $"{name} ({ctr})";
}
LoadEntry(entry);
System.Media.SystemSounds.Asterisk.Play();
}
private void B_ModDuration_Click(object sender, EventArgs e)
{
SaveEntry(entry);
foreach (var area in Tables.EncounterTables)
{
if (area.GroundSpawnDuration != 0)
area.GroundSpawnDuration = (int)NUD_ModDuration.Value;
if (area.WaterSpawnDuration != 0)
area.WaterSpawnDuration = (int)NUD_ModDuration.Value;
if (area.SkySpawnDuration != 0)
area.SkySpawnDuration = (int)NUD_ModDuration.Value;
}
LoadEntry(entry);
System.Media.SystemSounds.Asterisk.Play();
}
private void B_RandAll_Click(object sender, EventArgs e)
{
SaveEntry(entry);
var settings = (SpeciesSettings)PG_Species.SelectedObject;
settings.Gen2 = settings.Gen3 = settings.Gen4 = settings.Gen5 = settings.Gen6 = settings.Gen7 = false;
var rand = new SpeciesRandomizer(ROM.Info, ROM.Data.PersonalData);
rand.Initialize(settings, 808, 809);
RandomizeWild(rand, CHK_FillEmpty.Checked, CHK_Level.Checked);
LoadEntry(entry);
System.Media.SystemSounds.Asterisk.Play();
}
private void RandomizeWild(SpeciesRandomizer rand, bool fill, bool boost)
{
var pt = ROM.Data.PersonalData;
bool IsGrassOrWater(int s) => pt[s].IsType(Types.Water) || pt[s].IsType(Types.Grass);
foreach (var area in Tables.EncounterTables)
{
if (boost)
{
area.GroundTableLevelMin = Legal.GetModifiedLevel(area.GroundTableLevelMin, (double)NUD_LevelBoost.Value);
area.GroundTableLevelMax = Legal.GetModifiedLevel(area.GroundTableLevelMax, (double)NUD_LevelBoost.Value);
area.WaterTableLevelMin = Legal.GetModifiedLevel(area.WaterTableLevelMin, (double)NUD_LevelBoost.Value);
area.WaterTableLevelMax = Legal.GetModifiedLevel(area.WaterTableLevelMax, (double)NUD_LevelBoost.Value);
area.SkyTableLevelMin = Legal.GetModifiedLevel(area.SkyTableLevelMin, (double)NUD_LevelBoost.Value);
area.SkyTableLevelMax = Legal.GetModifiedLevel(area.SkyTableLevelMax, (double)NUD_LevelBoost.Value);
}
ApplyRand(area.GroundTable);
ApplyRand(area.WaterTable);
ApplyRand(area.SkyTable);
ApplyRand(area.OldRodTable);
ApplyRand(area.GoodRodTable);
ApplyRand(area.SuperRodTable);
}
void ApplyRand(IList<EncounterSlot7b> slots)
{
if (slots[0].Species == 0)
return;
for (int i = 0; i < slots.Count; i++)
{
var s = slots[i];
if (s.Species == 0)
{
if (!fill)
continue;
s.Species = slots.FirstOrDefault(z => z.Species != 0)?.Species ?? rand.GetRandomSpecies();
}
s.Species = rand.GetRandomSpecies(s.Species);
s.Form = 0; // mega & alolan forms don't spawn :(
if (fill)
s.Probability = RandomScaledRates[slots.Count][i];
}
}
if (CHK_ForceType.Checked)
{
var table = Tables.EncounterTables[0];
var slots = table.GroundTable;
while (!slots.Any(z => IsGrassOrWater(z.Species)))
ApplyRand(slots);
}
}
public static readonly Dictionary<int, int[]> RandomScaledRates = new()
{
[01] = new[] { 100 },
[04] = new[] { 60, 30, 7, 3 },
[05] = new[] { 40, 30, 18, 10, 2 },
[10] = new[] { 20, 15, 15, 10, 10, 10, 10, 5, 4, 1 },
};
private void B_Dump_Click(object sender, EventArgs e)
{
var strings = GetEncounterTableSummary(ROM, Tables);
var result = string.Join(Environment.NewLine, strings);
Clipboard.SetText(result);
System.Media.SystemSounds.Asterisk.Play();
}
private static IEnumerable<string> GetEncounterTableSummary(GameManager rom, EncounterArchive7b table)
{
var locationNames = rom.GetStrings(TextName.metlist_00000);
var specs = rom.GetStrings(TextName.SpeciesNames);
var locs = table.EncounterTables.Select(z => z.ZoneID);
var names = GetNames(locs, locationNames);
var dupeNamed = GetScreenedNames(names).ToArray();
return EncounterTable7bUtil.GetLines(table, dupeNamed, specs);
prev = name;
}
}
private static readonly Dictionary<string, int> LocIDTable = new()
{
["forest001"] = 39,
["r004d0101"] = 40,
["r004d0102"] = 40,
["r004d0103"] = 40,
["r010d0101"] = 41,
["r010d0102"] = 41,
["r010r0101"] = 42,
["r011d0101"] = 43,
["r020d0101"] = 44,
["r020d0102"] = 44,
["r020d0103"] = 44,
["r020d0104_1"] = 44,
["r020d0104_2"] = 44,
["r020d0105_1"] = 44,
["r020d0105_2"] = 44,
["r023d0101"] = 45,
["r023d0102"] = 45,
["r023d0103"] = 45,
["road001"] = 3,
["road002_1"] = 4,
["road002_2"] = 4,
["road003"] = 5,
["road004_1"] = 6,
["road004_2"] = 6,
["road005"] = 7,
["road006"] = 8,
["road007"] = 9,
["road008"] = 10,
["road009"] = 11,
["road010_1"] = 12,
["road010_2"] = 12,
["road011_1"] = 13,
["road011_2"] = 13,
["road012"] = 14,
["road013"] = 15,
["road014"] = 16,
["road015_1"] = 17,
["road015_2"] = 17,
["road016_1"] = 18,
["road016_2"] = 18,
["road017"] = 19,
["road018_1"] = 20,
["road018_2"] = 20,
["road019"] = 21,
["road020"] = 22,
["road020_2"] = 22,
["road021"] = 23,
["road022"] = 24,
["road023"] = 25,
["road024"] = 26,
["road025"] = 27,
["t004d0101"] = 46,
["t004d0102"] = 46,
["t004d0103"] = 46,
["t005r0303"] = 47,
["t005r0304"] = 47,
["t005r0305"] = 47,
["t005r0306"] = 47,
["t009r0201"] = 51,
["t009r0202"] = 51,
["t009r0203"] = 51,
["t009r0204"] = 51,
["town001"] = 28,
["town002"] = 29,
["town003"] = 30,
["town004"] = 31,
["town005"] = 32,
["town006"] = 33,
["town007"] = 34,
["town008"] = 35,
["town009"] = 36,
};
private static readonly Dictionary<ulong, string> DictHash = LocIDTable
.Select(z => new KeyValuePair<ulong, string>(FnvHash.HashFnv1a_64(z.Key), z.Key))
.ToDictionary(z => z.Key, z => z.Value);
private void CB_Location_SelectedIndexChanged(object sender, EventArgs e)
{
SaveEntry(entry);
entry = CB_Location.SelectedIndex;
var id = Tables.EncounterTables[entry].ZoneID;
var iname = LocIDTable.First(z => FnvHash.HashFnv1a_64(z.Key) == id).Key;
L_Hash.Text = Tables.EncounterTables[entry].ZoneID.ToString("X16") + " " + iname;
LoadEntry(entry);
}
private void LoadEntry(int i)
{
var arr = Tables.EncounterTables[i];
NUD_RankMin.Value = arr.TrainerRankMin;
NUD_RankMax.Value = arr.TrainerRankMax;
EL_Ground.LoadSlots(arr.GroundTable);
EL_Water.LoadSlots(arr.WaterTable);
EL_Old.LoadSlots(arr.OldRodTable);
EL_Good.LoadSlots(arr.GoodRodTable);
EL_Super.LoadSlots(arr.SuperRodTable);
EL_Sky.LoadSlots(arr.SkyTable);
EL_Ground.NUD_Min.Value = arr.GroundTableLevelMin;
EL_Ground.NUD_Max.Value = arr.GroundTableLevelMax;
EL_Ground.NUD_SpawnRate.Value = arr.GroundTableEncounterRate;
EL_Ground.NUD_Count.Value = arr.GroundSpawnCountMax;
EL_Ground.NUD_Duration.Value = arr.GroundSpawnDuration;
EL_Water.NUD_Min.Value = arr.WaterTableLevelMin;
EL_Water.NUD_Max.Value = arr.WaterTableLevelMax;
EL_Water.NUD_SpawnRate.Value = arr.WaterTableEncounterRate;
EL_Water.NUD_Count.Value = arr.WaterSpawnCountMax;
EL_Water.NUD_Duration.Value = arr.WaterSpawnDuration;
EL_Old.NUD_Min.Value = arr.OldRodTableLevelMin;
EL_Old.NUD_Max.Value = arr.OldRodTableLevelMax;
EL_Old.NUD_SpawnRate.Value = arr.OldRodTableEncounterRate;
EL_Good.NUD_Min.Value = arr.GoodRodTableLevelMin;
EL_Good.NUD_Max.Value = arr.GoodRodTableLevelMax;
EL_Good.NUD_SpawnRate.Value = arr.GoodRodTableEncounterRate;
EL_Super.NUD_Min.Value = arr.SuperRodTableLevelMin;
EL_Super.NUD_Max.Value = arr.SuperRodTableLevelMax;
EL_Super.NUD_SpawnRate.Value = arr.SuperRodTableEncounterRate;
EL_Sky.NUD_Min.Value = arr.SkyTableLevelMin;
EL_Sky.NUD_Max.Value = arr.SkyTableLevelMax;
EL_Sky.NUD_SpawnRate.Value = arr.SkyTableEncounterRate;
EL_Sky.NUD_Count.Value = arr.SkySpawnCountMax;
EL_Sky.NUD_Duration.Value = arr.SkySpawnDuration;
}
private void SaveEntry(int i)
{
if (i < 0)
return;
var arr = Tables.EncounterTables[i];
arr.TrainerRankMin = (int)NUD_RankMin.Value;
arr.TrainerRankMax = (int)NUD_RankMax.Value;
arr.GroundTableLevelMin = (int)EL_Ground.NUD_Min.Value;
arr.GroundTableLevelMax = (int)EL_Ground.NUD_Max.Value;
arr.GroundTableEncounterRate = (int)EL_Ground.NUD_SpawnRate.Value;
arr.GroundSpawnCountMax = (int)EL_Ground.NUD_Count.Value;
arr.GroundSpawnDuration = (int)EL_Ground.NUD_Duration.Value;
arr.WaterTableLevelMin = (int)EL_Water.NUD_Min.Value;
arr.WaterTableLevelMax = (int)EL_Water.NUD_Max.Value;
arr.WaterTableEncounterRate = (int)EL_Water.NUD_SpawnRate.Value;
arr.WaterSpawnCountMax = (int)EL_Water.NUD_Count.Value;
arr.WaterSpawnDuration = (int)EL_Water.NUD_Duration.Value;
arr.OldRodTableLevelMin = (int)EL_Old.NUD_Min.Value;
arr.OldRodTableLevelMax = (int)EL_Old.NUD_Max.Value;
arr.OldRodTableEncounterRate = (int)EL_Old.NUD_SpawnRate.Value;
arr.GoodRodTableLevelMin = (int)EL_Good.NUD_Min.Value;
arr.GoodRodTableLevelMax = (int)EL_Good.NUD_Max.Value;
arr.GoodRodTableEncounterRate = (int)EL_Good.NUD_SpawnRate.Value;
arr.SuperRodTableLevelMin = (int)EL_Super.NUD_Min.Value;
arr.SuperRodTableLevelMax = (int)EL_Super.NUD_Max.Value;
arr.SuperRodTableEncounterRate = (int)EL_Super.NUD_SpawnRate.Value;
arr.SkyTableLevelMin = (int)EL_Sky.NUD_Min.Value;
arr.SkyTableLevelMax = (int)EL_Sky.NUD_Max.Value;
arr.SkyTableEncounterRate = (int)EL_Sky.NUD_SpawnRate.Value;
arr.SkySpawnCountMax = (int)EL_Sky.NUD_Count.Value;
arr.SkySpawnDuration = (int)EL_Sky.NUD_Duration.Value;
EL_Ground.SaveCurrent();
EL_Water.SaveCurrent();
EL_Old.SaveCurrent();
EL_Good.SaveCurrent();
EL_Super.SaveCurrent();
EL_Sky.SaveCurrent();
}
private void B_Save_Click(object sender, EventArgs e)
{
SaveEntry(entry);
EL_Ground.SaveCurrent();
EL_Water.SaveCurrent();
EL_Old.SaveCurrent();
EL_Good.SaveCurrent();
EL_Super.SaveCurrent();
EL_Sky.SaveCurrent();
DialogResult = DialogResult.OK;
Close();
}
private void B_ModCount_Click(object sender, EventArgs e)
{
SaveEntry(entry);
foreach (var area in Tables.EncounterTables)
{
if (area.GroundSpawnCountMax != 0)
area.GroundSpawnCountMax = (int)NUD_ModCount.Value;
if (area.WaterSpawnCountMax != 0)
area.WaterSpawnCountMax = (int)NUD_ModCount.Value;
if (area.SkySpawnCountMax != 0)
area.SkySpawnCountMax = (int)NUD_ModCount.Value;
}
LoadEntry(entry);
System.Media.SystemSounds.Asterisk.Play();
}
private void B_ModRate_Click(object sender, EventArgs e)
{
SaveEntry(entry);
foreach (var area in Tables.EncounterTables)
{
if (area.GroundTableEncounterRate != 0)
area.GroundTableEncounterRate = (int)NUD_ModCount.Value;
if (area.WaterTableEncounterRate != 0)
area.WaterTableEncounterRate = (int)NUD_ModCount.Value;
if (area.SkyTableEncounterRate != 0)
area.SkyTableEncounterRate = (int)NUD_ModCount.Value;
}
LoadEntry(entry);
System.Media.SystemSounds.Asterisk.Play();
}
private void B_ModDuration_Click(object sender, EventArgs e)
{
SaveEntry(entry);
foreach (var area in Tables.EncounterTables)
{
if (area.GroundSpawnDuration != 0)
area.GroundSpawnDuration = (int)NUD_ModDuration.Value;
if (area.WaterSpawnDuration != 0)
area.WaterSpawnDuration = (int)NUD_ModDuration.Value;
if (area.SkySpawnDuration != 0)
area.SkySpawnDuration = (int)NUD_ModDuration.Value;
}
LoadEntry(entry);
System.Media.SystemSounds.Asterisk.Play();
}
private void B_RandAll_Click(object sender, EventArgs e)
{
SaveEntry(entry);
var settings = (SpeciesSettings)PG_Species.SelectedObject;
settings.Gen2 = settings.Gen3 = settings.Gen4 = settings.Gen5 = settings.Gen6 = settings.Gen7 = false;
var rand = new SpeciesRandomizer(ROM.Info, ROM.Data.PersonalData);
rand.Initialize(settings, 808, 809);
RandomizeWild(rand, CHK_FillEmpty.Checked, CHK_Level.Checked);
LoadEntry(entry);
System.Media.SystemSounds.Asterisk.Play();
}
private void RandomizeWild(SpeciesRandomizer rand, bool fill, bool boost)
{
var pt = ROM.Data.PersonalData;
bool IsGrassOrWater(int s) => pt[s].IsType(Types.Water) || pt[s].IsType(Types.Grass);
foreach (var area in Tables.EncounterTables)
{
if (boost)
{
area.GroundTableLevelMin = Legal.GetModifiedLevel(area.GroundTableLevelMin, (double)NUD_LevelBoost.Value);
area.GroundTableLevelMax = Legal.GetModifiedLevel(area.GroundTableLevelMax, (double)NUD_LevelBoost.Value);
area.WaterTableLevelMin = Legal.GetModifiedLevel(area.WaterTableLevelMin, (double)NUD_LevelBoost.Value);
area.WaterTableLevelMax = Legal.GetModifiedLevel(area.WaterTableLevelMax, (double)NUD_LevelBoost.Value);
area.SkyTableLevelMin = Legal.GetModifiedLevel(area.SkyTableLevelMin, (double)NUD_LevelBoost.Value);
area.SkyTableLevelMax = Legal.GetModifiedLevel(area.SkyTableLevelMax, (double)NUD_LevelBoost.Value);
}
ApplyRand(area.GroundTable);
ApplyRand(area.WaterTable);
ApplyRand(area.SkyTable);
ApplyRand(area.OldRodTable);
ApplyRand(area.GoodRodTable);
ApplyRand(area.SuperRodTable);
}
void ApplyRand(IList<EncounterSlot7b> slots)
{
if (slots[0].Species == 0)
return;
for (int i = 0; i < slots.Count; i++)
{
var s = slots[i];
if (s.Species == 0)
{
if (!fill)
continue;
s.Species = slots.FirstOrDefault(z => z.Species != 0)?.Species ?? rand.GetRandomSpecies();
}
s.Species = rand.GetRandomSpecies(s.Species);
s.Form = 0; // mega & alolan forms don't spawn :(
if (fill)
s.Probability = RandomScaledRates[slots.Count][i];
}
}
if (CHK_ForceType.Checked)
{
var table = Tables.EncounterTables[0];
var slots = table.GroundTable;
while (!slots.Any(z => IsGrassOrWater(z.Species)))
ApplyRand(slots);
}
}
public static readonly Dictionary<int, int[]> RandomScaledRates = new()
{
[01] = new[] { 100 },
[04] = new[] { 60, 30, 7, 3 },
[05] = new[] { 40, 30, 18, 10, 2 },
[10] = new[] { 20, 15, 15, 10, 10, 10, 10, 5, 4, 1 },
};
private void B_Dump_Click(object sender, EventArgs e)
{
var strings = GetEncounterTableSummary(ROM, Tables);
var result = string.Join(Environment.NewLine, strings);
Clipboard.SetText(result);
System.Media.SystemSounds.Asterisk.Play();
}
private static IEnumerable<string> GetEncounterTableSummary(GameManager rom, EncounterArchive7b table)
{
var locationNames = rom.GetStrings(TextName.metlist_00000);
var specs = rom.GetStrings(TextName.SpeciesNames);
var locs = table.EncounterTables.Select(z => z.ZoneID);
var names = GetNames(locs, locationNames);
var dupeNamed = GetScreenedNames(names).ToArray();
return EncounterTable7bUtil.GetLines(table, dupeNamed, specs);
}
}

View File

@@ -1,62 +1,61 @@
using System;
using System;
using System.Windows.Forms;
using pkNX.Game;
using pkNX.Structures;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public sealed partial class GenericEditor<T> : Form where T : class
{
public sealed partial class GenericEditor<T> : Form where T : class
public GenericEditor(DataCache<T> cache, string[] names, string title, Action? randomize = null, bool canSave = true)
{
public GenericEditor(DataCache<T> cache, string[] names, string title, Action? randomize = null, bool canSave = true)
InitializeComponent();
Cache = cache;
Text = title;
Names = names;
CB_EntryName.Items.AddRange(names);
CB_EntryName.SelectedIndex = 0;
if (!canSave)
B_Save.Enabled = false;
if (randomize == null)
{
InitializeComponent();
Cache = cache;
Text = title;
Names = names;
CB_EntryName.Items.AddRange(names);
CB_EntryName.SelectedIndex = 0;
if (!canSave)
B_Save.Enabled = false;
if (randomize == null)
{
B_Rand.Visible = false;
return;
}
B_Rand.Click += (_, __) =>
{
randomize();
LoadIndex(0);
System.Media.SystemSounds.Asterisk.Play();
};
B_Rand.Visible = false;
return;
}
private readonly string[] Names;
private readonly DataCache<T> Cache;
public bool Modified { get; set; }
private void CB_EntryName_SelectedIndexChanged(object sender, EventArgs e)
{
var index = CB_EntryName.SelectedIndex;
LoadIndex(index);
}
private void LoadIndex(int index) => Grid.SelectedObject = Cache[index];
private void B_Save_Click(object sender, EventArgs e)
B_Rand.Click += (_, __) =>
{
randomize();
LoadIndex(0);
Modified = true;
Close();
}
private void B_Dump_Click(object sender, EventArgs e)
{
var arr = Cache.LoadAll();
var result = TableUtil.GetNamedTypeTable(arr, Names, Text.Split(' ')[0]);
Clipboard.SetText(result);
System.Media.SystemSounds.Asterisk.Play();
}
};
}
private readonly string[] Names;
private readonly DataCache<T> Cache;
public bool Modified { get; set; }
private void CB_EntryName_SelectedIndexChanged(object sender, EventArgs e)
{
var index = CB_EntryName.SelectedIndex;
LoadIndex(index);
}
private void LoadIndex(int index) => Grid.SelectedObject = Cache[index];
private void B_Save_Click(object sender, EventArgs e)
{
LoadIndex(0);
Modified = true;
Close();
}
private void B_Dump_Click(object sender, EventArgs e)
{
var arr = Cache.LoadAll();
var result = TableUtil.GetNamedTypeTable(arr, Names, Text.Split(' ')[0]);
Clipboard.SetText(result);
System.Media.SystemSounds.Asterisk.Play();
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
@@ -8,269 +8,268 @@
using pkNX.Structures;
using pkNX.Structures.FlatBuffers;
namespace pkNX.WinForms.Subforms
namespace pkNX.WinForms.Subforms;
public partial class MapViewer8a : Form
{
public partial class MapViewer8a : Form
private readonly GameManagerPLA ROM;
private readonly GFPack Resident;
private readonly AreaSettingsTable8a Settings;
public readonly AreaInstance8a[] Areas;
private readonly bool Loading = true;
public MapViewer8a(GameManagerPLA rom, GFPack resident)
{
private readonly GameManagerPLA ROM;
private readonly GFPack Resident;
private readonly AreaSettingsTable8a Settings;
ROM = rom;
Resident = resident;
var bin_settings = resident.GetDataFullPath("bin/field/resident/AreaSettings.bin");
Settings = FlatBufferConverter.DeserializeFrom<AreaSettingsTable8a>(bin_settings);
public readonly AreaInstance8a[] Areas;
private readonly bool Loading = true;
InitializeComponent();
public MapViewer8a(GameManagerPLA rom, GFPack resident)
Areas = ResidentAreaSet.AreaNames.Select(z => AreaInstance8a.Create(Resident, z, Settings)).ToArray();
CB_Map.Items.AddRange(Areas.Select(z => z.ParentArea?.FriendlyAreaName ?? z.FriendlyAreaName).ToArray());
var speciesNames = ROM.GetStrings(TextName.SpeciesNames);
var pt = rom.Data.PersonalData;
var nameList = new List<ComboItem>();
foreach (var e in pt.Table.Cast<IPersonalMisc_1>())
{
ROM = rom;
Resident = resident;
var bin_settings = resident.GetDataFullPath("bin/field/resident/AreaSettings.bin");
Settings = FlatBufferConverter.DeserializeFrom<AreaSettingsTable8a>(bin_settings);
if (!e.IsPresentInGame)
continue;
InitializeComponent();
var species = e.ModelID;
if (nameList.All(z => z.Value != species))
nameList.Add(new(speciesNames[species], species));
}
Areas = ResidentAreaSet.AreaNames.Select(z => AreaInstance8a.Create(Resident, z, Settings)).ToArray();
CB_Map.Items.AddRange(Areas.Select(z => z.ParentArea?.FriendlyAreaName ?? z.FriendlyAreaName).ToArray());
nameList.Insert(0, new("(All)", -1));
nameList.Sort((x, y) => string.Compare(x.Text, y.Text, StringComparison.InvariantCulture));
var speciesNames = ROM.GetStrings(TextName.SpeciesNames);
var pt = rom.Data.PersonalData;
var nameList = new List<ComboItem>();
foreach (var e in pt.Table.Cast<IPersonalMisc_1>())
CB_Species.DisplayMember = nameof(ComboItem.Text);
CB_Species.ValueMember = nameof(ComboItem.Value);
CB_Species.DataSource = new BindingSource(nameList, null);
CB_Species.SelectedValue = -1;
Loading = false;
CB_Map.SelectedIndex = 1;
}
private class ComboItem
{
public ComboItem(string text, int value)
{
Text = text;
Value = value;
}
public string Text { get; }
public int Value { get; }
}
private void CB_Map_SelectedIndexChanged(object sender, EventArgs e)
{
UpdateMap(CB_Map.SelectedIndex, (int)CB_Species.SelectedValue);
}
private void CB_Species_SelectedIndexChanged(object sender, EventArgs e)
{
UpdateMap(CB_Map.SelectedIndex, (int)CB_Species.SelectedValue);
}
private List<AreaDef> Defs = new();
private string GetMapImagePath(AreaInstance8a area)
{
string mapName = area.AreaName switch
{
"ha_area00" => "map_lmap_pic_05_05",
"ha_area01" => "map_lmap_pic_00",
"ha_area02" => "map_lmap_pic_01",
"ha_area03" => "map_lmap_pic_02",
"ha_area04" => "map_lmap_pic_03",
"ha_area05" => "map_lmap_pic_04",
"ha_area06" => "map_lmap_pic_06",
_ => area.AreaName,
};
return $"map_pla\\{mapName}.png";
}
private void UpdateMap(int map, int species)
{
if (Loading)
return;
var area = Areas[map];
var mapImagePath = System.IO.Path.GetFullPath(GetMapImagePath(area));
if (System.IO.File.Exists(mapImagePath))
{
pictureBox1.BackgroundImage = Image.FromFile(mapImagePath);
}
else
{
WinFormsUtil.Error(string.Format("Unable to find map image at path: {0}", mapImagePath), "Automatic extraction of the map images is not yet supported.\nYou will have to extract them manually and place them at the location above. (You can use Switch-Toolbox for this.)");
pictureBox1.BackgroundImage = new Bitmap(1024, 1024);
}
using var gr = Graphics.FromImage(pictureBox1.BackgroundImage);
var r = new SolidBrush(Color.FromArgb(100, 255, 0, 0));
var g = new SolidBrush(Color.FromArgb(20, 20, 255, 10));
var b = new SolidBrush(Color.FromArgb(100, 10, 0, 255));
var c = new SolidBrush(Color.FromArgb(100, 0, 255, 255));
var rs = new Pen(Color.FromArgb(255, 255, 0, 0)) { Width = 3 };
var gs = new Pen(Color.FromArgb(255, 20, 255, 10)) { Width = 3 };
var bs = new Pen(Color.FromArgb(255, 10, 0, 255)) { Width = 3 };
var cs = new Pen(Color.FromArgb(255, 10, 255, 255)) { Width = 3 };
var coordinates = Defs = GetSpawnerInfo(species, area);
foreach (var o in coordinates)
{
var brush = o.Type switch
{
if (!e.IsPresentInGame)
continue;
var species = e.ModelID;
if (nameList.All(z => z.Value != species))
nameList.Add(new(speciesNames[species], species));
}
nameList.Insert(0, new("(All)", -1));
nameList.Sort((x, y) => string.Compare(x.Text, y.Text, StringComparison.InvariantCulture));
CB_Species.DisplayMember = nameof(ComboItem.Text);
CB_Species.ValueMember = nameof(ComboItem.Value);
CB_Species.DataSource = new BindingSource(nameList, null);
CB_Species.SelectedValue = -1;
Loading = false;
CB_Map.SelectedIndex = 1;
}
private class ComboItem
{
public ComboItem(string text, int value)
SpawnerType.Spawner => r,
SpawnerType.Wormhole => g,
SpawnerType.Landmark => b,
SpawnerType.Unown => c,
_ => throw new ArgumentOutOfRangeException(nameof(o.Type)),
};
var penS = o.Type switch
{
Text = text;
Value = value;
}
public string Text { get; }
public int Value { get; }
}
private void CB_Map_SelectedIndexChanged(object sender, EventArgs e)
{
UpdateMap(CB_Map.SelectedIndex, (int)CB_Species.SelectedValue);
}
private void CB_Species_SelectedIndexChanged(object sender, EventArgs e)
{
UpdateMap(CB_Map.SelectedIndex, (int)CB_Species.SelectedValue);
}
private List<AreaDef> Defs = new();
private string GetMapImagePath(AreaInstance8a area)
{
string mapName = area.AreaName switch
{
"ha_area00" => "map_lmap_pic_05_05",
"ha_area01" => "map_lmap_pic_00",
"ha_area02" => "map_lmap_pic_01",
"ha_area03" => "map_lmap_pic_02",
"ha_area04" => "map_lmap_pic_03",
"ha_area05" => "map_lmap_pic_04",
"ha_area06" => "map_lmap_pic_06",
_ => area.AreaName,
SpawnerType.Spawner => rs,
SpawnerType.Wormhole => gs,
SpawnerType.Landmark => bs,
SpawnerType.Unown => cs,
_ => throw new ArgumentOutOfRangeException(nameof(o.Type)),
};
return $"map_pla\\{mapName}.png";
}
var center = o.Position;
var radius = o.Radius;
private void UpdateMap(int map, int species)
{
if (Loading)
return;
var area = Areas[map];
var mapImagePath = System.IO.Path.GetFullPath(GetMapImagePath(area));
if (System.IO.File.Exists(mapImagePath))
{
pictureBox1.BackgroundImage = Image.FromFile(mapImagePath);
}
else
{
WinFormsUtil.Error(string.Format("Unable to find map image at path: {0}", mapImagePath), "Automatic extraction of the map images is not yet supported.\nYou will have to extract them manually and place them at the location above. (You can use Switch-Toolbox for this.)");
pictureBox1.BackgroundImage = new Bitmap(1024, 1024);
}
using var gr = Graphics.FromImage(pictureBox1.BackgroundImage);
var r = new SolidBrush(Color.FromArgb(100, 255, 0, 0));
var g = new SolidBrush(Color.FromArgb(20, 20, 255, 10));
var b = new SolidBrush(Color.FromArgb(100, 10, 0, 255));
var c = new SolidBrush(Color.FromArgb(100, 0, 255, 255));
var rs = new Pen(Color.FromArgb(255, 255, 0, 0)) { Width = 3 };
var gs = new Pen(Color.FromArgb(255, 20, 255, 10)) { Width = 3 };
var bs = new Pen(Color.FromArgb(255, 10, 0, 255)) { Width = 3 };
var cs = new Pen(Color.FromArgb(255, 10, 255, 255)) { Width = 3 };
var coordinates = Defs = GetSpawnerInfo(species, area);
foreach (var o in coordinates)
{
var brush = o.Type switch
{
SpawnerType.Spawner => r,
SpawnerType.Wormhole => g,
SpawnerType.Landmark => b,
SpawnerType.Unown => c,
_ => throw new ArgumentOutOfRangeException(nameof(o.Type)),
};
var penS = o.Type switch
{
SpawnerType.Spawner => rs,
SpawnerType.Wormhole => gs,
SpawnerType.Landmark => bs,
SpawnerType.Unown => cs,
_ => throw new ArgumentOutOfRangeException(nameof(o.Type)),
};
var center = o.Position;
var radius = o.Radius;
var x = center.X - radius;
var y = center.Z - radius;
var d = radius * 2;
gr.FillEllipse(brush, x, y, d, d);
gr.DrawEllipse(penS, x, y, d, d);
}
}
private static List<AreaDef> GetSpawnerInfo(int species, AreaInstance8a area)
{
var result = new List<AreaDef>();
foreach (var s in area.Spawners.Concat(area.SubAreas.SelectMany(z => z.Spawners)))
{
var table = s.Field_20_Value.EncounterTableID;
var slots = Array.Find(area.Encounters, z => z.TableID == table);
if (slots == null)
continue;
if (species != -1 && slots.Table.All(z => z.Species != species))
continue;
result.Add(new(slots.TableName, s.MinSpawnCount, s.MaxSpawnCount, s.Parameters.Coordinates, SpawnerType.Spawner, slots.Table, s.Scalar));
}
foreach (var s in area.Wormholes.Concat(area.SubAreas.SelectMany(z => z.Wormholes)))
{
var table = s.Field_20_Value.EncounterTableID;
var slots = Array.Find(area.Encounters, z => z.TableID == table);
if (slots == null)
continue;
if (species != -1 && slots.Table.All(z => z.Species != species))
continue;
result.Add(new(slots.TableName, s.MinSpawnCount, s.MaxSpawnCount, s.Parameters.Coordinates, SpawnerType.Wormhole, slots.Table, s.Scalar));
}
foreach (var a in area.LandMarks.Concat(area.SubAreas.SelectMany(z => z.LandMarks)))
{
var table = a.LandmarkItemSpawnTableID;
foreach (var l in area.LandItems.Concat(area.SubAreas.SelectMany(z => z.LandItems)))
{
if (l.LandmarkItemSpawnTableID != table)
continue;
var st = l.EncounterTableID;
var slots = Array.Find(area.Encounters, z => z.TableID == st);
if (slots == null)
continue;
if (species != -1 && slots.Table.All(z => z.Species != species))
continue;
result.Add(new(slots.TableName, 1, 1, a.Parameters.Coordinates, SpawnerType.Landmark, slots.Table, Math.Max(a.Scalar, 1) * 4));
}
}
if (species is not 201)
return result;
foreach (var u in area.Unown.Concat(area.SubAreas.SelectMany(z => z.Unown)))
{
var slots = Unown;
result.Add(new("Unown", 1, 1, u.Parameters.Coordinates, SpawnerType.Unown, slots, u.Number * 2));
}
return result;
}
private static readonly EncounterSlot8a[] Unown = { new() { Species = 201 } };
private void MapViewer8a_MouseMove(object sender, MouseEventArgs e)
{
SizeF imageSize = pictureBox1.BackgroundImage.Size;
SizeF controlSize = pictureBox1.Size;
float scaleX = imageSize.Width / controlSize.Width;
float scaleY = imageSize.Height / controlSize.Height;
var (x, z) = (e.X * scaleX, e.Y * scaleY);
L_CoordinateMouse.Text = $"{x}, {z}";
var dist = (int)NUD_Tolerance.Value;
var spawners = Defs
.Select(s => (Spawner: s, Distance: s.Position.DistanceTo(new(x, s.Position.Y, z))))
.Where(s => s.Distance <= s.Spawner.Radius + dist)
.OrderByDescending(s => s.Distance).ToArray();
if (spawners.Length == 0)
{
L_SpawnDump.Text = "";
return;
}
L_SpawnDump.Text = string.Join(Environment.NewLine, spawners.Select(s => s.Spawner.GetLine()));
var x = center.X - radius;
var y = center.Z - radius;
var d = radius * 2;
gr.FillEllipse(brush, x, y, d, d);
gr.DrawEllipse(penS, x, y, d, d);
}
}
public class AreaDef
private static List<AreaDef> GetSpawnerInfo(int species, AreaInstance8a area)
{
public readonly string NameSummary;
public readonly int Min;
public readonly int Max;
public readonly PlacementV3f8a Position;
public readonly SpawnerType Type;
public readonly EncounterSlot8a[] Slots;
public readonly float Radius;
var result = new List<AreaDef>();
public AreaDef(string NameSummary, int min, int max, PlacementV3f8a position, SpawnerType type, EncounterSlot8a[] slots, float radius)
foreach (var s in area.Spawners.Concat(area.SubAreas.SelectMany(z => z.Spawners)))
{
this.NameSummary = NameSummary;
Min = min;
Max = max;
Position = position;
Type = type;
Slots = slots;
Radius = radius;
var table = s.Field_20_Value.EncounterTableID;
var slots = Array.Find(area.Encounters, z => z.TableID == table);
if (slots == null)
continue;
if (species != -1 && slots.Table.All(z => z.Species != species))
continue;
result.Add(new(slots.TableName, s.MinSpawnCount, s.MaxSpawnCount, s.Parameters.Coordinates, SpawnerType.Spawner, slots.Table, s.Scalar));
}
public string GetLine()
foreach (var s in area.Wormholes.Concat(area.SubAreas.SelectMany(z => z.Wormholes)))
{
var species = string.Join(",", Slots.Select(x => (Species)x.Species));
return $"{NameSummary}\r\n{Position.ToTriple()} {Min}-{Max}: {species}";
var table = s.Field_20_Value.EncounterTableID;
var slots = Array.Find(area.Encounters, z => z.TableID == table);
if (slots == null)
continue;
if (species != -1 && slots.Table.All(z => z.Species != species))
continue;
result.Add(new(slots.TableName, s.MinSpawnCount, s.MaxSpawnCount, s.Parameters.Coordinates, SpawnerType.Wormhole, slots.Table, s.Scalar));
}
foreach (var a in area.LandMarks.Concat(area.SubAreas.SelectMany(z => z.LandMarks)))
{
var table = a.LandmarkItemSpawnTableID;
foreach (var l in area.LandItems.Concat(area.SubAreas.SelectMany(z => z.LandItems)))
{
if (l.LandmarkItemSpawnTableID != table)
continue;
var st = l.EncounterTableID;
var slots = Array.Find(area.Encounters, z => z.TableID == st);
if (slots == null)
continue;
if (species != -1 && slots.Table.All(z => z.Species != species))
continue;
result.Add(new(slots.TableName, 1, 1, a.Parameters.Coordinates, SpawnerType.Landmark, slots.Table, Math.Max(a.Scalar, 1) * 4));
}
}
if (species is not 201)
return result;
foreach (var u in area.Unown.Concat(area.SubAreas.SelectMany(z => z.Unown)))
{
var slots = Unown;
result.Add(new("Unown", 1, 1, u.Parameters.Coordinates, SpawnerType.Unown, slots, u.Number * 2));
}
return result;
}
private static readonly EncounterSlot8a[] Unown = { new() { Species = 201 } };
private void MapViewer8a_MouseMove(object sender, MouseEventArgs e)
{
SizeF imageSize = pictureBox1.BackgroundImage.Size;
SizeF controlSize = pictureBox1.Size;
float scaleX = imageSize.Width / controlSize.Width;
float scaleY = imageSize.Height / controlSize.Height;
var (x, z) = (e.X * scaleX, e.Y * scaleY);
L_CoordinateMouse.Text = $"{x}, {z}";
var dist = (int)NUD_Tolerance.Value;
var spawners = Defs
.Select(s => (Spawner: s, Distance: s.Position.DistanceTo(new(x, s.Position.Y, z))))
.Where(s => s.Distance <= s.Spawner.Radius + dist)
.OrderByDescending(s => s.Distance).ToArray();
if (spawners.Length == 0)
{
L_SpawnDump.Text = "";
return;
}
L_SpawnDump.Text = string.Join(Environment.NewLine, spawners.Select(s => s.Spawner.GetLine()));
}
}
public class AreaDef
{
public readonly string NameSummary;
public readonly int Min;
public readonly int Max;
public readonly PlacementV3f8a Position;
public readonly SpawnerType Type;
public readonly EncounterSlot8a[] Slots;
public readonly float Radius;
public AreaDef(string NameSummary, int min, int max, PlacementV3f8a position, SpawnerType type, EncounterSlot8a[] slots, float radius)
{
this.NameSummary = NameSummary;
Min = min;
Max = max;
Position = position;
Type = type;
Slots = slots;
Radius = radius;
}
public string GetLine()
{
var species = string.Join(",", Slots.Select(x => (Species)x.Species));
return $"{NameSummary}\r\n{Position.ToTriple()} {Min}-{Max}: {species}";
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
@@ -9,239 +9,238 @@
using pkNX.Structures;
using pkNX.Structures.FlatBuffers;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public sealed partial class SSWE : Form
{
public sealed partial class SSWE : Form
private readonly EncounterArchive8 Symbols;
private readonly EncounterArchive8 Hidden;
private readonly GameManagerSWSH ROM;
private ulong entry;
private readonly EncounterList8[] SL;
public SSWE(GameManagerSWSH rom, EncounterArchive8 sym, EncounterArchive8 hid)
{
private readonly EncounterArchive8 Symbols;
private readonly EncounterArchive8 Hidden;
private readonly GameManagerSWSH ROM;
private ulong entry;
InitializeComponent();
Symbols = sym;
Hidden = hid;
ROM = rom;
private readonly EncounterList8[] SL;
var spec = rom.GetStrings(TextName.SpeciesNames);
var species = (string[])spec.Clone();
species[0] = "";
EncounterList8.SpeciesNames = species;
public SSWE(GameManagerSWSH rom, EncounterArchive8 sym, EncounterArchive8 hid)
SL = new[] { SL_0, SL_1, SL_2, SL_3, SL_4, SL_5, SL_6, SL_7, SL_8, SL_9, SL_10 };
foreach (var z in SL)
z.Initialize();
PG_Species.SelectedObject = EditUtil.Settings.Species;
LoadLocations();
}
private class LocationHash
{
public ulong Hash { get; }
public string LocationName { get; }
public LocationHash(ulong hash, string loc)
{
InitializeComponent();
Symbols = sym;
Hidden = hid;
ROM = rom;
var spec = rom.GetStrings(TextName.SpeciesNames);
var species = (string[])spec.Clone();
species[0] = "";
EncounterList8.species = species;
SL = new[] { SL_0, SL_1, SL_2, SL_3, SL_4, SL_5, SL_6, SL_7, SL_8, SL_9, SL_10 };
foreach (var z in SL)
z.Initialize();
PG_Species.SelectedObject = EditUtil.Settings.Species;
LoadLocations();
}
private class LocationHash
{
public ulong Hash { get; }
public string LocationName { get; }
public LocationHash(ulong hash, string loc)
{
Hash = hash;
LocationName = loc;
}
}
public bool Modified { get; private set; }
public void LoadLocations()
{
static string GetLocationName(ulong id) => SWSHInfo.Zones.TryGetValue(id, out var zoneName) ? zoneName : id.ToString("X16");
var sl = Symbols.EncounterTables
.Select(area => new LocationHash(area.ZoneID, GetLocationName(area.ZoneID) + " [S]"));
var hl = Hidden.EncounterTables
.Select(area => new LocationHash(area.ZoneID, GetLocationName(area.ZoneID) + " [H]"));
var locs = sl.Concat(hl)
.OrderBy(z => z.LocationName)
.ToArray();
CB_Location.ValueMember = nameof(LocationHash.Hash);
CB_Location.DisplayMember = nameof(LocationHash.LocationName);
CB_Location.DataSource = new BindingSource(locs, null);
CB_Location.SelectedIndex = 0;
}
private void CB_Location_SelectedIndexChanged(object sender, EventArgs e)
{
SaveEntry(entry);
var item = (LocationHash)CB_Location.SelectedItem;
entry = item.Hash;
Debug.WriteLine($"Loading area data for [0x{entry:X16}] {item.LocationName}");
L_Hash.Text = entry.ToString("X16");
LoadEntry(entry);
}
private void LoadEntry(ulong zone)
{
Load(SL, Symbols, "Symbols");
Load(SL, Hidden, "Hidden");
void Load(EncounterList8[] arr, EncounterArchive8 arc, string name)
{
var table = Array.Find(arc.EncounterTables, z => z.ZoneID == zone);
if (table == null)
return;
L_Type.Text = name;
var subs = table.SubTables;
for (int i = 0; i < subs.Length; i++)
{
var t = subs[i];
arr[i].NUD_Max.Value = t.LevelMax;
arr[i].NUD_Min.Value = t.LevelMin;
arr[i].LoadSlots(subs[i].Slots);
arr[i].Visible = true;
}
// some tables don't have tree/fish
for (int i = subs.Length; i < arr.Length; i++)
arr[i].Visible = false;
}
}
private void SaveEntry(ulong zone)
{
if (zone == 0)
return;
Save(SL, Symbols);
Save(SL, Hidden);
void Save(EncounterList8[] arr, EncounterArchive8 arc)
{
var table = Array.Find(arc.EncounterTables, z => z.ZoneID == zone);
if (table == null)
return;
var subs = table.SubTables;
for (int i = 0; i < subs.Length; i++)
{
var t = subs[i];
t.LevelMax = (byte)arr[i].NUD_Max.Value;
t.LevelMin = (byte)arr[i].NUD_Min.Value;
arr[i].SaveCurrent();
}
}
}
private void B_Save_Click(object sender, EventArgs e)
{
SaveEntry(entry);
Modified = true;
Close();
}
private void B_RandAll_Click(object sender, EventArgs e)
{
SaveEntry(entry);
var settings = (SpeciesSettings)PG_Species.SelectedObject;
var rand = new SpeciesRandomizer(ROM.Info, ROM.Data.PersonalData);
var pt = ROM.Data.PersonalData;
var ban = pt.Table.Take(ROM.Info.MaxSpeciesID + 1)
.Select((z, i) => new { Species = i, Present = ((IPersonalInfoSWSH)z).IsPresentInGame })
.Where(z => !z.Present).Select(z => z.Species).ToArray();
rand.Initialize(settings, ban);
RandomizeWild(rand, CHK_FillEmpty.Checked, CHK_Level.Checked);
LoadEntry(entry);
System.Media.SystemSounds.Asterisk.Play();
}
private void RandomizeWild(SpeciesRandomizer rand, bool fill, bool boost)
{
var pt = ROM.Data.PersonalData;
var fr = new FormRandomizer(pt);
foreach (var area in Symbols.EncounterTables.Concat(Hidden.EncounterTables))
{
foreach (var sub in area.SubTables)
{
if (boost)
{
sub.LevelMin = (byte)Legal.GetModifiedLevel(sub.LevelMin, (double)NUD_LevelBoost.Value);
sub.LevelMax = (byte)Legal.GetModifiedLevel(sub.LevelMax, (double)NUD_LevelBoost.Value);
}
ApplyRand(sub.Slots);
}
}
void ApplyRand(IList<EncounterSlot8> slots)
{
if (slots[0].Species == 0)
return;
for (int i = 0; i < slots.Count; i++)
{
var s = slots[i];
if (s.Species == 0)
{
if (!fill)
continue;
s.Species = slots.FirstOrDefault(z => z.Species != 0)?.Species ?? rand.GetRandomSpecies();
s.Form = 0; // ensure it's not junk
}
s.Species = rand.GetRandomSpecies(s.Species);
s.Form = (byte)fr.GetRandomForme(s.Species, false, false, true, true, ROM.Data.PersonalData.Table);
if (fill)
s.Probability = RandomScaledRates[slots.Count][i];
}
}
}
public static readonly Dictionary<int, byte[]> RandomScaledRates = new()
{
[01] = new byte[] { 100 },
[04] = new byte[] { 60, 30, 7, 3 },
[05] = new byte[] { 40, 30, 18, 10, 2 },
[10] = new byte[] { 20, 15, 15, 10, 10, 10, 10, 5, 4, 1 },
};
private void TC_Tables_DrawItem(object sender, DrawItemEventArgs e)
{
var tc = (TabControl)sender;
Graphics g = e.Graphics;
// Get the item from the collection.
TabPage _tabPage = tc.TabPages[e.Index];
// Get the real bounds for the tab rectangle.
Rectangle _tabBounds = tc.GetTabRect(e.Index);
Brush _textBrush;
if (e.State == DrawItemState.Selected)
{
// Draw a different background color, and don't paint a focus rectangle.
_textBrush = new SolidBrush(Color.Red);
g.FillRectangle(Brushes.Beige, e.Bounds);
}
else
{
_textBrush = new SolidBrush(e.ForeColor);
e.DrawBackground();
}
// Use our own font.
Font _tabFont = new("Arial", (float)10.0, FontStyle.Bold, GraphicsUnit.Pixel);
// Draw string. Center the text.
StringFormat _stringFlags = new()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new StringFormat(_stringFlags));
Hash = hash;
LocationName = loc;
}
}
public bool Modified { get; private set; }
public void LoadLocations()
{
static string GetLocationName(ulong id) => SWSHInfo.Zones.TryGetValue(id, out var zoneName) ? zoneName : id.ToString("X16");
var sl = Symbols.EncounterTables
.Select(area => new LocationHash(area.ZoneID, GetLocationName(area.ZoneID) + " [S]"));
var hl = Hidden.EncounterTables
.Select(area => new LocationHash(area.ZoneID, GetLocationName(area.ZoneID) + " [H]"));
var locs = sl.Concat(hl)
.OrderBy(z => z.LocationName)
.ToArray();
CB_Location.ValueMember = nameof(LocationHash.Hash);
CB_Location.DisplayMember = nameof(LocationHash.LocationName);
CB_Location.DataSource = new BindingSource(locs, null);
CB_Location.SelectedIndex = 0;
}
private void CB_Location_SelectedIndexChanged(object sender, EventArgs e)
{
SaveEntry(entry);
var item = (LocationHash)CB_Location.SelectedItem;
entry = item.Hash;
Debug.WriteLine($"Loading area data for [0x{entry:X16}] {item.LocationName}");
L_Hash.Text = entry.ToString("X16");
LoadEntry(entry);
}
private void LoadEntry(ulong zone)
{
Load(SL, Symbols, "Symbols");
Load(SL, Hidden, "Hidden");
void Load(EncounterList8[] arr, EncounterArchive8 arc, string name)
{
var table = Array.Find(arc.EncounterTables, z => z.ZoneID == zone);
if (table == null)
return;
L_Type.Text = name;
var subs = table.SubTables;
for (int i = 0; i < subs.Length; i++)
{
var t = subs[i];
arr[i].NUD_Max.Value = t.LevelMax;
arr[i].NUD_Min.Value = t.LevelMin;
arr[i].LoadSlots(subs[i].Slots);
arr[i].Visible = true;
}
// some tables don't have tree/fish
for (int i = subs.Length; i < arr.Length; i++)
arr[i].Visible = false;
}
}
private void SaveEntry(ulong zone)
{
if (zone == 0)
return;
Save(SL, Symbols);
Save(SL, Hidden);
void Save(EncounterList8[] arr, EncounterArchive8 arc)
{
var table = Array.Find(arc.EncounterTables, z => z.ZoneID == zone);
if (table == null)
return;
var subs = table.SubTables;
for (int i = 0; i < subs.Length; i++)
{
var t = subs[i];
t.LevelMax = (byte)arr[i].NUD_Max.Value;
t.LevelMin = (byte)arr[i].NUD_Min.Value;
arr[i].SaveCurrent();
}
}
}
private void B_Save_Click(object sender, EventArgs e)
{
SaveEntry(entry);
Modified = true;
Close();
}
private void B_RandAll_Click(object sender, EventArgs e)
{
SaveEntry(entry);
var settings = (SpeciesSettings)PG_Species.SelectedObject;
var rand = new SpeciesRandomizer(ROM.Info, ROM.Data.PersonalData);
var pt = ROM.Data.PersonalData;
var ban = pt.Table.Take(ROM.Info.MaxSpeciesID + 1)
.Select((z, i) => new { Species = i, Present = ((IPersonalInfoSWSH)z).IsPresentInGame })
.Where(z => !z.Present).Select(z => z.Species).ToArray();
rand.Initialize(settings, ban);
RandomizeWild(rand, CHK_FillEmpty.Checked, CHK_Level.Checked);
LoadEntry(entry);
System.Media.SystemSounds.Asterisk.Play();
}
private void RandomizeWild(SpeciesRandomizer rand, bool fill, bool boost)
{
var pt = ROM.Data.PersonalData;
var fr = new FormRandomizer(pt);
foreach (var area in Symbols.EncounterTables.Concat(Hidden.EncounterTables))
{
foreach (var sub in area.SubTables)
{
if (boost)
{
sub.LevelMin = (byte)Legal.GetModifiedLevel(sub.LevelMin, (double)NUD_LevelBoost.Value);
sub.LevelMax = (byte)Legal.GetModifiedLevel(sub.LevelMax, (double)NUD_LevelBoost.Value);
}
ApplyRand(sub.Slots);
}
}
void ApplyRand(IList<EncounterSlot8> slots)
{
if (slots[0].Species == 0)
return;
for (int i = 0; i < slots.Count; i++)
{
var s = slots[i];
if (s.Species == 0)
{
if (!fill)
continue;
s.Species = slots.FirstOrDefault(z => z.Species != 0)?.Species ?? rand.GetRandomSpecies();
s.Form = 0; // ensure it's not junk
}
s.Species = rand.GetRandomSpecies(s.Species);
s.Form = (byte)fr.GetRandomForme(s.Species, false, false, true, true, ROM.Data.PersonalData.Table);
if (fill)
s.Probability = RandomScaledRates[slots.Count][i];
}
}
}
public static readonly Dictionary<int, byte[]> RandomScaledRates = new()
{
[01] = new byte[] { 100 },
[04] = new byte[] { 60, 30, 7, 3 },
[05] = new byte[] { 40, 30, 18, 10, 2 },
[10] = new byte[] { 20, 15, 15, 10, 10, 10, 10, 5, 4, 1 },
};
private void TC_Tables_DrawItem(object sender, DrawItemEventArgs e)
{
var tc = (TabControl)sender;
Graphics g = e.Graphics;
// Get the item from the collection.
TabPage _tabPage = tc.TabPages[e.Index];
// Get the real bounds for the tab rectangle.
Rectangle _tabBounds = tc.GetTabRect(e.Index);
Brush _textBrush;
if (e.State == DrawItemState.Selected)
{
// Draw a different background color, and don't paint a focus rectangle.
_textBrush = new SolidBrush(Color.Red);
g.FillRectangle(Brushes.Beige, e.Bounds);
}
else
{
_textBrush = new SolidBrush(e.ForeColor);
e.DrawBackground();
}
// Use our own font.
Font _tabFont = new("Arial", (float)10.0, FontStyle.Bold, GraphicsUnit.Pixel);
// Draw string. Center the text.
StringFormat _stringFlags = new()
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new StringFormat(_stringFlags));
}
}

View File

@@ -1,77 +1,76 @@
using System;
using System;
using System.Windows.Forms;
using pkNX.Game;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public sealed partial class ShinyRate : Form
{
public sealed partial class ShinyRate : Form
private readonly ShinyRateInfo Data;
private readonly bool Loaded;
public ShinyRate(ShinyRateInfo info)
{
private readonly ShinyRateInfo Data;
private readonly bool Loaded;
public ShinyRate(ShinyRateInfo info)
InitializeComponent();
Data = info;
// load initial state
RB_Always.Enabled = Data.AllowAlways;
if (Data.IsFixed)
{
InitializeComponent();
Data = info;
// load initial state
RB_Always.Enabled = Data.AllowAlways;
if (Data.IsFixed)
{
RB_Fixed.Checked = true;
NUD_Rerolls.Value = Data.GetFixedRate();
}
if (Data.IsAlways)
RB_Always.Checked = true;
if (Data.IsDefault)
RB_Default.Checked = true;
// force update labels
ChangePercent(this, EventArgs.Empty);
ChangeRerollCount(this, EventArgs.Empty);
Loaded = true;
RB_Fixed.Checked = true;
NUD_Rerolls.Value = Data.GetFixedRate();
}
if (Data.IsAlways)
RB_Always.Checked = true;
if (Data.IsDefault)
RB_Default.Checked = true;
public bool Modified { get; set; }
// force update labels
ChangePercent(this, EventArgs.Empty);
ChangeRerollCount(this, EventArgs.Empty);
Loaded = true;
}
private void B_Save_Click(object sender, EventArgs e)
{
Modified = true;
Close();
}
public bool Modified { get; set; }
private void ChangeSelection(object sender, EventArgs e)
{
GB_Rerolls.Enabled = GB_RerollHelper.Enabled = sender == RB_Fixed;
if (!Loaded)
return;
if (sender == RB_Default)
Data.SetDefault();
else if (sender == RB_Always)
Data.SetAlwaysShiny();
else
Data.SetFixedRate((int)NUD_Rerolls.Value);
}
private void B_Save_Click(object sender, EventArgs e)
{
Modified = true;
Close();
}
private void ChangeRerollCount(object sender, EventArgs e)
{
if (Loaded && RB_Fixed.Checked)
Data.SetFixedRate((int)NUD_Rerolls.Value);
private void ChangeSelection(object sender, EventArgs e)
{
GB_Rerolls.Enabled = GB_RerollHelper.Enabled = sender == RB_Fixed;
if (!Loaded)
return;
if (sender == RB_Default)
Data.SetDefault();
else if (sender == RB_Always)
Data.SetAlwaysShiny();
else
Data.SetFixedRate((int)NUD_Rerolls.Value);
}
int count = (int)NUD_Rerolls.Value;
const int bc = 4096;
var pct = 1 - Math.Pow((float)(bc - 1) / bc, count);
L_Overall.Text = $"~{pct:P}";
}
private void ChangeRerollCount(object sender, EventArgs e)
{
if (Loaded && RB_Fixed.Checked)
Data.SetFixedRate((int)NUD_Rerolls.Value);
private void ChangePercent(object sender, EventArgs e)
{
var pct = NUD_Rate.Value;
const int bc = 4096;
int count = (int)NUD_Rerolls.Value;
const int bc = 4096;
var pct = 1 - Math.Pow((float)(bc - 1) / bc, count);
L_Overall.Text = $"~{pct:P}";
}
var inv = (int)Math.Log(1 - ((float)pct / 100), (float)(bc - 1) / bc);
if (pct == 0)
pct = 0.00001m; // arbitrary nonzero
L_RerollCount.Text = $"Count: {inv:0} = 1:{(int)(1 / (pct / 100))}";
}
private void ChangePercent(object sender, EventArgs e)
{
var pct = NUD_Rate.Value;
const int bc = 4096;
var inv = (int)Math.Log(1 - ((float)pct / 100), (float)(bc - 1) / bc);
if (pct == 0)
pct = 0.00001m; // arbitrary nonzero
L_RerollCount.Text = $"Count: {inv:0} = 1:{(int)(1 / (pct / 100))}";
}
}

View File

@@ -1,97 +1,96 @@
using System;
using System;
using System.Linq;
using System.Windows.Forms;
using pkNX.Game;
using pkNX.Randomization;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public sealed partial class TMList : Form
{
public sealed partial class TMList : Form
private readonly int[] AllowedMoves;
private readonly string[] MoveNames;
private readonly ushort[] OriginalMoves;
public TMList(ushort[] moves, int[] allowed, string[] movenames)
{
private readonly int[] AllowedMoves;
private readonly string[] MoveNames;
private readonly ushort[] OriginalMoves;
InitializeComponent();
MoveNames = EditorUtil.SanitizeMoveList(movenames);
AllowedMoves = allowed;
SetupDGV(MoveNames);
LoadMoves(moves);
OriginalMoves = moves;
}
public TMList(ushort[] moves, int[] allowed, string[] movenames)
public bool Modified { get; set; }
public ushort[] FinalMoves { get; private set; } = Array.Empty<ushort>();
private void SetupDGV(string[] list)
{
dgvTM.Columns.Clear();
var dgvIndex = new DataGridViewTextBoxColumn();
{
InitializeComponent();
MoveNames = EditorUtil.SanitizeMoveList(movenames);
AllowedMoves = allowed;
SetupDGV(MoveNames);
LoadMoves(moves);
OriginalMoves = moves;
dgvIndex.HeaderText = "Index";
dgvIndex.DisplayIndex = 0;
dgvIndex.Width = 45;
dgvIndex.ReadOnly = true;
dgvIndex.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
dgvIndex.SortMode = DataGridViewColumnSortMode.NotSortable;
}
public bool Modified { get; set; }
public ushort[] FinalMoves { get; private set; } = Array.Empty<ushort>();
private void SetupDGV(string[] list)
var dgvMove = new DataGridViewComboBoxColumn();
{
dgvTM.Columns.Clear();
var dgvIndex = new DataGridViewTextBoxColumn();
{
dgvIndex.HeaderText = "Index";
dgvIndex.DisplayIndex = 0;
dgvIndex.Width = 45;
dgvIndex.ReadOnly = true;
dgvIndex.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
dgvIndex.SortMode = DataGridViewColumnSortMode.NotSortable;
}
var dgvMove = new DataGridViewComboBoxColumn();
{
dgvMove.HeaderText = "Move";
dgvMove.DisplayIndex = 1;
foreach (string t in list)
dgvMove.Items.Add(t); // add only the Names
dgvMove.HeaderText = "Move";
dgvMove.DisplayIndex = 1;
foreach (string t in list)
dgvMove.Items.Add(t); // add only the Names
dgvMove.Width = 133;
dgvMove.FlatStyle = FlatStyle.Flat;
dgvIndex.SortMode = DataGridViewColumnSortMode.NotSortable;
}
dgvTM.Columns.Add(dgvIndex);
dgvTM.Columns.Add(dgvMove);
dgvMove.Width = 133;
dgvMove.FlatStyle = FlatStyle.Flat;
dgvIndex.SortMode = DataGridViewColumnSortMode.NotSortable;
}
dgvTM.Columns.Add(dgvIndex);
dgvTM.Columns.Add(dgvMove);
}
public void LoadMoves(ushort[] tmlist)
public void LoadMoves(ushort[] tmlist)
{
dgvTM.Rows.Clear();
for (int i = 0; i < tmlist.Length; i++)
{
dgvTM.Rows.Clear();
for (int i = 0; i < tmlist.Length; i++)
{
dgvTM.Rows.Add();
dgvTM.Rows[i].Cells[0].Value = (i + 1).ToString();
dgvTM.Rows[i].Cells[1].Value = MoveNames[tmlist[i]];
}
}
public ushort[] SaveMoves()
{
ushort[] moves = new ushort[dgvTM.RowCount];
for (int i = 0; i < moves.Length; i++)
moves[i] = (ushort)Array.IndexOf(MoveNames, dgvTM.Rows[i].Cells[1].Value);
return moves;
}
private void B_Save_Click(object sender, EventArgs e)
{
Modified = true;
FinalMoves = SaveMoves();
Close();
}
private void B_RTM_Click(object sender, EventArgs e)
{
var moves = GetRandomMoves();
LoadMoves(moves);
System.Media.SystemSounds.Asterisk.Play();
}
private ushort[] GetRandomMoves()
{
var allowed = AllowedMoves.Select(z => (ushort)z).Except(new ushort[] { 0 }).ToArray();
var rand = new GenericRandomizer<ushort>(allowed);
return rand.GetMany(OriginalMoves.Length);
dgvTM.Rows.Add();
dgvTM.Rows[i].Cells[0].Value = (i + 1).ToString();
dgvTM.Rows[i].Cells[1].Value = MoveNames[tmlist[i]];
}
}
public ushort[] SaveMoves()
{
ushort[] moves = new ushort[dgvTM.RowCount];
for (int i = 0; i < moves.Length; i++)
moves[i] = (ushort)Array.IndexOf(MoveNames, dgvTM.Rows[i].Cells[1].Value);
return moves;
}
private void B_Save_Click(object sender, EventArgs e)
{
Modified = true;
FinalMoves = SaveMoves();
Close();
}
private void B_RTM_Click(object sender, EventArgs e)
{
var moves = GetRandomMoves();
LoadMoves(moves);
System.Media.SystemSounds.Asterisk.Play();
}
private ushort[] GetRandomMoves()
{
var allowed = AllowedMoves.Select(z => (ushort)z).Except(new ushort[] { 0 }).ToArray();
var rand = new GenericRandomizer<ushort>(allowed);
return rand.GetMany(OriginalMoves.Length);
}
}

View File

@@ -1,50 +1,49 @@
using System.IO;
using System.IO;
using pkNX.Containers;
using pkNX.Structures;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public class TextContainer
{
public class TextContainer
public readonly IFileContainer Container;
public readonly TextConfig? Config;
public bool Remap { get; set; }
private readonly string[]?[] Cache;
public TextContainer(IFileContainer c, TextConfig? t = null, bool remap = false)
{
public readonly IFileContainer Container;
public readonly TextConfig? Config;
public bool Remap { get; set; }
Remap = remap;
Config = t;
Container = c;
Cache = new string[Container.Count][];
}
private readonly string[]?[] Cache;
public int Length => Cache.Length;
public TextContainer(IFileContainer c, TextConfig? t = null, bool remap = false)
public string[] this[int index]
{
get => Cache[index] ??= GetLines(index);
set => Cache[index] = value;
}
private string[] GetLines(int index) => new TextFile(Container[index], Config, remapChars: Remap).Lines;
public string GetFileName(int i)
{
if (Container is FolderContainer f)
return Path.GetFileNameWithoutExtension(f.GetFileName(i));
return i.ToString();
}
public void Save()
{
for (int i = 0; i < Length; i++)
{
Remap = remap;
Config = t;
Container = c;
Cache = new string[Container.Count][];
}
public int Length => Cache.Length;
public string[] this[int index]
{
get => Cache[index] ??= GetLines(index);
set => Cache[index] = value;
}
private string[] GetLines(int index) => new TextFile(Container[index], Config, remapChars: Remap).Lines;
public string GetFileName(int i)
{
if (Container is FolderContainer f)
return Path.GetFileNameWithoutExtension(f.GetFileName(i));
return i.ToString();
}
public void Save()
{
for (int i = 0; i < Length; i++)
{
if (Cache[i] == null)
continue;
Container[i] = TextFile.GetBytes(Cache[i], Config, Remap);
}
if (Cache[i] == null)
continue;
Container[i] = TextFile.GetBytes(Cache[i], Config, Remap);
}
}
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -6,345 +6,344 @@
using System.Windows.Forms;
using pkNX.Randomization;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public partial class TextEditor : Form
{
public partial class TextEditor : Form
public enum TextEditorMode
{
public enum TextEditorMode
Common,
Script,
}
private readonly TextContainer TextData;
public TextEditor(TextContainer c, TextEditorMode mode)
{
InitializeComponent();
TextData = c;
Mode = mode;
for (int i = 0; i < TextData.Length; i++)
CB_Entry.Items.Add(c.GetFileName(i));
CB_Entry.SelectedIndex = 0;
dgv.EditMode = DataGridViewEditMode.EditOnEnter;
}
private readonly TextEditorMode Mode;
private int entry = -1;
// IO
private void B_Export_Click(object sender, EventArgs e)
{
if (TextData.Length <= 0) return;
using var dump = new SaveFileDialog {Filter = "Text File|*.txt"};
if (dump.ShowDialog() != DialogResult.OK)
return;
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNo,
"Remove newline formatting codes? (\\n,\\r,\\c)",
"Removing newline formatting will make it more readable but will prevent any importing of that dump.");
bool newline = result == DialogResult.Yes;
string path = dump.FileName;
ExportTextFile(path, newline, TextData);
}
private void B_Import_Click(object sender, EventArgs e)
{
if (TextData.Length <= 0) return;
using var dump = new OpenFileDialog { Filter = "Text File|*.txt" };
if (dump.ShowDialog() != DialogResult.OK)
return;
string path = dump.FileName;
if (!ImportTextFiles(path))
return;
// Reload the form with the new data.
ChangeEntry(this, e);
WinFormsUtil.Alert("Imported Text from Input Path:", path);
}
public static void ExportTextFile(string fileName, bool newline, TextContainer lineData)
{
using MemoryStream ms = new();
ms.Write(new byte[] {0xFF, 0xFE}, 0, 2); // Write Unicode BOM
using (TextWriter tw = new StreamWriter(ms, new UnicodeEncoding()))
{
Common,
Script,
}
private readonly TextContainer TextData;
public TextEditor(TextContainer c, TextEditorMode mode)
{
InitializeComponent();
TextData = c;
Mode = mode;
for (int i = 0; i < TextData.Length; i++)
CB_Entry.Items.Add(c.GetFileName(i));
CB_Entry.SelectedIndex = 0;
dgv.EditMode = DataGridViewEditMode.EditOnEnter;
}
private readonly TextEditorMode Mode;
private int entry = -1;
// IO
private void B_Export_Click(object sender, EventArgs e)
{
if (TextData.Length <= 0) return;
using var dump = new SaveFileDialog {Filter = "Text File|*.txt"};
if (dump.ShowDialog() != DialogResult.OK)
return;
var result = WinFormsUtil.Prompt(MessageBoxButtons.YesNo,
"Remove newline formatting codes? (\\n,\\r,\\c)",
"Removing newline formatting will make it more readable but will prevent any importing of that dump.");
bool newline = result == DialogResult.Yes;
string path = dump.FileName;
ExportTextFile(path, newline, TextData);
}
private void B_Import_Click(object sender, EventArgs e)
{
if (TextData.Length <= 0) return;
using var dump = new OpenFileDialog { Filter = "Text File|*.txt" };
if (dump.ShowDialog() != DialogResult.OK)
return;
string path = dump.FileName;
if (!ImportTextFiles(path))
return;
// Reload the form with the new data.
ChangeEntry(this, e);
WinFormsUtil.Alert("Imported Text from Input Path:", path);
}
public static void ExportTextFile(string fileName, bool newline, TextContainer lineData)
{
using MemoryStream ms = new();
ms.Write(new byte[] {0xFF, 0xFE}, 0, 2); // Write Unicode BOM
using (TextWriter tw = new StreamWriter(ms, new UnicodeEncoding()))
for (int i = 0; i < lineData.Length; i++)
{
for (int i = 0; i < lineData.Length; i++)
{
// Get Strings for the File
string[] data = lineData[i];
string fn = lineData.GetFileName(i);
WriteTextFile(tw, fn, data, newline);
}
}
File.WriteAllBytes(fileName, ms.ToArray());
}
private static void WriteTextFile(TextWriter tw, string fn, string[] data, bool newline = false)
{
// Append the File Header
tw.WriteLine("~~~~~~~~~~~~~~~");
tw.WriteLine("Text File : " + fn);
tw.WriteLine("~~~~~~~~~~~~~~~");
// Write the String to the File
foreach (string line in data)
{
tw.WriteLine(newline
? line.Replace("\\n\\n", " ")
.Replace("\\n", " ")
.Replace("\\c", "")
.Replace("\\r", "")
.Replace("\\\\", "\\")
.Replace("\\[", "[")
: line);
// Get Strings for the File
string[] data = lineData[i];
string fn = lineData.GetFileName(i);
WriteTextFile(tw, fn, data, newline);
}
}
File.WriteAllBytes(fileName, ms.ToArray());
}
private bool ImportTextFiles(string fileName)
private static void WriteTextFile(TextWriter tw, string fn, string[] data, bool newline = false)
{
// Append the File Header
tw.WriteLine("~~~~~~~~~~~~~~~");
tw.WriteLine("Text File : " + fn);
tw.WriteLine("~~~~~~~~~~~~~~~");
// Write the String to the File
foreach (string line in data)
{
string[] fileText = File.ReadAllLines(fileName, Encoding.Unicode);
string[][] textLines = new string[TextData.Length][];
int ctr = 0;
bool newlineFormatting = false;
// Loop through all files
for (int i = 0; i < fileText.Length; i++)
tw.WriteLine(newline
? line.Replace("\\n\\n", " ")
.Replace("\\n", " ")
.Replace("\\c", "")
.Replace("\\r", "")
.Replace("\\\\", "\\")
.Replace("\\[", "[")
: line);
}
}
private bool ImportTextFiles(string fileName)
{
string[] fileText = File.ReadAllLines(fileName, Encoding.Unicode);
string[][] textLines = new string[TextData.Length][];
int ctr = 0;
bool newlineFormatting = false;
// Loop through all files
for (int i = 0; i < fileText.Length; i++)
{
string line = fileText[i];
if (line != "~~~~~~~~~~~~~~~")
continue;
string[] brokenLine = fileText[i++ + 1].Split(new[] { " : " }, StringSplitOptions.None);
if (brokenLine.Length != 2)
{ WinFormsUtil.Error($"Invalid Line @ {i}, expected Text File : {ctr}"); return false; }
var file = brokenLine[1];
if (int.TryParse(file, out var fnum))
{
string line = fileText[i];
if (line != "~~~~~~~~~~~~~~~")
continue;
string[] brokenLine = fileText[i++ + 1].Split(new[] { " : " }, StringSplitOptions.None);
if (brokenLine.Length != 2)
{ WinFormsUtil.Error($"Invalid Line @ {i}, expected Text File : {ctr}"); return false; }
var file = brokenLine[1];
if (int.TryParse(file, out var fnum))
if (fnum != ctr)
{
if (fnum != ctr)
{
WinFormsUtil.Error($"Invalid Line @ {i}, expected Text File : {ctr}");
return false;
}
WinFormsUtil.Error($"Invalid Line @ {i}, expected Text File : {ctr}");
return false;
}
// else pray that the filename index lines up
i += 2; // Skip over the other header line
List<string> Lines = new();
while (i < fileText.Length && fileText[i] != "~~~~~~~~~~~~~~~")
{
Lines.Add(fileText[i]);
newlineFormatting |= fileText[i].Contains("\\n"); // Check if any line wasn't stripped of ingame formatting codes for human readability.
i++;
}
i--;
textLines[ctr++] = Lines.ToArray();
}
// else pray that the filename index lines up
// Error Check
if (ctr != TextData.Length)
i += 2; // Skip over the other header line
List<string> Lines = new();
while (i < fileText.Length && fileText[i] != "~~~~~~~~~~~~~~~")
{
WinFormsUtil.Error("The amount of Text Files in the input file does not match the required for the text file.",
Lines.Add(fileText[i]);
newlineFormatting |= fileText[i].Contains("\\n"); // Check if any line wasn't stripped of ingame formatting codes for human readability.
i++;
}
i--;
textLines[ctr++] = Lines.ToArray();
}
// Error Check
if (ctr != TextData.Length)
{
WinFormsUtil.Error("The amount of Text Files in the input file does not match the required for the text file.",
$"Received: {ctr}, Expected: {TextData.Length}"); return false; }
if (!newlineFormatting)
{
WinFormsUtil.Error("The input Text Files do not have the in-game newline formatting codes (\\n,\\r,\\c).",
"When exporting text, do not remove newline formatting."); return false; }
if (!newlineFormatting)
{
WinFormsUtil.Error("The input Text Files do not have the in-game newline formatting codes (\\n,\\r,\\c).",
"When exporting text, do not remove newline formatting."); return false; }
// All Text Lines received. Store all back.
for (int i = 0; i < TextData.Length; i++)
// All Text Lines received. Store all back.
for (int i = 0; i < TextData.Length; i++)
{
try { TextData[i] = textLines[i]; }
catch (Exception e) { WinFormsUtil.Error($"The input Text File (# {i}) failed to convert:", e.ToString()); return false; }
}
return true;
}
private void ChangeEntry(object sender, EventArgs e)
{
// Save All the old text
if (entry > -1 && sender != this)
{
try
{
try { TextData[i] = textLines[i]; }
catch (Exception e) { WinFormsUtil.Error($"The input Text File (# {i}) failed to convert:", e.ToString()); return false; }
TextData[entry] = GetCurrentDGLines();
}
return true;
catch (Exception ex) { WinFormsUtil.Error(ex.ToString()); }
}
private void ChangeEntry(object sender, EventArgs e)
{
// Save All the old text
if (entry > -1 && sender != this)
{
try
{
TextData[entry] = GetCurrentDGLines();
}
catch (Exception ex) { WinFormsUtil.Error(ex.ToString()); }
}
// Reset
entry = CB_Entry.SelectedIndex;
SetStringsDataGridView(TextData[entry]);
}
// Reset
entry = CB_Entry.SelectedIndex;
SetStringsDataGridView(TextData[entry]);
// Main Handling
private void SetStringsDataGridView(string[] textArray)
{
// Clear the datagrid row content to remove all text lines.
dgv.Rows.Clear();
// Clear the header columns, these are repopulated every time.
dgv.Columns.Clear();
if (textArray.Length == 0)
return;
// Reset settings and columns.
dgv.AllowUserToResizeColumns = false;
DataGridViewColumn dgvLine = new DataGridViewTextBoxColumn
{
HeaderText = "Line",
DisplayIndex = 0,
Width = 32,
ReadOnly = true,
SortMode = DataGridViewColumnSortMode.NotSortable
};
dgvLine.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
DataGridViewTextBoxColumn dgvText = new()
{
HeaderText = "Text",
DisplayIndex = 1,
SortMode = DataGridViewColumnSortMode.NotSortable,
AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
};
dgv.Columns.Add(dgvLine);
dgv.Columns.Add(dgvText);
dgv.Rows.Add(textArray.Length);
// Add the text lines into their cells.
for (int i = 0; i < textArray.Length; i++)
{
dgv.Rows[i].Cells[0].Value = i;
dgv.Rows[i].Cells[1].Value = textArray[i];
}
}
// Main Handling
private void SetStringsDataGridView(string[] textArray)
private string[] GetCurrentDGLines()
{
// Get Line Count
string[] lines = new string[dgv.RowCount];
for (int i = 0; i < dgv.RowCount; i++)
lines[i] = (string)dgv.Rows[i].Cells[1].Value;
return lines;
}
// Meta Usage
private void B_AddLine_Click(object sender, EventArgs e)
{
int currentRow = 0;
try { currentRow = dgv.CurrentRow.Index; }
catch { dgv.Rows.Add(); }
if (dgv.Rows.Count != 1 && (currentRow < dgv.Rows.Count - 1 || currentRow == 0))
{
// Clear the datagrid row content to remove all text lines.
dgv.Rows.Clear();
// Clear the header columns, these are repopulated every time.
dgv.Columns.Clear();
if (textArray.Length == 0)
return;
// Reset settings and columns.
dgv.AllowUserToResizeColumns = false;
DataGridViewColumn dgvLine = new DataGridViewTextBoxColumn
if (ModifierKeys != Keys.Control && currentRow != 0)
{
HeaderText = "Line",
DisplayIndex = 0,
Width = 32,
ReadOnly = true,
SortMode = DataGridViewColumnSortMode.NotSortable
};
dgvLine.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
DataGridViewTextBoxColumn dgvText = new()
{
HeaderText = "Text",
DisplayIndex = 1,
SortMode = DataGridViewColumnSortMode.NotSortable,
AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
};
dgv.Columns.Add(dgvLine);
dgv.Columns.Add(dgvText);
dgv.Rows.Add(textArray.Length);
// Add the text lines into their cells.
for (int i = 0; i < textArray.Length; i++)
{
dgv.Rows[i].Cells[0].Value = i;
dgv.Rows[i].Cells[1].Value = textArray[i];
}
}
private string[] GetCurrentDGLines()
{
// Get Line Count
string[] lines = new string[dgv.RowCount];
for (int i = 0; i < dgv.RowCount; i++)
lines[i] = (string)dgv.Rows[i].Cells[1].Value;
return lines;
}
// Meta Usage
private void B_AddLine_Click(object sender, EventArgs e)
{
int currentRow = 0;
try { currentRow = dgv.CurrentRow.Index; }
catch { dgv.Rows.Add(); }
if (dgv.Rows.Count != 1 && (currentRow < dgv.Rows.Count - 1 || currentRow == 0))
{
if (ModifierKeys != Keys.Control && currentRow != 0)
{
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Inserting in between rows will shift all subsequent lines.", "Continue?") != DialogResult.Yes)
return;
}
// Insert new Row after current row.
dgv.Rows.Insert(currentRow + 1);
}
for (int i = 0; i < dgv.Rows.Count; i++)
dgv.Rows[i].Cells[0].Value = i.ToString();
}
private void B_RemoveLine_Click(object sender, EventArgs e)
{
int currentRow = dgv.CurrentRow.Index;
if (currentRow < dgv.Rows.Count - 1)
{
if (ModifierKeys != Keys.Control && DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Deleting a row above other lines will shift all subsequent lines.", "Continue?"))
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Inserting in between rows will shift all subsequent lines.", "Continue?") != DialogResult.Yes)
return;
}
dgv.Rows.RemoveAt(currentRow);
// Resequence the Index Value column
for (int i = 0; i < dgv.Rows.Count; i++)
dgv.Rows[i].Cells[0].Value = i.ToString();
// Insert new Row after current row.
dgv.Rows.Insert(currentRow + 1);
}
private void SaveCurrentFile()
{
// Save any pending edits
dgv.EndEdit();
// Save All the old text
if (entry > -1)
TextData[entry] = GetCurrentDGLines();
}
private void B_Randomize_Click(object sender, EventArgs e)
{
// gametext can be horribly broken if randomized
if (Mode == TextEditorMode.Common && DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Randomizing Game Text is dangerous!", "Continue?"))
return;
// get if the user wants to randomize current text file or all files
var dr = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel,
$"Yes: Randomize ALL{Environment.NewLine}No: Randomize current Text File{Environment.NewLine}Cancel: Abort");
if (dr == DialogResult.Cancel)
return;
// get if pure shuffle or smart shuffle (no shuffle if variable present)
var drs = WinFormsUtil.Prompt(MessageBoxButtons.YesNo,
$"Smart shuffle:{Environment.NewLine}Yes: Shuffle if no Variable present{Environment.NewLine}No: Pure random!");
if (drs == DialogResult.Cancel)
return;
bool all = dr == DialogResult.Yes;
bool smart = drs == DialogResult.Yes;
// save current
if (entry > -1)
TextData[entry] = GetCurrentDGLines();
// single-entire looping
int start = all ? 0 : entry;
int end = all ? TextData.Length - 1 : entry;
// Gather strings
List<string> strings = new();
for (int i = start; i <= end; i++)
{
string[] data = TextData[i];
strings.AddRange(smart
? data.Where(line => !line.Contains("["))
: data);
}
// Shuffle up
string[] pool = strings.ToArray();
Util.Shuffle(pool);
// Apply Text
int ctr = 0;
for (int i = start; i <= end; i++)
{
string[] data = TextData[i];
for (int j = 0; j < data.Length; j++) // apply lines
{
if (!smart || !data[j].Contains("["))
data[j] = pool[ctr++];
}
TextData[i] = data;
}
// Load current text file
SetStringsDataGridView(TextData[entry]);
WinFormsUtil.Alert("Strings randomized!");
}
private void B_Save_Click(object sender, EventArgs e)
{
Modified = true;
SaveCurrentFile();
TextData.Save();
Close();
}
public bool Modified { get; set; }
for (int i = 0; i < dgv.Rows.Count; i++)
dgv.Rows[i].Cells[0].Value = i.ToString();
}
}
private void B_RemoveLine_Click(object sender, EventArgs e)
{
int currentRow = dgv.CurrentRow.Index;
if (currentRow < dgv.Rows.Count - 1)
{
if (ModifierKeys != Keys.Control && DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Deleting a row above other lines will shift all subsequent lines.", "Continue?"))
return;
}
dgv.Rows.RemoveAt(currentRow);
// Resequence the Index Value column
for (int i = 0; i < dgv.Rows.Count; i++)
dgv.Rows[i].Cells[0].Value = i.ToString();
}
private void SaveCurrentFile()
{
// Save any pending edits
dgv.EndEdit();
// Save All the old text
if (entry > -1)
TextData[entry] = GetCurrentDGLines();
}
private void B_Randomize_Click(object sender, EventArgs e)
{
// gametext can be horribly broken if randomized
if (Mode == TextEditorMode.Common && DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Randomizing Game Text is dangerous!", "Continue?"))
return;
// get if the user wants to randomize current text file or all files
var dr = WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel,
$"Yes: Randomize ALL{Environment.NewLine}No: Randomize current Text File{Environment.NewLine}Cancel: Abort");
if (dr == DialogResult.Cancel)
return;
// get if pure shuffle or smart shuffle (no shuffle if variable present)
var drs = WinFormsUtil.Prompt(MessageBoxButtons.YesNo,
$"Smart shuffle:{Environment.NewLine}Yes: Shuffle if no Variable present{Environment.NewLine}No: Pure random!");
if (drs == DialogResult.Cancel)
return;
bool all = dr == DialogResult.Yes;
bool smart = drs == DialogResult.Yes;
// save current
if (entry > -1)
TextData[entry] = GetCurrentDGLines();
// single-entire looping
int start = all ? 0 : entry;
int end = all ? TextData.Length - 1 : entry;
// Gather strings
List<string> strings = new();
for (int i = start; i <= end; i++)
{
string[] data = TextData[i];
strings.AddRange(smart
? data.Where(line => !line.Contains("["))
: data);
}
// Shuffle up
string[] pool = strings.ToArray();
Util.Shuffle(pool);
// Apply Text
int ctr = 0;
for (int i = start; i <= end; i++)
{
string[] data = TextData[i];
for (int j = 0; j < data.Length; j++) // apply lines
{
if (!smart || !data[j].Contains("["))
data[j] = pool[ctr++];
}
TextData[i] = data;
}
// Load current text file
SetStringsDataGridView(TextData[entry]);
WinFormsUtil.Alert("Strings randomized!");
}
private void B_Save_Click(object sender, EventArgs e)
{
Modified = true;
SaveCurrentFile();
TextData.Save();
Close();
}
public bool Modified { get; set; }
}

View File

@@ -1,131 +1,130 @@
using System;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using pkNX.Game;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public sealed partial class TypeChart : Form
{
public sealed partial class TypeChart : Form
private readonly string[] types;
private readonly TypeChartEditor Editor;
public byte[] Chart;
public bool Modified { get; set; }
private const int TypeWidth = 32; // px
private int TypeCount => types.Length;
public TypeChart(TypeChartEditor editor, string[] types)
{
private readonly string[] types;
private readonly TypeChartEditor Editor;
Editor = editor;
InitializeComponent();
this.types = types;
Chart = editor.Data;
LoadChart();
}
public byte[] Chart;
private void B_Save_Click(object sender, EventArgs e)
{
Modified = true;
SaveChart();
Close();
}
public bool Modified { get; set; }
private const int TypeWidth = 32; // px
private int TypeCount => types.Length;
private void SaveChart() => Chart = Editor.Data;
public TypeChart(TypeChartEditor editor, string[] types)
{
Editor = editor;
InitializeComponent();
this.types = types;
Chart = editor.Data;
LoadChart();
}
private void B_RTM_Click(object sender, EventArgs e)
{
Editor.Randomize();
Chart = Editor.Data;
LoadChart();
System.Media.SystemSounds.Asterisk.Play();
}
private void B_Save_Click(object sender, EventArgs e)
{
Modified = true;
SaveChart();
Close();
}
private void LoadChart() => PB_Chart.Image = GetGrid(Chart, TypeWidth, TypeCount);
private void SaveChart() => Chart = Editor.Data;
// gui logic below
private void B_RTM_Click(object sender, EventArgs e)
{
Editor.Randomize();
Chart = Editor.Data;
LoadChart();
System.Media.SystemSounds.Asterisk.Play();
}
private void MoveMouse(object sender, MouseEventArgs e)
{
GetCoordinate((PictureBox)sender, e, out int X, out int Y);
int index = (Y * TypeCount) + X;
if (index >= Chart.Length)
return;
UpdateLabel(X, Y, Chart[index]);
}
private void LoadChart() => PB_Chart.Image = GetGrid(Chart, TypeWidth, TypeCount);
private void ClickMouse(object sender, MouseEventArgs e)
{
GetCoordinate((PictureBox)sender, e, out int X, out int Y);
int index = (Y * TypeCount) + X;
if (index >= Chart.Length)
return;
// gui logic below
Chart[index] = ToggleEffectiveness(Chart[index], e.Button == MouseButtons.Left);
private void MoveMouse(object sender, MouseEventArgs e)
{
GetCoordinate((PictureBox)sender, e, out int X, out int Y);
int index = (Y * TypeCount) + X;
if (index >= Chart.Length)
return;
UpdateLabel(X, Y, Chart[index]);
}
UpdateLabel(X, Y, Chart[index]);
LoadChart();
}
private void ClickMouse(object sender, MouseEventArgs e)
{
GetCoordinate((PictureBox)sender, e, out int X, out int Y);
int index = (Y * TypeCount) + X;
if (index >= Chart.Length)
return;
private void UpdateLabel(int X, int Y, int value)
{
if (value >= effects.Length || X >= types.Length || Y >= types.Length)
return; // clicking and moving outside the box has invalid values
L_Hover.Text = $"[{X:00}x{Y:00}: {value:00}] {types[Y]} attacking {types[X]} {effects[value]}";
}
Chart[index] = ToggleEffectiveness(Chart[index], e.Button == MouseButtons.Left);
private readonly string[] effects =
{
"has no effect!",
"",
"is not very effective.",
"",
"does regular damage.",
"",
"",
"",
"is super effective!"
};
UpdateLabel(X, Y, Chart[index]);
LoadChart();
}
public static void GetCoordinate(Control sender, MouseEventArgs e, out int X, out int Y)
{
X = e.X / TypeWidth;
Y = e.Y / TypeWidth;
if (e.X == sender.Width - 1 - 2) // tweak because the furthest pixel is unused for transparent effect, and 2 px are used for border
X--;
if (e.Y == sender.Height - 1 - 2)
Y--;
}
private void UpdateLabel(int X, int Y, int value)
{
if (value >= effects.Length || X >= types.Length || Y >= types.Length)
return; // clicking and moving outside the box has invalid values
L_Hover.Text = $"[{X:00}x{Y:00}: {value:00}] {types[Y]} attacking {types[X]} {effects[value]}";
}
public static byte ToggleEffectiveness(byte currentValue, bool increase)
{
byte[] vals = { 0, 2, 4, 8 };
int curIndex = Array.IndexOf(vals, currentValue);
if (curIndex < 0)
return currentValue;
private readonly string[] effects =
{
"has no effect!",
"",
"is not very effective.",
"",
"does regular damage.",
"",
"",
"",
"is super effective!"
};
uint shift = (uint)(curIndex + (increase ? 1 : -1));
var newIndex = shift % vals.Length;
return vals[newIndex];
}
public static void GetCoordinate(Control sender, MouseEventArgs e, out int X, out int Y)
{
X = e.X / TypeWidth;
Y = e.Y / TypeWidth;
if (e.X == sender.Width - 1 - 2) // tweak because the furthest pixel is unused for transparent effect, and 2 px are used for border
X--;
if (e.Y == sender.Height - 1 - 2)
Y--;
}
public static Bitmap GetGrid(byte[] vals, int itemsize, int itemsPerRow)
{
// set up image
var bmpData = TypeChartEditor.GetTypeChartImageData(itemsize, itemsPerRow, vals, out int width, out int height);
return CreateImage(width, height, bmpData);
}
public static byte ToggleEffectiveness(byte currentValue, bool increase)
{
byte[] vals = { 0, 2, 4, 8 };
int curIndex = Array.IndexOf(vals, currentValue);
if (curIndex < 0)
return currentValue;
uint shift = (uint)(curIndex + (increase ? 1 : -1));
var newIndex = shift % vals.Length;
return vals[newIndex];
}
public static Bitmap GetGrid(byte[] vals, int itemsize, int itemsPerRow)
{
// set up image
var bmpData = TypeChartEditor.GetTypeChartImageData(itemsize, itemsPerRow, vals, out int width, out int height);
return CreateImage(width, height, bmpData);
}
private static Bitmap CreateImage(int width, int height, byte[] bmpData)
{
// assemble image
var b = new Bitmap(width, height, PixelFormat.Format32bppArgb);
var bData = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
System.Runtime.InteropServices.Marshal.Copy(bmpData, 0, bData.Scan0, bmpData.Length);
b.UnlockBits(bData);
return b;
}
private static Bitmap CreateImage(int width, int height, byte[] bmpData)
{
// assemble image
var b = new Bitmap(width, height, PixelFormat.Format32bppArgb);
var bData = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
System.Runtime.InteropServices.Marshal.Copy(bmpData, 0, bData.Scan0, bmpData.Length);
b.UnlockBits(bData);
return b;
}
}

View File

@@ -1,40 +1,39 @@
using System;
using System;
using System.Windows.Forms;
namespace pkNX.WinForms
namespace pkNX.WinForms;
public static class WinFormsUtil
{
public static class WinFormsUtil
/// <summary>
/// Displays a dialog showing the details of an error.
/// </summary>
/// <param name="lines">User-friendly message about the error.</param>
/// <returns>The <see cref="DialogResult"/> associated with the dialog.</returns>
internal static DialogResult Error(params string[] lines)
{
/// <summary>
/// Displays a dialog showing the details of an error.
/// </summary>
/// <param name="lines">User-friendly message about the error.</param>
/// <returns>The <see cref="DialogResult"/> associated with the dialog.</returns>
internal static DialogResult Error(params string[] lines)
{
System.Media.SystemSounds.Hand.Play();
string msg = string.Join(Environment.NewLine + Environment.NewLine, lines);
return MessageBox.Show(msg, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
internal static DialogResult Alert(params string[] lines)
{
System.Media.SystemSounds.Asterisk.Play();
string msg = string.Join(Environment.NewLine + Environment.NewLine, lines);
return MessageBox.Show(msg, "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
internal static DialogResult Prompt(MessageBoxButtons btn, params string[] lines)
{
System.Media.SystemSounds.Question.Play();
string msg = string.Join(Environment.NewLine + Environment.NewLine, lines);
return MessageBox.Show(msg, "Prompt", btn, MessageBoxIcon.Asterisk);
}
/// <summary>
/// Gets the selected value of the input <see cref="cb"/>. If no value is selected, will return 0.
/// </summary>
/// <param name="cb">ComboBox to retrieve value for.</param>
internal static int GetIndex(ComboBox cb) => (int)(cb.SelectedValue ?? 0);
System.Media.SystemSounds.Hand.Play();
string msg = string.Join(Environment.NewLine + Environment.NewLine, lines);
return MessageBox.Show(msg, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
internal static DialogResult Alert(params string[] lines)
{
System.Media.SystemSounds.Asterisk.Play();
string msg = string.Join(Environment.NewLine + Environment.NewLine, lines);
return MessageBox.Show(msg, "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
internal static DialogResult Prompt(MessageBoxButtons btn, params string[] lines)
{
System.Media.SystemSounds.Question.Play();
string msg = string.Join(Environment.NewLine + Environment.NewLine, lines);
return MessageBox.Show(msg, "Prompt", btn, MessageBoxIcon.Asterisk);
}
/// <summary>
/// Gets the selected value of the input <see cref="cb"/>. If no value is selected, will return 0.
/// </summary>
/// <param name="cb">ComboBox to retrieve value for.</param>
internal static int GetIndex(ComboBox cb) => (int)(cb.SelectedValue ?? 0);
}

View File

@@ -1,9 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFrameworks>net472</TargetFrameworks>
<TargetFrameworks>net6.0-windows</TargetFrameworks>
<UseWindowsForms>true</UseWindowsForms>
<RootNamespace>pkNX.WinForms</RootNamespace>
<NeutralLanguage>en</NeutralLanguage>
<Company>Project Pokémon</Company>
<Authors>Kaphotics</Authors>
<Product>pkNX</Product>
@@ -13,8 +14,6 @@
<AssemblyName>pkNX</AssemblyName>
<LangVersion>10</LangVersion>
<Nullable>enable</Nullable>
<GenerateResourceUsePreserializedResources>true</GenerateResourceUsePreserializedResources>
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
@@ -26,50 +25,19 @@
<ProjectReference Include="..\pkNX.Structures.FlatBuffers\pkNX.Structures.FlatBuffers.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net461'">
<Reference Include="System.Configuration" />
</ItemGroup>
<ItemGroup>
<Compile Update="Controls\EvolutionRow8a.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Update="Subforms\PokeDataUI8a.cs">
<SubType>Form</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="icon.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="IndexRange" Version="1.0.0" />
<PackageReference Include="System.Memory" Version="4.5.4" />
<PackageReference Include="System.Resources.Extensions" Version="5.0.0" />
</ItemGroup>
</Project>