void ResizeTrainers(int newCount) { // repoint the trainer table // original information var originalOffset = romInfo.GetInt32("trainers", "Data", 16); var originalSize = trainerCount * 40; var newOffset = -1; var newSize = newCount * 40; var buffer = new int[newCount]; // copy old table for moving rom.Seek(originalOffset); for (int i = 0; i < Math.Min(trainerCount, newCount); i++) { buffer[i] = rom.ReadPointer(); } // overwrite old table with free space rom.Seek(originalOffset); for (int i = 0; i < trainerCount; i++) { rom.WriteUInt32(0xFFFFFFFFu); } // find space for the new table if (newCount > trainerCount) { if (repointAutomaticallyToolStripMenuItem.Checked) { newOffset = rom.Find(0xFF, newSize, 0x720000); } else { using (var fs = new FreeSpaceDialog(rom, newSize, lastSearch)) { fs.Text = "Repoint Trainer Table"; if (fs.ShowDialog() == DialogResult.OK) { newOffset = fs.Offset; lastSearch = fs.SearchStart; } } } } else { newOffset = originalOffset; } if (newOffset == -1) { MessageBox.Show("Unable to resize trainer table!\nAborted.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // write new table rom.Seek(newOffset); for (int i = 0; i < newCount; i++) { rom.WritePointer(buffer[i]); } // TODO: trainers with an offset of 0 result in error, allow for 'blank' trainer // find and replace all pointers to table // update ini }
void SaveTrainer() { // repoint party if (trainer.RequiresRepoint) { int newOffset = -1; // find freespace if (repointAutomaticallyToolStripMenuItem.Checked) { newOffset = rom.Find(0xFF, trainer.PartySize, 0x720000); } else { using (var fs = new FreeSpaceDialog(rom, trainer.PartySize, lastSearch)) { fs.Text = "Repoint Party"; if (fs.ShowDialog() == DialogResult.OK) { newOffset = fs.Offset; lastSearch = fs.SearchStart; } } } if (newOffset == -1) { MessageBox.Show("Unable to repoint party!\nIt was not saved.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } // overwrite old party with freespace if (cleanRepointedTrainersToolStripMenuItem.Checked) { rom.Seek(trainer.PartyOffset); for (int i = 0; i < trainer.OriginalPartySize; i++) { rom.WriteByte(0xFF); } } // set new offset for party trainer.PartyOffset = newOffset; } //rom.Seek(romInfo.GetInt32("trainers", "Data", 16) + trainer.Index * 40); rom.Seek(romInfo.GetInt32("trainers", "Data", 16)); rom.ReadPointerAndSeek(); rom.Skip(trainer.Index * 40); // write trainer data rom.WriteByte((byte)((trainer.HasCustomAttacks ? 1 : 0) + (trainer.HasHeldItems ? 2 : 0))); rom.WriteByte(trainer.Class); rom.WriteByte((byte)((trainer.Gender << 7) + trainer.Music)); rom.WriteByte(trainer.Sprite); rom.WriteText(trainer.Name, 12, Table.Encoding.English); for (int i = 0; i < 4; i++) { rom.WriteUInt16(trainer.Items[i]); } rom.WriteByte((byte)(trainer.DoubleBattle ? 1 : 0)); rom.Skip(3); rom.WriteUInt32(trainer.AI); rom.WriteByte((byte)trainer.Party.Count); rom.Skip(3); rom.WritePointer(trainer.PartyOffset); if (trainer.Party.Count == 0) { return; } // write party rom.Seek(trainer.PartyOffset); foreach (var p in trainer.Party) { rom.WriteUInt16(p.EVs); rom.WriteUInt16(p.Level); rom.WriteUInt16(p.Species); if (trainer.HasHeldItems) { rom.WriteUInt16(p.HeldItem); } if (trainer.HasCustomAttacks) { for (int i = 0; i < 4; i++) { rom.WriteUInt16(p.Attacks[i]); } } if (!trainer.HasHeldItems) { rom.WriteUInt16(0); } } // finally, update original party size trainer.OriginalPartySize = trainer.PartySize; }