mirror of
https://github.com/kwsch/PKHeX
synced 2024-12-25 20:03:12 +00:00
358 lines
13 KiB
C#
358 lines
13 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Drawing;
|
|||
|
using System.IO;
|
|||
|
using System.Linq;
|
|||
|
using System.Windows.Forms;
|
|||
|
|
|||
|
namespace PKHeX
|
|||
|
{
|
|||
|
public partial class SAV_EventFlags : Form
|
|||
|
{
|
|||
|
public SAV_EventFlags()
|
|||
|
{
|
|||
|
InitializeComponent();
|
|||
|
|
|||
|
DragEnter += tabMain_DragEnter;
|
|||
|
DragDrop += tabMain_DragDrop;
|
|||
|
|
|||
|
flags = SAV.EventFlags;
|
|||
|
Constants = SAV.EventConsts;
|
|||
|
|
|||
|
CB_Stats.Items.Clear();
|
|||
|
for (int i = 0; i < Constants.Length; i++)
|
|||
|
CB_Stats.Items.Add(i.ToString());
|
|||
|
|
|||
|
TLP_Flags.Controls.Clear();
|
|||
|
TLP_Const.Controls.Clear();
|
|||
|
addFlagList(getStringList("flags"));
|
|||
|
addConstList(getStringList("const"));
|
|||
|
|
|||
|
Util.TranslateInterface(this, Main.curlanguage);
|
|||
|
|
|||
|
CB_Stats.SelectedIndex = 0;
|
|||
|
nud.Maximum = flags.Length - 1;
|
|||
|
nud.Text = "0";
|
|||
|
}
|
|||
|
|
|||
|
private readonly SaveFile SAV = Main.SAV.Clone();
|
|||
|
private readonly bool[] flags;
|
|||
|
private readonly ushort[] Constants;
|
|||
|
private const string flagTag = "bool_";
|
|||
|
private const string constTag = "const_";
|
|||
|
private const string flagLabelTag = "flag_";
|
|||
|
private const string constLabelTag = "L_";
|
|||
|
private bool editing;
|
|||
|
private int constEntry = -1;
|
|||
|
|
|||
|
private void B_Cancel_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
Close();
|
|||
|
}
|
|||
|
private void B_Save_Click(object sender, EventArgs e)
|
|||
|
{
|
|||
|
// Gather Updated Flags
|
|||
|
foreach (CheckBox flag in TLP_Flags.Controls)
|
|||
|
flags[getControlNum(flag)] = flag.Checked;
|
|||
|
SAV.EventFlags = flags;
|
|||
|
|
|||
|
// Copy back Constants
|
|||
|
changeConstantIndex(null, null); // Trigger Saving
|
|||
|
SAV.EventConsts = Constants;
|
|||
|
|
|||
|
Close();
|
|||
|
}
|
|||
|
|
|||
|
private string[] getStringList(string type)
|
|||
|
{
|
|||
|
string[] text = null;
|
|||
|
if (SAV.ORAS)
|
|||
|
text = Util.getStringList($"{type}_oras");
|
|||
|
else if (SAV.XY)
|
|||
|
text = Util.getStringList($"{type}_xy");
|
|||
|
return text;
|
|||
|
}
|
|||
|
private void addFlagList(string[] list)
|
|||
|
{
|
|||
|
if (list == null || list.Length == 0)
|
|||
|
{
|
|||
|
TLP_Flags.Controls.Add(new Label { Text = "Needs more research.", Name = "TLP_Flags_Research", ForeColor = Color.Red, AutoSize = true }, 0, 0);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Get list
|
|||
|
List<int> num = new List<int>();
|
|||
|
List<string> desc = new List<string>();
|
|||
|
|
|||
|
foreach (string[] split in list.Select(s => s.Split('\t')).Where(split => split.Length == 2))
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
int n = Convert.ToInt32(split[0]);
|
|||
|
if (num.Contains(n))
|
|||
|
continue;
|
|||
|
num.Add(n);
|
|||
|
desc.Add(split[1]);
|
|||
|
} catch { }
|
|||
|
}
|
|||
|
if (num.Count == 0)
|
|||
|
{
|
|||
|
TLP_Flags.Controls.Add(new Label { Text = "Needs more research.", Name = "TLP_Flags_Research", ForeColor = Color.Red, AutoSize = true }, 0, 0);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
for (int i = 0; i < num.Count; i++)
|
|||
|
{
|
|||
|
var lbl = new Label
|
|||
|
{
|
|||
|
Text = desc[i],
|
|||
|
Name = flagLabelTag + num[i].ToString("0000"),
|
|||
|
Margin = Padding.Empty,
|
|||
|
AutoSize = true
|
|||
|
};
|
|||
|
var chk = new CheckBox
|
|||
|
{
|
|||
|
Name = flagTag + num[i].ToString("0000"),
|
|||
|
CheckAlign = ContentAlignment.MiddleLeft,
|
|||
|
Margin = Padding.Empty,
|
|||
|
Checked = flags[num[i]],
|
|||
|
AutoSize = true
|
|||
|
};
|
|||
|
chk.CheckStateChanged += toggleFlag;
|
|||
|
TLP_Flags.Controls.Add(chk, 0, i);
|
|||
|
TLP_Flags.Controls.Add(lbl, 1, i);
|
|||
|
}
|
|||
|
}
|
|||
|
private void addConstList(string[] list)
|
|||
|
{
|
|||
|
if (list == null || list.Length == 0)
|
|||
|
{
|
|||
|
TLP_Const.Controls.Add(new Label { Text = "Needs more research.", Name = "TLP_Const_Research", ForeColor = Color.Red, AutoSize = true }, 0, 0);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Get list
|
|||
|
List<int> num = new List<int>();
|
|||
|
List<string> desc = new List<string>();
|
|||
|
|
|||
|
foreach (string[] split in list.Select(s => s.Split('\t')).Where(split => split.Length == 2))
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
int n = Convert.ToInt32(split[0]);
|
|||
|
if (num.Contains(n))
|
|||
|
continue;
|
|||
|
num.Add(n);
|
|||
|
desc.Add(split[1]);
|
|||
|
} catch { }
|
|||
|
}
|
|||
|
if (num.Count == 0)
|
|||
|
{
|
|||
|
TLP_Const.Controls.Add(new Label { Text = "Needs more research.", Name = "TLP_Const_Research", ForeColor = Color.Red, AutoSize = true }, 0, 0);
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
for (int i = 0; i < num.Count; i++)
|
|||
|
{
|
|||
|
var lbl = new Label
|
|||
|
{
|
|||
|
Text = desc[i],
|
|||
|
Name = constLabelTag + num[i].ToString("0000"),
|
|||
|
Margin = Padding.Empty,
|
|||
|
AutoSize = true
|
|||
|
};
|
|||
|
var mtb = new NumericUpDown
|
|||
|
{
|
|||
|
Maximum = short.MaxValue,
|
|||
|
Minimum = short.MinValue,
|
|||
|
Value = Constants[num[i]],
|
|||
|
Name = constTag + num[i].ToString("0000"),
|
|||
|
Margin = Padding.Empty,
|
|||
|
Width = 55,
|
|||
|
};
|
|||
|
mtb.TextChanged += toggleConst;
|
|||
|
TLP_Const.Controls.Add(mtb, 0, i);
|
|||
|
TLP_Const.Controls.Add(lbl, 1, i);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private int getControlNum(Control chk)
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
string source = chk.Name;
|
|||
|
return Convert.ToInt32(source.Substring(Math.Max(0, source.Length - 4)));
|
|||
|
}
|
|||
|
catch { return 0; }
|
|||
|
}
|
|||
|
private void changeCustomBool(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (editing)
|
|||
|
return;
|
|||
|
editing = true;
|
|||
|
flags[(int)nud.Value] = c_CustomFlag.Checked;
|
|||
|
CheckBox c = TLP_Flags.Controls[flagTag + nud.Value.ToString("0000")] as CheckBox;
|
|||
|
if (c != null)
|
|||
|
{
|
|||
|
c.Checked = c_CustomFlag.Checked;
|
|||
|
}
|
|||
|
editing = false;
|
|||
|
}
|
|||
|
private void changeCustomFlag(object sender, EventArgs e)
|
|||
|
{
|
|||
|
int flag = (int)nud.Value;
|
|||
|
if (flag >= flags.Length)
|
|||
|
{
|
|||
|
c_CustomFlag.Checked = false;
|
|||
|
c_CustomFlag.Enabled = false;
|
|||
|
nud.BackColor = Color.Red;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
c_CustomFlag.Enabled = true;
|
|||
|
nud.BackColor = Main.defaultControlWhite;
|
|||
|
c_CustomFlag.Checked = flags[flag];
|
|||
|
}
|
|||
|
}
|
|||
|
private void changeCustomFlag(object sender, KeyEventArgs e)
|
|||
|
{
|
|||
|
changeCustomFlag(null, (EventArgs)e);
|
|||
|
}
|
|||
|
private void toggleFlag(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (editing)
|
|||
|
return;
|
|||
|
editing = true;
|
|||
|
int flagnum = getControlNum((CheckBox) sender);
|
|||
|
flags[flagnum] = ((CheckBox)sender).Checked;
|
|||
|
if (nud.Value == flagnum)
|
|||
|
c_CustomFlag.Checked = flags[flagnum];
|
|||
|
editing = false;
|
|||
|
}
|
|||
|
|
|||
|
private void changeCustomConst(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (editing)
|
|||
|
return;
|
|||
|
editing = true;
|
|||
|
|
|||
|
editing = true;
|
|||
|
Constants[CB_Stats.SelectedIndex] = (ushort)(Util.ToUInt32(((MaskedTextBox)sender).Text) & 0xFFFF);
|
|||
|
MaskedTextBox m = TLP_Flags.Controls[constTag + CB_Stats.SelectedIndex.ToString("0000")] as MaskedTextBox;
|
|||
|
if (m != null)
|
|||
|
m.Text = MT_Stat.Text;
|
|||
|
|
|||
|
editing = false;
|
|||
|
}
|
|||
|
private void changeConstantIndex(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (constEntry > -1) // Set Entry
|
|||
|
Constants[constEntry] = (ushort)Math.Min(Util.ToUInt32(MT_Stat.Text), 0xFFFF);
|
|||
|
|
|||
|
constEntry = CB_Stats.SelectedIndex; // Get Entry
|
|||
|
MT_Stat.Text = Constants[constEntry].ToString();
|
|||
|
}
|
|||
|
private void toggleConst(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (editing)
|
|||
|
return;
|
|||
|
|
|||
|
editing = true;
|
|||
|
int constnum = getControlNum((NumericUpDown)sender);
|
|||
|
Constants[constnum] = (ushort)(Util.ToUInt32(((NumericUpDown)sender).Text) & 0xFFFF);
|
|||
|
if (constnum == CB_Stats.SelectedIndex)
|
|||
|
MT_Stat.Text = Constants[constnum].ToString();
|
|||
|
editing = false;
|
|||
|
}
|
|||
|
|
|||
|
private void changeSAV(object sender, EventArgs e)
|
|||
|
{
|
|||
|
if (TB_NewSAV.Text.Length > 0 && TB_OldSAV.Text.Length > 0)
|
|||
|
diffSaves();
|
|||
|
}
|
|||
|
private void openSAV(object sender, EventArgs e)
|
|||
|
{
|
|||
|
OpenFileDialog ofd = new OpenFileDialog();
|
|||
|
if (ofd.ShowDialog() == DialogResult.OK)
|
|||
|
loadSAV(sender, ofd.FileName);
|
|||
|
}
|
|||
|
private void loadSAV(object sender, string path)
|
|||
|
{
|
|||
|
if (sender == B_LoadOld)
|
|||
|
TB_OldSAV.Text = path;
|
|||
|
else
|
|||
|
TB_NewSAV.Text = path;
|
|||
|
}
|
|||
|
private void diffSaves()
|
|||
|
{
|
|||
|
if (!File.Exists(TB_OldSAV.Text)) { Util.Alert("Save 1 path invalid."); return; }
|
|||
|
if (!File.Exists(TB_NewSAV.Text)) { Util.Alert("Save 2 path invalid."); return; }
|
|||
|
if (new FileInfo(TB_OldSAV.Text).Length > 0x100000) { Util.Alert("Save 1 file invalid."); return; }
|
|||
|
if (new FileInfo(TB_NewSAV.Text).Length > 0x100000) { Util.Alert("Save 2 file invalid."); return; }
|
|||
|
|
|||
|
SaveFile s1 = SaveUtil.getVariantSAV(File.ReadAllBytes(TB_OldSAV.Text));
|
|||
|
SaveFile s2 = SaveUtil.getVariantSAV(File.ReadAllBytes(TB_NewSAV.Text));
|
|||
|
|
|||
|
if (s1.GetType() != s2.GetType())
|
|||
|
{ Util.Alert("Save types are different.", $"S1: {s1.GetType()}", $"S2: {s2.GetType()}"); return; }
|
|||
|
|
|||
|
string tbIsSet = "";
|
|||
|
string tbUnSet = "";
|
|||
|
try
|
|||
|
{
|
|||
|
bool[] oldBits = s1.EventFlags;
|
|||
|
bool[] newBits = s2.EventFlags;
|
|||
|
if (oldBits.Length != newBits.Length)
|
|||
|
{ Util.Alert("Event flag lengths for games are different.", $"S1: {(GameVersion)s1.Game}", $"S2: {(GameVersion)s2.Game}"); return; }
|
|||
|
|
|||
|
for (int i = 0; i < oldBits.Length; i++)
|
|||
|
{
|
|||
|
if (oldBits[i] == newBits[i]) continue;
|
|||
|
if (newBits[i])
|
|||
|
tbIsSet += i.ToString("0000") + ",";
|
|||
|
else
|
|||
|
tbUnSet += i.ToString("0000") + ",";
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
Util.Error(e.ToString());
|
|||
|
Console.Write(e);
|
|||
|
}
|
|||
|
TB_IsSet.Text = tbIsSet;
|
|||
|
TB_UnSet.Text = tbUnSet;
|
|||
|
|
|||
|
string r = "";
|
|||
|
try
|
|||
|
{
|
|||
|
ushort[] oldConst = s1.EventConsts;
|
|||
|
ushort[] newConst = s2.EventConsts;
|
|||
|
if (oldConst.Length != newConst.Length)
|
|||
|
{ Util.Alert("Event flag lengths for games are different.", $"S1: {(GameVersion)s1.Game}", $"S2: {(GameVersion)s2.Game}"); return; }
|
|||
|
|
|||
|
for (int i = 0; i < newConst.Length; i++)
|
|||
|
if (oldConst[i] != newConst[i])
|
|||
|
r += $"{i}: {oldConst[i]}->{newConst[i]}{Environment.NewLine}";
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
Util.Error(e.ToString());
|
|||
|
Console.Write(e);
|
|||
|
}
|
|||
|
|
|||
|
if (DialogResult.Yes != Util.Prompt(MessageBoxButtons.YesNo, "Copy Event Constant diff to clipboard?"))
|
|||
|
return;
|
|||
|
Clipboard.SetText(r);
|
|||
|
}
|
|||
|
|
|||
|
private void tabMain_DragEnter(object sender, DragEventArgs e)
|
|||
|
{
|
|||
|
if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
|
|||
|
}
|
|||
|
private void tabMain_DragDrop(object sender, DragEventArgs e)
|
|||
|
{
|
|||
|
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
|
|||
|
loadSAV(Util.Prompt(MessageBoxButtons.YesNo, "FlagDiff Researcher:", "Yes: Old Save" + Environment.NewLine + "No: New Save") == DialogResult.Yes ? B_LoadOld : B_LoadNew, files[0]);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|