diff options
author | Rafael Marçalo <public@rafaelmarcalo.xyz> | 2024-09-05 16:31:33 +0100 |
---|---|---|
committer | Rafael Marçalo <public@rafaelmarcalo.xyz> | 2024-09-05 16:31:33 +0100 |
commit | 8b67572ad7e1508341345dc46a2597e9fa170cbb (patch) | |
tree | 8f37c4d60ce0f07b9eaf30be34f39298da97b242 /src/com/pkrandom/constants/Gen4Constants.java | |
parent | b65f4a80da28e7ec4de16c8b1abf906e8d7be2c5 (diff) |
Diffstat (limited to 'src/com/pkrandom/constants/Gen4Constants.java')
-rw-r--r-- | src/com/pkrandom/constants/Gen4Constants.java | 2107 |
1 files changed, 2107 insertions, 0 deletions
diff --git a/src/com/pkrandom/constants/Gen4Constants.java b/src/com/pkrandom/constants/Gen4Constants.java new file mode 100644 index 0000000..91c5ff2 --- /dev/null +++ b/src/com/pkrandom/constants/Gen4Constants.java @@ -0,0 +1,2107 @@ +package com.pkrandom.constants; + +/*----------------------------------------------------------------------------*/ +/*-- Gen4Constants.java - Constants for DPPt and HGSS --*/ +/*-- --*/ +/*-- Part of "Universal Pokemon Randomizer ZX" by the UPR-ZX team --*/ +/*-- Pokemon and any associated names and the like are --*/ +/*-- trademark and (C) Nintendo 1996-2020. --*/ +/*-- --*/ +/*-- The custom code written here is licensed under the terms of the GPL: --*/ +/*-- --*/ +/*-- This program is free software: you can redistribute it and/or modify --*/ +/*-- it under the terms of the GNU General Public License as published by --*/ +/*-- the Free Software Foundation, either version 3 of the License, or --*/ +/*-- (at your option) any later version. --*/ +/*-- --*/ +/*-- This program is distributed in the hope that it will be useful, --*/ +/*-- but WITHOUT ANY WARRANTY; without even the implied warranty of --*/ +/*-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --*/ +/*-- GNU General Public License for more details. --*/ +/*-- --*/ +/*-- You should have received a copy of the GNU General Public License --*/ +/*-- along with this program. If not, see <http://www.gnu.org/licenses/>. --*/ +/*----------------------------------------------------------------------------*/ + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import com.pkrandom.pokemon.*; + +public class Gen4Constants { + + public static final int Type_DP = 0; + public static final int Type_Plat = 1; + public static final int Type_HGSS = 2; + + public static final int arm9Offset = 0x02000000; + + public static final int pokemonCount = 493, moveCount = 467; + private static final int dpFormeCount = 5, platHgSsFormeCount = 12; + public static final int formeOffset = 2; + + public static final int bsHPOffset = 0, bsAttackOffset = 1, bsDefenseOffset = 2, bsSpeedOffset = 3, + bsSpAtkOffset = 4, bsSpDefOffset = 5, bsPrimaryTypeOffset = 6, bsSecondaryTypeOffset = 7, + bsCatchRateOffset = 8, bsCommonHeldItemOffset = 12, bsRareHeldItemOffset = 14, bsGenderRatioOffset = 16, + bsGrowthCurveOffset = 19, bsAbility1Offset = 22, bsAbility2Offset = 23, bsTMHMCompatOffset = 28; + + public static final String starterCriesPrefix = "0004000C10BD0000000000000000000000E000000000000000E0000000000200"; + + public static final byte[] hgssStarterCodeSuffix = { 0x03, 0x03, 0x1A, 0x12, 0x1, 0x23, 0x0, 0x0 }; + + public static final int[] hgssFilesWithRivalScript = { 7, 23, 96, 110, 819, 850, 866 }; + + public static final byte[] hgssRivalScriptMagic = { (byte) 0xCE, 0x00, 0x0C, (byte) 0x80, 0x11, 0x00, 0x0C, + (byte) 0x80, (byte) 152, 0, 0x1C, 0x00, 0x05 }; + + public static final int[] ptFilesWithRivalScript = { 31, 36, 112, 123, 186, 427, 429, 1096 }; + + public static final int[] dpFilesWithRivalScript = { 34, 90, 118, 180, 195, 394 }; + + public static final byte[] dpptRivalScriptMagic = { (byte) 0xDE, 0x00, 0x0C, (byte) 0x80, 0x11, 0x00, 0x0C, + (byte) 0x80, (byte) 0x83, 0x01, 0x1C, 0x00, 0x01 }; + + public static final byte[] dpptTagBattleScriptMagic1 = { (byte) 0xDE, 0x00, 0x0C, (byte) 0x80, 0x28, 0x00, 0x04, + (byte) 0x80 }; + + public static final byte[] dpptTagBattleScriptMagic2 = { 0x11, 0x00, 0x0C, (byte) 0x80, (byte) 0x86, 0x01, 0x1C, + 0x00, 0x01 }; + + public static final int[] ptFilesWithTagScript = { 2, 136, 201, 236 }; + + public static final int[] dpFilesWithTagScript = { 2, 131, 230 }; + + public static final int dpStarterStringIndex = 19, ptStarterStringIndex = 36; + + public static final int fossilCount = 7; + + public static final String dpptTMDataPrefix = "D100D200D300D400", hgssTMDataPrefix = "1E003200"; + + public static final int tmCount = 92, hmCount = 8; + + public static final int tmItemOffset = Items.tm01; + + private static final int dpptTextCharsPerLine = 38, hgssTextCharsPerLine = 36; + + public static final String dpItemPalettesPrefix = "8D018E01210132018D018F0122013301", + pthgssItemPalettesPrefix = "8D018E01210133018D018F0122013401"; + + public static final int ptSpearPillarPortalScriptFile = 237; + + public static final int evolutionMethodCount = 26; + + public static final int highestAbilityIndex = Abilities.badDreams; + + public static final List<Integer> consumableHeldItems = Arrays.asList( + Items.cheriBerry, Items.chestoBerry, Items.pechaBerry, Items.rawstBerry, Items.aspearBerry, + Items.leppaBerry, Items.oranBerry, Items.persimBerry, Items.lumBerry, Items.sitrusBerry, Items.figyBerry, + Items.wikiBerry, Items.magoBerry, Items.aguavBerry, Items.iapapaBerry, Items.occaBerry, Items.passhoBerry, + Items.wacanBerry, Items.rindoBerry, Items.yacheBerry, Items.chopleBerry, Items.kebiaBerry, Items.shucaBerry, + Items.cobaBerry, Items.payapaBerry, Items.tangaBerry, Items.chartiBerry, Items.kasibBerry, Items.habanBerry, + Items.colburBerry, Items.babiriBerry, Items.chilanBerry, Items.liechiBerry, Items.ganlonBerry, + Items.salacBerry, Items.petayaBerry, Items.apicotBerry, Items.lansatBerry, Items.starfBerry, + Items.enigmaBerry, Items.micleBerry, Items.custapBerry, Items.jabocaBerry, Items.rowapBerry, + Items.berryJuice, Items.whiteHerb, Items.mentalHerb, Items.powerHerb, Items.focusSash); + + public static final List<Integer> allHeldItems = setupAllHeldItems(); + + private static List<Integer> setupAllHeldItems() { + List<Integer> list = new ArrayList<>(); + list.addAll(Arrays.asList(Items.brightPowder, Items.quickClaw, Items.choiceBand, Items.kingsRock, + Items.silverPowder, Items.focusBand, Items.scopeLens, Items.metalCoat, Items.leftovers, Items.softSand, + Items.hardStone, Items.miracleSeed, Items.blackGlasses, Items.blackBelt, Items.magnet, + Items.mysticWater, Items.sharpBeak, Items.poisonBarb, Items.neverMeltIce, Items.spellTag, + Items.twistedSpoon, Items.charcoal, Items.dragonFang, Items.silkScarf, Items.shellBell, + Items.seaIncense, Items.laxIncense, Items.wideLens, Items.muscleBand, Items.wiseGlasses, + Items.expertBelt, Items.lightClay, Items.lifeOrb, Items.toxicOrb, Items.flameOrb, Items.zoomLens, + Items.metronome, Items.ironBall, Items.laggingTail, Items.destinyKnot, Items.blackSludge, Items.icyRock, + Items.smoothRock, Items.heatRock, Items.dampRock, Items.gripClaw, Items.choiceScarf, Items.stickyBarb, + Items.shedShell, Items.bigRoot, Items.choiceSpecs, Items.flamePlate, Items.splashPlate, Items.zapPlate, + Items.meadowPlate, Items.iciclePlate, Items.fistPlate, Items.toxicPlate, Items.earthPlate, + Items.skyPlate, Items.mindPlate, Items.insectPlate, Items.stonePlate, Items.spookyPlate, + Items.dracoPlate, Items.dreadPlate, Items.ironPlate, Items.oddIncense, Items.rockIncense, + Items.fullIncense, Items.waveIncense, Items.roseIncense, Items.razorClaw, Items.razorFang)); + list.addAll(consumableHeldItems); + return list; + } + + public static final List<Integer> generalPurposeConsumableItems = Collections.unmodifiableList(Arrays.asList( + Items.cheriBerry, Items.chestoBerry, Items.pechaBerry, Items.rawstBerry, Items.aspearBerry, Items.leppaBerry, + Items.oranBerry, Items.persimBerry, Items.lumBerry, Items.sitrusBerry, Items.ganlonBerry, Items.salacBerry, + // An NPC pokemon's nature is generated randomly with IVs during gameplay. Therefore, we do not include + // the flavor berries because, prior to Gen 7, they aren't worth the risk. + Items.apicotBerry, Items.lansatBerry, Items.starfBerry, Items.enigmaBerry, Items.micleBerry, Items.custapBerry, + Items.jabocaBerry, Items.rowapBerry, Items.berryJuice, Items.whiteHerb, Items.mentalHerb, Items.focusSash)); + + public static final List<Integer> generalPurposeItems = Collections.unmodifiableList(Arrays.asList( + Items.brightPowder, Items.quickClaw, Items.kingsRock, Items.focusBand, Items.scopeLens, Items.leftovers, + Items.shellBell, Items.laxIncense, Items.wideLens, Items.expertBelt, Items.lifeOrb, Items.zoomLens, + Items.destinyKnot, Items.shedShell, Items.razorClaw, Items.razorFang)); + + public static final Map<Type, List<Integer>> typeBoostingItems = initializeTypeBoostingItems(); + + private static Map<Type, List<Integer>> initializeTypeBoostingItems() { + Map<Type, List<Integer>> map = new HashMap<>(); + map.put(Type.BUG, Arrays.asList(Items.silverPowder, Items.insectPlate)); + map.put(Type.DARK, Arrays.asList(Items.blackGlasses, Items.dreadPlate)); + map.put(Type.DRAGON, Arrays.asList(Items.dragonFang, Items.dracoPlate)); + map.put(Type.ELECTRIC, Arrays.asList(Items.magnet, Items.zapPlate)); + map.put(Type.FIGHTING, Arrays.asList(Items.blackBelt, Items.fistPlate)); + map.put(Type.FIRE, Arrays.asList(Items.charcoal, Items.flamePlate)); + map.put(Type.FLYING, Arrays.asList(Items.sharpBeak, Items.skyPlate)); + map.put(Type.GHOST, Arrays.asList(Items.spellTag, Items.spookyPlate)); + map.put(Type.GRASS, Arrays.asList(Items.miracleSeed, Items.meadowPlate, Items.roseIncense)); + map.put(Type.GROUND, Arrays.asList(Items.softSand, Items.earthPlate)); + map.put(Type.ICE, Arrays.asList(Items.neverMeltIce, Items.iciclePlate)); + map.put(Type.NORMAL, Arrays.asList(Items.silkScarf)); + map.put(Type.POISON, Arrays.asList(Items.poisonBarb, Items.toxicPlate)); + map.put(Type.PSYCHIC, Arrays.asList(Items.twistedSpoon, Items.mindPlate, Items.oddIncense)); + map.put(Type.ROCK, Arrays.asList(Items.hardStone, Items.stonePlate, Items.rockIncense)); + map.put(Type.STEEL, Arrays.asList(Items.metalCoat, Items.ironPlate)); + map.put(Type.WATER, Arrays.asList(Items.mysticWater, Items.seaIncense, Items.splashPlate, Items.waveIncense)); + map.put(null, Collections.emptyList()); // ??? type + return Collections.unmodifiableMap(map); + } + + public static final Map<Integer, List<Integer>> moveBoostingItems = initializeMoveBoostingItems(); + + private static Map<Integer, List<Integer>> initializeMoveBoostingItems() { + Map<Integer, List<Integer>> map = new HashMap<>(); + map.put(Moves.bounce, Arrays.asList(Items.powerHerb)); + map.put(Moves.dig, Arrays.asList(Items.powerHerb)); + map.put(Moves.dive, Arrays.asList(Items.powerHerb)); + map.put(Moves.fly, Arrays.asList(Items.powerHerb)); + map.put(Moves.razorWind, Arrays.asList(Items.powerHerb)); + map.put(Moves.skullBash, Arrays.asList(Items.powerHerb)); + map.put(Moves.skyAttack, Arrays.asList(Items.powerHerb)); + map.put(Moves.solarBeam, Arrays.asList(Items.powerHerb)); + + map.put(Moves.fling, Arrays.asList(Items.toxicOrb, Items.flameOrb, Items.ironBall)); + + map.put(Moves.trick, Arrays.asList(Items.toxicOrb, Items.flameOrb, Items.fullIncense, Items.laggingTail)); + map.put(Moves.switcheroo, Arrays.asList(Items.toxicOrb, Items.flameOrb, Items.fullIncense, Items.laggingTail)); + + map.put(Moves.trickRoom, Arrays.asList(Items.ironBall)); + + map.put(Moves.facade, Arrays.asList(Items.toxicOrb, Items.flameOrb)); + + map.put(Moves.psychoShift, Arrays.asList(Items.toxicOrb, Items.flameOrb)); + + map.put(Moves.lightScreen, Arrays.asList(Items.lightClay)); + map.put(Moves.reflect, Arrays.asList(Items.lightClay)); + + map.put(Moves.hail, Arrays.asList(Items.icyRock)); + + map.put(Moves.sandstorm, Arrays.asList(Items.smoothRock)); + + map.put(Moves.sunnyDay, Arrays.asList(Items.heatRock)); + + map.put(Moves.rainDance, Arrays.asList(Items.dampRock)); + + map.put(Moves.bind, Arrays.asList(Items.gripClaw)); + map.put(Moves.clamp, Arrays.asList(Items.gripClaw)); + map.put(Moves.fireSpin, Arrays.asList(Items.gripClaw)); + map.put(Moves.magmaStorm, Arrays.asList(Items.gripClaw)); + map.put(Moves.outrage, Arrays.asList(Items.gripClaw)); + map.put(Moves.sandTomb, Arrays.asList(Items.gripClaw)); + map.put(Moves.uproar, Arrays.asList(Items.gripClaw)); + map.put(Moves.whirlpool, Arrays.asList(Items.gripClaw)); + map.put(Moves.wrap, Arrays.asList(Items.gripClaw)); + + map.put(Moves.absorb, Arrays.asList(Items.bigRoot)); + map.put(Moves.aquaRing, Arrays.asList(Items.bigRoot)); + map.put(Moves.drainPunch, Arrays.asList(Items.bigRoot)); + map.put(Moves.dreamEater, Arrays.asList(Items.bigRoot)); + map.put(Moves.gigaDrain, Arrays.asList(Items.bigRoot)); + map.put(Moves.ingrain, Arrays.asList(Items.bigRoot)); + map.put(Moves.leechLife, Arrays.asList(Items.bigRoot)); + map.put(Moves.leechSeed, Arrays.asList(Items.bigRoot)); + map.put(Moves.megaDrain, Arrays.asList(Items.bigRoot)); + + return Collections.unmodifiableMap(map); + } + + public static final Map<Type, Integer> weaknessReducingBerries = initializeWeaknessReducingBerries(); + + private static Map<Type, Integer> initializeWeaknessReducingBerries() { + Map<Type, Integer> map = new HashMap<>(); + map.put(Type.FIRE, Items.occaBerry); + map.put(Type.WATER, Items.passhoBerry); + map.put(Type.ELECTRIC, Items.wacanBerry); + map.put(Type.GRASS, Items.rindoBerry); + map.put(Type.ICE, Items.yacheBerry); + map.put(Type.FIGHTING, Items.chopleBerry); + map.put(Type.POISON, Items.kebiaBerry); + map.put(Type.GROUND, Items.shucaBerry); + map.put(Type.FLYING, Items.cobaBerry); + map.put(Type.PSYCHIC, Items.payapaBerry); + map.put(Type.BUG, Items.tangaBerry); + map.put(Type.ROCK, Items.chartiBerry); + map.put(Type.GHOST, Items.kasibBerry); + map.put(Type.DRAGON, Items.habanBerry); + map.put(Type.DARK, Items.colburBerry); + map.put(Type.STEEL, Items.babiriBerry); + return Collections.unmodifiableMap(map); + } + + public static final Map<Integer, List<Integer>> speciesBoostingItems = initializeSpeciesBoostingItems(); + + private static Map<Integer, List<Integer>> initializeSpeciesBoostingItems() { + Map<Integer, List<Integer>> map = new HashMap<>(); + map.put(Species.dialga, Arrays.asList(Items.adamantOrb)); + map.put(Species.palkia, Arrays.asList(Items.lustrousOrb)); + map.put(Species.latias, Arrays.asList(Items.soulDew)); + map.put(Species.latios, Arrays.asList(Items.soulDew)); + map.put(Species.clamperl, Arrays.asList(Items.deepSeaTooth, Items.deepSeaScale)); + map.put(Species.pikachu, Arrays.asList(Items.lightBall)); + map.put(Species.chansey, Arrays.asList(Items.luckyPunch)); + map.put(Species.ditto, Arrays.asList(Items.metalPowder, Items.quickPowder)); + map.put(Species.cubone, Arrays.asList(Items.thickClub)); + map.put(Species.marowak, Arrays.asList(Items.thickClub)); + map.put(Species.farfetchd, Arrays.asList(Items.leek)); + return Collections.unmodifiableMap(map); + } + + public static final Map<Integer, List<Integer>> abilityBoostingItems = initializeAbilityBoostingItems(); + + private static Map<Integer, List<Integer>> initializeAbilityBoostingItems() { + Map<Integer, List<Integer>> map = new HashMap<>(); + map.put(Abilities.guts, Arrays.asList(Items.flameOrb, Items.toxicOrb)); + map.put(Abilities.magicGuard, Arrays.asList(Items.stickyBarb, Items.lifeOrb)); + return Collections.unmodifiableMap(map); + } + + public static final Map<Integer,List<Integer>> abilityVariations = setupAbilityVariations(); + + private static Map<Integer,List<Integer>> setupAbilityVariations() { + Map<Integer,List<Integer>> map = new HashMap<>(); + map.put(Abilities.insomnia, Arrays.asList(Abilities.insomnia, Abilities.vitalSpirit)); + map.put(Abilities.clearBody, Arrays.asList(Abilities.clearBody, Abilities.whiteSmoke)); + map.put(Abilities.hugePower, Arrays.asList(Abilities.hugePower, Abilities.purePower)); + map.put(Abilities.battleArmor, Arrays.asList(Abilities.battleArmor, Abilities.shellArmor)); + map.put(Abilities.cloudNine, Arrays.asList(Abilities.cloudNine, Abilities.airLock)); + map.put(Abilities.filter, Arrays.asList(Abilities.filter, Abilities.solidRock)); + + return map; + } + + // Note: Flower Gift is NOT useless in this generation; it is in this list solely for consistency with future generations. + public static final List<Integer> uselessAbilities = Arrays.asList(Abilities.forecast, Abilities.multitype, Abilities.flowerGift); + + public static final int dpptSetVarScript = 0x28, hgssSetVarScript = 0x29; + + public static final int scriptListTerminator = 0xFD13; + + public static final int itemScriptVariable = 0x8008; + + private static List<String> dpShopNames = Arrays.asList( + "Sunyshore Secondary", + "Jubilife Secondary", + "Floaroma Secondary", + "Oreburgh Secondary", + "Eterna Secondary", + "Eterna Herbs", + "Snowpoint Secondary", + "Solaceon Secondary", + "Pastoria Secondary", + "Celestic Secondary", + "Hearthome Secondary", + "Canalave Secondary", + "Veilstone Department Store Secret Base Decorations 1", + "Veilstone Department Store Secret Base Decorations 2", + "Veilstone Department Store Vitamins", + "Veilstone Department Store TMs 1", + "Sunyshore Market Seals 1", + "Sunyshore Market Seals 2", + "Sunyshore Market Seals 3", + "Sunyshore Market Seals 4", + "Veilstone Department Store TMs 2", + "Sunyshore Market Seals 5", + "Sunyshore Market Seals 6", + "Sunyshore Market Seals 7", + "Pokemon League Secondary", + "Veilstone Department Store X Items", + "Veilstone Department Store Healing", + "Veilstone Department Store Balls Etc.", + "Progressive Shops" + ); + + private static List<String> ptShopNames = Arrays.asList( + "Jubilife Secondary", + "Sunyshore Secondary", + "Floaroma Secondary", + "Oreburgh Secondary", + "Eterna Herbs", + "Canalave Secondary", + "Pastoria Secondary", + "Celestic Secondary", + "Snowpoint Secondary", + "Solaceon Secondary", + "Eterna Secondary", + "Hearthome Secondary", + "Veilstone Department Store B1 Berries", + "Veilstone Department Store Secret Base Decorations 1", + "Veilstone Department Store Vitamins", + "Veilstone Department Store Secret Base Decorations 2", + "Veilstone Department Store TMs 1", + "Sunyshore Market Seals 1", + "Sunyshore Market Seals 2", + "Sunyshore Market Seals 3", + "Sunyshore Market Seals 4", + "Veilstone Department Store TMs 2", + "Sunyshore Market Seals 5", + "Sunyshore Market Seals 6", + "Sunyshore Market Seals 7", + "Pokemon League Secondary", + "Veilstone Department Store X Items", + "Veilstone Department Store Healing", + "Veilstone Department Store Balls Etc.", + "Progressive Shops" + ); + + private static List<String> hgssShopNames = Arrays.asList( + "Cherrygrove Secondary", + "Cerulean Secondary", + "Ecruteak Secondary", + "Celadon Department Store Mail", + "Saffron Secondary", + "Violet Secondary", + "Blackthorn Secondary", + "Olivine Secondary", + "Fuchsia Secondary", + "Lavender Secondary", + "Pewter Secondary", + "Viridian Secondary", + "Azalea Secondary", + "Mahogany Before Hideout", + "Safari Zone Gate Southwest", + "Goldenrod Herb Shop", + "Cianwood Pharmacy", + "Veilstone Department Store Secret Base Decorations 1", + "Veilstone Department Store Secret Base Decorations 2", + "Goldenrod Department Store Vitamins", + "Celadon Department Store Vitamins", + "Mt. Moon Square", + "Sunyshore Market Seals 1", + "Sunyshore Market Seals 2", + "Sunyshore Market Seals 3", + "Sunyshore Market Seals 4", + "Sunyshore Market Seals 5", + "Sunyshore Market Seals 6", + "Unused Secondary", + "Sunyshore Market Seals 7", + "Pokeathlon Dome Data Card Shop 25-27", + "Goldenrod Department Store X Items", + "Celadon Department Store X Items", + "Mahogany After Hideout", + "Goldenrod Department Store Healing", + "Celadon Department Store Healing", + "Goldenrod Department Store Balls Etc.", + "Goldenrod TMs", + "Celadon Department Store Balls Etc.", + "Celadon TMs", + "Pokeathlon Dome Athlete Shop Sunday (Pre-National Dex)", + "Pokeathlon Dome Data Card Shop 19-24", + "Pokeathlon Dome Data Card Shop 1-6", + "Pokeathlon Dome Athlete Shop Monday (Pre-National Dex)", + "Pokeathlon Dome Athlete Shop Tuesday (Pre-National Dex)", + "Pokeathlon Dome Data Card Shop 7-12", + "Pokeathlon Dome Athlete Shop Wednesday (Pre-National Dex)", + "Pokeathlon Dome Athlete Shop Thursday (Pre-National Dex)", + "Pokeathlon Dome Athlete Shop Friday (Pre-National Dex)", + "Pokeathlon Dome Athlete Shop Saturday (Pre-National Dex)", + "Pokeathlon Dome Data Card Shop 13-18", + "Pokeathlon Dome Athlete Shop Sunday (Post-National Dex)", + "Pokeathlon Dome Athlete Shop Monday (Post-National Dex)", + "Pokeathlon Dome Athlete Shop Tuesday (Post-National Dex)", + "Pokeathlon Dome Athlete Shop Wednesday (Post-National Dex)", + "Pokeathlon Dome Athlete Shop Thursday (Post-National Dex)", + "Pokeathlon Dome Athlete Shop Friday (Post-National Dex)", + "Pokeathlon Dome Athlete Shop Saturday (Post-National Dex)", + "Progressive Shops" + ); + + public static List<String> getShopNames(int romType) { + if (romType == Type_DP) { + return dpShopNames; + } else if (romType == Type_Plat) { + return ptShopNames; + } else if (romType == Type_HGSS) { + return hgssShopNames; + } + return null; + } + + public static final List<Integer> evolutionItems = Arrays.asList(Items.sunStone, Items.moonStone, Items.fireStone, + Items.thunderStone, Items.waterStone, Items.leafStone, Items.shinyStone, Items.duskStone, Items.dawnStone, + Items.ovalStone, Items.kingsRock, Items.deepSeaTooth, Items.deepSeaScale, Items.metalCoat, Items.dragonScale, + Items.upgrade, Items.protector, Items.electirizer, Items.magmarizer, Items.dubiousDisc, Items.reaperCloth, + Items.razorClaw, Items.razorFang); + + public static final Map<Integer,String> formeSuffixes = setupFormeSuffixes(); + public static final Map<Integer,FormeInfo> formeMappings = setupFormeMappings(); + public static final Map<Integer,Integer> cosmeticForms = setupCosmeticForms(); + + private static final Map<Integer,Map<Integer,String>> formeSuffixesByBaseForme = setupFormeSuffixesByBaseForme(); + private static final Map<Integer,String> dummyFormeSuffixes = setupDummyFormeSuffixes(); + + private static final Map<Integer,Map<Integer,Integer>> absolutePokeNumsByBaseForme = setupAbsolutePokeNumsByBaseForme(); + private static final Map<Integer,Integer> dummyAbsolutePokeNums = setupDummyAbsolutePokeNums(); + + public static String getFormeSuffixByBaseForme(int baseForme, int formNum) { + return formeSuffixesByBaseForme.getOrDefault(baseForme,dummyFormeSuffixes).getOrDefault(formNum,""); + } + + public static Integer getAbsolutePokeNumByBaseForme(int baseForme, int formNum) { + return absolutePokeNumsByBaseForme.getOrDefault(baseForme,dummyAbsolutePokeNums).getOrDefault(formNum,baseForme); + } + + public static final String lyraEthanMarillSpritePrefix = "274E0604C301274E0704E101274E0804"; + + public static final List<Integer> hgssBigOverworldPokemon = Arrays.asList( + 536, // MMODEL_FOLLOWER_MON_STEELIX + 537, // MMODEL_FOLLOWER_MON_STEELIX_F + 579, // MMODEL_FOLLOWER_MON_LUGIA + 580, // MMODEL_FOLLOWER_MON_HO_OH + 651, // MMODEL_FOLLOWER_MON_WAILORD + 712, // MMODEL_FOLLOWER_MON_KYOGRE + 713, // MMODEL_FOLLOWER_MON_GROUDON + 714, // MMODEL_FOLLOWER_MON_RAYQUAZA + 833, // MMODEL_FOLLOWER_MON_DIALGA + 834, // MMODEL_FOLLOWER_MON_PALKIA + 836, // MMODEL_FOLLOWER_MON_REGIGIGAS + 837, // MMODEL_FOLLOWER_MON_GIRATINA + 838, // MMODEL_FOLLOWER_MON_GIRATINA_ORIGIN + 845, // MMODEL_FOLLOWER_MON_ARCEUS_NORMAL + 846, // MMODEL_FOLLOWER_MON_ARCEUS_FIGHTING + 847, // MMODEL_FOLLOWER_MON_ARCEUS_FLYING + 848, // MMODEL_FOLLOWER_MON_ARCEUS_POISON + 849, // MMODEL_FOLLOWER_MON_ARCEUS_GROUND + 850, // MMODEL_FOLLOWER_MON_ARCEUS_ROCK + 851, // MMODEL_FOLLOWER_MON_ARCEUS_BUG + 852, // MMODEL_FOLLOWER_MON_ARCEUS_GHOST + 853, // MMODEL_FOLLOWER_MON_ARCEUS_STEEL + 854, // MMODEL_FOLLOWER_MON_ARCEUS_MYSTERY + 855, // MMODEL_FOLLOWER_MON_ARCEUS_FIRE + 856, // MMODEL_FOLLOWER_MON_ARCEUS_WATER + 857, // MMODEL_FOLLOWER_MON_ARCEUS_GRASS + 858, // MMODEL_FOLLOWER_MON_ARCEUS_ELECTRIC + 859, // MMODEL_FOLLOWER_MON_ARCEUS_PSYCHIC + 860, // MMODEL_FOLLOWER_MON_ARCEUS_ICE + 861, // MMODEL_FOLLOWER_MON_ARCEUS_DRAGON + 862 // MMODEL_FOLLOWER_MON_ARCEUS_DARK + ); + + public static final List<Integer> hgssBannedOverworldPokemon = Arrays.asList( + // Unown alts (to avoid 28x chance of getting Unown) + // Arcues alts (to avoid 18x chance of getting Arceus) + 502, // MMODEL_FOLLOWER_MON_UNOWN_B + 503, // MMODEL_FOLLOWER_MON_UNOWN_C + 504, // MMODEL_FOLLOWER_MON_UNOWN_D + 505, // MMODEL_FOLLOWER_MON_UNOWN_E + 506, // MMODEL_FOLLOWER_MON_UNOWN_F + 507, // MMODEL_FOLLOWER_MON_UNOWN_G + 508, // MMODEL_FOLLOWER_MON_UNOWN_H + 509, // MMODEL_FOLLOWER_MON_UNOWN_I + 510, // MMODEL_FOLLOWER_MON_UNOWN_J + 511, // MMODEL_FOLLOWER_MON_UNOWN_K + 512, // MMODEL_FOLLOWER_MON_UNOWN_L + 513, // MMODEL_FOLLOWER_MON_UNOWN_M + 514, // MMODEL_FOLLOWER_MON_UNOWN_N + 515, // MMODEL_FOLLOWER_MON_UNOWN_O + 516, // MMODEL_FOLLOWER_MON_UNOWN_P + 517, // MMODEL_FOLLOWER_MON_UNOWN_Q + 518, // MMODEL_FOLLOWER_MON_UNOWN_R + 519, // MMODEL_FOLLOWER_MON_UNOWN_S + 520, // MMODEL_FOLLOWER_MON_UNOWN_T + 521, // MMODEL_FOLLOWER_MON_UNOWN_U + 522, // MMODEL_FOLLOWER_MON_UNOWN_V + 523, // MMODEL_FOLLOWER_MON_UNOWN_W + 524, // MMODEL_FOLLOWER_MON_UNOWN_X + 525, // MMODEL_FOLLOWER_MON_UNOWN_Y + 526, // MMODEL_FOLLOWER_MON_UNOWN_Z + 527, // MMODEL_FOLLOWER_MON_UNOWN_QMARK + 528, // MMODEL_FOLLOWER_MON_UNOWN_EXCL + 846, // MMODEL_FOLLOWER_MON_ARCEUS_FIGHTING + 847, // MMODEL_FOLLOWER_MON_ARCEUS_FLYING + 848, // MMODEL_FOLLOWER_MON_ARCEUS_POISON + 849, // MMODEL_FOLLOWER_MON_ARCEUS_GROUND + 850, // MMODEL_FOLLOWER_MON_ARCEUS_ROCK + 851, // MMODEL_FOLLOWER_MON_ARCEUS_BUG + 852, // MMODEL_FOLLOWER_MON_ARCEUS_GHOST + 853, // MMODEL_FOLLOWER_MON_ARCEUS_STEEL + 854, // MMODEL_FOLLOWER_MON_ARCEUS_MYSTERY + 855, // MMODEL_FOLLOWER_MON_ARCEUS_FIRE + 856, // MMODEL_FOLLOWER_MON_ARCEUS_WATER + 857, // MMODEL_FOLLOWER_MON_ARCEUS_GRASS + 858, // MMODEL_FOLLOWER_MON_ARCEUS_ELECTRIC + 859, // MMODEL_FOLLOWER_MON_ARCEUS_PSYCHIC + 860, // MMODEL_FOLLOWER_MON_ARCEUS_ICE + 861, // MMODEL_FOLLOWER_MON_ARCEUS_DRAGON + 862 // MMODEL_FOLLOWER_MON_ARCEUS_DARK + ); + + public static final int convertOverworldSpriteToSpecies(int overworldSpriteID) { + int speciesID = overworldSpriteID - 296; + + // Venusaur + if (overworldSpriteID >= 300) { + speciesID -= 1; + } + + // Pikachu + if (overworldSpriteID >= 323) { + speciesID -= 1; + } + + // Meganium + if (overworldSpriteID >= 453) { + speciesID -= 1; + } + + // Pichu + if (overworldSpriteID >= 472) { + speciesID -= 1; + } + + // Unown + if (overworldSpriteID >= 528) { + speciesID -= 27; + } else if (overworldSpriteID > 501) { + speciesID -= (overworldSpriteID - 501); + } + + // Wobbuffet + if (overworldSpriteID >= 530) { + speciesID -= 1; + } + + // Steelix + if (overworldSpriteID >= 537) { + speciesID -= 1; + } + + // Heracross + if (overworldSpriteID >= 544) { + speciesID -= 1; + } + + // Deoxys + if (overworldSpriteID >= 719) { + speciesID -= 3; + } else if (overworldSpriteID > 716) { + speciesID -= (overworldSpriteID - 716); + } + + // Burmy + if (overworldSpriteID >= 747) { + speciesID -= 2; + } else if (overworldSpriteID > 745) { + speciesID -= (overworldSpriteID - 745); + } + + // Wormadam + if (overworldSpriteID >= 750) { + speciesID -= 2; + } else if (overworldSpriteID > 748) { + speciesID -= (overworldSpriteID - 748); + } + + // Combee + if (overworldSpriteID >= 753) { + speciesID -= 1; + } + + // Shellos + if (overworldSpriteID >= 761) { + speciesID -= 1; + } + + // Gastrodon + if (overworldSpriteID >= 763) { + speciesID -= 1; + } + + // Gible + if (overworldSpriteID >= 784) { + speciesID -= 1; + } + + // Gabite + if (overworldSpriteID >= 786) { + speciesID -= 1; + } + + // Garchomp + if (overworldSpriteID >= 788) { + speciesID -= 1; + } + + // Hippopotas + if (overworldSpriteID >= 793) { + speciesID -= 1; + } + + // Hippowdon + if (overworldSpriteID >= 795) { + speciesID -= 1; + } + + // Rotom + if (overworldSpriteID >= 829) { + speciesID -= 5; + } else if (overworldSpriteID > 824) { + speciesID -= (overworldSpriteID - 824); + } + + // Giratina + if (overworldSpriteID >= 838) { + speciesID -= 1; + } + + // Arceus + if (overworldSpriteID > 845) { + speciesID -= (overworldSpriteID - 845); + } + + return speciesID; + } + + // The original slot each of the 20 "alternate" slots is mapped to + // swarmx2, dayx2, nightx2, pokeradarx4, GBAx10 + // NOTE: in the game data there are 6 fillers between pokeradar and GBA + + public static final int[] dpptAlternateSlots = new int[] { 0, 1, 2, 3, 2, 3, 4, 5, 10, 11, 8, 9, 8, 9, 8, 9, 8, 9, + 8, 9 }; + + public static final String[] dpptWaterSlotSetNames = new String[] { "Surfing", "Filler", "Old Rod", "Good Rod", + "Super Rod" }; + + public static final String[] hgssTimeOfDayNames = new String[] { "Morning", "Day", "Night" }; + + public static final String[] hgssNonGrassSetNames = new String[] { "", "Surfing", "Rock Smash", "Old Rod", + "Good Rod", "Super Rod" }; + public static final int hgssGoodRodReplacementIndex = 3, hgssSuperRodReplacementIndex = 1; + + public static final MoveCategory[] moveCategoryIndices = { MoveCategory.PHYSICAL, MoveCategory.SPECIAL, + MoveCategory.STATUS }; + + public static byte moveCategoryToByte(MoveCategory cat) { + switch (cat) { + case PHYSICAL: + return 0; + case SPECIAL: + return 1; + case STATUS: + default: + return 2; + } + } + + public static final int noDamageSleepEffect = 1, damagePoisonEffect = 2, damageAbsorbEffect = 3, damageBurnEffect = 4, + damageFreezeEffect = 5, damageParalyzeEffect = 6, dreamEaterEffect = 8, noDamageAtkPlusOneEffect = 10, + noDamageDefPlusOneEffect = 11, noDamageSpAtkPlusOneEffect = 13, noDamageEvasionPlusOneEffect = 16, + noDamageAtkMinusOneEffect = 18, noDamageDefMinusOneEffect = 19, noDamageSpeMinusOneEffect = 20, + noDamageAccuracyMinusOneEffect = 23, noDamageEvasionMinusOneEffect = 24, flinchEffect = 31, toxicEffect = 33, + razorWindEffect = 39, bindingEffect = 42, increasedCritEffect = 43, damageRecoil25PercentEffect = 48, + noDamageConfusionEffect = 49, noDamageAtkPlusTwoEffect = 50, noDamageDefPlusTwoEffect = 51, + noDamageSpePlusTwoEffect = 52, noDamageSpAtkPlusTwoEffect = 53, noDamageSpDefPlusTwoEffect = 54, + noDamageAtkMinusTwoEffect = 58, noDamageDefMinusTwoEffect = 59, noDamageSpeMinusTwoEffect = 60, + noDamageSpDefMinusTwoEffect = 62, noDamagePoisonEffect = 66, noDamageParalyzeEffect = 67, + damageAtkMinusOneEffect = 68, damageDefMinusOneEffect = 69, damageSpeMinusOneEffect = 70, + damageSpAtkMinusOneEffect = 71, damageSpDefMinusOneEffect = 72, damageAccuracyMinusOneEffect = 73, + skyAttackEffect = 75, damageConfusionEffect = 76, twineedleEffect = 77, rechargeEffect = 80, snoreEffect = 92, + trappingEffect = 106, minimizeEffect = 108, swaggerEffect = 118, damageBurnAndThawUserEffect = 125, + damageUserDefPlusOneEffect = 138, damageUserAtkPlusOneEffect = 139, damageUserAllPlusOneEffect = 140, + skullBashEffect = 145, twisterEffect = 146, futureSightAndDoomDesireEffect = 148, stompEffect = 150, + solarbeamEffect = 151, thunderEffect = 152, flyEffect = 155, defenseCurlEffect = 156, + fakeOutEffect = 158, flatterEffect = 166, noDamageBurnEffect = 167, chargeEffect = 174, + damageUserAtkAndDefMinusOneEffect = 182, damageRecoil33PercentEffect = 198, teeterDanceEffect = 199, + blazeKickEffect = 200, poisonFangEffect = 202, damageUserSpAtkMinusTwoEffect = 204, + noDamageAtkAndDefMinusOneEffect = 205, noDamageDefAndSpDefPlusOneEffect = 206, + noDamageAtkAndDefPlusOneEffect = 208, damagePoisonWithIncreasedCritEffect = 209, + noDamageSpAtkAndSpDefPlusOneEffect = 211, noDamageAtkAndSpePlusOneEffect = 212, + damageUserSpeMinusOneEffect = 218, damageUserDefAndSpDefMinusOneEffect = 229, flareBlitzEffect = 253, + diveEffect = 255, digEffect = 256, blizzardEffect = 260, voltTackleEffect = 262, bounceEffect = 263, + noDamageSpAtkMinusTwoEffect = 265, chatterEffect = 267, damageRecoil50PercentEffect = 269, + damageSpDefMinusTwoEffect = 271, shadowForceEffect = 272, fireFangEffect = 273, iceFangEffect = 274, + thunderFangEffect = 275, damageUserSpAtkPlusOneEffect = 276; + + public static final List<Integer> soundMoves = Arrays.asList(Moves.growl, Moves.roar, Moves.sing, Moves.supersonic, + Moves.screech, Moves.snore, Moves.uproar, Moves.metalSound, Moves.grassWhistle, Moves.hyperVoice, + Moves.bugBuzz, Moves.chatter, Moves.perishSong, Moves.healBell); + + public static final List<Integer> punchMoves = Arrays.asList(Moves.icePunch, Moves.firePunch, Moves.thunderPunch, + Moves.machPunch, Moves.focusPunch, Moves.dizzyPunch, Moves.dynamicPunch, Moves.hammerArm, Moves.megaPunch, + Moves.cometPunch, Moves.meteorMash, Moves.shadowPunch, Moves.drainPunch, Moves.bulletPunch, Moves.skyUppercut); + + public static final List<Integer> dpRequiredFieldTMs = Arrays.asList(2, 3, 5, 9, 12, 19, 23, 28, + 34, 39, 41, 43, 46, 47, 49, 50, 62, 69, 79, 80, 82, 84, 85, 87); + + public static final List<Integer> ptRequiredFieldTMs = Arrays.asList(2, 3, 5, 7, 9, 11, 12, 18, 19, + 23, 28, 34, 37, 39, 41, 43, 46, 47, 49, 50, 62, 69, 79, 80, 82, 84, 85, 87); + + public static final List<Integer> dpptFieldMoves = Arrays.asList( + Moves.cut, Moves.fly, Moves.surf, Moves.strength, Moves.flash, Moves.dig, Moves.teleport, + Moves.waterfall, Moves.rockSmash, Moves.sweetScent, Moves.defog, Moves.rockClimb); + + public static final List<Integer> hgssFieldMoves = Arrays.asList( + Moves.cut, Moves.fly, Moves.surf, Moves.strength, Moves.flash, Moves.dig, Moves.teleport, + Moves.whirlpool, Moves.waterfall, Moves.rockSmash, Moves.headbutt, Moves.sweetScent, Moves.rockClimb); + + public static final List<Integer> dpptEarlyRequiredHMMoves = Arrays.asList(Moves.rockSmash, Moves.cut); + + public static final List<Integer> hgssEarlyRequiredHMMoves = Collections.singletonList(Moves.cut); + + public static ItemList allowedItems, nonBadItems; + public static List<Integer> regularShopItems, opShopItems; + + public static final String shedinjaSpeciesLocator = "492080000090281C0521"; + + public static final int ilexForestScriptFile = 92, ilexForestStringsFile = 115; + public static final List<Integer> headbuttTutorScriptOffsets = Arrays.asList(0xF55, 0xFC5, 0x100A, 0x104C); + + private static final String doubleBattleFixPrefixDP = "022912D90221214201", doubleBattleFixPrefixPt = "022919D90221214205", + doubleBattleFixPrefixHGSS = "2C2815D00221214201"; + + public static final String feebasLevelPrefixDPPt = "019813B0F0BD", honeyTreeLevelPrefixDPPt = "F0BDF0B589B0051C0C1C"; + + private static final String runningShoesCheckPrefixDPPt = "281C0C24", runningShoesCheckPrefixHGSS = "301C0C24"; + + public static final String distortionWorldGroundCheckPrefix = "23D849187944C988090409148F44"; + + public static final List<String> dpptIntroPrefixes = Arrays.asList("381CF8BDC046", "08B0F8BD"); + + public static final String hpBarSpeedPrefix = "0CD106200090", expBarSpeedPrefix = "011C00D101212E6C", bothBarsSpeedPrefix = "70BD90421DDA"; + + public static final String dpptEggMoveTablePrefix = "40016601"; + + public static final String typeEffectivenessTableLocator = "000505000805"; + + private static final int trophyGardenGrassEncounterIndexDP = 304, trophyGardenGrassEncounterIndexPt = 308; + private static final List<Integer> marshGrassEncounterIndicesDP = Arrays.asList(76, 82, 88, 94, 100, 102), + marshGrassEncounterIndicesPt = Arrays.asList(76, 82, 88, 94, 100, 106); + + public static final String pickupTableLocator = "110012001A000300", rarePickupTableLocator = "19005C00DD00"; + public static final int numberOfCommonPickupItems = 18, numberOfRarePickupItems = 11; + + public static final String friendshipValueForEvoLocator = "DC286AD3"; + + public static final String perfectOddsBranchLocator = "FF2901D30425"; + + public static final int[] dpptOverworldDexMaps = new int[] { + 1, 2, 3, 4, 5, -1, -1, 6, -1, 7, // 0-9 (cities, pkmn league, wind/ironworks) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10-19 (all mt coronet) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 20-29 (mt coronet, great marsh, solaceon ruins) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 30-39 (all solaceon ruins) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 40-49 (solaceon ruins/v.road) + -1, -1, -1, -1, -1, -1, 8, -1, -1, -1, // 50-59 (v.road, stark mountain outer then inner, sendoff spring) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 60-69 (unknown, turnback cave) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 70-79 (all turnback cave) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80-89 (all unknown) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 90-99 (all unknown) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 100-109 (unknown, snowpoint temple) + -1, -1, -1, -1, -1, -1, -1, -1, 9, -1, // 110-119 (various dungeons, iron island outer/inner) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 120-129 (rest of iron island inner, old chateau) + -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, // 130-139 (old chateau, inner lakes, lakefronts) + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, // 140-149 (first few routes) + 22, -1, -1, -1, -1, -1, 23, 24, 25, 26, // 150-159 (route 209 + lost tower, more routes) + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, // 160-169 (routes; 220 is skipped until later) + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, // 170-179 (last few land routes, towns, resort area, first sea route) + 47, 48, 49, // 180-182 (other sea routes) + }; + + public static final int[] dpptDungeonDexMaps = new int[] { + -1, -1, -1, -1, -1, 1, 1, -1, 2, -1, // 0-9 (cities, pkmn league, wind/ironworks, mine/forest) + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 10-19 (all mt coronet) + 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, // 20-29 (mt coronet, great marsh, solaceon ruins) + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 30-39 (all solaceon ruins) + 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, // 40-49 (solaceon ruins/v.road) + 6, 6, 6, 7, 8, 8, -1, 9, 9, 10, // 50-59 (v.road, stark mountain outer then inner, sendoff spring) + -1, -1, -1, 10, 10, 10, 10, 10, 10, 10, // 60-69 (unknown, turnback cave) + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // 70-79 (all turnback cave) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80-89 (all unknown) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 90-99 (all unknown) + -1, -1, -1, -1, -1, -1, 11, 11, 11, 11, // 100-109 (unknown, snowpoint temple) + 11, 11, 12, 12, 13, 13, 13, 14, -1, 15, // 110-119 (various dungeons, iron island outer/inner) + 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, // 120-129 (rest of iron island inner, old chateau) + 16, 16, 16, 16, 17, 17, 18, 19, -1, -1, // 130-139 (old chateau, inner lakes, lakefronts) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 140-149 (first few routes) + -1, 20, 20, 20, 20, 20, -1, -1, -1, -1, // 150-159 (route 209 + lost tower, more routes) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160-169 (routes; 220 is skipped until later) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 170-179 (last few land routes, towns, resort area, first sea route) + -1, -1, -1, // 180-182 (other sea routes) + }; + + public static final int[] hgssOverworldDexMaps = new int[] { + 1, 2, 3, 4, 5, 6, -1, -1, 7, -1, // 0-9 (first few cities/routes, sprout tower + alph) + -1, -1, -1, -1, -1, -1, -1, 8, -1, -1, // 10-19 (more alph, union cave, r33, slowpoke) + -1, 9, 10, -1, -1, 11, 12, 13, -1, -1, // 20-29 (ilex, routes, natpark, routes, burned) + -1, -1, -1, -1, -1, -1, -1, -1, 14, 15, // 30-39 (bell tower, routes) + 16, 17, 18, -1, -1, -1, -1, -1, -1, -1, // 40-49 (olivine, routes, whirl islands, missing slots) + -1, 19, 20, -1, -1, -1, -1, 21, 22, 23, // 50-59 (missing, cianwood, routes, mortar) + -1, -1, -1, -1, -1, 24, -1, 25, 26, -1, // 60-69 (ice path, missing, blackthorn, dragons, routes, dark) + -1, 27, -1, -1, -1, -1, -1, -1, -1, -1, // 70-79 (dark, route 47, moon, seafoam, silver cave) + -1, -1, -1, -1, -1, 28, -1, -1, -1, -1, // 80-89 (more silver cave, cliff stuff, random bell tower) + -1, -1, 29, 30, 31, 32, 33, 34, 35, 36, // 90-99 (missing, saf zone, kanto routes/cities) + 37, 38, 39, 40, 41, 42, -1, -1, -1, -1, // 100-109 (more cities, some routes, more moon, RT) + -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 110-119 (vroad, routes 1-9) + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // 120-129 (routes 10-21) + 62, 63, -1, -1, -1, -1, 64, -1, -1, -1, // 130-139 (last 2 routes, tohjo, DC, VR, route 2 north, VF, CC) + -1, -1, // 140-141 (cerulean cave) + }; + + public static final int[] hgssDungeonDexMaps = new int[] { + -1, -1, -1, -1, -1, -1, 1, 1, -1, 2, // 0-9 (first few cities/routes, sprout tower + alph) + 2, 2, 2, 2, 3, 3, 3, -1, 4, 4, // 10-19 (more alph, union cave, r33, slowpoke) + 5, -1, -1, 6, -1, -1, -1, -1, 7, 7, // 20-29 (ilex, routes, natpark, routes, burned) + 8, 8, 8, 8, 8, 8, 8, 8, -1, -1, // 30-39 (bell tower, routes) + -1, -1, -1, 9, 9, -1, 9, -1, 9, -1, // 40-49 (olivine, routes, whirl islands, missing slots) + -1, -1, -1, 10, 10, 10, 10, -1, -1, -1, // 50-59 (missing, cianwood, routes, mortar) + 11, 11, 11, 11, -1, -1, 12, -1, -1, 13, // 60-69 (ice path, missing, blackthorn, dragons, routes, dark) + 13, -1, 14, 14, 15, 15, 15, 15, 15, 16, // 70-79 (dark, route 47, moon, seafoam, silver cave) + 16, 16, 17, 18, 8, -1, 16, 16, 16, 16, // 80-89 (more silver cave, cliff stuff, random bell tower) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 90-99 (missing, saf zone, kanto routes/cities) + -1, -1, -1, -1, -1, -1, 14, 14, 20, 20, // 100-109 (more cities, some routes, more moon, RT) + 21, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 110-119 (vroad, routes 1-9) + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 120-129 (routes 10-21) + -1, -1, 22, 23, 21, 21, -1, 24, -1, 25, // 130-139 (last 2 routes, tohjo, DC, VR, route 2 north, VF, CC) + 25, 25, // 140-141 (cerulean cave) + }; + + public static final int[] hgssHeadbuttOverworldDexMaps = new int[] { + 43, 44, 45, 46, 47, 48, 49, 50, 53, 29, // Routes 1-12, skipping 9 and 10 + 54, 55, 56, 59, 61, 63, 40, 41, 42, 2, // Routes 13-15, Route 18, Route 22, Routes 25-29 + 4, 5, 7, 8, 9, 10, 11, 12, 14, 15, // Routes 30-39 + 20, 21, 23, 25, 26, 32, 33, 65, 34, 35, // Routes 42-46, first five Kanto cities + 36, 37, 1, 3, 6, 66, 13, 22, 28, 60, // Remaining Kanto cities, Johto cities, Lake of Rage, Mt Silver, Route 21 + -1, -1, -1, 27, 39, 67, 64, 57, -1, // National Park, Ilex/Viridian Forest, Routes 47-48, Safari Zone Gate, Routes 2 (north) and 16, Mt Silver Cave + }; + + public static final int[] hgssHeadbuttDungeonDexMaps = new int[] { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Routes 1-12, skipping 9 and 10 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Routes 13-15, Route 18, Route 22, Routes 25-29 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Routes 30-39 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Routes 42-46, first five Kanto cities + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Remaining Kanto cities, Johto cities, Lake of Rage, Mt Silver, Route 21 + 6, 5, 24, -1, -1, -1, -1, -1, 16, // National Park, Ilex/Viridian Forest, Routes 47-48, Safari Zone Gate, Routes 2 (north) and 16, Mt Silver Cave + }; + + public static final int pokedexAreaDataSize = 495; + public static final int dpptMtCoronetDexIndex = 3, dpptGreatMarshDexIndex = 4, dpptTrophyGardenDexIndex = 14, dpptFloaromaMeadowDexIndex = 21; + public static final List<Integer> dpptOverworldHoneyTreeDexIndicies = Arrays.asList(6, 7, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 29, 30, 31, 34, 36, 37, 50); + public static final List<Integer> partnerTrainerIndices = Arrays.asList(608, 609, 610, 611, 612); + + static { + setupAllowedItems(); + } + + private static void setupAllowedItems() { + allowedItems = new ItemList(Items.enigmaStone); + // Key items + version exclusives + allowedItems.banRange(Items.explorerKit, 109); + // Unknown blank items or version exclusives + allowedItems.banRange(Items.griseousOrb, 23); + // HMs + allowedItems.banRange(Items.hm01, 8); + // TMs + allowedItems.tmRange(Items.tm01, 92); + + // non-bad items + // ban specific pokemon hold items, berries, apricorns, mail + nonBadItems = allowedItems.copy(); + + nonBadItems.banSingles(Items.oddKeystone, Items.griseousOrb, Items.soulDew, Items.lightBall, + Items.oranBerry, Items.quickPowder); + nonBadItems.banRange(Items.shoalSalt,2); + nonBadItems.banRange(Items.growthMulch, 4); // mulch + nonBadItems.banRange(Items.adamantOrb, 2); // orbs + nonBadItems.banRange(Items.mail1, 12); // mails + nonBadItems.banRange(Items.figyBerry, 25); // berries without useful battle effects + nonBadItems.banRange(Items.luckyPunch, 4); // pokemon specific + nonBadItems.banRange(Items.redScarf, 5); // contest scarves + + regularShopItems = new ArrayList<>(); + + regularShopItems.addAll(IntStream.rangeClosed(Items.ultraBall, Items.pokeBall).boxed().collect(Collectors.toList())); + regularShopItems.addAll(IntStream.rangeClosed(Items.potion, Items.revive).boxed().collect(Collectors.toList())); + regularShopItems.addAll(IntStream.rangeClosed(Items.superRepel, Items.repel).boxed().collect(Collectors.toList())); + + opShopItems = new ArrayList<>(); + + // "Money items" etc + opShopItems.add(Items.rareCandy); + opShopItems.addAll(IntStream.rangeClosed(Items.tinyMushroom, Items.nugget).boxed().collect(Collectors.toList())); + opShopItems.add(Items.rareBone); + opShopItems.add(Items.luckyEgg); + } + + public static String getDoubleBattleFixPrefix(int romType) { + if (romType == Gen4Constants.Type_DP) { + return doubleBattleFixPrefixDP; + } else if (romType == Gen4Constants.Type_Plat) { + return doubleBattleFixPrefixPt; + } else { + return doubleBattleFixPrefixHGSS; + } + } + + public static String getRunWithoutRunningShoesPrefix(int romType) { + if (romType == Gen4Constants.Type_DP || romType == Gen4Constants.Type_Plat) { + return runningShoesCheckPrefixDPPt; + } else { + return runningShoesCheckPrefixHGSS; + } + } + + public static int getTrophyGardenGrassEncounterIndex(int romType) { + if (romType == Gen4Constants.Type_DP) { + return trophyGardenGrassEncounterIndexDP; + } else { + return trophyGardenGrassEncounterIndexPt; + } + } + + public static List<Integer> getMarshGrassEncounterIndices(int romType) { + if (romType == Gen4Constants.Type_DP) { + return marshGrassEncounterIndicesDP; + } else { + return marshGrassEncounterIndicesPt; + } + } + + public static int getTextCharsPerLine(int romType) { + if (romType == Gen4Constants.Type_HGSS) { + return hgssTextCharsPerLine; + } else { + return dpptTextCharsPerLine; + } + } + + public static final Map<Integer,Integer> balancedItemPrices = Stream.of(new Integer[][] { + // Skip item index 0. All prices divided by 10 + {Items.masterBall, 300}, + {Items.ultraBall, 120}, + {Items.greatBall, 60}, + {Items.pokeBall, 20}, + {Items.safariBall, 50}, + {Items.netBall, 100}, + {Items.diveBall, 100}, + {Items.nestBall, 100}, + {Items.repeatBall, 100}, + {Items.timerBall, 100}, + {Items.luxuryBall, 100}, + {Items.premierBall, 20}, + {Items.duskBall, 100}, + {Items.healBall, 30}, + {Items.quickBall, 100}, + {Items.cherishBall, 20}, + {Items.potion, 30}, + {Items.antidote, 10}, + {Items.burnHeal, 25}, + {Items.iceHeal, 25}, + {Items.awakening, 25}, + {Items.paralyzeHeal, 20}, + {Items.fullRestore, 300}, + {Items.maxPotion, 250}, + {Items.hyperPotion, 120}, + {Items.superPotion, 70}, + {Items.fullHeal, 60}, + {Items.revive, 150}, + {Items.maxRevive, 400}, + {Items.freshWater, 40}, + {Items.sodaPop, 60}, + {Items.lemonade, 70}, + {Items.moomooMilk, 80}, + {Items.energyPowder, 40}, + {Items.energyRoot, 110}, + {Items.healPowder, 45}, + {Items.revivalHerb, 280}, + {Items.ether, 300}, + {Items.maxEther, 450}, + {Items.elixir, 1500}, + {Items.maxElixir, 1800}, + {Items.lavaCookie, 45}, + {Items.berryJuice, 10}, + {Items.sacredAsh, 1000}, + {Items.hpUp, 980}, + {Items.protein, 980}, + {Items.iron, 980}, + {Items.carbos, 980}, + {Items.calcium, 980}, + {Items.rareCandy, 1000}, + {Items.ppUp, 980}, + {Items.zinc, 980}, + {Items.ppMax, 2490}, + {Items.oldGateau, 45}, + {Items.guardSpec, 70}, + {Items.direHit, 65}, + {Items.xAttack, 50}, + {Items.xDefense, 55}, + {Items.xSpeed, 35}, + {Items.xAccuracy, 95}, + {Items.xSpAtk, 35}, + {Items.xSpDef, 35}, + {Items.pokeDoll, 100}, + {Items.fluffyTail, 100}, + {Items.blueFlute, 2}, + {Items.yellowFlute, 2}, + {Items.redFlute, 2}, + {Items.blackFlute, 2}, + {Items.whiteFlute, 2}, + {Items.shoalSalt, 2}, + {Items.shoalShell, 2}, + {Items.redShard, 40}, + {Items.blueShard, 40}, + {Items.yellowShard, 40}, + {Items.greenShard, 40}, + {Items.superRepel, 50}, + {Items.maxRepel, 70}, + {Items.escapeRope, 55}, + {Items.repel, 35}, + {Items.sunStone, 300}, + {Items.moonStone, 300}, + {Items.fireStone, 300}, + {Items.thunderStone, 300}, + {Items.waterStone, 300}, + {Items.leafStone, 300}, + {Items.tinyMushroom, 50}, + {Items.bigMushroom, 500}, + {Items.pearl, 140}, + {Items.bigPearl, 750}, + {Items.stardust, 200}, + {Items.starPiece, 980}, + {Items.nugget, 1000}, + {Items.heartScale, 500}, + {Items.honey, 50}, + {Items.growthMulch, 20}, + {Items.dampMulch, 20}, + {Items.stableMulch, 20}, + {Items.gooeyMulch, 20}, + {Items.rootFossil, 500}, + {Items.clawFossil, 500}, + {Items.helixFossil, 500}, + {Items.domeFossil, 500}, + {Items.oldAmber, 800}, + {Items.armorFossil, 500}, + {Items.skullFossil, 500}, + {Items.rareBone, 1000}, + {Items.shinyStone, 300}, + {Items.duskStone, 300}, + {Items.dawnStone, 300}, + {Items.ovalStone, 300}, + {Items.oddKeystone, 210}, + {Items.griseousOrb, 1000}, + {Items.tea, 0}, // unused in Gen 4 + {Items.unused114, 0}, + {Items.autograph, 0}, // unused in Gen 4 + {Items.douseDrive, 0}, // unused in Gen 4 + {Items.shockDrive, 0}, // unused in Gen 4 + {Items.burnDrive, 0}, // unused in Gen 4 + {Items.chillDrive, 0}, // unused in Gen 4 + {Items.unused120, 0}, // unused in Gen 4 + {Items.pokemonBox, 0}, // unused in Gen 4 + {Items.medicinePocket, 0}, // unused in Gen 4 + {Items.tmCase, 0}, // unused in Gen 4 + {Items.candyJar, 0}, // unused in Gen 4 + {Items.powerUpPocket, 0}, // unused in Gen 4 + {Items.clothingTrunk, 0}, // unused in Gen 4 + {Items.catchingPocket, 0}, // unused in Gen 4 + {Items.battlePocket, 0}, // unused in Gen 4 + {Items.unused129, 0}, + {Items.unused130, 0}, + {Items.unused131, 0}, + {Items.unused132, 0}, + {Items.unused133, 0}, + {Items.sweetHeart, 0}, // unused in Gen 4 + {Items.adamantOrb, 1000}, + {Items.lustrousOrb, 1000}, + {Items.mail1, 5}, + {Items.mail2, 5}, + {Items.mail3, 5}, + {Items.mail4, 5}, + {Items.mail5, 5}, + {Items.mail6, 5}, + {Items.mail7, 5}, + {Items.mail8, 5}, + {Items.mail9, 5}, + {Items.mail10, 5}, + {Items.mail11, 5}, + {Items.mail12, 5}, + {Items.cheriBerry, 20}, + {Items.chestoBerry, 25}, + {Items.pechaBerry, 10}, + {Items.rawstBerry, 25}, + {Items.aspearBerry, 25}, + {Items.leppaBerry, 300}, + {Items.oranBerry, 5}, + {Items.persimBerry, 20}, + {Items.lumBerry, 50}, + {Items.sitrusBerry, 50}, + {Items.figyBerry, 10}, + {Items.wikiBerry, 10}, + {Items.magoBerry, 10}, + {Items.aguavBerry, 10}, + {Items.iapapaBerry, 10}, + {Items.razzBerry, 50}, + {Items.blukBerry, 50}, + {Items.nanabBerry, 50}, + {Items.wepearBerry, 50}, + {Items.pinapBerry, 50}, + {Items.pomegBerry, 50}, + {Items.kelpsyBerry, 50}, + {Items.qualotBerry, 50}, + {Items.hondewBerry, 50}, + {Items.grepaBerry, 50}, + {Items.tamatoBerry, 50}, + {Items.cornnBerry, 50}, + {Items.magostBerry, 50}, + {Items.rabutaBerry, 50}, + {Items.nomelBerry, 50}, + {Items.spelonBerry, 50}, + {Items.pamtreBerry, 50}, + {Items.watmelBerry, 50}, + {Items.durinBerry, 50}, + {Items.belueBerry, 50}, + {Items.occaBerry, 100}, + {Items.passhoBerry, 100}, + {Items.wacanBerry, 100}, + {Items.rindoBerry, 100}, + {Items.yacheBerry, 100}, + {Items.chopleBerry, 100}, + {Items.kebiaBerry, 100}, + {Items.shucaBerry, 100}, + {Items.cobaBerry, 100}, + {Items.payapaBerry, 100}, + {Items.tangaBerry, 100}, + {Items.chartiBerry, 100}, + {Items.kasibBerry, 100}, + {Items.habanBerry, 100}, + {Items.colburBerry, 100}, + {Items.babiriBerry, 100}, + {Items.chilanBerry, 100}, + {Items.liechiBerry, 100}, + {Items.ganlonBerry, 100}, + {Items.salacBerry, 100}, + {Items.petayaBerry, 100}, + {Items.apicotBerry, 100}, + {Items.lansatBerry, 100}, + {Items.starfBerry, 100}, + {Items.enigmaBerry, 100}, + {Items.micleBerry, 100}, + {Items.custapBerry, 100}, + {Items.jabocaBerry, 100}, + {Items.rowapBerry, 100}, + {Items.brightPowder, 300}, + {Items.whiteHerb, 100}, + {Items.machoBrace, 300}, + {Items.expShare, 600}, + {Items.quickClaw, 450}, + {Items.sootheBell, 100}, + {Items.mentalHerb, 100}, + {Items.choiceBand, 1000}, + {Items.kingsRock, 500}, + {Items.silverPowder, 200}, + {Items.amuletCoin, 1500}, + {Items.cleanseTag, 100}, + {Items.soulDew, 20}, + {Items.deepSeaTooth, 300}, + {Items.deepSeaScale, 300}, + {Items.smokeBall, 20}, + {Items.everstone, 20}, + {Items.focusBand, 300}, + {Items.luckyEgg, 1000}, + {Items.scopeLens, 500}, + {Items.metalCoat, 300}, + {Items.leftovers, 1000}, + {Items.dragonScale, 300}, + {Items.lightBall, 10}, + {Items.softSand, 200}, + {Items.hardStone, 200}, + {Items.miracleSeed, 200}, + {Items.blackGlasses, 200}, + {Items.blackBelt, 200}, + {Items.magnet, 200}, + {Items.mysticWater, 200}, + {Items.sharpBeak, 200}, + {Items.poisonBarb, 200}, + {Items.neverMeltIce, 200}, + {Items.spellTag, 200}, + {Items.twistedSpoon, 200}, + {Items.charcoal, 200}, + {Items.dragonFang, 200}, + {Items.silkScarf, 200}, + {Items.upgrade, 300}, + {Items.shellBell, 600}, + {Items.seaIncense, 200}, + {Items.laxIncense, 300}, + {Items.luckyPunch, 1}, + {Items.metalPowder, 1}, + {Items.thickClub, 50}, + {Items.leek, 20}, + {Items.redScarf, 10}, + {Items.blueScarf, 10}, + {Items.pinkScarf, 10}, + {Items.greenScarf, 10}, + {Items.yellowScarf, 10}, + {Items.wideLens, 150}, + {Items.muscleBand, 200}, + {Items.wiseGlasses, 200}, + {Items.expertBelt, 600}, + {Items.lightClay, 150}, + {Items.lifeOrb, 1000}, + {Items.powerHerb, 100}, + {Items.toxicOrb, 150}, + {Items.flameOrb, 150}, + {Items.quickPowder, 1}, + {Items.focusSash, 200}, + {Items.zoomLens, 150}, + {Items.metronome, 300}, + {Items.ironBall, 100}, + {Items.laggingTail, 100}, + {Items.destinyKnot, 150}, + {Items.blackSludge, 500}, + {Items.icyRock, 20}, + {Items.smoothRock, 20}, + {Items.heatRock, 20}, + {Items.dampRock, 20}, + {Items.gripClaw, 150}, + {Items.choiceScarf, 1000}, + {Items.stickyBarb, 150}, + {Items.powerBracer, 300}, + {Items.powerBelt, 300}, + {Items.powerLens, 300}, + {Items.powerBand, 300}, + {Items.powerAnklet, 300}, + {Items.powerWeight, 300}, + {Items.shedShell, 50}, + {Items.bigRoot, 150}, + {Items.choiceSpecs, 1000}, + {Items.flamePlate, 200}, + {Items.splashPlate, 200}, + {Items.zapPlate, 200}, + {Items.meadowPlate, 200}, + {Items.iciclePlate, 200}, + {Items.fistPlate, 200}, + {Items.toxicPlate, 200}, + {Items.earthPlate, 200}, + {Items.skyPlate, 200}, + {Items.mindPlate, 200}, + {Items.insectPlate, 200}, + {Items.stonePlate, 200}, + {Items.spookyPlate, 200}, + {Items.dracoPlate, 200}, + {Items.dreadPlate, 200}, + {Items.ironPlate, 200}, + {Items.oddIncense, 200}, + {Items.rockIncense, 200}, + {Items.fullIncense, 100}, + {Items.waveIncense, 200}, + {Items.roseIncense, 200}, + {Items.luckIncense, 1500}, + {Items.pureIncense, 100}, + {Items.protector, 300}, + {Items.electirizer, 300}, + {Items.magmarizer, 300}, + {Items.dubiousDisc, 300}, + {Items.reaperCloth, 300}, + {Items.razorClaw, 500}, + {Items.razorFang, 500}, + {Items.tm01, 300}, + {Items.tm02, 300}, + {Items.tm03, 300}, + {Items.tm04, 150}, + {Items.tm05, 100}, + {Items.tm06, 300}, + {Items.tm07, 200}, + {Items.tm08, 150}, + {Items.tm09, 200}, + {Items.tm10, 200}, + {Items.tm11, 200}, + {Items.tm12, 150}, + {Items.tm13, 300}, + {Items.tm14, 550}, + {Items.tm15, 750}, + {Items.tm16, 200}, + {Items.tm17, 200}, + {Items.tm18, 200}, + {Items.tm19, 300}, + {Items.tm20, 200}, + {Items.tm21, 100}, + {Items.tm22, 300}, + {Items.tm23, 300}, + {Items.tm24, 300}, + {Items.tm25, 550}, + {Items.tm26, 300}, + {Items.tm27, 100}, + {Items.tm28, 200}, + {Items.tm29, 300}, + {Items.tm30, 300}, + {Items.tm31, 300}, + {Items.tm32, 100}, + {Items.tm33, 200}, + {Items.tm34, 300}, + {Items.tm35, 300}, + {Items.tm36, 300}, + {Items.tm37, 200}, + {Items.tm38, 550}, + {Items.tm39, 200}, + {Items.tm40, 300}, + {Items.tm41, 150}, + {Items.tm42, 300}, + {Items.tm43, 200}, + {Items.tm44, 300}, + {Items.tm45, 300}, + {Items.tm46, 200}, + {Items.tm47, 300}, + {Items.tm48, 300}, + {Items.tm49, 150}, + {Items.tm50, 550}, + {Items.tm51, 200}, + {Items.tm52, 550}, + {Items.tm53, 300}, + {Items.tm54, 200}, + {Items.tm55, 300}, + {Items.tm56, 200}, + {Items.tm57, 300}, + {Items.tm58, 200}, + {Items.tm59, 300}, + {Items.tm60, 300}, + {Items.tm61, 200}, + {Items.tm62, 300}, + {Items.tm63, 200}, + {Items.tm64, 750}, + {Items.tm65, 300}, + {Items.tm66, 300}, + {Items.tm67, 100}, + {Items.tm68, 750}, + {Items.tm69, 150}, + {Items.tm70, 100}, + {Items.tm71, 300}, + {Items.tm72, 300}, + {Items.tm73, 200}, + {Items.tm74, 300}, + {Items.tm75, 150}, + {Items.tm76, 200}, + {Items.tm77, 150}, + {Items.tm78, 150}, + {Items.tm79, 300}, + {Items.tm80, 300}, + {Items.tm81, 300}, + {Items.tm82, 100}, + {Items.tm83, 200}, + {Items.tm84, 300}, + {Items.tm85, 300}, + {Items.tm86, 300}, + {Items.tm87, 150}, + {Items.tm88, 300}, + {Items.tm89, 300}, + {Items.tm90, 200}, + {Items.tm91, 300}, + {Items.tm92, 550}, + {Items.hm01, 0}, + {Items.hm02, 0}, + {Items.hm03, 0}, + {Items.hm04, 0}, + {Items.hm05, 0}, + {Items.hm06, 0}, + {Items.hm07, 0}, + {Items.hm08, 0}, + {Items.explorerKit, 0}, + {Items.lootSack, 0}, + {Items.ruleBook, 0}, + {Items.pokeRadar, 0}, + {Items.pointCard, 0}, + {Items.journal, 0}, + {Items.sealCase, 0}, + {Items.fashionCase, 0}, + {Items.sealBag, 0}, + {Items.palPad, 0}, + {Items.worksKey, 0}, + {Items.oldCharm, 0}, + {Items.galacticKey, 0}, + {Items.redChain, 0}, + {Items.townMap, 0}, + {Items.vsSeeker, 0}, + {Items.coinCase, 0}, + {Items.oldRod, 0}, + {Items.goodRod, 0}, + {Items.superRod, 0}, + {Items.sprayduck, 0}, + {Items.poffinCase, 0}, + {Items.bike, 0}, + {Items.suiteKey, 0}, + {Items.oaksLetter, 0}, + {Items.lunarWing, 0}, + {Items.memberCard, 0}, + {Items.azureFlute, 0}, + {Items.ssTicketJohto, 0}, + {Items.contestPass, 0}, + {Items.magmaStone, 0}, + {Items.parcelSinnoh, 0}, + {Items.coupon1, 0}, + {Items.coupon2, 0}, + {Items.coupon3, 0}, + {Items.storageKeySinnoh, 0}, + {Items.secretPotion, 0}, + {Items.vsRecorder, 0}, + {Items.gracidea, 0}, + {Items.secretKeySinnoh, 0}, + {Items.apricornBox, 0}, + {Items.unownReport, 0}, + {Items.berryPots, 0}, + {Items.dowsingMachine, 0}, + {Items.blueCard, 0}, + {Items.slowpokeTail, 0}, + {Items.clearBell, 0}, + {Items.cardKeyJohto, 0}, + {Items.basementKeyJohto, 0}, + {Items.squirtBottle, 0}, + {Items.redScale, 0}, + {Items.lostItem, 0}, + {Items.pass, 0}, + {Items.machinePart, 0}, + {Items.silverWing, 0}, + {Items.rainbowWing, 0}, + {Items.mysteryEgg, 0}, + {Items.redApricorn, 2}, + {Items.blueApricorn, 2}, + {Items.yellowApricorn, 2}, + {Items.greenApricorn, 2}, + {Items.pinkApricorn, 2}, + {Items.whiteApricorn, 2}, + {Items.blackApricorn, 2}, + {Items.fastBall, 30}, + {Items.levelBall, 30}, + {Items.lureBall, 30}, + {Items.heavyBall, 30}, + {Items.loveBall, 30}, + {Items.friendBall, 30}, + {Items.moonBall, 30}, + {Items.sportBall, 30}, + {Items.parkBall, 0}, + {Items.photoAlbum, 0}, + {Items.gbSounds, 0}, + {Items.tidalBell, 0}, + {Items.rageCandyBar, 0}, + {Items.dataCard01, 0}, + {Items.dataCard02, 0}, + {Items.dataCard03, 0}, + {Items.dataCard04, 0}, + {Items.dataCard05, 0}, + {Items.dataCard06, 0}, + {Items.dataCard07, 0}, + {Items.dataCard08, 0}, + {Items.dataCard09, 0}, + {Items.dataCard10, 0}, + {Items.dataCard11, 0}, + {Items.dataCard12, 0}, + {Items.dataCard13, 0}, + {Items.dataCard14, 0}, + {Items.dataCard15, 0}, + {Items.dataCard16, 0}, + {Items.dataCard17, 0}, + {Items.dataCard18, 0}, + {Items.dataCard19, 0}, + {Items.dataCard20, 0}, + {Items.dataCard21, 0}, + {Items.dataCard22, 0}, + {Items.dataCard23, 0}, + {Items.dataCard24, 0}, + {Items.dataCard25, 0}, + {Items.dataCard26, 0}, + {Items.dataCard27, 0}, + {Items.jadeOrb, 0}, + {Items.lockCapsule, 0}, + {Items.redOrb, 0}, + {Items.blueOrb, 0}, + {Items.enigmaStone, 0}, + }).collect(Collectors.toMap(kv -> kv[0], kv -> kv[1])); + + public static final Type[] typeTable = constructTypeTable(); + + private static Type[] constructTypeTable() { + Type[] table = new Type[256]; + table[0x00] = Type.NORMAL; + table[0x01] = Type.FIGHTING; + table[0x02] = Type.FLYING; + table[0x03] = Type.POISON; + table[0x04] = Type.GROUND; + table[0x05] = Type.ROCK; + table[0x06] = Type.BUG; + table[0x07] = Type.GHOST; + table[0x08] = Type.STEEL; + table[0x0A] = Type.FIRE; + table[0x0B] = Type.WATER; + table[0x0C] = Type.GRASS; + table[0x0D] = Type.ELECTRIC; + table[0x0E] = Type.PSYCHIC; + table[0x0F] = Type.ICE; + table[0x10] = Type.DRAGON; + table[0x11] = Type.DARK; + return table; + } + + public static byte typeToByte(Type type) { + if (type == null) { + return 0x09; // ???-type + } + switch (type) { + case NORMAL: + return 0x00; + case FIGHTING: + return 0x01; + case FLYING: + return 0x02; + case POISON: + return 0x03; + case GROUND: + return 0x04; + case ROCK: + return 0x05; + case BUG: + return 0x06; + case GHOST: + return 0x07; + case FIRE: + return 0x0A; + case WATER: + return 0x0B; + case GRASS: + return 0x0C; + case ELECTRIC: + return 0x0D; + case PSYCHIC: + return 0x0E; + case ICE: + return 0x0F; + case DRAGON: + return 0x10; + case STEEL: + return 0x08; + case DARK: + return 0x11; + default: + return 0; // normal by default + } + } + + public static int getFormeCount(int romType) { + if (romType == Type_DP) { + return dpFormeCount; + } else if (romType == Type_Plat || romType == Type_HGSS) { + return platHgSsFormeCount; + } + return 0; + } + + private static Map<Integer,String> setupFormeSuffixes() { + Map<Integer,String> formeSuffixes = new HashMap<>(); + formeSuffixes.put(Species.Gen4Formes.deoxysA + formeOffset,"-A"); + formeSuffixes.put(Species.Gen4Formes.deoxysD + formeOffset,"-D"); + formeSuffixes.put(Species.Gen4Formes.deoxysS + formeOffset,"-S"); + formeSuffixes.put(Species.Gen4Formes.wormadamS + formeOffset,"-S"); + formeSuffixes.put(Species.Gen4Formes.wormadamT + formeOffset,"-T"); + formeSuffixes.put(Species.Gen4Formes.giratinaO + formeOffset,"-O"); + formeSuffixes.put(Species.Gen4Formes.shayminS + formeOffset,"-S"); + formeSuffixes.put(Species.Gen4Formes.rotomH + formeOffset,"-H"); + formeSuffixes.put(Species.Gen4Formes.rotomW + formeOffset,"-W"); + formeSuffixes.put(Species.Gen4Formes.rotomFr + formeOffset,"-Fr"); + formeSuffixes.put(Species.Gen4Formes.rotomFa + formeOffset,"-Fa"); + formeSuffixes.put(Species.Gen4Formes.rotomM + formeOffset,"-M"); + return formeSuffixes; + } + + private static Map<Integer,FormeInfo> setupFormeMappings() { + Map<Integer,FormeInfo> formeMappings = new TreeMap<>(); + + formeMappings.put(Species.Gen4Formes.deoxysA + formeOffset,new FormeInfo(Species.deoxys,1, 0)); + formeMappings.put(Species.Gen4Formes.deoxysD + formeOffset,new FormeInfo(Species.deoxys,2, 0)); + formeMappings.put(Species.Gen4Formes.deoxysS + formeOffset,new FormeInfo(Species.deoxys,3, 0)); + formeMappings.put(Species.Gen4Formes.wormadamS + formeOffset,new FormeInfo(Species.wormadam,1, 0)); + formeMappings.put(Species.Gen4Formes.wormadamT + formeOffset,new FormeInfo(Species.wormadam,2, 0)); + formeMappings.put(Species.Gen4Formes.giratinaO + formeOffset,new FormeInfo(Species.giratina,1, 0)); + formeMappings.put(Species.Gen4Formes.shayminS + formeOffset,new FormeInfo(Species.shaymin,1, 0)); + formeMappings.put(Species.Gen4Formes.rotomH + formeOffset,new FormeInfo(Species.rotom,1, 0)); + formeMappings.put(Species.Gen4Formes.rotomW + formeOffset,new FormeInfo(Species.rotom,2, 0)); + formeMappings.put(Species.Gen4Formes.rotomFr + formeOffset,new FormeInfo(Species.rotom,3, 0)); + formeMappings.put(Species.Gen4Formes.rotomFa + formeOffset,new FormeInfo(Species.rotom,4, 0)); + formeMappings.put(Species.Gen4Formes.rotomM + formeOffset,new FormeInfo(Species.rotom,5, 0)); + + return formeMappings; + } + + private static Map<Integer,Integer> setupCosmeticForms() { + Map<Integer,Integer> cosmeticForms = new TreeMap<>(); + + cosmeticForms.put(Species.unown, 28); + cosmeticForms.put(Species.burmy, 3); + cosmeticForms.put(Species.shellos, 2); + cosmeticForms.put(Species.gastrodon, 2); + return cosmeticForms; + } + + private static Map<Integer,Map<Integer,String>> setupFormeSuffixesByBaseForme() { + Map<Integer,Map<Integer,String>> map = new HashMap<>(); + + Map<Integer,String> deoxysMap = new HashMap<>(); + deoxysMap.put(1,"-A"); + deoxysMap.put(2,"-D"); + deoxysMap.put(3,"-S"); + map.put(Species.deoxys,deoxysMap); + + Map<Integer,String> wormadamMap = new HashMap<>(); + wormadamMap.put(1,"-S"); + wormadamMap.put(2,"-T"); + map.put(Species.wormadam,wormadamMap); + + Map<Integer,String> shayminMap = new HashMap<>(); + shayminMap.put(1,"-S"); + map.put(Species.shaymin,shayminMap); + + Map<Integer,String> giratinaMap = new HashMap<>(); + giratinaMap.put(1,"-O"); + map.put(Species.giratina,giratinaMap); + + Map<Integer,String> rotomMap = new HashMap<>(); + rotomMap.put(1,"-H"); + rotomMap.put(2,"-W"); + rotomMap.put(3,"-Fr"); + rotomMap.put(4,"-Fa"); + rotomMap.put(5,"-M"); + map.put(Species.rotom,rotomMap); + + return map; + } + + private static Map<Integer,String> setupDummyFormeSuffixes() { + Map<Integer,String> m = new HashMap<>(); + m.put(0,""); + return m; + } + + private static Map<Integer,Map<Integer,Integer>> setupAbsolutePokeNumsByBaseForme() { + Map<Integer,Map<Integer,Integer>> map = new HashMap<>(); + + Map<Integer,Integer> deoxysMap = new HashMap<>(); + deoxysMap.put(1,Species.Gen4Formes.deoxysA); + deoxysMap.put(2,Species.Gen4Formes.deoxysD); + deoxysMap.put(3,Species.Gen4Formes.deoxysS); + map.put(Species.deoxys, deoxysMap); + + Map<Integer,Integer> wormadamMap = new HashMap<>(); + wormadamMap.put(1,Species.Gen4Formes.wormadamS); + wormadamMap.put(2,Species.Gen4Formes.wormadamT); + map.put(Species.wormadam, wormadamMap); + + Map<Integer,Integer> giratinaMap = new HashMap<>(); + giratinaMap.put(1,Species.Gen4Formes.giratinaO); + map.put(Species.giratina, giratinaMap); + + Map<Integer,Integer> shayminMap = new HashMap<>(); + shayminMap.put(1,Species.Gen4Formes.shayminS); + map.put(Species.shaymin, shayminMap); + + Map<Integer,Integer> rotomMap = new HashMap<>(); + rotomMap.put(1,Species.Gen4Formes.rotomH); + rotomMap.put(2,Species.Gen4Formes.rotomW); + rotomMap.put(3,Species.Gen4Formes.rotomFr); + rotomMap.put(4,Species.Gen4Formes.rotomFa); + rotomMap.put(5,Species.Gen4Formes.rotomM); + map.put(Species.rotom, rotomMap); + + return map; + } + + private static Map<Integer,Integer> setupDummyAbsolutePokeNums() { + Map<Integer,Integer> m = new HashMap<>(); + m.put(255,0); + return m; + } + + public static void tagTrainersDP(List<Trainer> trs) { + // Gym Trainers + tag(trs, "GYM1", 0xf4, 0xf5); + tag(trs, "GYM2", 0x144, 0x103, 0x104, 0x15C); + tag(trs, "GYM3", 0x135, 0x136, 0x137, 0x138); + tag(trs, "GYM4", 0x1f1, 0x1f2, 0x191, 0x153, 0x125, 0x1E3); + tag(trs, "GYM5", 0x165, 0x145, 0x10a, 0x14a, 0x154, 0x157, 0x118, 0x11c); + tag(trs, "GYM6", 0x13a, 0x100, 0x101, 0x117, 0x16f, 0xe8, 0x11b); + tag(trs, "GYM7", 0x10c, 0x10d, 0x10e, 0x10f, 0x33b, 0x33c); + tag(trs, "GYM8", 0x158, 0x155, 0x12d, 0x12e, 0x12f, 0x11d, 0x119); + + // Gym Leaders + tag(trs, 0xf6, "GYM1-LEADER"); + tag(trs, 0x13b, "GYM2-LEADER"); + tag(trs, 0x13d, "GYM3-LEADER"); // Maylene + tag(trs, 0x13c, "GYM4-LEADER"); // Wake + tag(trs, 0x13e, "GYM5-LEADER"); // Fantina + tag(trs, 0xfa, "GYM6-LEADER"); // Byron + tag(trs, 0x13f, "GYM7-LEADER"); // Candice + tag(trs, 0x140, "GYM8-LEADER"); // Volkner + + // Elite 4 + tag(trs, 0x105, "ELITE1"); + tag(trs, 0x106, "ELITE2"); + tag(trs, 0x107, "ELITE3"); + tag(trs, 0x108, "ELITE4"); + tag(trs, 0x10b, "CHAMPION"); + + // Rival battles (8) + tagRivalConsecutive(trs, "RIVAL1", 0xf8); + tagRivalConsecutive(trs, "RIVAL2", 0x1d7); + tagRivalConsecutive(trs, "RIVAL3", 0x1da); + tagRivalConsecutive(trs, "RIVAL4", 0x1dd); + // Tag battle is not following ze usual format + tag(trs, 0x26b, "RIVAL5-0"); + tag(trs, 0x26c, "RIVAL5-1"); + tag(trs, 0x25f, "RIVAL5-2"); + // Back to normal + tagRivalConsecutive(trs, "RIVAL6", 0x1e0); + tagRivalConsecutive(trs, "RIVAL7", 0x346); + tagRivalConsecutive(trs, "RIVAL8", 0x349); + + // Themed + tag(trs, "THEMED:CYRUS-LEADER", 0x193, 0x194); + tag(trs, "THEMED:MARS-STRONG", 0x127, 0x195, 0x210); + tag(trs, "THEMED:JUPITER-STRONG", 0x196, 0x197); + tag(trs, "THEMED:SATURN-STRONG", 0x198, 0x199); + + // Lucas & Dawn tag battles + tagFriendConsecutive(trs, "FRIEND1", 0x265); + tagFriendConsecutive(trs, "FRIEND1", 0x268); + tagFriendConsecutive2(trs, "FRIEND2", 0x26D); + tagFriendConsecutive2(trs, "FRIEND2", 0x270); + + } + + public static void tagTrainersPt(List<Trainer> trs) { + // Gym Trainers + tag(trs, "GYM1", 0xf4, 0xf5); + tag(trs, "GYM2", 0x144, 0x103, 0x104, 0x15C); + tag(trs, "GYM3", 0x165, 0x145, 0x154, 0x157, 0x118, 0x11c); + tag(trs, "GYM4", 0x135, 0x136, 0x137, 0x138); + tag(trs, "GYM5", 0x1f1, 0x1f2, 0x191, 0x153, 0x125, 0x1E3); + tag(trs, "GYM6", 0x13a, 0x100, 0x101, 0x117, 0x16f, 0xe8, 0x11b); + tag(trs, "GYM7", 0x10c, 0x10d, 0x10e, 0x10f, 0x33b, 0x33c); + tag(trs, "GYM8", 0x158, 0x155, 0x12d, 0x12e, 0x12f, 0x11d, 0x119, 0x14b); + + // Gym Leaders + tag(trs, 0xf6, "GYM1-LEADER"); + tag(trs, 0x13b, "GYM2-LEADER"); + tag(trs, 0x13e, "GYM3-LEADER"); // Fantina + tag(trs, 0x13d, "GYM4-LEADER"); // Maylene + tag(trs, 0x13c, "GYM5-LEADER"); // Wake + tag(trs, 0xfa, "GYM6-LEADER"); // Byron + tag(trs, 0x13f, "GYM7-LEADER"); // Candice + tag(trs, 0x140, "GYM8-LEADER"); // Volkner + + // Elite 4 + tag(trs, 0x105, "ELITE1"); + tag(trs, 0x106, "ELITE2"); + tag(trs, 0x107, "ELITE3"); + tag(trs, 0x108, "ELITE4"); + tag(trs, 0x10b, "CHAMPION"); + + // Rival battles (10) + tagRivalConsecutive(trs, "RIVAL1", 0x353); + tagRivalConsecutive(trs, "RIVAL2", 0xf8); + tagRivalConsecutive(trs, "RIVAL3", 0x1d7); + tagRivalConsecutive(trs, "RIVAL4", 0x1da); + tagRivalConsecutive(trs, "RIVAL5", 0x1dd); + // Tag battle is not following ze usual format + tag(trs, 0x26b, "RIVAL6-0"); + tag(trs, 0x26c, "RIVAL6-1"); + tag(trs, 0x25f, "RIVAL6-2"); + // Back to normal + tagRivalConsecutive(trs, "RIVAL7", 0x1e0); + tagRivalConsecutive(trs, "RIVAL8", 0x346); + tagRivalConsecutive(trs, "RIVAL9", 0x349); + tagRivalConsecutive(trs, "RIVAL10", 0x368); + + // Battleground Gym Leaders + tag(trs, 0x35A, "GYM1"); + tag(trs, 0x359, "GYM2"); + tag(trs, 0x35C, "GYM3"); + tag(trs, 0x356, "GYM4"); + tag(trs, 0x35B, "GYM5"); + tag(trs, 0x358, "GYM6"); + tag(trs, 0x355, "GYM7"); + tag(trs, 0x357, "GYM8"); + + // Match vs Volkner and Flint in Battle Frontier + tag(trs, 0x399, "GYM8"); + tag(trs, 0x39A, "ELITE3"); + + // E4 rematch + tag(trs, 0x362, "ELITE1"); + tag(trs, 0x363, "ELITE2"); + tag(trs, 0x364, "ELITE3"); + tag(trs, 0x365, "ELITE4"); + tag(trs, 0x366, "CHAMPION"); + + // Themed + tag(trs, "THEMED:CYRUS-LEADER", 0x391, 0x193, 0x194); + tag(trs, "THEMED:MARS-STRONG", 0x127, 0x195, 0x210, 0x39e); + tag(trs, "THEMED:JUPITER-STRONG", 0x196, 0x197, 0x39f); + tag(trs, "THEMED:SATURN-STRONG", 0x198, 0x199); + + // Lucas & Dawn tag battles + tagFriendConsecutive(trs, "FRIEND1", 0x265); + tagFriendConsecutive(trs, "FRIEND1", 0x268); + tagFriendConsecutive2(trs, "FRIEND2", 0x26D); + tagFriendConsecutive2(trs, "FRIEND2", 0x270); + + } + + public static void tagTrainersHGSS(List<Trainer> trs) { + // Gym Trainers + tag(trs, "GYM1", 0x32, 0x1D); + tag(trs, "GYM2", 0x43, 0x44, 0x45, 0x0a); + tag(trs, "GYM3", 0x05, 0x46, 0x47, 0x16); + tag(trs, "GYM4", 0x1ed, 0x1ee, 0x59, 0x2e); + tag(trs, "GYM5", 0x9c, 0x9d, 0x9f, 0xfb); + tag(trs, "GYM7", 0x1e0, 0x1e1, 0x1e2, 0x1e3, 0x1e4); + tag(trs, "GYM8", 0x6e, 0x6f, 0x70, 0x75, 0x77); + + tag(trs, "GYM9", 0x134, 0x2ad); + tag(trs, "GYM10", 0x2a4, 0x2a5, 0x2a6, 0x129, 0x12a); + tag(trs, "GYM11", 0x18c, 0xe8, 0x151); + tag(trs, "GYM12", 0x150, 0x146, 0x164, 0x15a); + tag(trs, "GYM13", 0x53, 0x54, 0xb7, 0x88); + tag(trs, "GYM14", 0x170, 0x171, 0xe6, 0x19f); + tag(trs, "GYM15", 0x2b1, 0x2b2, 0x2b3, 0x2b4, 0x2b5, 0x2b6); + tag(trs, "GYM16", 0x2a9, 0x2aa, 0x2ab, 0x2ac); + + // Gym Leaders + tag(trs, 0x14, "GYM1-LEADER"); + tag(trs, 0x15, "GYM2-LEADER"); + tag(trs, 0x1e, "GYM3-LEADER"); + tag(trs, 0x1f, "GYM4-LEADER"); + tag(trs, 0x22, "GYM5-LEADER"); + tag(trs, 0x21, "GYM6-LEADER"); + tag(trs, 0x20, "GYM7-LEADER"); + tag(trs, 0x23, "GYM8-LEADER"); + + tag(trs, 0xFD, "GYM9-LEADER"); + tag(trs, 0xFE, "GYM10-LEADER"); + tag(trs, 0xFF, "GYM11-LEADER"); + tag(trs, 0x100, "GYM12-LEADER"); + tag(trs, 0x101, "GYM13-LEADER"); + tag(trs, 0x102, "GYM14-LEADER"); + tag(trs, 0x103, "GYM15-LEADER"); + tag(trs, 0x105, "GYM16-LEADER"); + + // Elite 4 + tag(trs, 0xf5, "ELITE1"); + tag(trs, 0xf7, "ELITE2"); + tag(trs, 0x1a2, "ELITE3"); + tag(trs, 0xf6, "ELITE4"); + tag(trs, 0xf4, "CHAMPION"); + + // Red + tag(trs, 0x104, "UBER"); + + // Gym Rematches + tag(trs, 0x2c8, "GYM1-LEADER"); + tag(trs, 0x2c9, "GYM2-LEADER"); + tag(trs, 0x2ca, "GYM3-LEADER"); + tag(trs, 0x2cb, "GYM4-LEADER"); + tag(trs, 0x2ce, "GYM5-LEADER"); + tag(trs, 0x2cd, "GYM6-LEADER"); + tag(trs, 0x2cc, "GYM7-LEADER"); + tag(trs, 0x2cf, "GYM8-LEADER"); + + tag(trs, 0x2d0, "GYM9-LEADER"); + tag(trs, 0x2d1, "GYM10-LEADER"); + tag(trs, 0x2d2, "GYM11-LEADER"); + tag(trs, 0x2d3, "GYM12-LEADER"); + tag(trs, 0x2d4, "GYM13-LEADER"); + tag(trs, 0x2d5, "GYM14-LEADER"); + tag(trs, 0x2d6, "GYM15-LEADER"); + tag(trs, 0x2d7, "GYM16-LEADER"); + + // Elite 4 Rematch + tag(trs, 0x2be, "ELITE1"); + tag(trs, 0x2bf, "ELITE2"); + tag(trs, 0x2c0, "ELITE3"); + tag(trs, 0x2c1, "ELITE4"); + tag(trs, 0x2bd, "CHAMPION"); + + // Rival Battles + tagRivalConsecutive(trs, "RIVAL1", 0x1F0); + + tag(trs, 0x10a, "RIVAL2-0"); + tag(trs, 0x10d, "RIVAL2-1"); + tag(trs, 0x1, "RIVAL2-2"); + + tag(trs, 0x10B, "RIVAL3-0"); + tag(trs, 0x10E, "RIVAL3-1"); + tag(trs, 0x107, "RIVAL3-2"); + + tag(trs, 0x121, "RIVAL4-0"); + tag(trs, 0x10f, "RIVAL4-1"); + tag(trs, 0x120, "RIVAL4-2"); + + tag(trs, 0x10C, "RIVAL5-0"); + tag(trs, 0x110, "RIVAL5-1"); + tag(trs, 0x108, "RIVAL5-2"); + + tagRivalConsecutive(trs, "RIVAL6", 0x11e); + tagRivalConsecutive(trs, "RIVAL7", 0x2e0); // dragons den tag battle + tagRivalConsecutive(trs, "RIVAL8", 0x1EA); + + // Clair & Lance match in Dragons Den + tag(trs, 0x2DE, "GYM8"); + tag(trs, 0x2DD, "CHAMPION"); + + tag(trs, 0xa0, "KIMONO1-STRONG"); + tag(trs, 0xa1, "KIMONO2-STRONG"); + tag(trs, 0xa2, "KIMONO3-STRONG"); + tag(trs, 0xa3, "KIMONO4-STRONG"); + tag(trs, 0xa4, "KIMONO5-STRONG"); + + // Themed + tag(trs, "THEMED:ARIANA-STRONG", 0x1df, 0x1de); + tag(trs, "THEMED:PETREL-STRONG", 0x1e8, 0x1e7); + tag(trs, "THEMED:PROTON-STRONG", 0x1e6, 0x2c2); + tag(trs, "THEMED:SPROUTTOWER", 0x2b, 0x33, 0x34, 0x35, 0x36, 0x37, 0x122); + + tag(trs,"LEADER",485); // Archer + } + + private static void tag(List<Trainer> allTrainers, int number, String tag) { + allTrainers.get(number - 1).tag = tag; + } + + private static void tag(List<Trainer> allTrainers, String tag, int... numbers) { + for (int num : numbers) { + allTrainers.get(num - 1).tag = tag; + } + } + + private static void tagRivalConsecutive(List<Trainer> allTrainers, String tag, int offsetFire) { + allTrainers.get(offsetFire - 1).tag = tag + "-0"; + allTrainers.get(offsetFire).tag = tag + "-1"; + allTrainers.get(offsetFire - 2).tag = tag + "-2"; + + } + + private static void tagFriendConsecutive(List<Trainer> allTrainers, String tag, int offsetGrass) { + allTrainers.get(offsetGrass - 1).tag = tag + "-1"; + allTrainers.get(offsetGrass).tag = tag + "-2"; + allTrainers.get(offsetGrass + 1).tag = tag + "-0"; + + } + + private static void tagFriendConsecutive2(List<Trainer> allTrainers, String tag, int offsetWater) { + allTrainers.get(offsetWater - 1).tag = tag + "-0"; + allTrainers.get(offsetWater).tag = tag + "-1"; + allTrainers.get(offsetWater + 1).tag = tag + "-2"; + + } + + public static void setMultiBattleStatusDP(List<Trainer> trs) { + // 407 + 528: Commander Mars and Commander Jupiter Multi Battle on Spear Pillar + // 414 + 415: Galactic Grunts in Jubilife City + // 419 + 426: Galactic Grunts in Lake Verity + // 420 + 427: Galactic Grunts in Lake Verity + // 521 + 527: Galactic Grunts on Spear Pillar + // 561 + 590: Double Battle with Dragon Tamer Drake and Black Belt Jarrett + // 835 + 836: Galactic Grunts in Iron Island + // 848 + 849: Galactic Grunts in Veilstone City + setMultiBattleStatus(trs, Trainer.MultiBattleStatus.ALWAYS, 414, 415, 419, 420, 426, 427, 521, 527, + 528, 561, 590, 835, 836, 848, 849 + ); + + // 34 + 35: Potential Double Battle with Camper Anthony and Picnicker Lauren + // 82 + 83: Potential Double Battle with Rich Boy Jason and Lady Melissa + // 84 + 85: Potential Double Battle with Gentleman Jeremy and Socialite Reina + // 95 + 96: Potential Double Battle with PKMN Ranger Jeffrey and PKMN Ranger Allison + // 104 + 106: Potential Double Battle with Swimmer Evan and Swimmer Mary + // 160 + 494: Potential Double Battle with Swimmer Erik and Swimmer Claire + // 186 + 191: Potential Double Battle with Swimmer Colton and Swimmer Paige + // 201 + 204: Potential Double Battle with Bug Catcher Jack and Lass Briana + // 202 + 203: Potential Double Battle with Bug Catcher Phillip and Bug Catcher Donald + // 205 + 206: Potential Double Battle with Psychic Elijah and Psychic Lindsey + // 278 + 287: Potential Double Battle with Ace Trainer Maya and Ace Trainer Dennis + // 337 + 359: Potential Double Battle with Sailor Marc and Tuber Conner + // 358 + 360: Potential Double Battle with Tuber Trenton and Tuber Mariel + // 372 + 445: Potential Double Battle with Battle Girl Tyler and Black Belt Kendal + // 373 + 386: Potential Double Battle with Bird Keeper Autumn and Dragon Tamer Joe + // 379 + 459: Potential Double Battle with Camper Diego and Picnicker Ana + // 383 + 443: Potential Double Battle with Collector Terry and Ruin Maniac Gerald + // 388 + 392: Potential Double Battle with Ace Trainer Jonah and Ace Trainer Brenda + // 389 + 393: Potential Double Battle with Ace Trainer Micah and Ace Trainer Brandi + // 390 + 394: Potential Double Battle with Ace Trainer Arthur and Ace Trainer Clarice + // 395 + 398: Potential Double Battle with Psychic Kody and Psychic Rachael + // 396 + 399: Potential Double Battle with Psychic Landon and Psychic Desiree + // 397 + 400: Potential Double Battle with Psychic Deandre and Psychic Kendra + // 446 + 499: Potential Double Battle with Black Belt Eddie and Veteran Terrell + // 447 + 500: Potential Double Battle with Black Belt Willie and Veteran Brenden + // 450 + 496: Potential Double Battle with Lass Cassidy and Youngster Wayne + // 452 + 453: Potential Double Battle with Hiker Damon and Hiker Maurice + // 454 + 455: Potential Double Battle with Hiker Reginald and Hiker Lorenzo + // 505 + 506: Potential Double Battle with Worker Brendon and Worker Quentin + // 555 + 560: Potential Double Battle with Bird Keeper Geneva and Dragon Tamer Stanley + // 556 + 589: Potential Double Battle with Bird Keeper Krystal and Black Belt Ray + // 562 + 606: Potential Double Battle with Dragon Tamer Kenny and Veteran Harlan + // 566 + 575: Potential Double Battle with Ace Trainer Felix and Ace Trainer Dana + // 569 + 579: Potential Double Battle with Ace Trainer Keenan and Ace Trainer Kassandra + // 570 + 580: Potential Double Battle with Ace Trainer Stefan and Ace Trainer Jasmin + // 571 + 581: Potential Double Battle with Ace Trainer Skylar and Ace Trainer Natasha + // 572 + 582: Potential Double Battle with Ace Trainer Abel and Ace Trainer Monique + // 584 + 586: Potential Double Battle with Psychic Sterling and Psychic Chelsey + // 591 + 596: Potential Double Battle with PKMN Ranger Kyler and PKMN Ranger Krista + // 594 + 554/585: Potential Double Battle with PKMN Ranger Ashlee and either Bird Keeper Audrey or Psychic Daisy + // 599 + 602: Potential Double Battle with Swimmer Sam and Swimmer Sophia + setMultiBattleStatus(trs, Trainer.MultiBattleStatus.POTENTIAL, 34, 35, 82, 83, 84, 85, 95, 96, 104, + 106, 160, 186, 191, 201, 202, 203, 204, 205, 206, 278, 287, 337, 358, 359, 360, 372, 373, 379, 383, 386, + 388, 389, 390, 392, 393, 394, 395, 396, 397, 398, 399, 400, 443, 445, 446, 447, 450, 452, 453, 454, 455, + 459, 494, 496, 499, 500, 505, 506, 554, 555, 556, 560, 562, 566, 569, 570, 571, 572, 575, 579, 580, 581, + 582, 584, 585, 586, 589, 591, 594, 596, 599, 602, 606 + ); + } + + public static void setMultiBattleStatusPt(List<Trainer> trs) { + // In addition to every single trainer listed in setCouldBeMultiBattleDP... + // 921 + 922: Elite Four Flint and Leader Volkner Multi Battle in the Fight Area + setMultiBattleStatus(trs, Trainer.MultiBattleStatus.ALWAYS, 414, 415, 419, 420, 426, 427, 521, 527, + 528, 561, 590, 835, 836, 848, 849, 921, 922 + ); + setMultiBattleStatus(trs, Trainer.MultiBattleStatus.POTENTIAL, 34, 35, 82, 83, 84, 85, 95, 96, 104, + 106, 160, 186, 191, 201, 202, 203, 204, 205, 206, 278, 287, 337, 358, 359, 360, 372, 373, 379, 383, 386, + 388, 389, 390, 392, 393, 394, 395, 396, 397, 398, 399, 400, 443, 445, 446, 447, 450, 452, 453, 454, 455, + 459, 494, 496, 499, 500, 505, 506, 554, 555, 556, 560, 562, 566, 569, 570, 571, 572, 575, 579, 580, 581, + 582, 584, 585, 586, 589, 591, 594, 596, 599, 602, 606 + ); + } + + public static void setMultiBattleStatusHGSS(List<Trainer> trs) { + // 120 + 417: Double Battle with Ace Trainer Irene and Ace Trainer Jenn + // 354 + 355: Double Battle with Lass Laura and Lass Shannon + // 479 + 499: Multi Battle with Executive Ariana and Team Rocket Grunt in Team Rocket HQ + // 679 + 680: Double Battle with Beauty Callie and Beauty Kassandra + // 733 + 734: Multi Battle with Champion Lance and Leader Clair in the Dragon's Den + setMultiBattleStatus(trs, Trainer.MultiBattleStatus.ALWAYS, 120, 354, 355, 417, 479, 499, 679, 680, 733, 734); + + // 147 + 151: Potential Double Battle with Camper Ted and Picnicker Erin + // 423: Potential Double Battle with Pokéfan Jeremy. His potential teammate (Pokéfan Georgia) has more than + // three Pokemon in the vanilla game, so we leave her be. + // 564 + 567: Potential Double Battle with Teacher Clarice and School Kid Torin + // 575 + 576: Potential Double Battle with Biker Dan and Biker Theron + // 577 + 579: Potential Double Battle with Biker Markey and Biker Teddy + setMultiBattleStatus(trs, Trainer.MultiBattleStatus.POTENTIAL, 147, 151, 423, 564, 567, 575, 576, 577, 579); + } + + private static void setMultiBattleStatus(List<Trainer> allTrainers, Trainer.MultiBattleStatus status, int... numbers) { + for (int num : numbers) { + if (allTrainers.size() > (num - 1)) { + allTrainers.get(num - 1).multiBattleStatus = status; + } + } + } + +} |