diff options
author | tom-overton <tom.overton@outlook.com> | 2021-11-30 21:58:57 -0800 |
---|---|---|
committer | tom-overton <tom.overton@outlook.com> | 2021-11-30 21:59:03 -0800 |
commit | 8de76ba96b838f64600aa3ffb826c0aad1078fa2 (patch) | |
tree | dd4fb1f4420f17e45c2cbdb0d6938cc1ba140e8f /src | |
parent | 092413713ebf9e86431339e440d16310179abaff (diff) |
XY: Add support for randomizing the roamer while they roam
We already supported randomizing the roamer when they come to rest
at the Sea Spirit's Den, but while they were roaming, they were still
Articuno/Zapdos/Moltres. This allows the randomizer to patch the
executable such that the roamer is the same both when it roams and
when it comes to rest.
Diffstat (limited to 'src')
-rw-r--r-- | src/com/dabomstew/pkrandom/config/gen6_offsets.ini | 1 | ||||
-rw-r--r-- | src/com/dabomstew/pkrandom/constants/Gen6Constants.java | 5 | ||||
-rw-r--r-- | src/com/dabomstew/pkrandom/romhandlers/Gen6RomHandler.java | 64 |
3 files changed, 69 insertions, 1 deletions
diff --git a/src/com/dabomstew/pkrandom/config/gen6_offsets.ini b/src/com/dabomstew/pkrandom/config/gen6_offsets.ini index 4222a7c..5943ffc 100644 --- a/src/com/dabomstew/pkrandom/config/gen6_offsets.ini +++ b/src/com/dabomstew/pkrandom/config/gen6_offsets.ini @@ -65,6 +65,7 @@ BoxLegendaryOffsets=[2, 12] BoxLegendaryScriptOffsets=[4658, 5430, 16798] LinkedStaticEncounterOffsets=[1:3, 2:12] MainGameLegendaries=[716] +RoamingLegendaryOffsets=[6, 7, 8] [Y] Game=CTR-P-EK2A diff --git a/src/com/dabomstew/pkrandom/constants/Gen6Constants.java b/src/com/dabomstew/pkrandom/constants/Gen6Constants.java index c858111..445fdee 100644 --- a/src/com/dabomstew/pkrandom/constants/Gen6Constants.java +++ b/src/com/dabomstew/pkrandom/constants/Gen6Constants.java @@ -239,13 +239,16 @@ public class Gen6Constants { public static final int[] boxLegendaryCodeOffsetsXY = new int[]{ 144, 300, 584 }; public static final String rayquazaFunctionPrefixORAS = "0900A0E1F08FBDE8"; public static final int[] rayquazaScriptOffsetsORAS = new int[]{ 3334, 14734 }, rayquazaCodeOffsetsORAS = new int[]{ 136, 292, 576 }; - public static final String nationalDexFunctionLocator = "080094E5010000E21080BDE8170F122F",xyGetDexFlagFunctionLocator = "000055E30100A0030A00000A", + public static final String nationalDexFunctionLocator = "080094E5010000E21080BDE8170F122F", xyGetDexFlagFunctionLocator = "000055E30100A0030A00000A", orasGetHoennDexCaughtFunctionPrefix = "170F122F1CC15800"; public static final int megastoneTableStartingOffsetORAS = 0xABA, megastoneTableEntrySizeORAS = 0x20, megastoneTableLengthORAS = 27; public static final String pickupTableLocator = "110012001A00"; public static final int numberOfPickupItems = 29; + public static final String xyRoamerFreeSpacePostfix = "540095E50220A0E30810A0E1", xyRoamerSpeciesLocator = "9040A0030400000A", + xyRoamerLevelPrefix = "B020DDE13F3BC1E3"; + public static final List<Integer> consumableHeldItems = setupAllConsumableItems(); private static List<Integer> setupAllConsumableItems() { diff --git a/src/com/dabomstew/pkrandom/romhandlers/Gen6RomHandler.java b/src/com/dabomstew/pkrandom/romhandlers/Gen6RomHandler.java index 6aa4fd4..7d9d3af 100644 --- a/src/com/dabomstew/pkrandom/romhandlers/Gen6RomHandler.java +++ b/src/com/dabomstew/pkrandom/romhandlers/Gen6RomHandler.java @@ -2113,6 +2113,7 @@ public class Gen6RomHandler extends Abstract3DSRomHandler { int[] boxLegendaryOffsets = romEntry.arrayEntries.get("BoxLegendaryOffsets"); StaticEncounter boxLegendaryEncounter = staticPokemon.get(boxLegendaryOffsets[0]); fixBoxLegendariesXY(boxLegendaryEncounter.pkmn.number); + setRoamersXY(staticPokemon); } else { StaticEncounter rayquazaEncounter = staticPokemon.get(romEntry.getInt("RayquazaEncounterNumber")); fixRayquazaORAS(rayquazaEncounter.pkmn.number); @@ -2187,6 +2188,69 @@ public class Gen6RomHandler extends Abstract3DSRomHandler { writeFile(romEntry.getString("StaticPokemon"), staticCRO); } + private void setRoamersXY(List<StaticEncounter> staticPokemon) throws IOException { + int[] roamingLegendaryOffsets = romEntry.arrayEntries.get("RoamingLegendaryOffsets"); + StaticEncounter[] roamers = new StaticEncounter[roamingLegendaryOffsets.length]; + for (int i = 0; i < roamers.length; i++) { + roamers[i] = staticPokemon.get(roamingLegendaryOffsets[i]); + } + int roamerSpeciesOffset = find(code, Gen6Constants.xyRoamerSpeciesLocator); + int freeSpaceOffset = find(code, Gen6Constants.xyRoamerFreeSpacePostfix); + if (roamerSpeciesOffset > 0 && freeSpaceOffset > 0) { + // In order to make this code work with all versions of XY, we had to find the *end* of our free space. + // The beginning is five instructions back. + freeSpaceOffset -= 20; + + // The unmodified code looks like this: + // nop + // bl FUN_0041b710 + // nop + // nop + // b LAB_003b7d1c + // We want to move both branches to the top so that we have 12 bytes of space to work with. + // Start by moving "bl FUN_0041b710" up one instruction, making sure to adjust the branch accordingly. + code[freeSpaceOffset] = (byte)(code[freeSpaceOffset + 4] + 1); + code[freeSpaceOffset + 1] = code[freeSpaceOffset + 5]; + code[freeSpaceOffset + 2] = code[freeSpaceOffset + 6]; + code[freeSpaceOffset + 3] = code[freeSpaceOffset + 7]; + + // Now move "b LAB_003b7d1c" up three instructions, again adjusting the branch accordingly. + code[freeSpaceOffset + 4] = (byte)(code[freeSpaceOffset + 16] + 3); + code[freeSpaceOffset + 5] = code[freeSpaceOffset + 17]; + code[freeSpaceOffset + 6] = code[freeSpaceOffset + 18]; + code[freeSpaceOffset + 7] = code[freeSpaceOffset + 19]; + + // In the free space now opened up, write the three roamer species. + for (int i = 0; i < roamers.length; i++) { + int offset = freeSpaceOffset + 8 + (i * 4); + int species = roamers[i].pkmn.getBaseNumber(); + FileFunctions.writeFullIntLittleEndian(code, offset, species); + } + + // To load the species ID, the game currently does "moveq r4, #0x90" for Articuno and similar + // things for Zapdos and Moltres. Instead, just pc-relative load what we wrote before. The fact + // that we change the conditional moveq to the unconditional pc-relative load only matters for + // the case where the player's starter index is *not* 0, 1, or 2, but that can't happen outside + // of save editing. + for (int i = 0; i < roamers.length; i++) { + int offset = roamerSpeciesOffset + (i * 12); + code[offset] = (byte)(0xAC - (8 * i)); + code[offset + 1] = 0x41; + code[offset + 2] = (byte) 0x9F; + code[offset + 3] = (byte) 0xE5; + } + } + + // The level of the roamer is set by a separate function in DllField. + byte[] fieldCRO = readFile(romEntry.getString("Field")); + int levelOffset = find(fieldCRO, Gen6Constants.xyRoamerLevelPrefix); + if (levelOffset > 0) { + levelOffset += Gen6Constants.xyRoamerLevelPrefix.length() / 2; // because it was a prefix + fieldCRO[levelOffset] = (byte) roamers[0].level; + } + writeFile(romEntry.getString("Field"), fieldCRO); + } + private void fixRayquazaORAS(int rayquazaEncounterSpecies) throws IOException { // We need to edit the script file or otherwise the text will still say "Rayquaza" int rayquazaScriptFile = romEntry.getInt("RayquazaEncounterScriptNumber"); |