mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-04-26 02:29:59 -05:00
478 lines
15 KiB
C#
478 lines
15 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Windows.Forms;
|
|
using PKHeX.Core;
|
|
using static PKHeX.Core.MessageStrings;
|
|
|
|
namespace PKHeX.WinForms;
|
|
|
|
public partial class SAV_SecretBase : Form
|
|
{
|
|
private readonly SaveFile Origin;
|
|
private readonly SAV6AO SAV;
|
|
|
|
private SecretBase6? CurrentBase;
|
|
private int CurrentPKMIndex;
|
|
private SecretBase6PKM? CurrentPKM;
|
|
|
|
private int CurrentPlacementIndex;
|
|
private SecretBase6GoodPlacement? CurrentPlacement;
|
|
|
|
private bool loading = true;
|
|
|
|
public SAV_SecretBase(SAV6AO sav)
|
|
{
|
|
InitializeComponent();
|
|
WinFormsUtil.TranslateInterface(this, Main.CurrentLanguage);
|
|
SAV = (SAV6AO)(Origin = sav).Clone();
|
|
|
|
NUD_FObject.Maximum = SecretBase6.COUNT_GOODS - 1; // zero indexed!
|
|
NUD_FPKM.Maximum = SecretBase6Other.COUNT_TEAM - 1; // zero indexed!
|
|
PG_Base.Font = FontUtil.GetPKXFont();
|
|
|
|
SetupComboBoxes();
|
|
ReloadSecretBaseList();
|
|
LB_Bases.SelectedIndex = 0;
|
|
|
|
// Extra data
|
|
NUD_CapturedRecord.Value = SAV.Records.GetRecord(080);
|
|
}
|
|
|
|
private void SetupComboBoxes()
|
|
{
|
|
CB_Ball.InitializeBinding();
|
|
CB_HeldItem.InitializeBinding();
|
|
CB_Species.InitializeBinding();
|
|
CB_Nature.InitializeBinding();
|
|
CB_Ability.InitializeBinding();
|
|
CB_Form.InitializeBinding();
|
|
|
|
var filtered = GameInfo.FilteredSources;
|
|
CB_Ball.DataSource = new BindingSource(filtered.Balls, string.Empty);
|
|
CB_HeldItem.DataSource = new BindingSource(filtered.Items, string.Empty);
|
|
CB_Species.DataSource = new BindingSource(filtered.Species, string.Empty);
|
|
CB_Nature.DataSource = new BindingSource(filtered.Natures, string.Empty);
|
|
|
|
CB_Move1.InitializeBinding();
|
|
CB_Move2.InitializeBinding();
|
|
CB_Move3.InitializeBinding();
|
|
CB_Move4.InitializeBinding();
|
|
|
|
var moves = filtered.Moves;
|
|
CB_Move1.DataSource = new BindingSource(moves, string.Empty);
|
|
CB_Move2.DataSource = new BindingSource(moves, string.Empty);
|
|
CB_Move3.DataSource = new BindingSource(moves, string.Empty);
|
|
CB_Move4.DataSource = new BindingSource(moves, string.Empty);
|
|
}
|
|
|
|
private void ReloadSecretBaseList()
|
|
{
|
|
loading = true;
|
|
int index = LB_Bases.SelectedIndex;
|
|
LB_Bases.Items.Clear();
|
|
|
|
var block = SAV.SecretBase;
|
|
var self = block.GetSecretBaseSelf();
|
|
LB_Bases.Items.Add($"* {self.TrainerName}");
|
|
for (int i = 0; i < SecretBase6Block.OtherSecretBaseCount; i++)
|
|
{
|
|
var other = block.GetSecretBaseOther(i);
|
|
string name = other.TrainerName;
|
|
if (string.IsNullOrWhiteSpace(name))
|
|
name = "Empty";
|
|
LB_Bases.Items.Add($"{i + 1:00} {name}");
|
|
}
|
|
|
|
if (index >= 0)
|
|
LB_Bases.SelectedIndex = index;
|
|
|
|
loading = false;
|
|
}
|
|
|
|
private void ResetLoadNew()
|
|
{
|
|
// Wipe all cached references so nothing is inadvertently saved
|
|
CurrentPKM = null;
|
|
CurrentPlacement = null;
|
|
CurrentBase = null;
|
|
|
|
CurrentPKMIndex = -1;
|
|
CurrentPlacementIndex = -1;
|
|
}
|
|
|
|
private SecretBase6 GetSecretBaseReference(int index)
|
|
{
|
|
if (index == 0)
|
|
return SAV.SecretBase.GetSecretBaseSelf();
|
|
return SAV.SecretBase.GetSecretBaseOther(index - 1);
|
|
}
|
|
|
|
private void LoadCurrent(SecretBase6 bdata)
|
|
{
|
|
loading = true;
|
|
CurrentBase = bdata;
|
|
|
|
PG_Base.SelectedObject = bdata;
|
|
|
|
var pIndex = (int)NUD_FObject.Value;
|
|
LoadPlacement(bdata.GetPlacement(pIndex), pIndex);
|
|
if (bdata is SecretBase6Other o)
|
|
LoadOtherData(o);
|
|
else
|
|
SetOtherDataVisible(false);
|
|
|
|
loading = false;
|
|
}
|
|
|
|
private void SaveCurrent(SecretBase6 bdata)
|
|
{
|
|
SavePlacement((int)NUD_FObject.Value);
|
|
if (bdata is SecretBase6Other o)
|
|
SaveOtherData(o);
|
|
}
|
|
|
|
private void LoadPlacement(SecretBase6GoodPlacement p, int index)
|
|
{
|
|
SavePlacement(index);
|
|
CurrentPlacement = p;
|
|
CurrentPlacementIndex = index;
|
|
|
|
NUD_FObjType.Value = Clamp(NUD_FObjType, p.Good);
|
|
NUD_FX.Value = Clamp(NUD_FX, p.X);
|
|
NUD_FY.Value = Clamp(NUD_FY, p.Y);
|
|
NUD_FRot.Value = Clamp(NUD_FRot, p.Rotation);
|
|
static decimal Clamp(NumericUpDown nud, decimal value) => Math.Clamp(value, nud.Minimum, nud.Maximum);
|
|
}
|
|
|
|
private void SavePlacement(int index)
|
|
{
|
|
var p = CurrentPlacement;
|
|
if (p is null || index < 0)
|
|
return;
|
|
|
|
p.Good = (ushort)NUD_FObjType.Value;
|
|
p.X = (ushort)NUD_FX.Value;
|
|
p.Y = (ushort)NUD_FY.Value;
|
|
p.Rotation = (byte)NUD_FRot.Value;
|
|
}
|
|
|
|
private void SaveOtherData(SecretBase6Other full)
|
|
{
|
|
var pk = CurrentPKM;
|
|
var index = CurrentPKMIndex;
|
|
if (pk is not null && index >= 0)
|
|
{
|
|
SavePKM(pk);
|
|
full.SetParticipant(index, pk);
|
|
}
|
|
}
|
|
|
|
private void LoadOtherData(SecretBase6Other full)
|
|
{
|
|
var pIndex = CurrentPKMIndex = (int)NUD_FPKM.Value;
|
|
var pk = full.GetParticipant(pIndex);
|
|
LoadPKM(pk);
|
|
SetOtherDataVisible(true);
|
|
}
|
|
|
|
private void SetOtherDataVisible(bool visible)
|
|
{
|
|
PAN_PKM.Visible = visible;
|
|
}
|
|
|
|
private void SavePKM(SecretBase6PKM pk)
|
|
{
|
|
pk.EncryptionConstant = Util.GetHexValue(TB_EC.Text);
|
|
pk.Species = (ushort)WinFormsUtil.GetIndex(CB_Species);
|
|
pk.HeldItem = WinFormsUtil.GetIndex(CB_HeldItem);
|
|
pk.Ability = WinFormsUtil.GetIndex(CB_Ability);
|
|
pk.AbilityNumber = CB_Ability.SelectedIndex << 1;
|
|
pk.Nature = (Nature)WinFormsUtil.GetIndex(CB_Nature);
|
|
pk.Gender = EntityGender.GetFromString(Label_Gender.Text);
|
|
pk.Form = (byte)CB_Form.SelectedIndex;
|
|
pk.EV_HP = Math.Clamp(Convert.ToInt32(TB_HPEV.Text) , 0, EffortValues.Max252);
|
|
pk.EV_ATK = Math.Clamp(Convert.ToInt32(TB_ATKEV.Text), 0, EffortValues.Max252);
|
|
pk.EV_DEF = Math.Clamp(Convert.ToInt32(TB_DEFEV.Text), 0, EffortValues.Max252);
|
|
pk.EV_SPA = Math.Clamp(Convert.ToInt32(TB_SPAEV.Text), 0, EffortValues.Max252);
|
|
pk.EV_SPD = Math.Clamp(Convert.ToInt32(TB_SPDEV.Text), 0, EffortValues.Max252);
|
|
pk.EV_SPE = Math.Clamp(Convert.ToInt32(TB_SPEEV.Text), 0, EffortValues.Max252);
|
|
pk.Move1 = (ushort)WinFormsUtil.GetIndex(CB_Move1);
|
|
pk.Move2 = (ushort)WinFormsUtil.GetIndex(CB_Move2);
|
|
pk.Move3 = (ushort)WinFormsUtil.GetIndex(CB_Move3);
|
|
pk.Move4 = (ushort)WinFormsUtil.GetIndex(CB_Move4);
|
|
pk.Move1_PPUps = CB_PPu1.SelectedIndex;
|
|
pk.Move2_PPUps = CB_PPu2.SelectedIndex;
|
|
pk.Move3_PPUps = CB_PPu3.SelectedIndex;
|
|
pk.Move4_PPUps = CB_PPu4.SelectedIndex;
|
|
pk.IV_HP = Convert.ToByte(TB_HPIV.Text) & 0x1F;
|
|
pk.IV_ATK = Convert.ToByte(TB_ATKIV.Text) & 0x1F;
|
|
pk.IV_DEF = Convert.ToByte(TB_DEFIV.Text) & 0x1F;
|
|
pk.IV_SPA = Convert.ToByte(TB_SPAIV.Text) & 0x1F;
|
|
pk.IV_SPD = Convert.ToByte(TB_SPDIV.Text) & 0x1F;
|
|
pk.IV_SPE = Convert.ToByte(TB_SPEIV.Text) & 0x1F;
|
|
pk.IsShiny = CHK_Shiny.Checked;
|
|
pk.CurrentFriendship = Convert.ToByte(TB_Friendship.Text);
|
|
pk.Ball = (byte)WinFormsUtil.GetIndex(CB_Ball);
|
|
pk.CurrentLevel = Convert.ToByte(TB_Level.Text);
|
|
}
|
|
|
|
private void LoadPKM(SecretBase6PKM pk)
|
|
{
|
|
CurrentPKM = pk;
|
|
|
|
// Put data into fields.
|
|
TB_EC.Text = pk.EncryptionConstant.ToString("X8");
|
|
SetGenderLabel(pk.Gender);
|
|
CB_Species.SelectedValue = (int)pk.Species;
|
|
CB_HeldItem.SelectedValue = pk.HeldItem;
|
|
CB_Form.SelectedIndex = pk.Form;
|
|
|
|
CB_Nature.SelectedValue = (int)pk.Nature;
|
|
CB_Ball.SelectedValue = (int)pk.Ball;
|
|
|
|
TB_HPIV.Text = pk.IV_HP.ToString();
|
|
TB_ATKIV.Text = pk.IV_ATK.ToString();
|
|
TB_DEFIV.Text = pk.IV_DEF.ToString();
|
|
TB_SPAIV.Text = pk.IV_SPA.ToString();
|
|
TB_SPDIV.Text = pk.IV_SPD.ToString();
|
|
TB_SPEIV.Text = pk.IV_SPE.ToString();
|
|
|
|
TB_HPEV.Text = pk.EV_HP.ToString();
|
|
TB_ATKEV.Text = pk.EV_ATK.ToString();
|
|
TB_DEFEV.Text = pk.EV_DEF.ToString();
|
|
TB_SPAEV.Text = pk.EV_SPA.ToString();
|
|
TB_SPDEV.Text = pk.EV_SPD.ToString();
|
|
TB_SPEEV.Text = pk.EV_SPE.ToString();
|
|
|
|
TB_Friendship.Text = pk.CurrentFriendship.ToString();
|
|
TB_Level.Text = pk.CurrentLevel.ToString();
|
|
|
|
CB_Move1.SelectedValue = (int)pk.Move1;
|
|
CB_Move2.SelectedValue = (int)pk.Move2;
|
|
CB_Move3.SelectedValue = (int)pk.Move3;
|
|
CB_Move4.SelectedValue = (int)pk.Move4;
|
|
CB_PPu1.SelectedIndex = pk.Move1_PPUps;
|
|
CB_PPu2.SelectedIndex = pk.Move2_PPUps;
|
|
CB_PPu3.SelectedIndex = pk.Move3_PPUps;
|
|
CB_PPu4.SelectedIndex = pk.Move4_PPUps;
|
|
|
|
CHK_Shiny.Checked = pk.IsShiny;
|
|
|
|
// Set Ability
|
|
SetAbilityList(pk.Species, pk.Form, pk.AbilityNumber >> 1);
|
|
}
|
|
|
|
#region Editing Index Changing
|
|
private void ChangeIndexBase(object sender, EventArgs e)
|
|
{
|
|
int index = LB_Bases.SelectedIndex;
|
|
if (index < 0 || loading)
|
|
return;
|
|
|
|
var bdata = CurrentBase;
|
|
if (bdata != null)
|
|
SaveCurrent(bdata);
|
|
|
|
ResetLoadNew();
|
|
bdata = CurrentBase = GetSecretBaseReference(index);
|
|
LoadCurrent(bdata);
|
|
}
|
|
|
|
private void ChangeIndexPlacement(object sender, EventArgs e)
|
|
{
|
|
var bdata = CurrentBase;
|
|
if (bdata is null)
|
|
return;
|
|
|
|
SavePlacement(CurrentPlacementIndex);
|
|
var pIndex = (int)NUD_FObject.Value;
|
|
LoadPlacement(bdata.GetPlacement(pIndex), pIndex);
|
|
}
|
|
|
|
private void ChangeIndexPKM(object sender, EventArgs e)
|
|
{
|
|
var bdata = CurrentBase;
|
|
if (bdata is not SecretBase6Other o)
|
|
return;
|
|
|
|
var pk = CurrentPKM;
|
|
if (pk is null || CurrentPKMIndex < 0)
|
|
return;
|
|
|
|
SavePKM(pk);
|
|
o.SetParticipant(CurrentPKMIndex, pk);
|
|
|
|
var index = CurrentPKMIndex = (int)NUD_FPKM.Value;
|
|
pk = o.GetParticipant(index);
|
|
LoadPKM(pk);
|
|
}
|
|
#endregion
|
|
|
|
#region PKM
|
|
private void SetAbilityList()
|
|
{
|
|
var species = (ushort)WinFormsUtil.GetIndex(CB_Species);
|
|
var form = (byte)CB_Form.SelectedIndex;
|
|
var index = CB_Ability.SelectedIndex;
|
|
SetAbilityList(species, form, index);
|
|
}
|
|
|
|
private void SetAbilityList(ushort species, byte form, int abilityIndex)
|
|
{
|
|
var abilities = PersonalTable.AO.GetFormEntry(species, form);
|
|
var list = GameInfo.FilteredSources.GetAbilityList(abilities);
|
|
CB_Ability.DataSource = new BindingSource(list, string.Empty);
|
|
CB_Ability.SelectedIndex = abilityIndex < 3 ? abilityIndex : 0;
|
|
}
|
|
|
|
private void SetForms()
|
|
{
|
|
var species = (ushort)WinFormsUtil.GetIndex(CB_Species);
|
|
bool hasForms = FormInfo.HasFormSelection(PersonalTable.AO[species], species, 6);
|
|
CB_Form.Enabled = CB_Form.Visible = hasForms;
|
|
|
|
var list = FormConverter.GetFormList(species, GameInfo.Strings.types, GameInfo.Strings.forms, Main.GenderSymbols, SAV.Context);
|
|
CB_Form.DataSource = new BindingSource(list, string.Empty);
|
|
}
|
|
|
|
private void UpdateSpecies(object sender, EventArgs e)
|
|
{
|
|
// Get Forms for Given Species
|
|
SetForms();
|
|
|
|
var species = WinFormsUtil.GetIndex(CB_Species);
|
|
|
|
// Set a sane gender
|
|
var pi = SAV.Personal[species];
|
|
var gender = pi.IsDualGender
|
|
? EntityGender.GetFromString(Label_Gender.Text)
|
|
: pi.FixedGender();
|
|
SetGenderLabel(gender);
|
|
|
|
SetAbilityList();
|
|
}
|
|
|
|
private void UpdateForm(object sender, EventArgs e)
|
|
{
|
|
SetAbilityList();
|
|
|
|
// If form has a single gender, account for it.
|
|
if (EntityGender.GetFromString(CB_Form.Text) < 2)
|
|
Label_Gender.Text = Main.GenderSymbols[CB_Form.SelectedIndex];
|
|
}
|
|
|
|
private void Label_Gender_Click(object sender, EventArgs e)
|
|
{
|
|
var species = WinFormsUtil.GetIndex(CB_Species);
|
|
var pi = SAV.Personal[species];
|
|
byte gender;
|
|
if (pi.IsDualGender) // dual gender
|
|
gender = (byte)((EntityGender.GetFromString(Label_Gender.Text) ^ 1) & 1);
|
|
else
|
|
gender = pi.FixedGender();
|
|
Label_Gender.Text = Main.GenderSymbols[gender];
|
|
}
|
|
|
|
private void SetGenderLabel(byte gender)
|
|
{
|
|
var symbols = Main.GenderSymbols;
|
|
if ((uint)gender >= symbols.Count)
|
|
gender = 0;
|
|
Label_Gender.Text = symbols[gender];
|
|
}
|
|
#endregion
|
|
|
|
#region I/O
|
|
private void B_Import_Click(object sender, EventArgs e)
|
|
{
|
|
using var ofd = new OpenFileDialog();
|
|
if (ofd.ShowDialog() != DialogResult.OK)
|
|
return;
|
|
|
|
var path = ofd.FileName;
|
|
if (new FileInfo(path).Length is not (SecretBase6.SIZE or SecretBase6Other.SIZE))
|
|
return;
|
|
|
|
var data = File.ReadAllBytes(path);
|
|
var obj = SecretBase6.Read(data);
|
|
// shouldn't happen, we already size-check above.
|
|
ArgumentNullException.ThrowIfNull(obj);
|
|
|
|
var sb = CurrentBase;
|
|
ArgumentNullException.ThrowIfNull(sb);
|
|
|
|
ResetLoadNew();
|
|
sb.Load(obj);
|
|
ReloadSecretBaseList();
|
|
LoadCurrent(sb);
|
|
System.Media.SystemSounds.Asterisk.Play();
|
|
}
|
|
|
|
private void B_Export_Click(object sender, EventArgs e)
|
|
{
|
|
var sb = CurrentBase;
|
|
ArgumentNullException.ThrowIfNull(sb);
|
|
|
|
SaveCurrent(sb);
|
|
var tr = sb.TrainerName;
|
|
if (string.IsNullOrWhiteSpace(tr))
|
|
tr = "Trainer";
|
|
using var sfd = new SaveFileDialog();
|
|
sfd.Filter = "Secret Base Data|*.sb6";
|
|
sfd.FileName = $"{sb.BaseLocation:D2} - {Util.CleanFileName(tr)}.sb6";
|
|
if (sfd.ShowDialog() != DialogResult.OK)
|
|
return;
|
|
|
|
var path = sfd.FileName;
|
|
var data = sb.Write();
|
|
File.WriteAllBytes(path, data);
|
|
}
|
|
#endregion
|
|
|
|
#region Meta Buttons
|
|
private void B_FDelete_Click(object sender, EventArgs e)
|
|
{
|
|
if (LB_Bases.SelectedIndex < 1)
|
|
{
|
|
WinFormsUtil.Alert(MsgSecretBaseDeleteSelf);
|
|
return;
|
|
}
|
|
|
|
int index = LB_Bases.SelectedIndex - 1;
|
|
var bdata = CurrentBase;
|
|
ArgumentNullException.ThrowIfNull(bdata);
|
|
|
|
string BaseTrainer = bdata.TrainerName;
|
|
if (string.IsNullOrEmpty(BaseTrainer))
|
|
BaseTrainer = "Empty";
|
|
|
|
var dr = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, string.Format(MsgSecretBaseDeleteConfirm, BaseTrainer, index));
|
|
if (dr != DialogResult.Yes)
|
|
return;
|
|
|
|
SAV.Blocks.SecretBase.DeleteOther(index);
|
|
ReloadSecretBaseList();
|
|
ResetLoadNew();
|
|
bdata = CurrentBase = GetSecretBaseReference(index + 1);
|
|
LoadCurrent(bdata);
|
|
LB_Bases.SelectedIndex = index + 1;
|
|
}
|
|
|
|
private void B_GiveDecor_Click(object sender, EventArgs e) => SAV.Blocks.SecretBase.GiveAllGoods();
|
|
private void B_Cancel_Click(object sender, EventArgs e) => Close();
|
|
|
|
private void B_Save_Click(object sender, EventArgs e)
|
|
{
|
|
uint flags = (uint)NUD_CapturedRecord.Value;
|
|
SAV.Records.SetRecord(080, (int)flags);
|
|
|
|
var bdata = CurrentBase;
|
|
if (bdata != null)
|
|
SaveCurrent(bdata);
|
|
|
|
Origin.CopyChangesFrom(SAV);
|
|
Close();
|
|
}
|
|
#endregion
|
|
}
|