using System; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace PKHeX { public partial class SAV_HallOfFame : Form { public SAV_HallOfFame() { InitializeComponent(); Util.TranslateInterface(this, Main.curlanguage); Array.Copy(SAV.Data, SAV.HoF, data, 0, data.Length); //Copy HoF section of save into Data Setup(); editor_spec = new object[]{ GB_OT, GB_CurrentMoves, CB_Species, CB_HeldItem, TB_EC, TB_VN, CAL_MetDate, CHK_Nicknamed, CHK_Shiny, L_PartyNum, L_Victory, L_Shiny, L_Level, Label_TID, Label_Form, Label_Gender, Label_HeldItem, Label_OT, Label_TID, Label_SID, Label_Species, TB_Level, NUP_PartyIndex, Label_EncryptionConstant, Label_MetDate, }; LB_DataEntry.SelectedIndex = 0; NUP_PartyIndex_ValueChanged(null, null); try { TB_Nickname.Font = PKX.getPKXFont(11); } catch (Exception e) { Util.Alert("Font loading failed...", e.ToString()); } editing = true; } private bool editing; private readonly SAV6 SAV = new SAV6(Main.SAV.Data); private readonly string[] gendersymbols = Main.gendersymbols; private readonly byte[] data = new byte[0x1B40]; private readonly object[] editor_spec; private void Setup() { CB_Species.Items.Clear(); CB_HeldItem.Items.Clear(); CB_Move1.Items.Clear(); CB_Move2.Items.Clear(); CB_Move3.Items.Clear(); CB_Move4.Items.Clear(); #region Species { CB_Species.DisplayMember = "Text"; CB_Species.ValueMember = "Value"; CB_Species.DataSource = Util.getCBList(Main.specieslist.Skip(1).Take(SAV.MaxSpeciesID).ToArray(), null); } #endregion #region Moves { CB_Move1.DisplayMember = CB_Move2.DisplayMember = CB_Move3.DisplayMember = CB_Move4.DisplayMember = "Text"; CB_Move1.ValueMember = CB_Move2.ValueMember = CB_Move3.ValueMember = CB_Move4.ValueMember = "Value"; CB_Move1.DataSource = new BindingSource(Main.MoveDataSource, null); CB_Move2.DataSource = new BindingSource(Main.MoveDataSource, null); CB_Move3.DataSource = new BindingSource(Main.MoveDataSource, null); CB_Move4.DataSource = new BindingSource(Main.MoveDataSource, null); } #endregion #region Items { CB_HeldItem.DisplayMember = "Text"; CB_HeldItem.ValueMember = "Value"; CB_HeldItem.DataSource = new BindingSource(Main.ItemDataSource, null); } #endregion } private void B_Cancel_Click(object sender, EventArgs e) { Close(); } private void B_Close_Click(object sender, EventArgs e) { Array.Copy(data, 0, Main.SAV.Data, SAV.HoF, data.Length); Main.SAV.Edited = true; Close(); } private void displayEntry(object sender, EventArgs e) { editing = false; RTB.Font = new Font("Courier New", 8); RTB.LanguageOption = RichTextBoxLanguageOptions.DualFont; int index = LB_DataEntry.SelectedIndex; int offset = index * 0x1B4; uint vnd = BitConverter.ToUInt32(data, offset + 0x1B0); uint vn = vnd & 0xFF; TB_VN.Text = vn.ToString("000"); string s = "Entry #" + vn + Environment.NewLine; uint date = vnd >> 14 & 0x1FFFF; uint year = (date & 0xFF) + 2000; uint month = date >> 8 & 0xF; uint day = date >> 12; if (day == 0) { s += "No records in this slot."; foreach (object t in editor_spec) ((Control)t).Enabled = false; editing = false; NUP_PartyIndex_ValueChanged(sender, e); goto end; } foreach (object t in editor_spec) ((Control)t).Enabled = true; s += "Date: " + year + "/" + month + "/" + day + "" + Environment.NewLine + Environment.NewLine; CAL_MetDate.Value = new DateTime((int)year, (int)month, (int)day); int moncount = 0; for (int i = 0; i < 6; i++) { int species = BitConverter.ToUInt16(data, offset + 0x00); int helditem = BitConverter.ToUInt16(data, offset + 0x02); int move1 = BitConverter.ToUInt16(data, offset + 0x04); int move2 = BitConverter.ToUInt16(data, offset + 0x06); int move3 = BitConverter.ToUInt16(data, offset + 0x08); int move4 = BitConverter.ToUInt16(data, offset + 0x0A); int TID = BitConverter.ToUInt16(data, offset + 0x10); int SID = BitConverter.ToUInt16(data, offset + 0x12); uint slgf = BitConverter.ToUInt32(data, offset + 0x14); // uint form = slgf & 0x1F; uint gender = slgf >> 5 & 3; // 0 M; 1 F; 2 G uint level = slgf >> 7 & 0x7F; uint shiny = slgf >> 14 & 0x1; // uint unkn = slgf >> 15; string nickname = Util.TrimFromZero(Encoding.Unicode.GetString(data, offset + 0x18, 22)); string OTname = Util.TrimFromZero(Encoding.Unicode.GetString(data, offset + 0x30, 22)); if (species == 0) continue; moncount++; string genderstr=gendersymbols[gender]; string shinystr = shiny == 1 ? "Yes" : "No"; s += "Name: " + nickname; s += " (" + Main.specieslist[species] + " - " + genderstr + ")" + Environment.NewLine; s += "Level: " + level + Environment.NewLine; s += "Shiny: " + shinystr + Environment.NewLine; s += "Held Item: " + Main.itemlist[helditem] + Environment.NewLine; s += "Move 1: " + Main.movelist[move1] + Environment.NewLine; s += "Move 2: " + Main.movelist[move2] + Environment.NewLine; s += "Move 3: " + Main.movelist[move3] + Environment.NewLine; s += "Move 4: " + Main.movelist[move4] + Environment.NewLine; s += "OT: " + OTname + " (" + TID + "/" + SID + ")" + Environment.NewLine; s += Environment.NewLine; offset += 0x48; } if (sender != null) { NUP_PartyIndex.Maximum = moncount == 0 ? 1 : moncount; NUP_PartyIndex.Value = 1; NUP_PartyIndex_ValueChanged(sender, e); } else editing = true; end: RTB.Text = s; RTB.Font = new Font("Courier New", 8); } private void NUP_PartyIndex_ValueChanged(object sender, EventArgs e) { editing = false; int index = LB_DataEntry.SelectedIndex; int offset = index * 0x1B4 + (Convert.ToInt32(NUP_PartyIndex.Value)-1) * 0x48; if (offset < 0) return; int species = BitConverter.ToUInt16(data, offset + 0x00); CB_Species.SelectedValue = species; int item = BitConverter.ToUInt16(data, offset + 0x02); CB_HeldItem.SelectedValue = item; int move1 = BitConverter.ToUInt16(data, offset + 0x04); int move2 = BitConverter.ToUInt16(data, offset + 0x06); int move3 = BitConverter.ToUInt16(data, offset + 0x08); int move4 = BitConverter.ToUInt16(data, offset + 0x0A); CB_Move1.SelectedValue = move1; CB_Move2.SelectedValue = move2; CB_Move3.SelectedValue = move3; CB_Move4.SelectedValue = move4; uint EC = BitConverter.ToUInt32(data, offset + 0xC); TB_EC.Text = EC.ToString("X8"); TB_TID.Text = BitConverter.ToUInt16(data, offset + 0x10).ToString("00000"); TB_SID.Text = BitConverter.ToUInt16(data, offset + 0x12).ToString("00000"); TB_Nickname.Text = Util.TrimFromZero(Encoding.Unicode.GetString(data, offset + 0x18, 22)); TB_OT.Text = Util.TrimFromZero(Encoding.Unicode.GetString(data, offset + 0x30, 22)); uint slgf = BitConverter.ToUInt32(data, offset + 0x14); uint form = slgf & 0x1F; uint gender = slgf >> 5 & 3; // 0 M; 1 F; 2 G uint level = slgf >> 7 & 0x7F; uint shiny = slgf >> 14 & 0x1; uint nick = BitConverter.ToUInt16(data,offset+0x16); CHK_Shiny.Checked = shiny == 1; TB_Level.Text = level.ToString("000"); CHK_Nicknamed.Checked = nick == 1; setForms(); CB_Form.SelectedIndex = (int)form; setGenderLabel((int)gender); updateNickname(sender, e); bpkx.Image = PKX.getSprite(species, (int)form, (int)gender, item, false, shiny == 1); editing = true; } private void Write_Entry(object sender, EventArgs e) { if (!editing) return; //Don't do writing until loaded Validate_TextBoxes(); byte[] StringBuffer = new byte[22]; //Mimic in-game behavior of not clearing strings. It's awful, but accuracy > good. string[] text_writes = new string[6 * 2]; //2 strings per mon, 6 mons int index = LB_DataEntry.SelectedIndex; int offset = index * 0x1B4; for (int i = 0; i < text_writes.Length; i++) { string nickname = Util.TrimFromZero(Encoding.Unicode.GetString(data, offset + 0x18, 22)); string OTname = Util.TrimFromZero(Encoding.Unicode.GetString(data, offset + 0x30, 22)); text_writes[i] = nickname; i++; text_writes[i] = OTname; offset += 0x48; } int partymember = Convert.ToInt32(NUP_PartyIndex.Value) - 1; text_writes[partymember * 2] = TB_Nickname.Text; text_writes[partymember * 2 + 1] = TB_OT.Text; offset = index * 0x1B4 + partymember * 0x48; Array.Copy(BitConverter.GetBytes(Convert.ToUInt16(CB_Species.SelectedValue)), 0, data, offset + 0x00, 2); Array.Copy(BitConverter.GetBytes(Convert.ToUInt16(CB_HeldItem.SelectedValue)), 0, data, offset + 0x02, 2); Array.Copy(BitConverter.GetBytes(Convert.ToUInt16(CB_Move1.SelectedValue)), 0, data, offset + 0x04, 2); Array.Copy(BitConverter.GetBytes(Convert.ToUInt16(CB_Move2.SelectedValue)), 0, data, offset + 0x06, 2); Array.Copy(BitConverter.GetBytes(Convert.ToUInt16(CB_Move3.SelectedValue)), 0, data, offset + 0x08, 2); Array.Copy(BitConverter.GetBytes(Convert.ToUInt16(CB_Move4.SelectedValue)), 0, data, offset + 0x0A, 2); Array.Copy(BitConverter.GetBytes(Convert.ToUInt32(TB_EC.Text,16)), 0, data, offset + 0x0C, 4); Array.Copy(BitConverter.GetBytes(Convert.ToUInt16(TB_TID.Text)), 0, data, offset + 0x010, 2); Array.Copy(BitConverter.GetBytes(Convert.ToUInt16(TB_SID.Text)), 0, data, offset + 0x012, 2); #region Write Strings { int ofs = index * 0x1B4; for (int i = 0; i < 6; i++) { Array.Copy(Encoding.Unicode.GetBytes(text_writes[i * 2]), StringBuffer, text_writes[i*2].Length*2); int pos = text_writes[i * 2].Length * 2; if (pos 721) TB_Nickname.Text = ""; else { // get language string l = Main.curlanguage; TB_Nickname.Text = Util.getStringList("species", l)[species]; } } TB_Nickname.ReadOnly = !CHK_Nicknamed.Checked; Write_Entry(null, null); } private void setForms() { int species = Util.getIndex(CB_Species); bool hasForms = Legal.PersonalAO[species].HasFormes || new[] { 664, 665, 414 }.Contains(species); CB_Form.Enabled = CB_Form.Visible = hasForms; CB_Form.DisplayMember = "Text"; CB_Form.ValueMember = "Value"; CB_Form.DataSource = PKX.getFormList(species, Main.types, Main.forms, Main.gendersymbols).ToList(); } private void updateSpecies(object sender, EventArgs e) { setForms(); updateNickname(null, null); } private void updateShiny(object sender, EventArgs e) { if (!editing) return; //Don't do writing until loaded bpkx.Image = PKX.getSprite(Util.getIndex(CB_Species), CB_Form.SelectedIndex & 0x1F, PKX.getGender(Label_Gender.Text), Util.getIndex(CB_HeldItem), false, CHK_Shiny.Checked); Write_Entry(null, null); } private void updateGender(object sender, EventArgs e) { // Get Gender Threshold int species = Util.getIndex(CB_Species); int gt = PKX.Personal[species].Gender; if (gt == 255) Label_Gender.Text = gendersymbols[2]; else if (gt == 254) Label_Gender.Text = gendersymbols[1]; else if (gt == 0) Label_Gender.Text = gendersymbols[0]; if (gt == 255 || gt == 0 || gt == 254) // Single gender/genderless abort return; if (gt < 256) // If not a single gender(less) species: { Label_Gender.Text = PKX.getGender(Label_Gender.Text) == 0 ? gendersymbols[1] : gendersymbols[0]; if (PKX.getGender(CB_Form.Text) == 0 && Label_Gender.Text != gendersymbols[0]) CB_Form.SelectedIndex = 1; else if (PKX.getGender(CB_Form.Text) == 1 && Label_Gender.Text != gendersymbols[1]) CB_Form.SelectedIndex = 0; } if (species == 668) CB_Form.SelectedIndex = PKX.getGender(Label_Gender.Text); Write_Entry(null, null); } private void setGenderLabel(int gender) { if (gender == 0) Label_Gender.Text = gendersymbols[0]; // Male else if (gender == 1) Label_Gender.Text = gendersymbols[1]; // Female else Label_Gender.Text = gendersymbols[2]; // Genderless Write_Entry(null, null); } private void B_CopyText_Click(object sender, EventArgs e) { Clipboard.SetText(RTB.Text); } private void B_Delete_Click(object sender, EventArgs e) { if (LB_DataEntry.SelectedIndex < 1) { Util.Alert("Cannot delete your first Hall of Fame Clear entry."); return; } int index = LB_DataEntry.SelectedIndex; if (Util.Prompt(MessageBoxButtons.YesNo, $"Delete Entry {index} from your records?") != DialogResult.Yes) return; int offset = index * 0x1B4; if (index != 15) Array.Copy(data, offset + 0x1B4, data, offset, 0x1B4 * (15 - index)); // Ensure Last Entry is Cleared Array.Copy(new byte[0x1B4], 0, data, 0x1B4 * 15, 0x1B4); displayEntry(LB_DataEntry, null); } private void changeNickname(object sender, MouseEventArgs e) { TextBox tb = !(sender is TextBox) ? TB_Nickname : sender as TextBox; // Special Character Form if (ModifierKeys != Keys.Control) return; if (Application.OpenForms.Cast
().Any(form => form.Name == typeof(f2_Text).Name)) { Util.Alert("Window is already open."); return; } new f2_Text(tb).Show(); } } }