Restructured Trainer names length expansion patch

This commit is contained in:
AdAstra-LD 2023-12-04 03:33:47 +01:00
parent 7383eb8bf6
commit c60d2bfe2c
4 changed files with 110 additions and 90 deletions

View File

@ -8603,6 +8603,8 @@ namespace DSPRE {
}
private void SetupTrainerEditor() {
disableHandlers = true;
SetTrainerNameMaxLen();
SetupTrainerClassEncounterMusicTable();
/* Extract essential NARCs sub-archives*/
statusLabelMessage("Setting up Trainer Editor...");
@ -9020,26 +9022,6 @@ namespace DSPRE {
}
private void trainerSaveCurrentButton_Click(object sender, EventArgs e) {
if (!ROMToolboxDialog.flag_TrainerNamesExpanded && trainerNameTextBox.Text.Length > TrainerFile.maxNameLen) {
DialogResult d2;
MessageBox.Show($"The length of this Trainer name exceeds {TrainerFile.maxNameLen} characters.",
"Trainer data could not be saved!", MessageBoxButtons.OK, MessageBoxIcon.Error);
d2 = MessageBox.Show("Within the RomToolBox (found near the wild editor) you can expand this limit if you are working on an English or Spanish rom (for now).",
"Do you wish to go there now?", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (d2 == DialogResult.Yes) {
romToolBoxToolStripMenuItem_Click(null, null);
}
return;
}
if (trainerNameTextBox.Text.Length > ROMToolboxDialog.expandedTrainerNameLength) {
MessageBox.Show($"The length of this Trainer name exceeds {ROMToolboxDialog.expandedTrainerNameLength} characters.",
"Trainer data could not be saved!", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
currentTrainerFile.trp.partyCount = (byte)partyCountUpDown.Value;
currentTrainerFile.trp.chooseMoves = trainerMovesCheckBox.Checked;
currentTrainerFile.trp.chooseItems = trainerItemsCheckBox.Checked;
@ -9115,7 +9097,20 @@ namespace DSPRE {
UpdateCurrentTrainerName(newName: trainerNameTextBox.Text);
UpdateCurrentTrainerShownName();
MessageBox.Show("Trainer saved successfully!", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
if (trainerNameTextBox.Text.Length > RomInfo.trainerNameMaxLen - 1) { //Subtract 1 to account for special end character.
//Expose a smaller limit to the user
if (RomInfo.trainerNameLenOffset >= 0) {
MessageBox.Show($"Trainer File saved successfully. However:\nYou attempted to save a Trainer whose name exceeds {RomInfo.trainerNameMaxLen-1} characters.\nThis may lead to issues in game." +
(ROMToolboxDialog.flag_TrainerNamesExpanded ? "\n\nIt's recommended that you use a shorter name." : "\n\nRefer to the ROM Toolbox to extend Trainer names."),
"Saved successfully, but...", MessageBoxButtons.OK, MessageBoxIcon.Warning);
} else {
MessageBox.Show($"Trainer File saved successfully. However:\nThe Trainer name length could not be safely determined for this ROM.\n" +
$"You attempted to save a Trainer whose name exceeds {RomInfo.trainerNameMaxLen-1} characters.\nThis will most likely lead to issues in game.",
"Saved successfully, but...", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
} else {
MessageBox.Show("Trainer saved successfully!", "Saved successfully", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void UpdateCurrentTrainerShownName() {

View File

@ -321,7 +321,7 @@ namespace DSPRE.ROMFiles {
}
}
public class TrainerFile : RomFile {
public const int maxNameLen = 7;
public const int defaultNameLen = 7; //Does not include special \0 end character!
public const int POKE_IN_PARTY = 6;
public static readonly string NAME_NOT_FOUND = "NAME READ ERROR";

View File

@ -30,7 +30,7 @@ namespace DSPRE {
public static bool overlay1MustBeRestoredFromBackup { get; private set; } = true;
public static int expandedTrainerNameLength = 12;
public static readonly int expandedTrainerNameLength = 12;
#region Constructor
public ROMToolboxDialog() {
@ -40,14 +40,15 @@ namespace DSPRE {
if (RomInfo.gameLanguage == gLangEnum.English || RomInfo.gameLanguage == gLangEnum.Spanish) {
CheckARM9ExpansionApplied();
CheckExpandedTrainerNamespatchApplied();
} else {
DisableARM9patch("Unsupported\nlanguage");
DisableBDHCamPatch("Unsupported\nlanguage");
DisableScrcmdRepointPatch("Unsupported\nlanguage");
DisableTrainerNameExpansionPatch("Unsuported\nlanguage");
}
CheckExpandedTrainerNamesPatchApplied();
switch (RomInfo.gameFamily) {
case gFamEnum.DP:
DisableOverlay1patch("Unsupported");
@ -316,33 +317,21 @@ namespace DSPRE {
//throw new NotImplementedException();
}
public void CheckExpandedTrainerNamespatchApplied() {
if (!flag_TrainerNamesExpanded) {
uint position = 0x6AC32;
switch (RomInfo.gameFamily) {
case gFamEnum.DP:
if (RomInfo.gameLanguage.Equals(gLangEnum.English)) position = 0x6AC32;
else if (RomInfo.gameLanguage.Equals(gLangEnum.Spanish)) position = 0x6AC8E;
break;
case gFamEnum.Plat:
if (RomInfo.gameLanguage.Equals(gLangEnum.English)) position = 0x791DE;
else if (RomInfo.gameLanguage.Equals(gLangEnum.Spanish)) position = 0x7927E;
break;
case gFamEnum.HGSS:
if (RomInfo.gameLanguage.Equals(gLangEnum.English) || RomInfo.gameVersion.Equals(gVerEnum.SoulSilver)) position = 0x7342E;
else if (RomInfo.gameLanguage.Equals(gLangEnum.Spanish)) position = 0x73426;
break;
}
byte initValue = DSUtils.ARM9.ReadByte(position);
if (initValue > (byte)TrainerFile.maxNameLen) {
DisableTrainerNameExpansionPatch("Already\nApplied");
ROMToolboxDialog.flag_TrainerNamesExpanded = true;
ROMToolboxDialog.expandedTrainerNameLength = initValue;
}
} else {
public void CheckExpandedTrainerNamesPatchApplied() {
if (flag_TrainerNamesExpanded) {
DisableTrainerNameExpansionPatch("Already\nApplied");
}
} else {
if (RomInfo.trainerNameLenOffset < 0 ) {
DisableTrainerNameExpansionPatch("Unsupported");
} else {
int v = RomInfo.SetTrainerNameMaxLen();
if (v > TrainerFile.defaultNameLen+1) {
DisableTrainerNameExpansionPatch("Already\nApplied");
ROMToolboxDialog.flag_TrainerNamesExpanded = true;
}
}
}
}
#endregion
@ -832,46 +821,24 @@ namespace DSPRE {
// HeartGold Spain ARM9 at 0x73426
// SoulSilver USA ARM9 at 0x7342E
// SoulSilver Spain ARM9 at 0x7342E // TODO: Verify
DialogResult d;
int position = 0x7342E;
bool gameFamGood = true;
d = MessageBox.Show($"Applying this patch will set the Trainer Name max length to {ROMToolboxDialog.expandedTrainerNameLength}.\n" +
"Please note that if you have modified the ARM9 these offsets may be wrong.\n" +
"If you have done so we encourage you to seek in your ARM9 for where to make the modification as your offset might change.\n\n" +
DialogResult d = MessageBox.Show($"Applying this patch will set the Trainer Name max length to {ROMToolboxDialog.expandedTrainerNameLength-1} usable characters.\n" +
"Are you sure you want to proceed?",
"Confirm to proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (d == DialogResult.Yes) {
switch (RomInfo.gameFamily) {
case gFamEnum.DP:
if (RomInfo.gameLanguage.Equals(gLangEnum.English)) position = 0x6AC32;
else if (RomInfo.gameLanguage.Equals(gLangEnum.Spanish)) position = 0x6AC8E;
else gameFamGood = false;
break;
case gFamEnum.Plat:
if (RomInfo.gameLanguage.Equals(gLangEnum.English)) position = 0x791DE;
else if (RomInfo.gameLanguage.Equals(gLangEnum.Spanish)) position = 0x7927E;
else gameFamGood = false;
break;
case gFamEnum.HGSS:
if (RomInfo.gameLanguage.Equals(gLangEnum.English) || RomInfo.gameVersion.Equals(gVerEnum.SoulSilver)) position = 0x7342E;
else if (RomInfo.gameLanguage.Equals(gLangEnum.Spanish)) position = 0x73426;
else gameFamGood = false;
break;
}
if (gameFamGood) {
using (DSUtils.ARM9.Writer wr = new DSUtils.ARM9.Writer()) {
wr.BaseStream.Position = position;
try {
using (DSUtils.ARM9.Writer wr = new DSUtils.ARM9.Writer(RomInfo.trainerNameLenOffset)) {
wr.Write((byte)ROMToolboxDialog.expandedTrainerNameLength);
}
ROMToolboxDialog.flag_TrainerNamesExpanded = true;
DisableTrainerNameExpansionPatch("Already applied");
expandTrainerNamesCB.Visible = true;
MessageBox.Show("Trainer Names have been expanded.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information);
} else {
MessageBox.Show("Sorry this game language does not have a recorded offset for this patch.\n\n" +
"Reach out in our discord if you want to help researching it!",
"Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information);
RomInfo.SetTrainerNameMaxLen();
MessageBox.Show("Trainer Names have been extended.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information);
} catch (IOException) {
MessageBox.Show("ARM9 could not be written.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
} else {
MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information);

View File

@ -65,6 +65,8 @@ namespace DSPRE {
public static int trainerClassMessageNumber { get; private set; }
public static int trainerNamesMessageNumber { get; private set; }
public static int locationNamesTextNumber { get; private set; }
public static int trainerNameLenOffset { get; private set; }
public static int trainerNameMaxLen { get; private set; }
public static string internalNamesLocation { get; private set; }
public static readonly byte internalNameLength = 16;
@ -183,6 +185,7 @@ namespace DSPRE {
SetLocationNamesTextNumber();
SetTrainerNamesMessageNumber();
SetTrainerClassMessageNumber();
SetTrainerNameLenOffset();
/* System */
ScriptCommandParametersDict = BuildCommandParametersDatabase(gameFamily);
@ -742,7 +745,7 @@ namespace DSPRE {
}
}
private void SetItemScriptFileNumber() {
private static void SetItemScriptFileNumber() {
switch (gameFamily) {
case gFamEnum.DP:
itemScriptFileNumber = 370;
@ -755,7 +758,7 @@ namespace DSPRE {
break;
}
}
private void SetNullEncounterID() {
private static void SetNullEncounterID() {
switch (gameFamily) {
case gFamEnum.DP:
case gFamEnum.Plat:
@ -767,7 +770,7 @@ namespace DSPRE {
}
}
private void SetAbilityNamesTextNumber() {
private static void SetAbilityNamesTextNumber() {
switch (gameFamily) {
case gFamEnum.DP:
abilityNamesTextNumber = 552;
@ -783,7 +786,7 @@ namespace DSPRE {
}
}
private void SetAttackNamesTextNumber() {
private static void SetAttackNamesTextNumber() {
switch (gameFamily) {
case gFamEnum.DP:
attackNamesTextNumber = 588;
@ -796,7 +799,7 @@ namespace DSPRE {
break;
}
}
private void SetItemNamesTextNumber() {
private static void SetItemNamesTextNumber() {
switch (gameFamily) {
case gFamEnum.DP:
itemNamesTextNumber = 344;
@ -809,7 +812,7 @@ namespace DSPRE {
break;
}
}
private void SetLocationNamesTextNumber() {
private static void SetLocationNamesTextNumber() {
switch (gameFamily) {
case gFamEnum.DP:
locationNamesTextNumber = 382;
@ -822,7 +825,7 @@ namespace DSPRE {
break;
}
}
private void SetPokemonNamesTextNumber() {
private static void SetPokemonNamesTextNumber() {
switch (gameFamily) {
case gFamEnum.DP:
pokemonNamesTextNumbers = new int[2] { 362, 363 };
@ -835,7 +838,7 @@ namespace DSPRE {
break;
}
}
private void SetTrainerNamesMessageNumber() {
private static void SetTrainerNamesMessageNumber() {
switch (gameFamily) {
case gFamEnum.DP:
trainerNamesMessageNumber = 559;
@ -854,7 +857,7 @@ namespace DSPRE {
break;
}
}
private void SetTrainerClassMessageNumber() {
private static void SetTrainerClassMessageNumber() {
switch (gameFamily) {
case gFamEnum.DP:
trainerClassMessageNumber = 560;
@ -874,6 +877,61 @@ namespace DSPRE {
}
}
private static void SetTrainerNameLenOffset() {
switch (RomInfo.gameFamily) {
case gFamEnum.DP:
switch (RomInfo.gameLanguage) {
case gLangEnum.English:
trainerNameLenOffset = 0x6AC32;
break;
case gLangEnum.Spanish:
trainerNameLenOffset = 0x6AC8E;
break;
default:
trainerNameLenOffset = -1;
break;
}
break;
case gFamEnum.Plat:
switch (RomInfo.gameLanguage) {
case gLangEnum.English:
trainerNameLenOffset = 0x791DE;
break;
case gLangEnum.Spanish:
case gLangEnum.German:
trainerNameLenOffset = 0x7927E;
break;
default:
trainerNameLenOffset = -1;
break;
}
break;
case gFamEnum.HGSS:
if (RomInfo.gameLanguage.Equals(gLangEnum.English) || RomInfo.gameVersion.Equals(gVerEnum.SoulSilver)) {
trainerNameLenOffset = 0x7342E;
} else if (RomInfo.gameLanguage.Equals(gLangEnum.Spanish)) {
trainerNameLenOffset = 0x73426;
} else {
trainerNameLenOffset = -1;
}
break;
}
}
public static int SetTrainerNameMaxLen() {
if(trainerNameLenOffset < 0) {
trainerNameMaxLen = TrainerFile.defaultNameLen;
} else {
using (DSUtils.ARM9.Reader ar = new DSUtils.ARM9.Reader(trainerNameLenOffset)) {
trainerNameMaxLen = ar.ReadByte();
}
}
return trainerNameMaxLen;
}
public string GetBuildingModelsDirPath(bool interior) => interior ? gameDirs[DirNames.interiorBuildingModels].unpackedDir : gameDirs[DirNames.exteriorBuildingModels].unpackedDir;
public string GetRomNameFromWorkdir() => workDir.Substring(0, workDir.Length - folderSuffix.Length - 1);
public static int GetHeaderCount() => (int)new FileInfo(internalNamesLocation).Length / internalNameLength;