pokefirered/src/pokemon.c
2019-10-21 10:42:24 -04:00

6588 lines
207 KiB
C

#define IS_POKEMON_C
#include "global.h"
#include "pokemon.h"
#include "random.h"
#include "main.h"
#include "text.h"
#include "data.h"
#include "string_util.h"
#include "battle.h"
#include "battle_main.h"
#include "item.h"
#include "event_data.h"
#include "util.h"
#include "pokemon_storage_system.h"
#include "battle_gfx_sfx_util.h"
#include "battle_controllers.h"
#include "evolution_scene.h"
#include "battle_message.h"
#include "battle_util.h"
#include "link.h"
#include "m4a.h"
#include "sound.h"
#include "pokedex.h"
#include "strings.h"
#include "malloc.h"
#include "overworld.h"
#include "party_menu.h"
#include "field_specials.h"
#include "constants/items.h"
#include "constants/item_effects.h"
#include "constants/species.h"
#include "constants/hoenn_cries.h"
#include "constants/pokemon.h"
#include "constants/abilities.h"
#include "constants/flags.h"
#include "constants/moves.h"
#include "constants/trainer_classes.h"
#include "constants/facility_trainer_classes.h"
#include "constants/hold_effects.h"
#include "constants/battle_move_effects.h"
// Extracts the upper 16 bits of a 32-bit number
#define HIHALF(n) (((n) & 0xFFFF0000) >> 16)
// Extracts the lower 16 bits of a 32-bit number
#define LOHALF(n) ((n) & 0xFFFF)
#define SPECIES_TO_HOENN(name) [SPECIES_##name - 1] = HOENN_DEX_##name
#define SPECIES_TO_NATIONAL(name) [SPECIES_##name - 1] = NATIONAL_DEX_##name
#define HOENN_TO_NATIONAL(name) [HOENN_DEX_##name - 1] = NATIONAL_DEX_##name
struct OakSpeechNidoranFStruct
{
u8 spriteCount:4;
u8 battlePosition:4;
u8 frameCount;
u8 enable;
bool8 enable2;
u32 sizePerSprite;
u8 *dataBuffer;
u8 **bufferPtrs;
struct SpriteTemplate *templates;
struct SpriteFrameImage *frameImages;
};
// TODO: move sLearningMoveTableID, gPlayerPartyCount, gEnemyPartyCount,
// gEnemyParty, gPlayerParty here after resolving symbol ref in between.
extern u8 sLearningMoveTableID;
EWRAM_DATA struct SpriteTemplate gMultiuseSpriteTemplate = {0};
static EWRAM_DATA struct OakSpeechNidoranFStruct *sOakSpeechNidoranResources = NULL;
static union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType);
static u16 GetDeoxysStat(struct Pokemon *mon, s32 statId);
static bool8 IsShinyOtIdPersonality(u32 otId, u32 personality);
static u16 ModifyStatByNature(u8 nature, u16 n, u8 statIndex);
static u8 GetNatureFromPersonality(u32 personality);
static bool8 sub_8042BE8(struct Pokemon *mon, u32 unused, u32 healMask, u8 battleId);
static bool8 HealStatusConditions(struct Pokemon *mon, u32 unused, u32 healMask, u8 battleId);
static bool8 IsPokemonStorageFull(void);
static u8 SendMonToPC(struct Pokemon* mon);
static void EncryptBoxMon(struct BoxPokemon *boxMon);
static void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move);
static void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon);
static u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move);
static u8 GetLevelFromMonExp(struct Pokemon *mon);
static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon);
#include "data/battle_moves.h"
static const u8 sUnreferencedData[] = { 0x34, 0x00, 0x10, 0x00, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 };
static const u16 sSpeciesToHoennPokedexNum[] = // Assigns all species to the Hoenn Dex Index (Summary No. for Hoenn Dex)
{
SPECIES_TO_HOENN(BULBASAUR),
SPECIES_TO_HOENN(IVYSAUR),
SPECIES_TO_HOENN(VENUSAUR),
SPECIES_TO_HOENN(CHARMANDER),
SPECIES_TO_HOENN(CHARMELEON),
SPECIES_TO_HOENN(CHARIZARD),
SPECIES_TO_HOENN(SQUIRTLE),
SPECIES_TO_HOENN(WARTORTLE),
SPECIES_TO_HOENN(BLASTOISE),
SPECIES_TO_HOENN(CATERPIE),
SPECIES_TO_HOENN(METAPOD),
SPECIES_TO_HOENN(BUTTERFREE),
SPECIES_TO_HOENN(WEEDLE),
SPECIES_TO_HOENN(KAKUNA),
SPECIES_TO_HOENN(BEEDRILL),
SPECIES_TO_HOENN(PIDGEY),
SPECIES_TO_HOENN(PIDGEOTTO),
SPECIES_TO_HOENN(PIDGEOT),
SPECIES_TO_HOENN(RATTATA),
SPECIES_TO_HOENN(RATICATE),
SPECIES_TO_HOENN(SPEAROW),
SPECIES_TO_HOENN(FEAROW),
SPECIES_TO_HOENN(EKANS),
SPECIES_TO_HOENN(ARBOK),
SPECIES_TO_HOENN(PIKACHU),
SPECIES_TO_HOENN(RAICHU),
SPECIES_TO_HOENN(SANDSHREW),
SPECIES_TO_HOENN(SANDSLASH),
SPECIES_TO_HOENN(NIDORAN_F),
SPECIES_TO_HOENN(NIDORINA),
SPECIES_TO_HOENN(NIDOQUEEN),
SPECIES_TO_HOENN(NIDORAN_M),
SPECIES_TO_HOENN(NIDORINO),
SPECIES_TO_HOENN(NIDOKING),
SPECIES_TO_HOENN(CLEFAIRY),
SPECIES_TO_HOENN(CLEFABLE),
SPECIES_TO_HOENN(VULPIX),
SPECIES_TO_HOENN(NINETALES),
SPECIES_TO_HOENN(JIGGLYPUFF),
SPECIES_TO_HOENN(WIGGLYTUFF),
SPECIES_TO_HOENN(ZUBAT),
SPECIES_TO_HOENN(GOLBAT),
SPECIES_TO_HOENN(ODDISH),
SPECIES_TO_HOENN(GLOOM),
SPECIES_TO_HOENN(VILEPLUME),
SPECIES_TO_HOENN(PARAS),
SPECIES_TO_HOENN(PARASECT),
SPECIES_TO_HOENN(VENONAT),
SPECIES_TO_HOENN(VENOMOTH),
SPECIES_TO_HOENN(DIGLETT),
SPECIES_TO_HOENN(DUGTRIO),
SPECIES_TO_HOENN(MEOWTH),
SPECIES_TO_HOENN(PERSIAN),
SPECIES_TO_HOENN(PSYDUCK),
SPECIES_TO_HOENN(GOLDUCK),
SPECIES_TO_HOENN(MANKEY),
SPECIES_TO_HOENN(PRIMEAPE),
SPECIES_TO_HOENN(GROWLITHE),
SPECIES_TO_HOENN(ARCANINE),
SPECIES_TO_HOENN(POLIWAG),
SPECIES_TO_HOENN(POLIWHIRL),
SPECIES_TO_HOENN(POLIWRATH),
SPECIES_TO_HOENN(ABRA),
SPECIES_TO_HOENN(KADABRA),
SPECIES_TO_HOENN(ALAKAZAM),
SPECIES_TO_HOENN(MACHOP),
SPECIES_TO_HOENN(MACHOKE),
SPECIES_TO_HOENN(MACHAMP),
SPECIES_TO_HOENN(BELLSPROUT),
SPECIES_TO_HOENN(WEEPINBELL),
SPECIES_TO_HOENN(VICTREEBEL),
SPECIES_TO_HOENN(TENTACOOL),
SPECIES_TO_HOENN(TENTACRUEL),
SPECIES_TO_HOENN(GEODUDE),
SPECIES_TO_HOENN(GRAVELER),
SPECIES_TO_HOENN(GOLEM),
SPECIES_TO_HOENN(PONYTA),
SPECIES_TO_HOENN(RAPIDASH),
SPECIES_TO_HOENN(SLOWPOKE),
SPECIES_TO_HOENN(SLOWBRO),
SPECIES_TO_HOENN(MAGNEMITE),
SPECIES_TO_HOENN(MAGNETON),
SPECIES_TO_HOENN(FARFETCHD),
SPECIES_TO_HOENN(DODUO),
SPECIES_TO_HOENN(DODRIO),
SPECIES_TO_HOENN(SEEL),
SPECIES_TO_HOENN(DEWGONG),
SPECIES_TO_HOENN(GRIMER),
SPECIES_TO_HOENN(MUK),
SPECIES_TO_HOENN(SHELLDER),
SPECIES_TO_HOENN(CLOYSTER),
SPECIES_TO_HOENN(GASTLY),
SPECIES_TO_HOENN(HAUNTER),
SPECIES_TO_HOENN(GENGAR),
SPECIES_TO_HOENN(ONIX),
SPECIES_TO_HOENN(DROWZEE),
SPECIES_TO_HOENN(HYPNO),
SPECIES_TO_HOENN(KRABBY),
SPECIES_TO_HOENN(KINGLER),
SPECIES_TO_HOENN(VOLTORB),
SPECIES_TO_HOENN(ELECTRODE),
SPECIES_TO_HOENN(EXEGGCUTE),
SPECIES_TO_HOENN(EXEGGUTOR),
SPECIES_TO_HOENN(CUBONE),
SPECIES_TO_HOENN(MAROWAK),
SPECIES_TO_HOENN(HITMONLEE),
SPECIES_TO_HOENN(HITMONCHAN),
SPECIES_TO_HOENN(LICKITUNG),
SPECIES_TO_HOENN(KOFFING),
SPECIES_TO_HOENN(WEEZING),
SPECIES_TO_HOENN(RHYHORN),
SPECIES_TO_HOENN(RHYDON),
SPECIES_TO_HOENN(CHANSEY),
SPECIES_TO_HOENN(TANGELA),
SPECIES_TO_HOENN(KANGASKHAN),
SPECIES_TO_HOENN(HORSEA),
SPECIES_TO_HOENN(SEADRA),
SPECIES_TO_HOENN(GOLDEEN),
SPECIES_TO_HOENN(SEAKING),
SPECIES_TO_HOENN(STARYU),
SPECIES_TO_HOENN(STARMIE),
SPECIES_TO_HOENN(MR_MIME),
SPECIES_TO_HOENN(SCYTHER),
SPECIES_TO_HOENN(JYNX),
SPECIES_TO_HOENN(ELECTABUZZ),
SPECIES_TO_HOENN(MAGMAR),
SPECIES_TO_HOENN(PINSIR),
SPECIES_TO_HOENN(TAUROS),
SPECIES_TO_HOENN(MAGIKARP),
SPECIES_TO_HOENN(GYARADOS),
SPECIES_TO_HOENN(LAPRAS),
SPECIES_TO_HOENN(DITTO),
SPECIES_TO_HOENN(EEVEE),
SPECIES_TO_HOENN(VAPOREON),
SPECIES_TO_HOENN(JOLTEON),
SPECIES_TO_HOENN(FLAREON),
SPECIES_TO_HOENN(PORYGON),
SPECIES_TO_HOENN(OMANYTE),
SPECIES_TO_HOENN(OMASTAR),
SPECIES_TO_HOENN(KABUTO),
SPECIES_TO_HOENN(KABUTOPS),
SPECIES_TO_HOENN(AERODACTYL),
SPECIES_TO_HOENN(SNORLAX),
SPECIES_TO_HOENN(ARTICUNO),
SPECIES_TO_HOENN(ZAPDOS),
SPECIES_TO_HOENN(MOLTRES),
SPECIES_TO_HOENN(DRATINI),
SPECIES_TO_HOENN(DRAGONAIR),
SPECIES_TO_HOENN(DRAGONITE),
SPECIES_TO_HOENN(MEWTWO),
SPECIES_TO_HOENN(MEW),
SPECIES_TO_HOENN(CHIKORITA),
SPECIES_TO_HOENN(BAYLEEF),
SPECIES_TO_HOENN(MEGANIUM),
SPECIES_TO_HOENN(CYNDAQUIL),
SPECIES_TO_HOENN(QUILAVA),
SPECIES_TO_HOENN(TYPHLOSION),
SPECIES_TO_HOENN(TOTODILE),
SPECIES_TO_HOENN(CROCONAW),
SPECIES_TO_HOENN(FERALIGATR),
SPECIES_TO_HOENN(SENTRET),
SPECIES_TO_HOENN(FURRET),
SPECIES_TO_HOENN(HOOTHOOT),
SPECIES_TO_HOENN(NOCTOWL),
SPECIES_TO_HOENN(LEDYBA),
SPECIES_TO_HOENN(LEDIAN),
SPECIES_TO_HOENN(SPINARAK),
SPECIES_TO_HOENN(ARIADOS),
SPECIES_TO_HOENN(CROBAT),
SPECIES_TO_HOENN(CHINCHOU),
SPECIES_TO_HOENN(LANTURN),
SPECIES_TO_HOENN(PICHU),
SPECIES_TO_HOENN(CLEFFA),
SPECIES_TO_HOENN(IGGLYBUFF),
SPECIES_TO_HOENN(TOGEPI),
SPECIES_TO_HOENN(TOGETIC),
SPECIES_TO_HOENN(NATU),
SPECIES_TO_HOENN(XATU),
SPECIES_TO_HOENN(MAREEP),
SPECIES_TO_HOENN(FLAAFFY),
SPECIES_TO_HOENN(AMPHAROS),
SPECIES_TO_HOENN(BELLOSSOM),
SPECIES_TO_HOENN(MARILL),
SPECIES_TO_HOENN(AZUMARILL),
SPECIES_TO_HOENN(SUDOWOODO),
SPECIES_TO_HOENN(POLITOED),
SPECIES_TO_HOENN(HOPPIP),
SPECIES_TO_HOENN(SKIPLOOM),
SPECIES_TO_HOENN(JUMPLUFF),
SPECIES_TO_HOENN(AIPOM),
SPECIES_TO_HOENN(SUNKERN),
SPECIES_TO_HOENN(SUNFLORA),
SPECIES_TO_HOENN(YANMA),
SPECIES_TO_HOENN(WOOPER),
SPECIES_TO_HOENN(QUAGSIRE),
SPECIES_TO_HOENN(ESPEON),
SPECIES_TO_HOENN(UMBREON),
SPECIES_TO_HOENN(MURKROW),
SPECIES_TO_HOENN(SLOWKING),
SPECIES_TO_HOENN(MISDREAVUS),
SPECIES_TO_HOENN(UNOWN),
SPECIES_TO_HOENN(WOBBUFFET),
SPECIES_TO_HOENN(GIRAFARIG),
SPECIES_TO_HOENN(PINECO),
SPECIES_TO_HOENN(FORRETRESS),
SPECIES_TO_HOENN(DUNSPARCE),
SPECIES_TO_HOENN(GLIGAR),
SPECIES_TO_HOENN(STEELIX),
SPECIES_TO_HOENN(SNUBBULL),
SPECIES_TO_HOENN(GRANBULL),
SPECIES_TO_HOENN(QWILFISH),
SPECIES_TO_HOENN(SCIZOR),
SPECIES_TO_HOENN(SHUCKLE),
SPECIES_TO_HOENN(HERACROSS),
SPECIES_TO_HOENN(SNEASEL),
SPECIES_TO_HOENN(TEDDIURSA),
SPECIES_TO_HOENN(URSARING),
SPECIES_TO_HOENN(SLUGMA),
SPECIES_TO_HOENN(MAGCARGO),
SPECIES_TO_HOENN(SWINUB),
SPECIES_TO_HOENN(PILOSWINE),
SPECIES_TO_HOENN(CORSOLA),
SPECIES_TO_HOENN(REMORAID),
SPECIES_TO_HOENN(OCTILLERY),
SPECIES_TO_HOENN(DELIBIRD),
SPECIES_TO_HOENN(MANTINE),
SPECIES_TO_HOENN(SKARMORY),
SPECIES_TO_HOENN(HOUNDOUR),
SPECIES_TO_HOENN(HOUNDOOM),
SPECIES_TO_HOENN(KINGDRA),
SPECIES_TO_HOENN(PHANPY),
SPECIES_TO_HOENN(DONPHAN),
SPECIES_TO_HOENN(PORYGON2),
SPECIES_TO_HOENN(STANTLER),
SPECIES_TO_HOENN(SMEARGLE),
SPECIES_TO_HOENN(TYROGUE),
SPECIES_TO_HOENN(HITMONTOP),
SPECIES_TO_HOENN(SMOOCHUM),
SPECIES_TO_HOENN(ELEKID),
SPECIES_TO_HOENN(MAGBY),
SPECIES_TO_HOENN(MILTANK),
SPECIES_TO_HOENN(BLISSEY),
SPECIES_TO_HOENN(RAIKOU),
SPECIES_TO_HOENN(ENTEI),
SPECIES_TO_HOENN(SUICUNE),
SPECIES_TO_HOENN(LARVITAR),
SPECIES_TO_HOENN(PUPITAR),
SPECIES_TO_HOENN(TYRANITAR),
SPECIES_TO_HOENN(LUGIA),
SPECIES_TO_HOENN(HO_OH),
SPECIES_TO_HOENN(CELEBI),
SPECIES_TO_HOENN(OLD_UNOWN_B),
SPECIES_TO_HOENN(OLD_UNOWN_C),
SPECIES_TO_HOENN(OLD_UNOWN_D),
SPECIES_TO_HOENN(OLD_UNOWN_E),
SPECIES_TO_HOENN(OLD_UNOWN_F),
SPECIES_TO_HOENN(OLD_UNOWN_G),
SPECIES_TO_HOENN(OLD_UNOWN_H),
SPECIES_TO_HOENN(OLD_UNOWN_I),
SPECIES_TO_HOENN(OLD_UNOWN_J),
SPECIES_TO_HOENN(OLD_UNOWN_K),
SPECIES_TO_HOENN(OLD_UNOWN_L),
SPECIES_TO_HOENN(OLD_UNOWN_M),
SPECIES_TO_HOENN(OLD_UNOWN_N),
SPECIES_TO_HOENN(OLD_UNOWN_O),
SPECIES_TO_HOENN(OLD_UNOWN_P),
SPECIES_TO_HOENN(OLD_UNOWN_Q),
SPECIES_TO_HOENN(OLD_UNOWN_R),
SPECIES_TO_HOENN(OLD_UNOWN_S),
SPECIES_TO_HOENN(OLD_UNOWN_T),
SPECIES_TO_HOENN(OLD_UNOWN_U),
SPECIES_TO_HOENN(OLD_UNOWN_V),
SPECIES_TO_HOENN(OLD_UNOWN_W),
SPECIES_TO_HOENN(OLD_UNOWN_X),
SPECIES_TO_HOENN(OLD_UNOWN_Y),
SPECIES_TO_HOENN(OLD_UNOWN_Z),
SPECIES_TO_HOENN(TREECKO),
SPECIES_TO_HOENN(GROVYLE),
SPECIES_TO_HOENN(SCEPTILE),
SPECIES_TO_HOENN(TORCHIC),
SPECIES_TO_HOENN(COMBUSKEN),
SPECIES_TO_HOENN(BLAZIKEN),
SPECIES_TO_HOENN(MUDKIP),
SPECIES_TO_HOENN(MARSHTOMP),
SPECIES_TO_HOENN(SWAMPERT),
SPECIES_TO_HOENN(POOCHYENA),
SPECIES_TO_HOENN(MIGHTYENA),
SPECIES_TO_HOENN(ZIGZAGOON),
SPECIES_TO_HOENN(LINOONE),
SPECIES_TO_HOENN(WURMPLE),
SPECIES_TO_HOENN(SILCOON),
SPECIES_TO_HOENN(BEAUTIFLY),
SPECIES_TO_HOENN(CASCOON),
SPECIES_TO_HOENN(DUSTOX),
SPECIES_TO_HOENN(LOTAD),
SPECIES_TO_HOENN(LOMBRE),
SPECIES_TO_HOENN(LUDICOLO),
SPECIES_TO_HOENN(SEEDOT),
SPECIES_TO_HOENN(NUZLEAF),
SPECIES_TO_HOENN(SHIFTRY),
SPECIES_TO_HOENN(NINCADA),
SPECIES_TO_HOENN(NINJASK),
SPECIES_TO_HOENN(SHEDINJA),
SPECIES_TO_HOENN(TAILLOW),
SPECIES_TO_HOENN(SWELLOW),
SPECIES_TO_HOENN(SHROOMISH),
SPECIES_TO_HOENN(BRELOOM),
SPECIES_TO_HOENN(SPINDA),
SPECIES_TO_HOENN(WINGULL),
SPECIES_TO_HOENN(PELIPPER),
SPECIES_TO_HOENN(SURSKIT),
SPECIES_TO_HOENN(MASQUERAIN),
SPECIES_TO_HOENN(WAILMER),
SPECIES_TO_HOENN(WAILORD),
SPECIES_TO_HOENN(SKITTY),
SPECIES_TO_HOENN(DELCATTY),
SPECIES_TO_HOENN(KECLEON),
SPECIES_TO_HOENN(BALTOY),
SPECIES_TO_HOENN(CLAYDOL),
SPECIES_TO_HOENN(NOSEPASS),
SPECIES_TO_HOENN(TORKOAL),
SPECIES_TO_HOENN(SABLEYE),
SPECIES_TO_HOENN(BARBOACH),
SPECIES_TO_HOENN(WHISCASH),
SPECIES_TO_HOENN(LUVDISC),
SPECIES_TO_HOENN(CORPHISH),
SPECIES_TO_HOENN(CRAWDAUNT),
SPECIES_TO_HOENN(FEEBAS),
SPECIES_TO_HOENN(MILOTIC),
SPECIES_TO_HOENN(CARVANHA),
SPECIES_TO_HOENN(SHARPEDO),
SPECIES_TO_HOENN(TRAPINCH),
SPECIES_TO_HOENN(VIBRAVA),
SPECIES_TO_HOENN(FLYGON),
SPECIES_TO_HOENN(MAKUHITA),
SPECIES_TO_HOENN(HARIYAMA),
SPECIES_TO_HOENN(ELECTRIKE),
SPECIES_TO_HOENN(MANECTRIC),
SPECIES_TO_HOENN(NUMEL),
SPECIES_TO_HOENN(CAMERUPT),
SPECIES_TO_HOENN(SPHEAL),
SPECIES_TO_HOENN(SEALEO),
SPECIES_TO_HOENN(WALREIN),
SPECIES_TO_HOENN(CACNEA),
SPECIES_TO_HOENN(CACTURNE),
SPECIES_TO_HOENN(SNORUNT),
SPECIES_TO_HOENN(GLALIE),
SPECIES_TO_HOENN(LUNATONE),
SPECIES_TO_HOENN(SOLROCK),
SPECIES_TO_HOENN(AZURILL),
SPECIES_TO_HOENN(SPOINK),
SPECIES_TO_HOENN(GRUMPIG),
SPECIES_TO_HOENN(PLUSLE),
SPECIES_TO_HOENN(MINUN),
SPECIES_TO_HOENN(MAWILE),
SPECIES_TO_HOENN(MEDITITE),
SPECIES_TO_HOENN(MEDICHAM),
SPECIES_TO_HOENN(SWABLU),
SPECIES_TO_HOENN(ALTARIA),
SPECIES_TO_HOENN(WYNAUT),
SPECIES_TO_HOENN(DUSKULL),
SPECIES_TO_HOENN(DUSCLOPS),
SPECIES_TO_HOENN(ROSELIA),
SPECIES_TO_HOENN(SLAKOTH),
SPECIES_TO_HOENN(VIGOROTH),
SPECIES_TO_HOENN(SLAKING),
SPECIES_TO_HOENN(GULPIN),
SPECIES_TO_HOENN(SWALOT),
SPECIES_TO_HOENN(TROPIUS),
SPECIES_TO_HOENN(WHISMUR),
SPECIES_TO_HOENN(LOUDRED),
SPECIES_TO_HOENN(EXPLOUD),
SPECIES_TO_HOENN(CLAMPERL),
SPECIES_TO_HOENN(HUNTAIL),
SPECIES_TO_HOENN(GOREBYSS),
SPECIES_TO_HOENN(ABSOL),
SPECIES_TO_HOENN(SHUPPET),
SPECIES_TO_HOENN(BANETTE),
SPECIES_TO_HOENN(SEVIPER),
SPECIES_TO_HOENN(ZANGOOSE),
SPECIES_TO_HOENN(RELICANTH),
SPECIES_TO_HOENN(ARON),
SPECIES_TO_HOENN(LAIRON),
SPECIES_TO_HOENN(AGGRON),
SPECIES_TO_HOENN(CASTFORM),
SPECIES_TO_HOENN(VOLBEAT),
SPECIES_TO_HOENN(ILLUMISE),
SPECIES_TO_HOENN(LILEEP),
SPECIES_TO_HOENN(CRADILY),
SPECIES_TO_HOENN(ANORITH),
SPECIES_TO_HOENN(ARMALDO),
SPECIES_TO_HOENN(RALTS),
SPECIES_TO_HOENN(KIRLIA),
SPECIES_TO_HOENN(GARDEVOIR),
SPECIES_TO_HOENN(BAGON),
SPECIES_TO_HOENN(SHELGON),
SPECIES_TO_HOENN(SALAMENCE),
SPECIES_TO_HOENN(BELDUM),
SPECIES_TO_HOENN(METANG),
SPECIES_TO_HOENN(METAGROSS),
SPECIES_TO_HOENN(REGIROCK),
SPECIES_TO_HOENN(REGICE),
SPECIES_TO_HOENN(REGISTEEL),
SPECIES_TO_HOENN(KYOGRE),
SPECIES_TO_HOENN(GROUDON),
SPECIES_TO_HOENN(RAYQUAZA),
SPECIES_TO_HOENN(LATIAS),
SPECIES_TO_HOENN(LATIOS),
SPECIES_TO_HOENN(JIRACHI),
SPECIES_TO_HOENN(DEOXYS),
SPECIES_TO_HOENN(CHIMECHO),
};
static const u16 sSpeciesToNationalPokedexNum[] = // Assigns all species to the National Dex Index (Summary No. for National Dex)
{
SPECIES_TO_NATIONAL(BULBASAUR),
SPECIES_TO_NATIONAL(IVYSAUR),
SPECIES_TO_NATIONAL(VENUSAUR),
SPECIES_TO_NATIONAL(CHARMANDER),
SPECIES_TO_NATIONAL(CHARMELEON),
SPECIES_TO_NATIONAL(CHARIZARD),
SPECIES_TO_NATIONAL(SQUIRTLE),
SPECIES_TO_NATIONAL(WARTORTLE),
SPECIES_TO_NATIONAL(BLASTOISE),
SPECIES_TO_NATIONAL(CATERPIE),
SPECIES_TO_NATIONAL(METAPOD),
SPECIES_TO_NATIONAL(BUTTERFREE),
SPECIES_TO_NATIONAL(WEEDLE),
SPECIES_TO_NATIONAL(KAKUNA),
SPECIES_TO_NATIONAL(BEEDRILL),
SPECIES_TO_NATIONAL(PIDGEY),
SPECIES_TO_NATIONAL(PIDGEOTTO),
SPECIES_TO_NATIONAL(PIDGEOT),
SPECIES_TO_NATIONAL(RATTATA),
SPECIES_TO_NATIONAL(RATICATE),
SPECIES_TO_NATIONAL(SPEAROW),
SPECIES_TO_NATIONAL(FEAROW),
SPECIES_TO_NATIONAL(EKANS),
SPECIES_TO_NATIONAL(ARBOK),
SPECIES_TO_NATIONAL(PIKACHU),
SPECIES_TO_NATIONAL(RAICHU),
SPECIES_TO_NATIONAL(SANDSHREW),
SPECIES_TO_NATIONAL(SANDSLASH),
SPECIES_TO_NATIONAL(NIDORAN_F),
SPECIES_TO_NATIONAL(NIDORINA),
SPECIES_TO_NATIONAL(NIDOQUEEN),
SPECIES_TO_NATIONAL(NIDORAN_M),
SPECIES_TO_NATIONAL(NIDORINO),
SPECIES_TO_NATIONAL(NIDOKING),
SPECIES_TO_NATIONAL(CLEFAIRY),
SPECIES_TO_NATIONAL(CLEFABLE),
SPECIES_TO_NATIONAL(VULPIX),
SPECIES_TO_NATIONAL(NINETALES),
SPECIES_TO_NATIONAL(JIGGLYPUFF),
SPECIES_TO_NATIONAL(WIGGLYTUFF),
SPECIES_TO_NATIONAL(ZUBAT),
SPECIES_TO_NATIONAL(GOLBAT),
SPECIES_TO_NATIONAL(ODDISH),
SPECIES_TO_NATIONAL(GLOOM),
SPECIES_TO_NATIONAL(VILEPLUME),
SPECIES_TO_NATIONAL(PARAS),
SPECIES_TO_NATIONAL(PARASECT),
SPECIES_TO_NATIONAL(VENONAT),
SPECIES_TO_NATIONAL(VENOMOTH),
SPECIES_TO_NATIONAL(DIGLETT),
SPECIES_TO_NATIONAL(DUGTRIO),
SPECIES_TO_NATIONAL(MEOWTH),
SPECIES_TO_NATIONAL(PERSIAN),
SPECIES_TO_NATIONAL(PSYDUCK),
SPECIES_TO_NATIONAL(GOLDUCK),
SPECIES_TO_NATIONAL(MANKEY),
SPECIES_TO_NATIONAL(PRIMEAPE),
SPECIES_TO_NATIONAL(GROWLITHE),
SPECIES_TO_NATIONAL(ARCANINE),
SPECIES_TO_NATIONAL(POLIWAG),
SPECIES_TO_NATIONAL(POLIWHIRL),
SPECIES_TO_NATIONAL(POLIWRATH),
SPECIES_TO_NATIONAL(ABRA),
SPECIES_TO_NATIONAL(KADABRA),
SPECIES_TO_NATIONAL(ALAKAZAM),
SPECIES_TO_NATIONAL(MACHOP),
SPECIES_TO_NATIONAL(MACHOKE),
SPECIES_TO_NATIONAL(MACHAMP),
SPECIES_TO_NATIONAL(BELLSPROUT),
SPECIES_TO_NATIONAL(WEEPINBELL),
SPECIES_TO_NATIONAL(VICTREEBEL),
SPECIES_TO_NATIONAL(TENTACOOL),
SPECIES_TO_NATIONAL(TENTACRUEL),
SPECIES_TO_NATIONAL(GEODUDE),
SPECIES_TO_NATIONAL(GRAVELER),
SPECIES_TO_NATIONAL(GOLEM),
SPECIES_TO_NATIONAL(PONYTA),
SPECIES_TO_NATIONAL(RAPIDASH),
SPECIES_TO_NATIONAL(SLOWPOKE),
SPECIES_TO_NATIONAL(SLOWBRO),
SPECIES_TO_NATIONAL(MAGNEMITE),
SPECIES_TO_NATIONAL(MAGNETON),
SPECIES_TO_NATIONAL(FARFETCHD),
SPECIES_TO_NATIONAL(DODUO),
SPECIES_TO_NATIONAL(DODRIO),
SPECIES_TO_NATIONAL(SEEL),
SPECIES_TO_NATIONAL(DEWGONG),
SPECIES_TO_NATIONAL(GRIMER),
SPECIES_TO_NATIONAL(MUK),
SPECIES_TO_NATIONAL(SHELLDER),
SPECIES_TO_NATIONAL(CLOYSTER),
SPECIES_TO_NATIONAL(GASTLY),
SPECIES_TO_NATIONAL(HAUNTER),
SPECIES_TO_NATIONAL(GENGAR),
SPECIES_TO_NATIONAL(ONIX),
SPECIES_TO_NATIONAL(DROWZEE),
SPECIES_TO_NATIONAL(HYPNO),
SPECIES_TO_NATIONAL(KRABBY),
SPECIES_TO_NATIONAL(KINGLER),
SPECIES_TO_NATIONAL(VOLTORB),
SPECIES_TO_NATIONAL(ELECTRODE),
SPECIES_TO_NATIONAL(EXEGGCUTE),
SPECIES_TO_NATIONAL(EXEGGUTOR),
SPECIES_TO_NATIONAL(CUBONE),
SPECIES_TO_NATIONAL(MAROWAK),
SPECIES_TO_NATIONAL(HITMONLEE),
SPECIES_TO_NATIONAL(HITMONCHAN),
SPECIES_TO_NATIONAL(LICKITUNG),
SPECIES_TO_NATIONAL(KOFFING),
SPECIES_TO_NATIONAL(WEEZING),
SPECIES_TO_NATIONAL(RHYHORN),
SPECIES_TO_NATIONAL(RHYDON),
SPECIES_TO_NATIONAL(CHANSEY),
SPECIES_TO_NATIONAL(TANGELA),
SPECIES_TO_NATIONAL(KANGASKHAN),
SPECIES_TO_NATIONAL(HORSEA),
SPECIES_TO_NATIONAL(SEADRA),
SPECIES_TO_NATIONAL(GOLDEEN),
SPECIES_TO_NATIONAL(SEAKING),
SPECIES_TO_NATIONAL(STARYU),
SPECIES_TO_NATIONAL(STARMIE),
SPECIES_TO_NATIONAL(MR_MIME),
SPECIES_TO_NATIONAL(SCYTHER),
SPECIES_TO_NATIONAL(JYNX),
SPECIES_TO_NATIONAL(ELECTABUZZ),
SPECIES_TO_NATIONAL(MAGMAR),
SPECIES_TO_NATIONAL(PINSIR),
SPECIES_TO_NATIONAL(TAUROS),
SPECIES_TO_NATIONAL(MAGIKARP),
SPECIES_TO_NATIONAL(GYARADOS),
SPECIES_TO_NATIONAL(LAPRAS),
SPECIES_TO_NATIONAL(DITTO),
SPECIES_TO_NATIONAL(EEVEE),
SPECIES_TO_NATIONAL(VAPOREON),
SPECIES_TO_NATIONAL(JOLTEON),
SPECIES_TO_NATIONAL(FLAREON),
SPECIES_TO_NATIONAL(PORYGON),
SPECIES_TO_NATIONAL(OMANYTE),
SPECIES_TO_NATIONAL(OMASTAR),
SPECIES_TO_NATIONAL(KABUTO),
SPECIES_TO_NATIONAL(KABUTOPS),
SPECIES_TO_NATIONAL(AERODACTYL),
SPECIES_TO_NATIONAL(SNORLAX),
SPECIES_TO_NATIONAL(ARTICUNO),
SPECIES_TO_NATIONAL(ZAPDOS),
SPECIES_TO_NATIONAL(MOLTRES),
SPECIES_TO_NATIONAL(DRATINI),
SPECIES_TO_NATIONAL(DRAGONAIR),
SPECIES_TO_NATIONAL(DRAGONITE),
SPECIES_TO_NATIONAL(MEWTWO),
SPECIES_TO_NATIONAL(MEW),
SPECIES_TO_NATIONAL(CHIKORITA),
SPECIES_TO_NATIONAL(BAYLEEF),
SPECIES_TO_NATIONAL(MEGANIUM),
SPECIES_TO_NATIONAL(CYNDAQUIL),
SPECIES_TO_NATIONAL(QUILAVA),
SPECIES_TO_NATIONAL(TYPHLOSION),
SPECIES_TO_NATIONAL(TOTODILE),
SPECIES_TO_NATIONAL(CROCONAW),
SPECIES_TO_NATIONAL(FERALIGATR),
SPECIES_TO_NATIONAL(SENTRET),
SPECIES_TO_NATIONAL(FURRET),
SPECIES_TO_NATIONAL(HOOTHOOT),
SPECIES_TO_NATIONAL(NOCTOWL),
SPECIES_TO_NATIONAL(LEDYBA),
SPECIES_TO_NATIONAL(LEDIAN),
SPECIES_TO_NATIONAL(SPINARAK),
SPECIES_TO_NATIONAL(ARIADOS),
SPECIES_TO_NATIONAL(CROBAT),
SPECIES_TO_NATIONAL(CHINCHOU),
SPECIES_TO_NATIONAL(LANTURN),
SPECIES_TO_NATIONAL(PICHU),
SPECIES_TO_NATIONAL(CLEFFA),
SPECIES_TO_NATIONAL(IGGLYBUFF),
SPECIES_TO_NATIONAL(TOGEPI),
SPECIES_TO_NATIONAL(TOGETIC),
SPECIES_TO_NATIONAL(NATU),
SPECIES_TO_NATIONAL(XATU),
SPECIES_TO_NATIONAL(MAREEP),
SPECIES_TO_NATIONAL(FLAAFFY),
SPECIES_TO_NATIONAL(AMPHAROS),
SPECIES_TO_NATIONAL(BELLOSSOM),
SPECIES_TO_NATIONAL(MARILL),
SPECIES_TO_NATIONAL(AZUMARILL),
SPECIES_TO_NATIONAL(SUDOWOODO),
SPECIES_TO_NATIONAL(POLITOED),
SPECIES_TO_NATIONAL(HOPPIP),
SPECIES_TO_NATIONAL(SKIPLOOM),
SPECIES_TO_NATIONAL(JUMPLUFF),
SPECIES_TO_NATIONAL(AIPOM),
SPECIES_TO_NATIONAL(SUNKERN),
SPECIES_TO_NATIONAL(SUNFLORA),
SPECIES_TO_NATIONAL(YANMA),
SPECIES_TO_NATIONAL(WOOPER),
SPECIES_TO_NATIONAL(QUAGSIRE),
SPECIES_TO_NATIONAL(ESPEON),
SPECIES_TO_NATIONAL(UMBREON),
SPECIES_TO_NATIONAL(MURKROW),
SPECIES_TO_NATIONAL(SLOWKING),
SPECIES_TO_NATIONAL(MISDREAVUS),
SPECIES_TO_NATIONAL(UNOWN),
SPECIES_TO_NATIONAL(WOBBUFFET),
SPECIES_TO_NATIONAL(GIRAFARIG),
SPECIES_TO_NATIONAL(PINECO),
SPECIES_TO_NATIONAL(FORRETRESS),
SPECIES_TO_NATIONAL(DUNSPARCE),
SPECIES_TO_NATIONAL(GLIGAR),
SPECIES_TO_NATIONAL(STEELIX),
SPECIES_TO_NATIONAL(SNUBBULL),
SPECIES_TO_NATIONAL(GRANBULL),
SPECIES_TO_NATIONAL(QWILFISH),
SPECIES_TO_NATIONAL(SCIZOR),
SPECIES_TO_NATIONAL(SHUCKLE),
SPECIES_TO_NATIONAL(HERACROSS),
SPECIES_TO_NATIONAL(SNEASEL),
SPECIES_TO_NATIONAL(TEDDIURSA),
SPECIES_TO_NATIONAL(URSARING),
SPECIES_TO_NATIONAL(SLUGMA),
SPECIES_TO_NATIONAL(MAGCARGO),
SPECIES_TO_NATIONAL(SWINUB),
SPECIES_TO_NATIONAL(PILOSWINE),
SPECIES_TO_NATIONAL(CORSOLA),
SPECIES_TO_NATIONAL(REMORAID),
SPECIES_TO_NATIONAL(OCTILLERY),
SPECIES_TO_NATIONAL(DELIBIRD),
SPECIES_TO_NATIONAL(MANTINE),
SPECIES_TO_NATIONAL(SKARMORY),
SPECIES_TO_NATIONAL(HOUNDOUR),
SPECIES_TO_NATIONAL(HOUNDOOM),
SPECIES_TO_NATIONAL(KINGDRA),
SPECIES_TO_NATIONAL(PHANPY),
SPECIES_TO_NATIONAL(DONPHAN),
SPECIES_TO_NATIONAL(PORYGON2),
SPECIES_TO_NATIONAL(STANTLER),
SPECIES_TO_NATIONAL(SMEARGLE),
SPECIES_TO_NATIONAL(TYROGUE),
SPECIES_TO_NATIONAL(HITMONTOP),
SPECIES_TO_NATIONAL(SMOOCHUM),
SPECIES_TO_NATIONAL(ELEKID),
SPECIES_TO_NATIONAL(MAGBY),
SPECIES_TO_NATIONAL(MILTANK),
SPECIES_TO_NATIONAL(BLISSEY),
SPECIES_TO_NATIONAL(RAIKOU),
SPECIES_TO_NATIONAL(ENTEI),
SPECIES_TO_NATIONAL(SUICUNE),
SPECIES_TO_NATIONAL(LARVITAR),
SPECIES_TO_NATIONAL(PUPITAR),
SPECIES_TO_NATIONAL(TYRANITAR),
SPECIES_TO_NATIONAL(LUGIA),
SPECIES_TO_NATIONAL(HO_OH),
SPECIES_TO_NATIONAL(CELEBI),
SPECIES_TO_NATIONAL(OLD_UNOWN_B),
SPECIES_TO_NATIONAL(OLD_UNOWN_C),
SPECIES_TO_NATIONAL(OLD_UNOWN_D),
SPECIES_TO_NATIONAL(OLD_UNOWN_E),
SPECIES_TO_NATIONAL(OLD_UNOWN_F),
SPECIES_TO_NATIONAL(OLD_UNOWN_G),
SPECIES_TO_NATIONAL(OLD_UNOWN_H),
SPECIES_TO_NATIONAL(OLD_UNOWN_I),
SPECIES_TO_NATIONAL(OLD_UNOWN_J),
SPECIES_TO_NATIONAL(OLD_UNOWN_K),
SPECIES_TO_NATIONAL(OLD_UNOWN_L),
SPECIES_TO_NATIONAL(OLD_UNOWN_M),
SPECIES_TO_NATIONAL(OLD_UNOWN_N),
SPECIES_TO_NATIONAL(OLD_UNOWN_O),
SPECIES_TO_NATIONAL(OLD_UNOWN_P),
SPECIES_TO_NATIONAL(OLD_UNOWN_Q),
SPECIES_TO_NATIONAL(OLD_UNOWN_R),
SPECIES_TO_NATIONAL(OLD_UNOWN_S),
SPECIES_TO_NATIONAL(OLD_UNOWN_T),
SPECIES_TO_NATIONAL(OLD_UNOWN_U),
SPECIES_TO_NATIONAL(OLD_UNOWN_V),
SPECIES_TO_NATIONAL(OLD_UNOWN_W),
SPECIES_TO_NATIONAL(OLD_UNOWN_X),
SPECIES_TO_NATIONAL(OLD_UNOWN_Y),
SPECIES_TO_NATIONAL(OLD_UNOWN_Z),
SPECIES_TO_NATIONAL(TREECKO),
SPECIES_TO_NATIONAL(GROVYLE),
SPECIES_TO_NATIONAL(SCEPTILE),
SPECIES_TO_NATIONAL(TORCHIC),
SPECIES_TO_NATIONAL(COMBUSKEN),
SPECIES_TO_NATIONAL(BLAZIKEN),
SPECIES_TO_NATIONAL(MUDKIP),
SPECIES_TO_NATIONAL(MARSHTOMP),
SPECIES_TO_NATIONAL(SWAMPERT),
SPECIES_TO_NATIONAL(POOCHYENA),
SPECIES_TO_NATIONAL(MIGHTYENA),
SPECIES_TO_NATIONAL(ZIGZAGOON),
SPECIES_TO_NATIONAL(LINOONE),
SPECIES_TO_NATIONAL(WURMPLE),
SPECIES_TO_NATIONAL(SILCOON),
SPECIES_TO_NATIONAL(BEAUTIFLY),
SPECIES_TO_NATIONAL(CASCOON),
SPECIES_TO_NATIONAL(DUSTOX),
SPECIES_TO_NATIONAL(LOTAD),
SPECIES_TO_NATIONAL(LOMBRE),
SPECIES_TO_NATIONAL(LUDICOLO),
SPECIES_TO_NATIONAL(SEEDOT),
SPECIES_TO_NATIONAL(NUZLEAF),
SPECIES_TO_NATIONAL(SHIFTRY),
SPECIES_TO_NATIONAL(NINCADA),
SPECIES_TO_NATIONAL(NINJASK),
SPECIES_TO_NATIONAL(SHEDINJA),
SPECIES_TO_NATIONAL(TAILLOW),
SPECIES_TO_NATIONAL(SWELLOW),
SPECIES_TO_NATIONAL(SHROOMISH),
SPECIES_TO_NATIONAL(BRELOOM),
SPECIES_TO_NATIONAL(SPINDA),
SPECIES_TO_NATIONAL(WINGULL),
SPECIES_TO_NATIONAL(PELIPPER),
SPECIES_TO_NATIONAL(SURSKIT),
SPECIES_TO_NATIONAL(MASQUERAIN),
SPECIES_TO_NATIONAL(WAILMER),
SPECIES_TO_NATIONAL(WAILORD),
SPECIES_TO_NATIONAL(SKITTY),
SPECIES_TO_NATIONAL(DELCATTY),
SPECIES_TO_NATIONAL(KECLEON),
SPECIES_TO_NATIONAL(BALTOY),
SPECIES_TO_NATIONAL(CLAYDOL),
SPECIES_TO_NATIONAL(NOSEPASS),
SPECIES_TO_NATIONAL(TORKOAL),
SPECIES_TO_NATIONAL(SABLEYE),
SPECIES_TO_NATIONAL(BARBOACH),
SPECIES_TO_NATIONAL(WHISCASH),
SPECIES_TO_NATIONAL(LUVDISC),
SPECIES_TO_NATIONAL(CORPHISH),
SPECIES_TO_NATIONAL(CRAWDAUNT),
SPECIES_TO_NATIONAL(FEEBAS),
SPECIES_TO_NATIONAL(MILOTIC),
SPECIES_TO_NATIONAL(CARVANHA),
SPECIES_TO_NATIONAL(SHARPEDO),
SPECIES_TO_NATIONAL(TRAPINCH),
SPECIES_TO_NATIONAL(VIBRAVA),
SPECIES_TO_NATIONAL(FLYGON),
SPECIES_TO_NATIONAL(MAKUHITA),
SPECIES_TO_NATIONAL(HARIYAMA),
SPECIES_TO_NATIONAL(ELECTRIKE),
SPECIES_TO_NATIONAL(MANECTRIC),
SPECIES_TO_NATIONAL(NUMEL),
SPECIES_TO_NATIONAL(CAMERUPT),
SPECIES_TO_NATIONAL(SPHEAL),
SPECIES_TO_NATIONAL(SEALEO),
SPECIES_TO_NATIONAL(WALREIN),
SPECIES_TO_NATIONAL(CACNEA),
SPECIES_TO_NATIONAL(CACTURNE),
SPECIES_TO_NATIONAL(SNORUNT),
SPECIES_TO_NATIONAL(GLALIE),
SPECIES_TO_NATIONAL(LUNATONE),
SPECIES_TO_NATIONAL(SOLROCK),
SPECIES_TO_NATIONAL(AZURILL),
SPECIES_TO_NATIONAL(SPOINK),
SPECIES_TO_NATIONAL(GRUMPIG),
SPECIES_TO_NATIONAL(PLUSLE),
SPECIES_TO_NATIONAL(MINUN),
SPECIES_TO_NATIONAL(MAWILE),
SPECIES_TO_NATIONAL(MEDITITE),
SPECIES_TO_NATIONAL(MEDICHAM),
SPECIES_TO_NATIONAL(SWABLU),
SPECIES_TO_NATIONAL(ALTARIA),
SPECIES_TO_NATIONAL(WYNAUT),
SPECIES_TO_NATIONAL(DUSKULL),
SPECIES_TO_NATIONAL(DUSCLOPS),
SPECIES_TO_NATIONAL(ROSELIA),
SPECIES_TO_NATIONAL(SLAKOTH),
SPECIES_TO_NATIONAL(VIGOROTH),
SPECIES_TO_NATIONAL(SLAKING),
SPECIES_TO_NATIONAL(GULPIN),
SPECIES_TO_NATIONAL(SWALOT),
SPECIES_TO_NATIONAL(TROPIUS),
SPECIES_TO_NATIONAL(WHISMUR),
SPECIES_TO_NATIONAL(LOUDRED),
SPECIES_TO_NATIONAL(EXPLOUD),
SPECIES_TO_NATIONAL(CLAMPERL),
SPECIES_TO_NATIONAL(HUNTAIL),
SPECIES_TO_NATIONAL(GOREBYSS),
SPECIES_TO_NATIONAL(ABSOL),
SPECIES_TO_NATIONAL(SHUPPET),
SPECIES_TO_NATIONAL(BANETTE),
SPECIES_TO_NATIONAL(SEVIPER),
SPECIES_TO_NATIONAL(ZANGOOSE),
SPECIES_TO_NATIONAL(RELICANTH),
SPECIES_TO_NATIONAL(ARON),
SPECIES_TO_NATIONAL(LAIRON),
SPECIES_TO_NATIONAL(AGGRON),
SPECIES_TO_NATIONAL(CASTFORM),
SPECIES_TO_NATIONAL(VOLBEAT),
SPECIES_TO_NATIONAL(ILLUMISE),
SPECIES_TO_NATIONAL(LILEEP),
SPECIES_TO_NATIONAL(CRADILY),
SPECIES_TO_NATIONAL(ANORITH),
SPECIES_TO_NATIONAL(ARMALDO),
SPECIES_TO_NATIONAL(RALTS),
SPECIES_TO_NATIONAL(KIRLIA),
SPECIES_TO_NATIONAL(GARDEVOIR),
SPECIES_TO_NATIONAL(BAGON),
SPECIES_TO_NATIONAL(SHELGON),
SPECIES_TO_NATIONAL(SALAMENCE),
SPECIES_TO_NATIONAL(BELDUM),
SPECIES_TO_NATIONAL(METANG),
SPECIES_TO_NATIONAL(METAGROSS),
SPECIES_TO_NATIONAL(REGIROCK),
SPECIES_TO_NATIONAL(REGICE),
SPECIES_TO_NATIONAL(REGISTEEL),
SPECIES_TO_NATIONAL(KYOGRE),
SPECIES_TO_NATIONAL(GROUDON),
SPECIES_TO_NATIONAL(RAYQUAZA),
SPECIES_TO_NATIONAL(LATIAS),
SPECIES_TO_NATIONAL(LATIOS),
SPECIES_TO_NATIONAL(JIRACHI),
SPECIES_TO_NATIONAL(DEOXYS),
SPECIES_TO_NATIONAL(CHIMECHO),
};
static const u16 sHoennToNationalOrder[] = // Assigns Hoenn Dex Pokémon (Using National Dex Index)
{
HOENN_TO_NATIONAL(TREECKO),
HOENN_TO_NATIONAL(GROVYLE),
HOENN_TO_NATIONAL(SCEPTILE),
HOENN_TO_NATIONAL(TORCHIC),
HOENN_TO_NATIONAL(COMBUSKEN),
HOENN_TO_NATIONAL(BLAZIKEN),
HOENN_TO_NATIONAL(MUDKIP),
HOENN_TO_NATIONAL(MARSHTOMP),
HOENN_TO_NATIONAL(SWAMPERT),
HOENN_TO_NATIONAL(POOCHYENA),
HOENN_TO_NATIONAL(MIGHTYENA),
HOENN_TO_NATIONAL(ZIGZAGOON),
HOENN_TO_NATIONAL(LINOONE),
HOENN_TO_NATIONAL(WURMPLE),
HOENN_TO_NATIONAL(SILCOON),
HOENN_TO_NATIONAL(BEAUTIFLY),
HOENN_TO_NATIONAL(CASCOON),
HOENN_TO_NATIONAL(DUSTOX),
HOENN_TO_NATIONAL(LOTAD),
HOENN_TO_NATIONAL(LOMBRE),
HOENN_TO_NATIONAL(LUDICOLO),
HOENN_TO_NATIONAL(SEEDOT),
HOENN_TO_NATIONAL(NUZLEAF),
HOENN_TO_NATIONAL(SHIFTRY),
HOENN_TO_NATIONAL(TAILLOW),
HOENN_TO_NATIONAL(SWELLOW),
HOENN_TO_NATIONAL(WINGULL),
HOENN_TO_NATIONAL(PELIPPER),
HOENN_TO_NATIONAL(RALTS),
HOENN_TO_NATIONAL(KIRLIA),
HOENN_TO_NATIONAL(GARDEVOIR),
HOENN_TO_NATIONAL(SURSKIT),
HOENN_TO_NATIONAL(MASQUERAIN),
HOENN_TO_NATIONAL(SHROOMISH),
HOENN_TO_NATIONAL(BRELOOM),
HOENN_TO_NATIONAL(SLAKOTH),
HOENN_TO_NATIONAL(VIGOROTH),
HOENN_TO_NATIONAL(SLAKING),
HOENN_TO_NATIONAL(ABRA),
HOENN_TO_NATIONAL(KADABRA),
HOENN_TO_NATIONAL(ALAKAZAM),
HOENN_TO_NATIONAL(NINCADA),
HOENN_TO_NATIONAL(NINJASK),
HOENN_TO_NATIONAL(SHEDINJA),
HOENN_TO_NATIONAL(WHISMUR),
HOENN_TO_NATIONAL(LOUDRED),
HOENN_TO_NATIONAL(EXPLOUD),
HOENN_TO_NATIONAL(MAKUHITA),
HOENN_TO_NATIONAL(HARIYAMA),
HOENN_TO_NATIONAL(GOLDEEN),
HOENN_TO_NATIONAL(SEAKING),
HOENN_TO_NATIONAL(MAGIKARP),
HOENN_TO_NATIONAL(GYARADOS),
HOENN_TO_NATIONAL(AZURILL),
HOENN_TO_NATIONAL(MARILL),
HOENN_TO_NATIONAL(AZUMARILL),
HOENN_TO_NATIONAL(GEODUDE),
HOENN_TO_NATIONAL(GRAVELER),
HOENN_TO_NATIONAL(GOLEM),
HOENN_TO_NATIONAL(NOSEPASS),
HOENN_TO_NATIONAL(SKITTY),
HOENN_TO_NATIONAL(DELCATTY),
HOENN_TO_NATIONAL(ZUBAT),
HOENN_TO_NATIONAL(GOLBAT),
HOENN_TO_NATIONAL(CROBAT),
HOENN_TO_NATIONAL(TENTACOOL),
HOENN_TO_NATIONAL(TENTACRUEL),
HOENN_TO_NATIONAL(SABLEYE),
HOENN_TO_NATIONAL(MAWILE),
HOENN_TO_NATIONAL(ARON),
HOENN_TO_NATIONAL(LAIRON),
HOENN_TO_NATIONAL(AGGRON),
HOENN_TO_NATIONAL(MACHOP),
HOENN_TO_NATIONAL(MACHOKE),
HOENN_TO_NATIONAL(MACHAMP),
HOENN_TO_NATIONAL(MEDITITE),
HOENN_TO_NATIONAL(MEDICHAM),
HOENN_TO_NATIONAL(ELECTRIKE),
HOENN_TO_NATIONAL(MANECTRIC),
HOENN_TO_NATIONAL(PLUSLE),
HOENN_TO_NATIONAL(MINUN),
HOENN_TO_NATIONAL(MAGNEMITE),
HOENN_TO_NATIONAL(MAGNETON),
HOENN_TO_NATIONAL(VOLTORB),
HOENN_TO_NATIONAL(ELECTRODE),
HOENN_TO_NATIONAL(VOLBEAT),
HOENN_TO_NATIONAL(ILLUMISE),
HOENN_TO_NATIONAL(ODDISH),
HOENN_TO_NATIONAL(GLOOM),
HOENN_TO_NATIONAL(VILEPLUME),
HOENN_TO_NATIONAL(BELLOSSOM),
HOENN_TO_NATIONAL(DODUO),
HOENN_TO_NATIONAL(DODRIO),
HOENN_TO_NATIONAL(ROSELIA),
HOENN_TO_NATIONAL(GULPIN),
HOENN_TO_NATIONAL(SWALOT),
HOENN_TO_NATIONAL(CARVANHA),
HOENN_TO_NATIONAL(SHARPEDO),
HOENN_TO_NATIONAL(WAILMER),
HOENN_TO_NATIONAL(WAILORD),
HOENN_TO_NATIONAL(NUMEL),
HOENN_TO_NATIONAL(CAMERUPT),
HOENN_TO_NATIONAL(SLUGMA),
HOENN_TO_NATIONAL(MAGCARGO),
HOENN_TO_NATIONAL(TORKOAL),
HOENN_TO_NATIONAL(GRIMER),
HOENN_TO_NATIONAL(MUK),
HOENN_TO_NATIONAL(KOFFING),
HOENN_TO_NATIONAL(WEEZING),
HOENN_TO_NATIONAL(SPOINK),
HOENN_TO_NATIONAL(GRUMPIG),
HOENN_TO_NATIONAL(SANDSHREW),
HOENN_TO_NATIONAL(SANDSLASH),
HOENN_TO_NATIONAL(SPINDA),
HOENN_TO_NATIONAL(SKARMORY),
HOENN_TO_NATIONAL(TRAPINCH),
HOENN_TO_NATIONAL(VIBRAVA),
HOENN_TO_NATIONAL(FLYGON),
HOENN_TO_NATIONAL(CACNEA),
HOENN_TO_NATIONAL(CACTURNE),
HOENN_TO_NATIONAL(SWABLU),
HOENN_TO_NATIONAL(ALTARIA),
HOENN_TO_NATIONAL(ZANGOOSE),
HOENN_TO_NATIONAL(SEVIPER),
HOENN_TO_NATIONAL(LUNATONE),
HOENN_TO_NATIONAL(SOLROCK),
HOENN_TO_NATIONAL(BARBOACH),
HOENN_TO_NATIONAL(WHISCASH),
HOENN_TO_NATIONAL(CORPHISH),
HOENN_TO_NATIONAL(CRAWDAUNT),
HOENN_TO_NATIONAL(BALTOY),
HOENN_TO_NATIONAL(CLAYDOL),
HOENN_TO_NATIONAL(LILEEP),
HOENN_TO_NATIONAL(CRADILY),
HOENN_TO_NATIONAL(ANORITH),
HOENN_TO_NATIONAL(ARMALDO),
HOENN_TO_NATIONAL(IGGLYBUFF),
HOENN_TO_NATIONAL(JIGGLYPUFF),
HOENN_TO_NATIONAL(WIGGLYTUFF),
HOENN_TO_NATIONAL(FEEBAS),
HOENN_TO_NATIONAL(MILOTIC),
HOENN_TO_NATIONAL(CASTFORM),
HOENN_TO_NATIONAL(STARYU),
HOENN_TO_NATIONAL(STARMIE),
HOENN_TO_NATIONAL(KECLEON),
HOENN_TO_NATIONAL(SHUPPET),
HOENN_TO_NATIONAL(BANETTE),
HOENN_TO_NATIONAL(DUSKULL),
HOENN_TO_NATIONAL(DUSCLOPS),
HOENN_TO_NATIONAL(TROPIUS),
HOENN_TO_NATIONAL(CHIMECHO),
HOENN_TO_NATIONAL(ABSOL),
HOENN_TO_NATIONAL(VULPIX),
HOENN_TO_NATIONAL(NINETALES),
HOENN_TO_NATIONAL(PICHU),
HOENN_TO_NATIONAL(PIKACHU),
HOENN_TO_NATIONAL(RAICHU),
HOENN_TO_NATIONAL(PSYDUCK),
HOENN_TO_NATIONAL(GOLDUCK),
HOENN_TO_NATIONAL(WYNAUT),
HOENN_TO_NATIONAL(WOBBUFFET),
HOENN_TO_NATIONAL(NATU),
HOENN_TO_NATIONAL(XATU),
HOENN_TO_NATIONAL(GIRAFARIG),
HOENN_TO_NATIONAL(PHANPY),
HOENN_TO_NATIONAL(DONPHAN),
HOENN_TO_NATIONAL(PINSIR),
HOENN_TO_NATIONAL(HERACROSS),
HOENN_TO_NATIONAL(RHYHORN),
HOENN_TO_NATIONAL(RHYDON),
HOENN_TO_NATIONAL(SNORUNT),
HOENN_TO_NATIONAL(GLALIE),
HOENN_TO_NATIONAL(SPHEAL),
HOENN_TO_NATIONAL(SEALEO),
HOENN_TO_NATIONAL(WALREIN),
HOENN_TO_NATIONAL(CLAMPERL),
HOENN_TO_NATIONAL(HUNTAIL),
HOENN_TO_NATIONAL(GOREBYSS),
HOENN_TO_NATIONAL(RELICANTH),
HOENN_TO_NATIONAL(CORSOLA),
HOENN_TO_NATIONAL(CHINCHOU),
HOENN_TO_NATIONAL(LANTURN),
HOENN_TO_NATIONAL(LUVDISC),
HOENN_TO_NATIONAL(HORSEA),
HOENN_TO_NATIONAL(SEADRA),
HOENN_TO_NATIONAL(KINGDRA),
HOENN_TO_NATIONAL(BAGON),
HOENN_TO_NATIONAL(SHELGON),
HOENN_TO_NATIONAL(SALAMENCE),
HOENN_TO_NATIONAL(BELDUM),
HOENN_TO_NATIONAL(METANG),
HOENN_TO_NATIONAL(METAGROSS),
HOENN_TO_NATIONAL(REGIROCK),
HOENN_TO_NATIONAL(REGICE),
HOENN_TO_NATIONAL(REGISTEEL),
HOENN_TO_NATIONAL(LATIAS),
HOENN_TO_NATIONAL(LATIOS),
HOENN_TO_NATIONAL(KYOGRE),
HOENN_TO_NATIONAL(GROUDON),
HOENN_TO_NATIONAL(RAYQUAZA),
HOENN_TO_NATIONAL(JIRACHI),
HOENN_TO_NATIONAL(DEOXYS),
HOENN_TO_NATIONAL(BULBASAUR), // Pokémon from here onwards are UNSEEN in the HoennDex.
HOENN_TO_NATIONAL(IVYSAUR),
HOENN_TO_NATIONAL(VENUSAUR),
HOENN_TO_NATIONAL(CHARMANDER),
HOENN_TO_NATIONAL(CHARMELEON),
HOENN_TO_NATIONAL(CHARIZARD),
HOENN_TO_NATIONAL(SQUIRTLE),
HOENN_TO_NATIONAL(WARTORTLE),
HOENN_TO_NATIONAL(BLASTOISE),
HOENN_TO_NATIONAL(CATERPIE),
HOENN_TO_NATIONAL(METAPOD),
HOENN_TO_NATIONAL(BUTTERFREE),
HOENN_TO_NATIONAL(WEEDLE),
HOENN_TO_NATIONAL(KAKUNA),
HOENN_TO_NATIONAL(BEEDRILL),
HOENN_TO_NATIONAL(PIDGEY),
HOENN_TO_NATIONAL(PIDGEOTTO),
HOENN_TO_NATIONAL(PIDGEOT),
HOENN_TO_NATIONAL(RATTATA),
HOENN_TO_NATIONAL(RATICATE),
HOENN_TO_NATIONAL(SPEAROW),
HOENN_TO_NATIONAL(FEAROW),
HOENN_TO_NATIONAL(EKANS),
HOENN_TO_NATIONAL(ARBOK),
HOENN_TO_NATIONAL(NIDORAN_F),
HOENN_TO_NATIONAL(NIDORINA),
HOENN_TO_NATIONAL(NIDOQUEEN),
HOENN_TO_NATIONAL(NIDORAN_M),
HOENN_TO_NATIONAL(NIDORINO),
HOENN_TO_NATIONAL(NIDOKING),
HOENN_TO_NATIONAL(CLEFAIRY),
HOENN_TO_NATIONAL(CLEFABLE),
HOENN_TO_NATIONAL(PARAS),
HOENN_TO_NATIONAL(PARASECT),
HOENN_TO_NATIONAL(VENONAT),
HOENN_TO_NATIONAL(VENOMOTH),
HOENN_TO_NATIONAL(DIGLETT),
HOENN_TO_NATIONAL(DUGTRIO),
HOENN_TO_NATIONAL(MEOWTH),
HOENN_TO_NATIONAL(PERSIAN),
HOENN_TO_NATIONAL(MANKEY),
HOENN_TO_NATIONAL(PRIMEAPE),
HOENN_TO_NATIONAL(GROWLITHE),
HOENN_TO_NATIONAL(ARCANINE),
HOENN_TO_NATIONAL(POLIWAG),
HOENN_TO_NATIONAL(POLIWHIRL),
HOENN_TO_NATIONAL(POLIWRATH),
HOENN_TO_NATIONAL(BELLSPROUT),
HOENN_TO_NATIONAL(WEEPINBELL),
HOENN_TO_NATIONAL(VICTREEBEL),
HOENN_TO_NATIONAL(PONYTA),
HOENN_TO_NATIONAL(RAPIDASH),
HOENN_TO_NATIONAL(SLOWPOKE),
HOENN_TO_NATIONAL(SLOWBRO),
HOENN_TO_NATIONAL(FARFETCHD),
HOENN_TO_NATIONAL(SEEL),
HOENN_TO_NATIONAL(DEWGONG),
HOENN_TO_NATIONAL(SHELLDER),
HOENN_TO_NATIONAL(CLOYSTER),
HOENN_TO_NATIONAL(GASTLY),
HOENN_TO_NATIONAL(HAUNTER),
HOENN_TO_NATIONAL(GENGAR),
HOENN_TO_NATIONAL(ONIX),
HOENN_TO_NATIONAL(DROWZEE),
HOENN_TO_NATIONAL(HYPNO),
HOENN_TO_NATIONAL(KRABBY),
HOENN_TO_NATIONAL(KINGLER),
HOENN_TO_NATIONAL(EXEGGCUTE),
HOENN_TO_NATIONAL(EXEGGUTOR),
HOENN_TO_NATIONAL(CUBONE),
HOENN_TO_NATIONAL(MAROWAK),
HOENN_TO_NATIONAL(HITMONLEE),
HOENN_TO_NATIONAL(HITMONCHAN),
HOENN_TO_NATIONAL(LICKITUNG),
HOENN_TO_NATIONAL(CHANSEY),
HOENN_TO_NATIONAL(TANGELA),
HOENN_TO_NATIONAL(KANGASKHAN),
HOENN_TO_NATIONAL(MR_MIME),
HOENN_TO_NATIONAL(SCYTHER),
HOENN_TO_NATIONAL(JYNX),
HOENN_TO_NATIONAL(ELECTABUZZ),
HOENN_TO_NATIONAL(MAGMAR),
HOENN_TO_NATIONAL(TAUROS),
HOENN_TO_NATIONAL(LAPRAS),
HOENN_TO_NATIONAL(DITTO),
HOENN_TO_NATIONAL(EEVEE),
HOENN_TO_NATIONAL(VAPOREON),
HOENN_TO_NATIONAL(JOLTEON),
HOENN_TO_NATIONAL(FLAREON),
HOENN_TO_NATIONAL(PORYGON),
HOENN_TO_NATIONAL(OMANYTE),
HOENN_TO_NATIONAL(OMASTAR),
HOENN_TO_NATIONAL(KABUTO),
HOENN_TO_NATIONAL(KABUTOPS),
HOENN_TO_NATIONAL(AERODACTYL),
HOENN_TO_NATIONAL(SNORLAX),
HOENN_TO_NATIONAL(ARTICUNO),
HOENN_TO_NATIONAL(ZAPDOS),
HOENN_TO_NATIONAL(MOLTRES),
HOENN_TO_NATIONAL(DRATINI),
HOENN_TO_NATIONAL(DRAGONAIR),
HOENN_TO_NATIONAL(DRAGONITE),
HOENN_TO_NATIONAL(MEWTWO),
HOENN_TO_NATIONAL(MEW),
HOENN_TO_NATIONAL(CHIKORITA),
HOENN_TO_NATIONAL(BAYLEEF),
HOENN_TO_NATIONAL(MEGANIUM),
HOENN_TO_NATIONAL(CYNDAQUIL),
HOENN_TO_NATIONAL(QUILAVA),
HOENN_TO_NATIONAL(TYPHLOSION),
HOENN_TO_NATIONAL(TOTODILE),
HOENN_TO_NATIONAL(CROCONAW),
HOENN_TO_NATIONAL(FERALIGATR),
HOENN_TO_NATIONAL(SENTRET),
HOENN_TO_NATIONAL(FURRET),
HOENN_TO_NATIONAL(HOOTHOOT),
HOENN_TO_NATIONAL(NOCTOWL),
HOENN_TO_NATIONAL(LEDYBA),
HOENN_TO_NATIONAL(LEDIAN),
HOENN_TO_NATIONAL(SPINARAK),
HOENN_TO_NATIONAL(ARIADOS),
HOENN_TO_NATIONAL(CLEFFA),
HOENN_TO_NATIONAL(TOGEPI),
HOENN_TO_NATIONAL(TOGETIC),
HOENN_TO_NATIONAL(MAREEP),
HOENN_TO_NATIONAL(FLAAFFY),
HOENN_TO_NATIONAL(AMPHAROS),
HOENN_TO_NATIONAL(SUDOWOODO),
HOENN_TO_NATIONAL(POLITOED),
HOENN_TO_NATIONAL(HOPPIP),
HOENN_TO_NATIONAL(SKIPLOOM),
HOENN_TO_NATIONAL(JUMPLUFF),
HOENN_TO_NATIONAL(AIPOM),
HOENN_TO_NATIONAL(SUNKERN),
HOENN_TO_NATIONAL(SUNFLORA),
HOENN_TO_NATIONAL(YANMA),
HOENN_TO_NATIONAL(WOOPER),
HOENN_TO_NATIONAL(QUAGSIRE),
HOENN_TO_NATIONAL(ESPEON),
HOENN_TO_NATIONAL(UMBREON),
HOENN_TO_NATIONAL(MURKROW),
HOENN_TO_NATIONAL(SLOWKING),
HOENN_TO_NATIONAL(MISDREAVUS),
HOENN_TO_NATIONAL(UNOWN),
HOENN_TO_NATIONAL(PINECO),
HOENN_TO_NATIONAL(FORRETRESS),
HOENN_TO_NATIONAL(DUNSPARCE),
HOENN_TO_NATIONAL(GLIGAR),
HOENN_TO_NATIONAL(STEELIX),
HOENN_TO_NATIONAL(SNUBBULL),
HOENN_TO_NATIONAL(GRANBULL),
HOENN_TO_NATIONAL(QWILFISH),
HOENN_TO_NATIONAL(SCIZOR),
HOENN_TO_NATIONAL(SHUCKLE),
HOENN_TO_NATIONAL(SNEASEL),
HOENN_TO_NATIONAL(TEDDIURSA),
HOENN_TO_NATIONAL(URSARING),
HOENN_TO_NATIONAL(SWINUB),
HOENN_TO_NATIONAL(PILOSWINE),
HOENN_TO_NATIONAL(REMORAID),
HOENN_TO_NATIONAL(OCTILLERY),
HOENN_TO_NATIONAL(DELIBIRD),
HOENN_TO_NATIONAL(MANTINE),
HOENN_TO_NATIONAL(HOUNDOUR),
HOENN_TO_NATIONAL(HOUNDOOM),
HOENN_TO_NATIONAL(PORYGON2),
HOENN_TO_NATIONAL(STANTLER),
HOENN_TO_NATIONAL(SMEARGLE),
HOENN_TO_NATIONAL(TYROGUE),
HOENN_TO_NATIONAL(HITMONTOP),
HOENN_TO_NATIONAL(SMOOCHUM),
HOENN_TO_NATIONAL(ELEKID),
HOENN_TO_NATIONAL(MAGBY),
HOENN_TO_NATIONAL(MILTANK),
HOENN_TO_NATIONAL(BLISSEY),
HOENN_TO_NATIONAL(RAIKOU),
HOENN_TO_NATIONAL(ENTEI),
HOENN_TO_NATIONAL(SUICUNE),
HOENN_TO_NATIONAL(LARVITAR),
HOENN_TO_NATIONAL(PUPITAR),
HOENN_TO_NATIONAL(TYRANITAR),
HOENN_TO_NATIONAL(LUGIA),
HOENN_TO_NATIONAL(HO_OH),
HOENN_TO_NATIONAL(CELEBI),
HOENN_TO_NATIONAL(OLD_UNOWN_B),
HOENN_TO_NATIONAL(OLD_UNOWN_C),
HOENN_TO_NATIONAL(OLD_UNOWN_D),
HOENN_TO_NATIONAL(OLD_UNOWN_E),
HOENN_TO_NATIONAL(OLD_UNOWN_F),
HOENN_TO_NATIONAL(OLD_UNOWN_G),
HOENN_TO_NATIONAL(OLD_UNOWN_H),
HOENN_TO_NATIONAL(OLD_UNOWN_I),
HOENN_TO_NATIONAL(OLD_UNOWN_J),
HOENN_TO_NATIONAL(OLD_UNOWN_K),
HOENN_TO_NATIONAL(OLD_UNOWN_L),
HOENN_TO_NATIONAL(OLD_UNOWN_M),
HOENN_TO_NATIONAL(OLD_UNOWN_N),
HOENN_TO_NATIONAL(OLD_UNOWN_O),
HOENN_TO_NATIONAL(OLD_UNOWN_P),
HOENN_TO_NATIONAL(OLD_UNOWN_Q),
HOENN_TO_NATIONAL(OLD_UNOWN_R),
HOENN_TO_NATIONAL(OLD_UNOWN_S),
HOENN_TO_NATIONAL(OLD_UNOWN_T),
HOENN_TO_NATIONAL(OLD_UNOWN_U),
HOENN_TO_NATIONAL(OLD_UNOWN_V),
HOENN_TO_NATIONAL(OLD_UNOWN_W),
HOENN_TO_NATIONAL(OLD_UNOWN_X),
HOENN_TO_NATIONAL(OLD_UNOWN_Y),
HOENN_TO_NATIONAL(OLD_UNOWN_Z),
};
static const struct SpindaSpot sSpindaSpotGraphics[] =
{
{16, 7, INCBIN_U16("graphics/spinda_spots/spot_0.bin")},
{40, 8, INCBIN_U16("graphics/spinda_spots/spot_1.bin")},
{22, 25, INCBIN_U16("graphics/spinda_spots/spot_2.bin")},
{34, 26, INCBIN_U16("graphics/spinda_spots/spot_3.bin")}
};
#include "data/pokemon/item_effects.h"
static const s8 sNatureStatTable[][5] =
{
// Atk Def Spd Sp.Atk Sp.Def
{ 0, 0, 0, 0, 0}, // Hardy
{ +1, -1, 0, 0, 0}, // Lonely
{ +1, 0, -1, 0, 0}, // Brave
{ +1, 0, 0, -1, 0}, // Adamant
{ +1, 0, 0, 0, -1}, // Naughty
{ -1, +1, 0, 0, 0}, // Bold
{ 0, 0, 0, 0, 0}, // Docile
{ 0, +1, -1, 0, 0}, // Relaxed
{ 0, +1, 0, -1, 0}, // Impish
{ 0, +1, 0, 0, -1}, // Lax
{ -1, 0, +1, 0, 0}, // Timid
{ 0, -1, +1, 0, 0}, // Hasty
{ 0, 0, 0, 0, 0}, // Serious
{ 0, 0, +1, -1, 0}, // Jolly
{ 0, 0, +1, 0, -1}, // Naive
{ -1, 0, 0, +1, 0}, // Modest
{ 0, -1, 0, +1, 0}, // Mild
{ 0, 0, -1, +1, 0}, // Quiet
{ 0, 0, 0, 0, 0}, // Bashful
{ 0, 0, 0, +1, -1}, // Rash
{ -1, 0, 0, 0, +1}, // Calm
{ 0, -1, 0, 0, +1}, // Gentle
{ 0, 0, -1, 0, +1}, // Sassy
{ 0, 0, 0, -1, +1}, // Careful
{ 0, 0, 0, 0, 0}, // Quirky
};
#include "data/pokemon/tmhm_learnsets.h"
#include "data/pokemon/trainer_class_lookups.h"
#include "data/pokemon/cry_ids.h"
#include "data/pokemon/experience_tables.h"
#include "data/pokemon/base_stats.h"
#include "data/pokemon/level_up_learnsets.h"
#include "data/pokemon/evolution.h"
#include "data/pokemon/level_up_learnset_pointers.h"
static const s8 sPokeblockFlavorCompatibilityTable[] =
{
// Cool, Beauty, Cute, Smart, Tough
0, 0, 0, 0, 0, // Hardy
1, 0, 0, 0, -1, // Lonely
1, 0, -1, 0, 0, // Brave
1, -1, 0, 0, 0, // Adamant
1, 0, 0, -1, 0, // Naughty
-1, 0, 0, 0, 1, // Bold
0, 0, 0, 0, 0, // Docile
0, 0, -1, 0, 1, // Relaxed
0, -1, 0, 0, 1, // Impish
0, 0, 0, -1, 1, // Lax
-1, 0, 1, 0, 0, // Timid
0, 0, 1, 0, -1, // Hasty
0, 0, 0, 0, 0, // Serious
0, -1, 1, 0, 0, // Jolly
0, 0, 1, -1, 0, // Naive
-1, 1, 0, 0, 0, // Modest
0, 1, 0, 0, -1, // Mild
0, 1, -1, 0, 0, // Quiet
0, 0, 0, 0, 0, // Bashful
0, 1, 0, -1, 0, // Rash
-1, 0, 0, 1, 0, // Calm
0, 0, 0, 1, -1, // Gentle
0, 0, -1, 1, 0, // Sassy
0, -1, 0, 1, 0, // Careful
0, 0, 0, 0, 0 // Quirky
};
const u8 gPPUpGetMask[] = { 0x03, 0x0c, 0x30, 0xc0 }; // Masks for getting PP Up count, also PP Max values
const u8 gPPUpSetMask[] = { 0xfc, 0xf3, 0xcf, 0x3f }; // Masks for setting PP Up count
const u8 gPPUpAddMask[] = { 0x01, 0x04, 0x10, 0x40 }; // Values added to PP Up count
const u8 gStatStageRatios[][2] =
{
{ 10, 40 },
{ 10, 35 },
{ 10, 30 },
{ 10, 25 },
{ 10, 20 },
{ 10, 15 },
{ 10, 10 },
{ 15, 10 },
{ 20, 10 },
{ 25, 10 },
{ 30, 10 },
{ 35, 10 },
{ 40, 10 },
{ 138, 174 },
{ 108, 120 },
};
static const u8 sFiller = _("");
static const u8 sHoldEffectToType[][2] =
{
{HOLD_EFFECT_BUG_POWER, TYPE_BUG},
{HOLD_EFFECT_STEEL_POWER, TYPE_STEEL},
{HOLD_EFFECT_GROUND_POWER, TYPE_GROUND},
{HOLD_EFFECT_ROCK_POWER, TYPE_ROCK},
{HOLD_EFFECT_GRASS_POWER, TYPE_GRASS},
{HOLD_EFFECT_DARK_POWER, TYPE_DARK},
{HOLD_EFFECT_FIGHTING_POWER, TYPE_FIGHTING},
{HOLD_EFFECT_ELECTRIC_POWER, TYPE_ELECTRIC},
{HOLD_EFFECT_WATER_POWER, TYPE_WATER},
{HOLD_EFFECT_FLYING_POWER, TYPE_FLYING},
{HOLD_EFFECT_POISON_POWER, TYPE_POISON},
{HOLD_EFFECT_ICE_POWER, TYPE_ICE},
{HOLD_EFFECT_GHOST_POWER, TYPE_GHOST},
{HOLD_EFFECT_PSYCHIC_POWER, TYPE_PSYCHIC},
{HOLD_EFFECT_FIRE_POWER, TYPE_FIRE},
{HOLD_EFFECT_DRAGON_POWER, TYPE_DRAGON},
{HOLD_EFFECT_NORMAL_POWER, TYPE_NORMAL},
};
const struct SpriteTemplate gUnknown_825DEF0[] =
{
{
.tileTag = SPRITE_INVALID_TAG,
.paletteTag = 0,
.oam = &gUnknown_824F018,
.anims = NULL,
.images = gUnknown_8234698,
.affineAnims = gSpriteAffineAnimTable_82348C8,
.callback = sub_80120C4,
},
{
.tileTag = SPRITE_INVALID_TAG,
.paletteTag = 0,
.oam = &gUnknown_824F010,
.anims = NULL,
.images = gUnknown_82346B8,
.affineAnims = gSpriteAffineAnimTable_8234944,
.callback = oac_poke_opponent,
},
{
.tileTag = SPRITE_INVALID_TAG,
.paletteTag = 0,
.oam = &gUnknown_824F018,
.anims = NULL,
.images = gUnknown_82346D8,
.affineAnims = gSpriteAffineAnimTable_82348C8,
.callback = sub_80120C4,
},
{
.tileTag = SPRITE_INVALID_TAG,
.paletteTag = 0,
.oam = &gUnknown_824F010,
.anims = NULL,
.images = gUnknown_82346F8,
.affineAnims = gSpriteAffineAnimTable_8234944,
.callback = oac_poke_opponent,
},
};
const struct SpriteTemplate gUnknown_825DF50[] =
{
{
.tileTag = SPRITE_INVALID_TAG,
.paletteTag = 0,
.oam = &gUnknown_824F018,
.anims = NULL,
.images = gTrainerBackPicTable_Red,
.affineAnims = gSpriteAffineAnimTable_82348C8,
.callback = sub_80120C4,
},
{
.tileTag = SPRITE_INVALID_TAG,
.paletteTag = 0,
.oam = &gUnknown_824F018,
.anims = NULL,
.images = gTrainerBackPicTable_Leaf,
.affineAnims = gSpriteAffineAnimTable_82348C8,
.callback = sub_80120C4,
},
{
.tileTag = SPRITE_INVALID_TAG,
.paletteTag = 0,
.oam = &gUnknown_824F018,
.anims = NULL,
.images = gTrainerBackPicTable_RSBrendan,
.affineAnims = gSpriteAffineAnimTable_82348C8,
.callback = sub_80120C4,
},
{
.tileTag = SPRITE_INVALID_TAG,
.paletteTag = 0,
.oam = &gUnknown_824F018,
.anims = NULL,
.images = gTrainerBackPicTable_RSMay,
.affineAnims = gSpriteAffineAnimTable_82348C8,
.callback = sub_80120C4,
},
{
.tileTag = SPRITE_INVALID_TAG,
.paletteTag = 0,
.oam = &gUnknown_824F018,
.anims = NULL,
.images = gTrainerBackPicTable_PokeDude,
.affineAnims = gSpriteAffineAnimTable_82348C8,
.callback = sub_80120C4,
},
{
.tileTag = SPRITE_INVALID_TAG,
.paletteTag = 0,
.oam = &gUnknown_824F018,
.anims = NULL,
.images = gTrainerBackPicTable_OldMan,
.affineAnims = gSpriteAffineAnimTable_82348C8,
.callback = sub_80120C4,
},
};
static const u8 sSecretBaseFacilityClasses[][5] =
{
{ FACILITY_CLASS_YOUNGSTER_2, FACILITY_CLASS_YOUNGSTER_2, FACILITY_CLASS_YOUNGSTER_2, FACILITY_CLASS_YOUNGSTER_2, FACILITY_CLASS_YOUNGSTER_2 },
{ FACILITY_CLASS_YOUNGSTER_2, FACILITY_CLASS_YOUNGSTER_2, FACILITY_CLASS_YOUNGSTER_2, FACILITY_CLASS_YOUNGSTER_2, FACILITY_CLASS_YOUNGSTER_2 },
};
static const u8 sGetMonDataEVConstants[] =
{
MON_DATA_HP_EV,
MON_DATA_ATK_EV,
MON_DATA_DEF_EV,
MON_DATA_SPEED_EV,
MON_DATA_SPDEF_EV,
MON_DATA_SPATK_EV
};
static const u8 gUnknown_825DFF0[] =
{
STAT_ATK, STAT_ATK, STAT_SPEED, STAT_DEF, STAT_SPATK, STAT_ACC
};
static const s8 sFriendshipEventDeltas[][3] =
{
{ 5, 3, 2 },
{ 5, 3, 2 },
{ 1, 1, 0 },
{ 3, 2, 1 },
{ 1, 1, 0 },
{ 1, 1, 1 },
{ 3, 3, 3 },
{-1, -1, -1 },
{-5, -5, -10 },
{-5, -5, -10 },
};
static const u16 sHMMoves[] =
{
MOVE_CUT, MOVE_FLY, MOVE_SURF, MOVE_STRENGTH, MOVE_FLASH,
MOVE_ROCK_SMASH, MOVE_WATERFALL, MOVE_DIVE, 0xFFFF
};
static const u16 sDeoxysBaseStats[] =
{
50, // Hp
180, // Attack
20, // Defense
150, // Speed
180, // Sp.Attack
20, // Sp.Defense
};
const u16 gLinkPlayerFacilityClasses[] =
{
FACILITY_CLASS_COOLTRAINER_3, FACILITY_CLASS_BLACK_BELT_2, FACILITY_CLASS_CAMPER_2, FACILITY_CLASS_YOUNGSTER_2, FACILITY_CLASS_PSYCHIC_3,
FACILITY_CLASS_BUG_CATCHER_2, FACILITY_CLASS_TAMER, FACILITY_CLASS_JUGGLER, FACILITY_CLASS_COOLTRAINER_4, FACILITY_CLASS_CHANNELER,
FACILITY_CLASS_PICNICKER_2, FACILITY_CLASS_LASS_2, FACILITY_CLASS_PSYCHIC_4, FACILITY_CLASS_CRUSH_GIRL, FACILITY_CLASS_PKMN_BREEDER_3,
FACILITY_CLASS_BEAUTY_2, FACILITY_CLASS_AQUA_LEADER,
};
static const struct OamData sOakSpeechNidoranFDummyOamData =
{
.y = 0,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = 0,
.x = 0,
.matrixNum = 0,
.size = 3,
.tileNum = 0,
.priority = 0,
.paletteNum = 0,
};
static const struct SpriteTemplate sOakSpeechNidoranFDummyTemplate =
{
.tileTag = SPRITE_INVALID_TAG,
.paletteTag = SPRITE_INVALID_TAG,
.oam = &sOakSpeechNidoranFDummyOamData,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCallbackDummy,
};
// code
void ZeroBoxMonData(struct BoxPokemon *boxMon)
{
u8 *raw = (u8 *)boxMon;
u32 i;
for (i = 0; i < sizeof(struct BoxPokemon); i++)
raw[i] = 0;
}
void ZeroMonData(struct Pokemon *mon)
{
u32 arg;
ZeroBoxMonData(&mon->box);
arg = 0;
SetMonData(mon, MON_DATA_STATUS, &arg);
SetMonData(mon, MON_DATA_LEVEL, &arg);
SetMonData(mon, MON_DATA_HP, &arg);
SetMonData(mon, MON_DATA_MAX_HP, &arg);
SetMonData(mon, MON_DATA_ATK, &arg);
SetMonData(mon, MON_DATA_DEF, &arg);
SetMonData(mon, MON_DATA_SPEED, &arg);
SetMonData(mon, MON_DATA_SPATK, &arg);
SetMonData(mon, MON_DATA_SPDEF, &arg);
arg = 255;
SetMonData(mon, MON_DATA_MAIL, &arg);
}
void ZeroPlayerPartyMons(void)
{
s32 i;
for (i = 0; i < PARTY_SIZE; i++)
ZeroMonData(&gPlayerParty[i]);
}
void ZeroEnemyPartyMons(void)
{
s32 i;
for (i = 0; i < PARTY_SIZE; i++)
ZeroMonData(&gEnemyParty[i]);
}
void CreateMon(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId)
{
u32 arg;
ZeroMonData(mon);
CreateBoxMon(&mon->box, species, level, fixedIV, hasFixedPersonality, fixedPersonality, otIdType, fixedOtId);
SetMonData(mon, MON_DATA_LEVEL, &level);
arg = 255;
SetMonData(mon, MON_DATA_MAIL, &arg);
CalculateMonStats(mon);
}
void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId)
{
u8 speciesName[POKEMON_NAME_LENGTH + 1];
u32 personality;
u32 value;
u16 checksum;
ZeroBoxMonData(boxMon);
if (hasFixedPersonality)
personality = fixedPersonality;
else
personality = Random32();
SetBoxMonData(boxMon, MON_DATA_PERSONALITY, &personality);
//Determine original trainer ID
if (otIdType == OT_ID_RANDOM_NO_SHINY) //Pokemon cannot be shiny
{
u32 shinyValue;
do
{
value = Random32();
shinyValue = HIHALF(value) ^ LOHALF(value) ^ HIHALF(personality) ^ LOHALF(personality);
} while (shinyValue < 8);
}
else if (otIdType == OT_ID_PRESET) //Pokemon has a preset OT ID
{
value = fixedOtId;
}
else //Player is the OT
{
value = gSaveBlock2Ptr->playerTrainerId[0]
| (gSaveBlock2Ptr->playerTrainerId[1] << 8)
| (gSaveBlock2Ptr->playerTrainerId[2] << 16)
| (gSaveBlock2Ptr->playerTrainerId[3] << 24);
}
SetBoxMonData(boxMon, MON_DATA_OT_ID, &value);
checksum = CalculateBoxMonChecksum(boxMon);
SetBoxMonData(boxMon, MON_DATA_CHECKSUM, &checksum);
EncryptBoxMon(boxMon);
GetSpeciesName(speciesName, species);
SetBoxMonData(boxMon, MON_DATA_NICKNAME, speciesName);
SetBoxMonData(boxMon, MON_DATA_LANGUAGE, &gGameLanguage);
SetBoxMonData(boxMon, MON_DATA_OT_NAME, gSaveBlock2Ptr->playerName);
SetBoxMonData(boxMon, MON_DATA_SPECIES, &species);
SetBoxMonData(boxMon, MON_DATA_EXP, &gExperienceTables[gBaseStats[species].growthRate][level]);
SetBoxMonData(boxMon, MON_DATA_FRIENDSHIP, &gBaseStats[species].friendship);
value = GetCurrentRegionMapSectionId();
SetBoxMonData(boxMon, MON_DATA_MET_LOCATION, &value);
SetBoxMonData(boxMon, MON_DATA_MET_LEVEL, &level);
SetBoxMonData(boxMon, MON_DATA_MET_GAME, &gGameVersion);
value = ITEM_POKE_BALL;
SetBoxMonData(boxMon, MON_DATA_POKEBALL, &value);
SetBoxMonData(boxMon, MON_DATA_OT_GENDER, &gSaveBlock2Ptr->playerGender);
if (fixedIV < 32)
{
SetBoxMonData(boxMon, MON_DATA_HP_IV, &fixedIV);
SetBoxMonData(boxMon, MON_DATA_ATK_IV, &fixedIV);
SetBoxMonData(boxMon, MON_DATA_DEF_IV, &fixedIV);
SetBoxMonData(boxMon, MON_DATA_SPEED_IV, &fixedIV);
SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &fixedIV);
SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &fixedIV);
}
else
{
u32 iv;
value = Random();
iv = value & 0x1F;
SetBoxMonData(boxMon, MON_DATA_HP_IV, &iv);
iv = (value & 0x3E0) >> 5;
SetBoxMonData(boxMon, MON_DATA_ATK_IV, &iv);
iv = (value & 0x7C00) >> 10;
SetBoxMonData(boxMon, MON_DATA_DEF_IV, &iv);
value = Random();
iv = value & 0x1F;
SetBoxMonData(boxMon, MON_DATA_SPEED_IV, &iv);
iv = (value & 0x3E0) >> 5;
SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &iv);
iv = (value & 0x7C00) >> 10;
SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &iv);
}
if (gBaseStats[species].abilities[1])
{
value = personality & 1;
SetBoxMonData(boxMon, MON_DATA_ABILITY_NUM, &value);
}
GiveBoxMonInitialMoveset(boxMon);
}
void CreateMonWithNature(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 nature)
{
u32 personality;
do
{
personality = Random32();
}
while (nature != GetNatureFromPersonality(personality));
CreateMon(mon, species, level, fixedIV, 1, personality, OT_ID_PLAYER_ID, 0);
}
void CreateMonWithGenderNatureLetter(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 gender, u8 nature, u8 unownLetter)
{
u32 personality;
if ((u8)(unownLetter - 1) < 28)
{
u16 actualLetter;
do
{
personality = Random32();
actualLetter = ((((personality & 0x3000000) >> 18) | ((personality & 0x30000) >> 12) | ((personality & 0x300) >> 6) | (personality & 0x3)) % 28);
}
while (nature != GetNatureFromPersonality(personality)
|| gender != GetGenderFromSpeciesAndPersonality(species, personality)
|| actualLetter != unownLetter - 1);
}
else
{
do
{
personality = Random32();
}
while (nature != GetNatureFromPersonality(personality)
|| gender != GetGenderFromSpeciesAndPersonality(species, personality));
}
CreateMon(mon, species, level, fixedIV, 1, personality, OT_ID_PLAYER_ID, 0);
}
// Used to create the Old Man's Weedle?
void CreateMaleMon(struct Pokemon *mon, u16 species, u8 level)
{
u32 personality;
u32 otId;
do
{
otId = Random32();
personality = Random32();
}
while (GetGenderFromSpeciesAndPersonality(species, personality) != MON_MALE);
CreateMon(mon, species, level, 32, 1, personality, OT_ID_PRESET, otId);
}
void CreateMonWithIVsPersonality(struct Pokemon *mon, u16 species, u8 level, u32 ivs, u32 personality)
{
CreateMon(mon, species, level, 0, 1, personality, OT_ID_PLAYER_ID, 0);
SetMonData(mon, MON_DATA_IVS, &ivs);
CalculateMonStats(mon);
}
static void CreateMonWithIVsOTID(struct Pokemon *mon, u16 species, u8 level, u8 *ivs, u32 otId)
{
CreateMon(mon, species, level, 0, 0, 0, OT_ID_PRESET, otId);
SetMonData(mon, MON_DATA_HP_IV, &ivs[0]);
SetMonData(mon, MON_DATA_ATK_IV, &ivs[1]);
SetMonData(mon, MON_DATA_DEF_IV, &ivs[2]);
SetMonData(mon, MON_DATA_SPEED_IV, &ivs[3]);
SetMonData(mon, MON_DATA_SPATK_IV, &ivs[4]);
SetMonData(mon, MON_DATA_SPDEF_IV, &ivs[5]);
CalculateMonStats(mon);
}
void CreateMonWithEVSpread(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 evSpread)
{
s32 i;
s32 statCount = 0;
u16 evAmount;
u8 evsBits;
CreateMon(mon, species, level, fixedIV, 0, 0, 0, 0);
evsBits = evSpread;
for (i = 0; i < NUM_STATS; i++)
{
if (evsBits & 1)
statCount++;
evsBits >>= 1;
}
evAmount = MAX_TOTAL_EVS / statCount;
evsBits = 1;
for (i = 0; i < NUM_STATS; i++)
{
if (evSpread & evsBits)
SetMonData(mon, MON_DATA_HP_EV + i, &evAmount);
evsBits <<= 1;
}
CalculateMonStats(mon);
}
void CreateBattleTowerMon(struct Pokemon *mon, struct BattleTowerPokemon *src)
{
s32 i;
u8 value;
CreateMon(mon, src->species, src->level, 0, 1, src->personality, 1, src->otId);
for (i = 0; i < 4; i++)
SetMonMoveSlot(mon, src->moves[i], i);
SetMonData(mon, MON_DATA_PP_BONUSES, &src->ppBonuses);
SetMonData(mon, MON_DATA_HELD_ITEM, &src->heldItem);
// Why is this commented out in FR/LG?
/*
StringCopy(nickname, src->nickname);
if (nickname[0] == 0xFC && nickname[1] == 0x15)
language = LANGUAGE_JAPANESE;
else
language = GAME_LANGUAGE;
SetMonData(mon, MON_DATA_LANGUAGE, &language);
Text_StripExtCtrlCodes(nickname);
*/
SetMonData(mon, MON_DATA_NICKNAME, &src->nickname);
SetMonData(mon, MON_DATA_FRIENDSHIP, &src->friendship);
SetMonData(mon, MON_DATA_HP_EV, &src->hpEV);
SetMonData(mon, MON_DATA_ATK_EV, &src->attackEV);
SetMonData(mon, MON_DATA_DEF_EV, &src->defenseEV);
SetMonData(mon, MON_DATA_SPEED_EV, &src->speedEV);
SetMonData(mon, MON_DATA_SPATK_EV, &src->spAttackEV);
SetMonData(mon, MON_DATA_SPDEF_EV, &src->spDefenseEV);
value = src->abilityNum;
SetMonData(mon, MON_DATA_ABILITY_NUM, &value);
value = src->hpIV;
SetMonData(mon, MON_DATA_HP_IV, &value);
value = src->attackIV;
SetMonData(mon, MON_DATA_ATK_IV, &value);
value = src->defenseIV;
SetMonData(mon, MON_DATA_DEF_IV, &value);
value = src->speedIV;
SetMonData(mon, MON_DATA_SPEED_IV, &value);
value = src->spAttackIV;
SetMonData(mon, MON_DATA_SPATK_IV, &value);
value = src->spDefenseIV;
SetMonData(mon, MON_DATA_SPDEF_IV, &value);
CalculateMonStats(mon);
}
static void CreateObedientMon(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId)
{
bool32 obedient = TRUE;
CreateMon(mon, species, level, fixedIV, hasFixedPersonality, fixedPersonality, otIdType, fixedOtId);
SetMonData(mon, MON_DATA_OBEDIENCE, &obedient);
}
void sub_803E23C(struct Pokemon *mon, struct BattleTowerPokemon *dest)
{
s32 i;
u16 heldItem;
dest->species = GetMonData(mon, MON_DATA_SPECIES, NULL);
heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, NULL);
if (heldItem == ITEM_ENIGMA_BERRY)
heldItem = 0;
dest->heldItem = heldItem;
for (i = 0; i < 4; i++)
dest->moves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, NULL);
dest->level = GetMonData(mon, MON_DATA_LEVEL, NULL);
dest->ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
dest->otId = GetMonData(mon, MON_DATA_OT_ID, NULL);
dest->hpEV = GetMonData(mon, MON_DATA_HP_EV, NULL);
dest->attackEV = GetMonData(mon, MON_DATA_ATK_EV, NULL);
dest->defenseEV = GetMonData(mon, MON_DATA_DEF_EV, NULL);
dest->speedEV = GetMonData(mon, MON_DATA_SPEED_EV, NULL);
dest->spAttackEV = GetMonData(mon, MON_DATA_SPATK_EV, NULL);
dest->spDefenseEV = GetMonData(mon, MON_DATA_SPDEF_EV, NULL);
dest->friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL);
dest->hpIV = GetMonData(mon, MON_DATA_HP_IV, NULL);
dest->attackIV = GetMonData(mon, MON_DATA_ATK_IV, NULL);
dest->defenseIV = GetMonData(mon, MON_DATA_DEF_IV, NULL);
dest->speedIV = GetMonData(mon, MON_DATA_SPEED_IV, NULL);
dest->spAttackIV = GetMonData(mon, MON_DATA_SPATK_IV, NULL);
dest->spDefenseIV = GetMonData(mon, MON_DATA_SPDEF_IV, NULL);
dest->abilityNum = GetMonData(mon, MON_DATA_ABILITY_NUM, NULL);
dest->personality = GetMonData(mon, MON_DATA_PERSONALITY, NULL);
GetMonData(mon, MON_DATA_NICKNAME, dest->nickname);
}
static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon)
{
u16 checksum = 0;
union PokemonSubstruct *substruct0 = GetSubstruct(boxMon, boxMon->personality, 0);
union PokemonSubstruct *substruct1 = GetSubstruct(boxMon, boxMon->personality, 1);
union PokemonSubstruct *substruct2 = GetSubstruct(boxMon, boxMon->personality, 2);
union PokemonSubstruct *substruct3 = GetSubstruct(boxMon, boxMon->personality, 3);
s32 i;
for (i = 0; i < 6; i++)
checksum += substruct0->raw[i];
for (i = 0; i < 6; i++)
checksum += substruct1->raw[i];
for (i = 0; i < 6; i++)
checksum += substruct2->raw[i];
for (i = 0; i < 6; i++)
checksum += substruct3->raw[i];
return checksum;
}
#define CALC_STAT(base, iv, ev, statIndex, field) \
{ \
u8 baseStat = gBaseStats[species].base; \
s32 n = (((2 * baseStat + iv + ev / 4) * level) / 100) + 5; \
u8 nature = GetNature(mon); \
n = ModifyStatByNature(nature, n, statIndex); \
SetMonData(mon, field, &n); \
}
void CalculateMonStats(struct Pokemon *mon)
{
s32 oldMaxHP = GetMonData(mon, MON_DATA_MAX_HP, NULL);
s32 currentHP = GetMonData(mon, MON_DATA_HP, NULL);
s32 hpIV = GetMonData(mon, MON_DATA_HP_IV, NULL);
s32 hpEV = GetMonData(mon, MON_DATA_HP_EV, NULL);
s32 attackIV = GetMonData(mon, MON_DATA_ATK_IV, NULL);
s32 attackEV = GetMonData(mon, MON_DATA_ATK_EV, NULL);
s32 defenseIV = GetMonData(mon, MON_DATA_DEF_IV, NULL);
s32 defenseEV = GetMonData(mon, MON_DATA_DEF_EV, NULL);
s32 speedIV = GetMonData(mon, MON_DATA_SPEED_IV, NULL);
s32 speedEV = GetMonData(mon, MON_DATA_SPEED_EV, NULL);
s32 spAttackIV = GetMonData(mon, MON_DATA_SPATK_IV, NULL);
s32 spAttackEV = GetMonData(mon, MON_DATA_SPATK_EV, NULL);
s32 spDefenseIV = GetMonData(mon, MON_DATA_SPDEF_IV, NULL);
s32 spDefenseEV = GetMonData(mon, MON_DATA_SPDEF_EV, NULL);
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
s32 level = GetLevelFromMonExp(mon);
s32 newMaxHP;
SetMonData(mon, MON_DATA_LEVEL, &level);
if (species == SPECIES_SHEDINJA)
{
newMaxHP = 1;
}
else
{
s32 n = 2 * gBaseStats[species].baseHP + hpIV;
newMaxHP = (((n + hpEV / 4) * level) / 100) + level + 10;
}
gBattleScripting.field_23 = newMaxHP - oldMaxHP;
if (gBattleScripting.field_23 == 0)
gBattleScripting.field_23 = 1;
SetMonData(mon, MON_DATA_MAX_HP, &newMaxHP);
CALC_STAT(baseAttack, attackIV, attackEV, STAT_ATK, MON_DATA_ATK)
CALC_STAT(baseDefense, defenseIV, defenseEV, STAT_DEF, MON_DATA_DEF)
CALC_STAT(baseSpeed, speedIV, speedEV, STAT_SPEED, MON_DATA_SPEED)
CALC_STAT(baseSpAttack, spAttackIV, spAttackEV, STAT_SPATK, MON_DATA_SPATK)
CALC_STAT(baseSpDefense, spDefenseIV, spDefenseEV, STAT_SPDEF, MON_DATA_SPDEF)
if (species == SPECIES_SHEDINJA)
{
if (currentHP != 0 || oldMaxHP == 0)
currentHP = 1;
else
return;
}
else
{
if (currentHP == 0 && oldMaxHP == 0)
currentHP = newMaxHP;
else if (currentHP != 0)
currentHP += newMaxHP - oldMaxHP;
else
return;
}
SetMonData(mon, MON_DATA_HP, &currentHP);
}
void BoxMonToMon(struct BoxPokemon *src, struct Pokemon *dest)
{
u32 value = 0;
dest->box = *src;
SetMonData(dest, MON_DATA_STATUS, &value);
SetMonData(dest, MON_DATA_HP, &value);
SetMonData(dest, MON_DATA_MAX_HP, &value);
value = 255;
SetMonData(dest, MON_DATA_MAIL, &value);
CalculateMonStats(dest);
}
static u8 GetLevelFromMonExp(struct Pokemon *mon)
{
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
u32 exp = GetMonData(mon, MON_DATA_EXP, NULL);
s32 level = 1;
while (level <= MAX_MON_LEVEL && gExperienceTables[gBaseStats[species].growthRate][level] <= exp)
level++;
return level - 1;
}
u8 GetLevelFromBoxMonExp(struct BoxPokemon *boxMon)
{
u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
u32 exp = GetBoxMonData(boxMon, MON_DATA_EXP, NULL);
s32 level = 1;
while (level <= MAX_MON_LEVEL && gExperienceTables[gBaseStats[species].growthRate][level] <= exp)
level++;
return level - 1;
}
u16 GiveMoveToMon(struct Pokemon *mon, u16 move)
{
return GiveMoveToBoxMon(&mon->box, move);
}
static u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
{
s32 i;
for (i = 0; i < 4; i++)
{
u16 existingMove = GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, NULL);
if (!existingMove)
{
SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &move);
SetBoxMonData(boxMon, MON_DATA_PP1 + i, &gBattleMoves[move].pp);
return move;
}
if (existingMove == move)
return -2;
}
return -1;
}
u16 GiveMoveToBattleMon(struct BattlePokemon *mon, u16 move)
{
s32 i;
for (i = 0; i < 4; i++)
{
if (!mon->moves[i])
{
mon->moves[i] = move;
mon->pp[i] = gBattleMoves[move].pp;
return move;
}
}
return -1;
}
void SetMonMoveSlot(struct Pokemon *mon, u16 move, u8 slot)
{
SetMonData(mon, MON_DATA_MOVE1 + slot, &move);
SetMonData(mon, MON_DATA_PP1 + slot, &gBattleMoves[move].pp);
}
void SetBattleMonMoveSlot(struct BattlePokemon *mon, u16 move, u8 slot)
{
mon->moves[slot] = move;
mon->pp[slot] = gBattleMoves[move].pp;
}
static void GiveMonInitialMoveset(struct Pokemon *mon)
{
GiveBoxMonInitialMoveset(&mon->box);
}
static void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon)
{
u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
s32 level = GetLevelFromBoxMonExp(boxMon);
s32 i;
for (i = 0; gLevelUpLearnsets[species][i] != LEVEL_UP_END; i++)
{
u16 moveLevel;
u16 move;
moveLevel = (gLevelUpLearnsets[species][i] & 0xFE00);
if (moveLevel > (level << 9))
break;
move = (gLevelUpLearnsets[species][i] & 0x1FF);
if (GiveMoveToBoxMon(boxMon, move) == 0xFFFF)
DeleteFirstMoveAndGiveMoveToBoxMon(boxMon, move);
}
}
u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove)
{
u32 retVal = 0;
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
u8 level = GetMonData(mon, MON_DATA_LEVEL, NULL);
// since you can learn more than one move per level
// the game needs to know whether you decided to
// learn it or keep the old set to avoid asking
// you to learn the same move over and over again
if (firstMove)
{
sLearningMoveTableID = 0;
while ((gLevelUpLearnsets[species][sLearningMoveTableID] & 0xFE00) != (level << 9))
{
sLearningMoveTableID++;
if (gLevelUpLearnsets[species][sLearningMoveTableID] == LEVEL_UP_END)
return 0;
}
}
if ((gLevelUpLearnsets[species][sLearningMoveTableID] & 0xFE00) == (level << 9))
{
gMoveToLearn = (gLevelUpLearnsets[species][sLearningMoveTableID] & 0x1FF);
sLearningMoveTableID++;
retVal = GiveMoveToMon(mon, gMoveToLearn);
}
return retVal;
}
void DeleteFirstMoveAndGiveMoveToMon(struct Pokemon *mon, u16 move)
{
s32 i;
u16 moves[4];
u8 pp[4];
u8 ppBonuses;
for (i = 0; i < 3; i++)
{
moves[i] = GetMonData(mon, MON_DATA_MOVE2 + i, NULL);
pp[i] = GetMonData(mon, MON_DATA_PP2 + i, NULL);
}
ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
ppBonuses >>= 2;
moves[3] = move;
pp[3] = gBattleMoves[move].pp;
for (i = 0; i < 4; i++)
{
SetMonData(mon, MON_DATA_MOVE1 + i, &moves[i]);
SetMonData(mon, MON_DATA_PP1 + i, &pp[i]);
}
SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses);
}
static void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
{
s32 i;
u16 moves[4];
u8 pp[4];
u8 ppBonuses;
for (i = 0; i < 3; i++)
{
moves[i] = GetBoxMonData(boxMon, MON_DATA_MOVE2 + i, NULL);
pp[i] = GetBoxMonData(boxMon, MON_DATA_PP2 + i, NULL);
}
ppBonuses = GetBoxMonData(boxMon, MON_DATA_PP_BONUSES, NULL);
ppBonuses >>= 2;
moves[3] = move;
pp[3] = gBattleMoves[move].pp;
for (i = 0; i < 4; i++)
{
SetBoxMonData(boxMon, MON_DATA_MOVE1 + i, &moves[i]);
SetBoxMonData(boxMon, MON_DATA_PP1 + i, &pp[i]);
}
SetBoxMonData(boxMon, MON_DATA_PP_BONUSES, &ppBonuses);
}
#define APPLY_STAT_MOD(var, mon, stat, statIndex) \
{ \
(var) = (stat) * (gStatStageRatios)[(mon)->statStages[(statIndex)]][0]; \
(var) /= (gStatStageRatios)[(mon)->statStages[(statIndex)]][1]; \
}
s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 sideStatus, u16 powerOverride, u8 typeOverride, u8 battlerIdAtk, u8 battlerIdDef)
{
u32 i;
s32 damage = 0;
s32 damageHelper;
u8 type;
u16 attack, defense;
u16 spAttack, spDefense;
u8 defenderHoldEffect;
u8 defenderHoldEffectParam;
u8 attackerHoldEffect;
u8 attackerHoldEffectParam;
if (!powerOverride)
gBattleMovePower = gBattleMoves[move].power;
else
gBattleMovePower = powerOverride;
if (!typeOverride)
type = gBattleMoves[move].type;
else
type = typeOverride & 0x3F;
attack = attacker->attack;
defense = defender->defense;
spAttack = attacker->spAttack;
spDefense = defender->spDefense;
if (attacker->item == ITEM_ENIGMA_BERRY)
{
attackerHoldEffect = gEnigmaBerries[battlerIdAtk].holdEffect;
attackerHoldEffectParam = gEnigmaBerries[battlerIdAtk].holdEffectParam;
}
else
{
attackerHoldEffect = ItemId_GetHoldEffect(attacker->item);
attackerHoldEffectParam = ItemId_GetHoldEffectParam(attacker->item);
}
if (defender->item == ITEM_ENIGMA_BERRY)
{
defenderHoldEffect = gEnigmaBerries[battlerIdDef].holdEffect;
defenderHoldEffectParam = gEnigmaBerries[battlerIdDef].holdEffectParam;
}
else
{
defenderHoldEffect = ItemId_GetHoldEffect(defender->item);
defenderHoldEffectParam = ItemId_GetHoldEffectParam(defender->item);
}
if (attacker->ability == ABILITY_HUGE_POWER || attacker->ability == ABILITY_PURE_POWER)
attack *= 2;
// In FRLG, the Battle Tower and opponent checks are stubbed here.
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | /*BATTLE_TYPE_BATTLE_TOWER |*/ BATTLE_TYPE_EREADER_TRAINER)))
{
if (FlagGet(FLAG_BADGE01_GET)
&& !GetBattlerSide(battlerIdAtk))
attack = (110 * attack) / 100;
}
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | /*BATTLE_TYPE_BATTLE_TOWER |*/ BATTLE_TYPE_EREADER_TRAINER)))
{
if (FlagGet(FLAG_BADGE05_GET)
&& !GetBattlerSide(battlerIdDef))
defense = (110 * defense) / 100;
}
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | /*BATTLE_TYPE_BATTLE_TOWER |*/ BATTLE_TYPE_EREADER_TRAINER)))
{
if (FlagGet(FLAG_BADGE07_GET)
&& !GetBattlerSide(battlerIdAtk))
spAttack = (110 * spAttack) / 100;
}
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | /*BATTLE_TYPE_BATTLE_TOWER |*/ BATTLE_TYPE_EREADER_TRAINER)))
{
if (FlagGet(FLAG_BADGE07_GET)
&& !GetBattlerSide(battlerIdDef))
spDefense = (110 * spDefense) / 100;
}
for (i = 0; i < NELEMS(sHoldEffectToType); i++)
{
if (attackerHoldEffect == sHoldEffectToType[i][0]
&& type == sHoldEffectToType[i][1])
{
if (IS_TYPE_PHYSICAL(type))
attack = (attack * (attackerHoldEffectParam + 100)) / 100;
else
spAttack = (spAttack * (attackerHoldEffectParam + 100)) / 100;
break;
}
}
if (attackerHoldEffect == HOLD_EFFECT_CHOICE_BAND)
attack = (150 * attack) / 100;
if (attackerHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & (BATTLE_TYPE_BATTLE_TOWER)) && (attacker->species == SPECIES_LATIAS || attacker->species == SPECIES_LATIOS))
spAttack = (150 * spAttack) / 100;
if (defenderHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & (BATTLE_TYPE_BATTLE_TOWER)) && (defender->species == SPECIES_LATIAS || defender->species == SPECIES_LATIOS))
spDefense = (150 * spDefense) / 100;
if (attackerHoldEffect == HOLD_EFFECT_DEEP_SEA_TOOTH && attacker->species == SPECIES_CLAMPERL)
spAttack *= 2;
if (defenderHoldEffect == HOLD_EFFECT_DEEP_SEA_SCALE && defender->species == SPECIES_CLAMPERL)
spDefense *= 2;
if (attackerHoldEffect == HOLD_EFFECT_LIGHT_BALL && attacker->species == SPECIES_PIKACHU)
spAttack *= 2;
if (defenderHoldEffect == HOLD_EFFECT_METAL_POWDER && defender->species == SPECIES_DITTO)
defense *= 2;
if (attackerHoldEffect == HOLD_EFFECT_THICK_CLUB && (attacker->species == SPECIES_CUBONE || attacker->species == SPECIES_MAROWAK))
attack *= 2;
if (defender->ability == ABILITY_THICK_FAT && (type == TYPE_FIRE || type == TYPE_ICE))
spAttack /= 2;
if (attacker->ability == ABILITY_HUSTLE)
attack = (150 * attack) / 100;
if (attacker->ability == ABILITY_PLUS && ABILITY_ON_FIELD2(ABILITY_MINUS))
spAttack = (150 * spAttack) / 100;
if (attacker->ability == ABILITY_MINUS && ABILITY_ON_FIELD2(ABILITY_PLUS))
spAttack = (150 * spAttack) / 100;
if (attacker->ability == ABILITY_GUTS && attacker->status1)
attack = (150 * attack) / 100;
if (defender->ability == ABILITY_MARVEL_SCALE && defender->status1)
defense = (150 * defense) / 100;
if (type == TYPE_ELECTRIC && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFD, 0))
gBattleMovePower /= 2;
if (type == TYPE_FIRE && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFE, 0))
gBattleMovePower /= 2;
if (type == TYPE_GRASS && attacker->ability == ABILITY_OVERGROW && attacker->hp <= (attacker->maxHP / 3))
gBattleMovePower = (150 * gBattleMovePower) / 100;
if (type == TYPE_FIRE && attacker->ability == ABILITY_BLAZE && attacker->hp <= (attacker->maxHP / 3))
gBattleMovePower = (150 * gBattleMovePower) / 100;
if (type == TYPE_WATER && attacker->ability == ABILITY_TORRENT && attacker->hp <= (attacker->maxHP / 3))
gBattleMovePower = (150 * gBattleMovePower) / 100;
if (type == TYPE_BUG && attacker->ability == ABILITY_SWARM && attacker->hp <= (attacker->maxHP / 3))
gBattleMovePower = (150 * gBattleMovePower) / 100;
if (gBattleMoves[gCurrentMove].effect == EFFECT_EXPLOSION)
defense /= 2;
if (IS_TYPE_PHYSICAL(type))
{
if (gCritMultiplier == 2)
{
if (attacker->statStages[STAT_ATK] > 6)
APPLY_STAT_MOD(damage, attacker, attack, STAT_ATK)
else
damage = attack;
}
else
APPLY_STAT_MOD(damage, attacker, attack, STAT_ATK)
damage = damage * gBattleMovePower;
damage *= (2 * attacker->level / 5 + 2);
if (gCritMultiplier == 2)
{
if (defender->statStages[STAT_DEF] < 6)
APPLY_STAT_MOD(damageHelper, defender, defense, STAT_DEF)
else
damageHelper = defense;
}
else
APPLY_STAT_MOD(damageHelper, defender, defense, STAT_DEF)
damage = damage / damageHelper;
damage /= 50;
if ((attacker->status1 & STATUS1_BURN) && attacker->ability != ABILITY_GUTS)
damage /= 2;
if ((sideStatus & SIDE_STATUS_REFLECT) && gCritMultiplier == 1)
{
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMonsInBattle(BATTLE_ALIVE_DEF_SIDE) == 2)
damage = 2 * (damage / 3);
else
damage /= 2;
}
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMonsInBattle(BATTLE_ALIVE_DEF_SIDE) == 2)
damage /= 2;
// moves always do at least 1 damage.
if (damage == 0)
damage = 1;
}
if (type == TYPE_MYSTERY)
damage = 0; // is ??? type. does 0 damage.
if (IS_TYPE_SPECIAL(type))
{
if (gCritMultiplier == 2)
{
if (attacker->statStages[STAT_SPATK] > 6)
APPLY_STAT_MOD(damage, attacker, spAttack, STAT_SPATK)
else
damage = spAttack;
}
else
APPLY_STAT_MOD(damage, attacker, spAttack, STAT_SPATK)
damage = damage * gBattleMovePower;
damage *= (2 * attacker->level / 5 + 2);
if (gCritMultiplier == 2)
{
if (defender->statStages[STAT_SPDEF] < 6)
APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_SPDEF)
else
damageHelper = spDefense;
}
else
APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_SPDEF)
damage = (damage / damageHelper);
damage /= 50;
if ((sideStatus & SIDE_STATUS_LIGHTSCREEN) && gCritMultiplier == 1)
{
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMonsInBattle(BATTLE_ALIVE_DEF_SIDE) == 2)
damage = 2 * (damage / 3);
else
damage /= 2;
}
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMonsInBattle(BATTLE_ALIVE_DEF_SIDE) == 2)
damage /= 2;
// are effects of weather negated with cloud nine or air lock
if (WEATHER_HAS_EFFECT2)
{
if (gBattleWeather & WEATHER_RAIN_TEMPORARY)
{
switch (type)
{
case TYPE_FIRE:
damage /= 2;
break;
case TYPE_WATER:
damage = (15 * damage) / 10;
break;
}
}
// any weather except sun weakens solar beam
if ((gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_HAIL)) && gCurrentMove == MOVE_SOLAR_BEAM)
damage /= 2;
// sunny
if (gBattleWeather & WEATHER_SUN_ANY)
{
switch (type)
{
case TYPE_FIRE:
damage = (15 * damage) / 10;
break;
case TYPE_WATER:
damage /= 2;
break;
}
}
}
// flash fire triggered
if ((gBattleResources->flags->flags[battlerIdAtk] & RESOURCE_FLAG_FLASH_FIRE) && type == TYPE_FIRE)
damage = (15 * damage) / 10;
}
return damage + 2;
}
u8 CountAliveMonsInBattle(u8 caseId)
{
s32 i;
u8 retVal = 0;
switch (caseId)
{
case BATTLE_ALIVE_EXCEPT_ACTIVE:
for (i = 0; i < 4; i++)
{
if (i != gActiveBattler && !(gAbsentBattlerFlags & gBitTable[i]))
retVal++;
}
break;
case BATTLE_ALIVE_ATK_SIDE:
for (i = 0; i < 4; i++)
{
if (GetBattlerSide(i) == GetBattlerSide(gBattlerAttacker) && !(gAbsentBattlerFlags & gBitTable[i]))
retVal++;
}
break;
case BATTLE_ALIVE_DEF_SIDE:
for (i = 0; i < 4; i++)
{
if (GetBattlerSide(i) == GetBattlerSide(gBattlerTarget) && !(gAbsentBattlerFlags & gBitTable[i]))
retVal++;
}
break;
}
return retVal;
}
u8 GetDefaultMoveTarget(u8 battlerId)
{
u8 opposing = BATTLE_OPPOSITE(GetBattlerPosition(battlerId) & BIT_SIDE);
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
return GetBattlerAtPosition(opposing);
if (CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_ACTIVE) > 1)
{
u8 position;
if ((Random() & 1) == 0)
position = BATTLE_PARTNER(opposing);
else
position = opposing;
return GetBattlerAtPosition(position);
}
else
{
if ((gAbsentBattlerFlags & gBitTable[opposing]))
return GetBattlerAtPosition(BATTLE_PARTNER(opposing));
else
return GetBattlerAtPosition(opposing);
}
}
u8 GetMonGender(struct Pokemon *mon)
{
return GetBoxMonGender(&mon->box);
}
u8 GetBoxMonGender(struct BoxPokemon *boxMon)
{
u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
u32 personality = GetBoxMonData(boxMon, MON_DATA_PERSONALITY, NULL);
switch (gBaseStats[species].genderRatio)
{
case MON_MALE:
case MON_FEMALE:
case MON_GENDERLESS:
return gBaseStats[species].genderRatio;
}
if (gBaseStats[species].genderRatio > (personality & 0xFF))
return MON_FEMALE;
else
return MON_MALE;
}
u8 GetGenderFromSpeciesAndPersonality(u16 species, u32 personality)
{
switch (gBaseStats[species].genderRatio)
{
case MON_MALE:
case MON_FEMALE:
case MON_GENDERLESS:
return gBaseStats[species].genderRatio;
}
if (gBaseStats[species].genderRatio > (personality & 0xFF))
return MON_FEMALE;
else
return MON_MALE;
}
void SetMultiuseSpriteTemplateToPokemon(u16 speciesTag, u8 battlerPosition)
{
if (gMonSpritesGfxPtr != NULL)
{
if (battlerPosition >= 4)
battlerPosition = 0;
gMultiuseSpriteTemplate = gMonSpritesGfxPtr->templates[battlerPosition];
}
else
{
if (sOakSpeechNidoranResources)
{
if (battlerPosition >= (s8)sOakSpeechNidoranResources->battlePosition) // why a cast?!? changing the unk0_2 type to s8 causes extra shifts, but a cast is the correct fix. why, compiler?
battlerPosition = 0;
gMultiuseSpriteTemplate = sOakSpeechNidoranResources->templates[battlerPosition];
}
else
{
if (battlerPosition >= 4)
battlerPosition = 0;
gMultiuseSpriteTemplate = gUnknown_825DEF0[battlerPosition];
}
}
gMultiuseSpriteTemplate.paletteTag = speciesTag;
gMultiuseSpriteTemplate.anims = gSpriteAnimTable_82349BC;
}
void SetMultiuseSpriteTemplateToTrainerBack(u16 trainerSpriteId, u8 battlerPosition)
{
gMultiuseSpriteTemplate.paletteTag = trainerSpriteId;
if (battlerPosition == B_POSITION_PLAYER_LEFT || battlerPosition == B_POSITION_PLAYER_RIGHT)
{
gMultiuseSpriteTemplate = gUnknown_825DF50[trainerSpriteId];
gMultiuseSpriteTemplate.anims = gTrainerBackAnimsPtrTable[trainerSpriteId];
}
else
{
if (gMonSpritesGfxPtr != NULL)
gMultiuseSpriteTemplate = gMonSpritesGfxPtr->templates[battlerPosition];
else
gMultiuseSpriteTemplate = gUnknown_825DEF0[battlerPosition];
gMultiuseSpriteTemplate.anims = gTrainerFrontAnimsPtrTable[trainerSpriteId];
}
}
static void EncryptBoxMon(struct BoxPokemon *boxMon)
{
u32 i;
for (i = 0; i < 12; i++)
{
boxMon->secure.raw[i] ^= boxMon->personality;
boxMon->secure.raw[i] ^= boxMon->otId;
}
}
static void DecryptBoxMon(struct BoxPokemon *boxMon)
{
u32 i;
for (i = 0; i < 12; i++)
{
boxMon->secure.raw[i] ^= boxMon->otId;
boxMon->secure.raw[i] ^= boxMon->personality;
}
}
#define SUBSTRUCT_CASE(n, v1, v2, v3, v4) \
case n: \
{ \
union PokemonSubstruct *substructs0 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs1 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs2 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs3 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs4 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs5 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs6 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs7 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs8 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs9 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs10 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs11 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs12 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs13 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs14 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs15 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs16 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs17 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs18 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs19 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs20 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs21 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs22 = boxMon->secure.substructs; \
union PokemonSubstruct *substructs23 = boxMon->secure.substructs; \
\
switch (substructType) \
{ \
case 0: \
substruct = &substructs ## n [v1]; \
break; \
case 1: \
substruct = &substructs ## n [v2]; \
break; \
case 2: \
substruct = &substructs ## n [v3]; \
break; \
case 3: \
substruct = &substructs ## n [v4]; \
break; \
} \
break; \
} \
static union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType)
{
union PokemonSubstruct *substruct = NULL;
switch (personality % 24)
{
SUBSTRUCT_CASE( 0,0,1,2,3)
SUBSTRUCT_CASE( 1,0,1,3,2)
SUBSTRUCT_CASE( 2,0,2,1,3)
SUBSTRUCT_CASE( 3,0,3,1,2)
SUBSTRUCT_CASE( 4,0,2,3,1)
SUBSTRUCT_CASE( 5,0,3,2,1)
SUBSTRUCT_CASE( 6,1,0,2,3)
SUBSTRUCT_CASE( 7,1,0,3,2)
SUBSTRUCT_CASE( 8,2,0,1,3)
SUBSTRUCT_CASE( 9,3,0,1,2)
SUBSTRUCT_CASE(10,2,0,3,1)
SUBSTRUCT_CASE(11,3,0,2,1)
SUBSTRUCT_CASE(12,1,2,0,3)
SUBSTRUCT_CASE(13,1,3,0,2)
SUBSTRUCT_CASE(14,2,1,0,3)
SUBSTRUCT_CASE(15,3,1,0,2)
SUBSTRUCT_CASE(16,2,3,0,1)
SUBSTRUCT_CASE(17,3,2,0,1)
SUBSTRUCT_CASE(18,1,2,3,0)
SUBSTRUCT_CASE(19,1,3,2,0)
SUBSTRUCT_CASE(20,2,1,3,0)
SUBSTRUCT_CASE(21,3,1,2,0)
SUBSTRUCT_CASE(22,2,3,1,0)
SUBSTRUCT_CASE(23,3,2,1,0)
}
return substruct;
}
u32 GetMonData(struct Pokemon *mon, s32 field, u8* data)
{
u32 ret;
switch (field)
{
case MON_DATA_STATUS:
ret = mon->status;
break;
case MON_DATA_LEVEL:
ret = mon->level;
break;
case MON_DATA_HP:
ret = mon->hp;
break;
case MON_DATA_MAX_HP:
ret = mon->maxHP;
break;
case MON_DATA_ATK:
ret = GetDeoxysStat(mon, STAT_ATK);
if (!ret)
ret = mon->attack;
break;
case MON_DATA_DEF:
ret = GetDeoxysStat(mon, STAT_DEF);
if (!ret)
ret = mon->defense;
break;
case MON_DATA_SPEED:
ret = GetDeoxysStat(mon, STAT_SPEED);
if (!ret)
ret = mon->speed;
break;
case MON_DATA_SPATK:
ret = GetDeoxysStat(mon, STAT_SPATK);
if (!ret)
ret = mon->spAttack;
break;
case MON_DATA_SPDEF:
ret = GetDeoxysStat(mon, STAT_SPDEF);
if (!ret)
ret = mon->spDefense;
break;
case MON_DATA_ATK2:
ret = mon->attack;
break;
case MON_DATA_DEF2:
ret = mon->defense;
break;
case MON_DATA_SPEED2:
ret = mon->speed;
break;
case MON_DATA_SPATK2:
ret = mon->spAttack;
break;
case MON_DATA_SPDEF2:
ret = mon->spDefense;
break;
case MON_DATA_MAIL:
ret = mon->mail;
break;
default:
ret = GetBoxMonData(&mon->box, field, data);
break;
}
return ret;
}
u32 GetBoxMonData(struct BoxPokemon *boxMon, s32 field, u8 *data)
{
s32 i;
u32 retVal = 0;
struct PokemonSubstruct0 *substruct0 = NULL;
struct PokemonSubstruct1 *substruct1 = NULL;
struct PokemonSubstruct2 *substruct2 = NULL;
struct PokemonSubstruct3 *substruct3 = NULL;
if (field > MON_DATA_10)
{
substruct0 = &(GetSubstruct(boxMon, boxMon->personality, 0)->type0);
substruct1 = &(GetSubstruct(boxMon, boxMon->personality, 1)->type1);
substruct2 = &(GetSubstruct(boxMon, boxMon->personality, 2)->type2);
substruct3 = &(GetSubstruct(boxMon, boxMon->personality, 3)->type3);
DecryptBoxMon(boxMon);
if (CalculateBoxMonChecksum(boxMon) != boxMon->checksum)
{
boxMon->isBadEgg = 1;
boxMon->isEgg = 1;
substruct3->isEgg = 1;
}
}
switch (field)
{
case MON_DATA_PERSONALITY:
retVal = boxMon->personality;
break;
case MON_DATA_OT_ID:
retVal = boxMon->otId;
break;
case MON_DATA_NICKNAME:
{
if (boxMon->isBadEgg)
{
for (retVal = 0;
retVal < POKEMON_NAME_LENGTH && gText_BadEgg[retVal] != EOS;
data[retVal] = gText_BadEgg[retVal], retVal++) {}
data[retVal] = EOS;
}
else if (boxMon->isEgg)
{
StringCopy(data, gText_EggNickname);
retVal = StringLength(data);
}
else if (boxMon->language == LANGUAGE_JAPANESE)
{
data[0] = EXT_CTRL_CODE_BEGIN;
data[1] = EXT_CTRL_CODE_JPN;
// FRLG changed i < 7 to i < 6
for (retVal = 2, i = 0;
i < 6 && boxMon->nickname[i] != EOS;
data[retVal] = boxMon->nickname[i], retVal++, i++) {}
data[retVal++] = EXT_CTRL_CODE_BEGIN;
data[retVal++] = EXT_CTRL_CODE_ENG;
data[retVal] = EOS;
}
else
{
for (retVal = 0;
retVal < POKEMON_NAME_LENGTH;
data[retVal] = boxMon->nickname[retVal], retVal++){}
data[retVal] = EOS;
}
break;
}
case MON_DATA_LANGUAGE:
retVal = boxMon->language;
break;
case MON_DATA_SANITY_IS_BAD_EGG:
retVal = boxMon->isBadEgg;
break;
case MON_DATA_SANITY_HAS_SPECIES:
retVal = boxMon->hasSpecies;
break;
case MON_DATA_SANITY_IS_EGG:
retVal = boxMon->isEgg;
break;
case MON_DATA_OT_NAME:
{
retVal = 0;
// FRLG changed this to 7 which used to be PLAYER_NAME_LENGTH
while (retVal < 7)
{
data[retVal] = boxMon->otName[retVal];
retVal++;
}
data[retVal] = EOS;
break;
}
case MON_DATA_MARKINGS:
retVal = boxMon->markings;
break;
case MON_DATA_CHECKSUM:
retVal = boxMon->checksum;
break;
case MON_DATA_10:
retVal = boxMon->unknown;
break;
case MON_DATA_SPECIES:
retVal = boxMon->isBadEgg ? SPECIES_EGG : substruct0->species;
break;
case MON_DATA_HELD_ITEM:
retVal = substruct0->heldItem;
break;
case MON_DATA_EXP:
retVal = substruct0->experience;
break;
case MON_DATA_PP_BONUSES:
retVal = substruct0->ppBonuses;
break;
case MON_DATA_FRIENDSHIP:
retVal = substruct0->friendship;
break;
case MON_DATA_MOVE1:
case MON_DATA_MOVE2:
case MON_DATA_MOVE3:
case MON_DATA_MOVE4:
retVal = substruct1->moves[field - MON_DATA_MOVE1];
break;
case MON_DATA_PP1:
case MON_DATA_PP2:
case MON_DATA_PP3:
case MON_DATA_PP4:
retVal = substruct1->pp[field - MON_DATA_PP1];
break;
case MON_DATA_HP_EV:
retVal = substruct2->hpEV;
break;
case MON_DATA_ATK_EV:
retVal = substruct2->attackEV;
break;
case MON_DATA_DEF_EV:
retVal = substruct2->defenseEV;
break;
case MON_DATA_SPEED_EV:
retVal = substruct2->speedEV;
break;
case MON_DATA_SPATK_EV:
retVal = substruct2->spAttackEV;
break;
case MON_DATA_SPDEF_EV:
retVal = substruct2->spDefenseEV;
break;
case MON_DATA_COOL:
retVal = substruct2->cool;
break;
case MON_DATA_BEAUTY:
retVal = substruct2->beauty;
break;
case MON_DATA_CUTE:
retVal = substruct2->cute;
break;
case MON_DATA_SMART:
retVal = substruct2->smart;
break;
case MON_DATA_TOUGH:
retVal = substruct2->tough;
break;
case MON_DATA_SHEEN:
retVal = substruct2->sheen;
break;
case MON_DATA_POKERUS:
retVal = substruct3->pokerus;
break;
case MON_DATA_MET_LOCATION:
retVal = substruct3->metLocation;
break;
case MON_DATA_MET_LEVEL:
retVal = substruct3->metLevel;
break;
case MON_DATA_MET_GAME:
retVal = substruct3->metGame;
break;
case MON_DATA_POKEBALL:
retVal = substruct3->pokeball;
break;
case MON_DATA_OT_GENDER:
retVal = substruct3->otGender;
break;
case MON_DATA_HP_IV:
retVal = substruct3->hpIV;
break;
case MON_DATA_ATK_IV:
retVal = substruct3->attackIV;
break;
case MON_DATA_DEF_IV:
retVal = substruct3->defenseIV;
break;
case MON_DATA_SPEED_IV:
retVal = substruct3->speedIV;
break;
case MON_DATA_SPATK_IV:
retVal = substruct3->spAttackIV;
break;
case MON_DATA_SPDEF_IV:
retVal = substruct3->spDefenseIV;
break;
case MON_DATA_IS_EGG:
retVal = substruct3->isEgg;
break;
case MON_DATA_ABILITY_NUM:
retVal = substruct3->abilityNum;
break;
case MON_DATA_COOL_RIBBON:
retVal = substruct3->coolRibbon;
break;
case MON_DATA_BEAUTY_RIBBON:
retVal = substruct3->beautyRibbon;
break;
case MON_DATA_CUTE_RIBBON:
retVal = substruct3->cuteRibbon;
break;
case MON_DATA_SMART_RIBBON:
retVal = substruct3->smartRibbon;
break;
case MON_DATA_TOUGH_RIBBON:
retVal = substruct3->toughRibbon;
break;
case MON_DATA_CHAMPION_RIBBON:
retVal = substruct3->championRibbon;
break;
case MON_DATA_WINNING_RIBBON:
retVal = substruct3->winningRibbon;
break;
case MON_DATA_VICTORY_RIBBON:
retVal = substruct3->victoryRibbon;
break;
case MON_DATA_ARTIST_RIBBON:
retVal = substruct3->artistRibbon;
break;
case MON_DATA_EFFORT_RIBBON:
retVal = substruct3->effortRibbon;
break;
case MON_DATA_GIFT_RIBBON_1:
retVal = substruct3->giftRibbon1;
break;
case MON_DATA_GIFT_RIBBON_2:
retVal = substruct3->giftRibbon2;
break;
case MON_DATA_GIFT_RIBBON_3:
retVal = substruct3->giftRibbon3;
break;
case MON_DATA_GIFT_RIBBON_4:
retVal = substruct3->giftRibbon4;
break;
case MON_DATA_GIFT_RIBBON_5:
retVal = substruct3->giftRibbon5;
break;
case MON_DATA_GIFT_RIBBON_6:
retVal = substruct3->giftRibbon6;
break;
case MON_DATA_GIFT_RIBBON_7:
retVal = substruct3->giftRibbon7;
break;
case MON_DATA_FATEFUL_ENCOUNTER:
retVal = substruct3->fatefulEncounter;
break;
case MON_DATA_OBEDIENCE:
retVal = substruct3->obedient;
break;
case MON_DATA_SPECIES2:
retVal = substruct0->species;
if (substruct0->species && (substruct3->isEgg || boxMon->isBadEgg))
retVal = SPECIES_EGG;
break;
case MON_DATA_IVS:
retVal = substruct3->hpIV | (substruct3->attackIV << 5) | (substruct3->defenseIV << 10) | (substruct3->speedIV << 15) | (substruct3->spAttackIV << 20) | (substruct3->spDefenseIV << 25);
break;
case MON_DATA_KNOWN_MOVES:
if (substruct0->species && !substruct3->isEgg)
{
u16 *moves = (u16 *)data;
s32 i = 0;
while (moves[i] != 355)
{
u16 move = moves[i];
if (substruct1->moves[0] == move
|| substruct1->moves[1] == move
|| substruct1->moves[2] == move
|| substruct1->moves[3] == move)
retVal |= gBitTable[i];
i++;
}
}
break;
case MON_DATA_RIBBON_COUNT:
retVal = 0;
if (substruct0->species && !substruct3->isEgg)
{
retVal += substruct3->coolRibbon;
retVal += substruct3->beautyRibbon;
retVal += substruct3->cuteRibbon;
retVal += substruct3->smartRibbon;
retVal += substruct3->toughRibbon;
retVal += substruct3->championRibbon;
retVal += substruct3->winningRibbon;
retVal += substruct3->victoryRibbon;
retVal += substruct3->artistRibbon;
retVal += substruct3->effortRibbon;
retVal += substruct3->giftRibbon1;
retVal += substruct3->giftRibbon2;
retVal += substruct3->giftRibbon3;
retVal += substruct3->giftRibbon4;
retVal += substruct3->giftRibbon5;
retVal += substruct3->giftRibbon6;
retVal += substruct3->giftRibbon7;
}
break;
case MON_DATA_RIBBONS:
retVal = 0;
if (substruct0->species && !substruct3->isEgg)
{
retVal = substruct3->championRibbon
| (substruct3->coolRibbon << 1)
| (substruct3->beautyRibbon << 4)
| (substruct3->cuteRibbon << 7)
| (substruct3->smartRibbon << 10)
| (substruct3->toughRibbon << 13)
| (substruct3->winningRibbon << 16)
| (substruct3->victoryRibbon << 17)
| (substruct3->artistRibbon << 18)
| (substruct3->effortRibbon << 19)
| (substruct3->giftRibbon1 << 20)
| (substruct3->giftRibbon2 << 21)
| (substruct3->giftRibbon3 << 22)
| (substruct3->giftRibbon4 << 23)
| (substruct3->giftRibbon5 << 24)
| (substruct3->giftRibbon6 << 25)
| (substruct3->giftRibbon7 << 26);
}
break;
default:
break;
}
if (field > MON_DATA_10)
EncryptBoxMon(boxMon);
return retVal;
}
#define SET8(lhs) (lhs) = *data
#define SET16(lhs) (lhs) = data[0] + (data[1] << 8)
#define SET32(lhs) (lhs) = data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24)
void SetMonData(struct Pokemon *mon, s32 field, const void *dataArg)
{
const u8 *data = dataArg;
switch (field)
{
case MON_DATA_STATUS:
SET32(mon->status);
break;
case MON_DATA_LEVEL:
SET8(mon->level);
break;
case MON_DATA_HP:
SET16(mon->hp);
break;
case MON_DATA_MAX_HP:
SET16(mon->maxHP);
break;
case MON_DATA_ATK:
case MON_DATA_ATK2:
SET16(mon->attack);
break;
case MON_DATA_DEF:
case MON_DATA_DEF2:
SET16(mon->defense);
break;
case MON_DATA_SPEED:
case MON_DATA_SPEED2:
SET16(mon->speed);
break;
case MON_DATA_SPATK:
case MON_DATA_SPATK2:
SET16(mon->spAttack);
break;
case MON_DATA_SPDEF:
case MON_DATA_SPDEF2:
SET16(mon->spDefense);
break;
case MON_DATA_MAIL:
SET8(mon->mail);
break;
case MON_DATA_SPECIES2:
break;
// why did FRLG go out of its way to specify all of these for default?
case MON_DATA_IVS:
case MON_DATA_CHAMPION_RIBBON:
case MON_DATA_WINNING_RIBBON:
case MON_DATA_VICTORY_RIBBON:
case MON_DATA_ARTIST_RIBBON:
case MON_DATA_EFFORT_RIBBON:
case MON_DATA_GIFT_RIBBON_1:
case MON_DATA_GIFT_RIBBON_2:
case MON_DATA_GIFT_RIBBON_3:
case MON_DATA_GIFT_RIBBON_4:
case MON_DATA_GIFT_RIBBON_5:
case MON_DATA_GIFT_RIBBON_6:
case MON_DATA_GIFT_RIBBON_7:
case MON_DATA_FATEFUL_ENCOUNTER:
case MON_DATA_OBEDIENCE:
case MON_DATA_KNOWN_MOVES:
case MON_DATA_RIBBON_COUNT:
case MON_DATA_RIBBONS:
default:
SetBoxMonData(&mon->box, field, data);
break;
}
}
void SetBoxMonData(struct BoxPokemon *boxMon, s32 field, const void *dataArg)
{
const u8 *data = dataArg;
struct PokemonSubstruct0 *substruct0 = NULL;
struct PokemonSubstruct1 *substruct1 = NULL;
struct PokemonSubstruct2 *substruct2 = NULL;
struct PokemonSubstruct3 *substruct3 = NULL;
if (field > MON_DATA_10)
{
substruct0 = &(GetSubstruct(boxMon, boxMon->personality, 0)->type0);
substruct1 = &(GetSubstruct(boxMon, boxMon->personality, 1)->type1);
substruct2 = &(GetSubstruct(boxMon, boxMon->personality, 2)->type2);
substruct3 = &(GetSubstruct(boxMon, boxMon->personality, 3)->type3);
DecryptBoxMon(boxMon);
if (CalculateBoxMonChecksum(boxMon) != boxMon->checksum)
{
boxMon->isBadEgg = 1;
boxMon->isEgg = 1;
substruct3->isEgg = 1;
EncryptBoxMon(boxMon);
return;
}
}
switch (field)
{
case MON_DATA_PERSONALITY:
SET32(boxMon->personality);
break;
case MON_DATA_OT_ID:
SET32(boxMon->otId);
break;
case MON_DATA_NICKNAME:
{
s32 i;
for (i = 0; i < POKEMON_NAME_LENGTH; i++)
boxMon->nickname[i] = data[i];
break;
}
case MON_DATA_LANGUAGE:
SET8(boxMon->language);
break;
case MON_DATA_SANITY_IS_BAD_EGG:
SET8(boxMon->isBadEgg);
break;
case MON_DATA_SANITY_HAS_SPECIES:
SET8(boxMon->hasSpecies);
break;
case MON_DATA_SANITY_IS_EGG:
SET8(boxMon->isEgg);
break;
case MON_DATA_OT_NAME:
{
s32 i;
for (i = 0; i < 7; i++)
boxMon->otName[i] = data[i];
break;
}
case MON_DATA_MARKINGS:
SET8(boxMon->markings);
break;
case MON_DATA_CHECKSUM:
SET16(boxMon->checksum);
break;
case MON_DATA_10:
SET16(boxMon->unknown);
break;
case MON_DATA_SPECIES:
{
SET16(substruct0->species);
if (substruct0->species)
boxMon->hasSpecies = 1;
else
boxMon->hasSpecies = 0;
break;
}
case MON_DATA_HELD_ITEM:
SET16(substruct0->heldItem);
break;
case MON_DATA_EXP:
SET32(substruct0->experience);
break;
case MON_DATA_PP_BONUSES:
SET8(substruct0->ppBonuses);
break;
case MON_DATA_FRIENDSHIP:
SET8(substruct0->friendship);
break;
case MON_DATA_MOVE1:
case MON_DATA_MOVE2:
case MON_DATA_MOVE3:
case MON_DATA_MOVE4:
SET16(substruct1->moves[field - MON_DATA_MOVE1]);
break;
case MON_DATA_PP1:
case MON_DATA_PP2:
case MON_DATA_PP3:
case MON_DATA_PP4:
SET8(substruct1->pp[field - MON_DATA_PP1]);
break;
case MON_DATA_HP_EV:
SET8(substruct2->hpEV);
break;
case MON_DATA_ATK_EV:
SET8(substruct2->attackEV);
break;
case MON_DATA_DEF_EV:
SET8(substruct2->defenseEV);
break;
case MON_DATA_SPEED_EV:
SET8(substruct2->speedEV);
break;
case MON_DATA_SPATK_EV:
SET8(substruct2->spAttackEV);
break;
case MON_DATA_SPDEF_EV:
SET8(substruct2->spDefenseEV);
break;
case MON_DATA_COOL:
SET8(substruct2->cool);
break;
case MON_DATA_BEAUTY:
SET8(substruct2->beauty);
break;
case MON_DATA_CUTE:
SET8(substruct2->cute);
break;
case MON_DATA_SMART:
SET8(substruct2->smart);
break;
case MON_DATA_TOUGH:
SET8(substruct2->tough);
break;
case MON_DATA_SHEEN:
SET8(substruct2->sheen);
break;
case MON_DATA_POKERUS:
SET8(substruct3->pokerus);
break;
case MON_DATA_MET_LOCATION:
SET8(substruct3->metLocation);
break;
case MON_DATA_MET_LEVEL:
{
u8 metLevel = *data;
substruct3->metLevel = metLevel;
break;
}
case MON_DATA_MET_GAME:
SET8(substruct3->metGame);
break;
case MON_DATA_POKEBALL:
{
u8 pokeball = *data;
substruct3->pokeball = pokeball;
break;
}
case MON_DATA_OT_GENDER:
SET8(substruct3->otGender);
break;
case MON_DATA_HP_IV:
SET8(substruct3->hpIV);
break;
case MON_DATA_ATK_IV:
SET8(substruct3->attackIV);
break;
case MON_DATA_DEF_IV:
SET8(substruct3->defenseIV);
break;
case MON_DATA_SPEED_IV:
SET8(substruct3->speedIV);
break;
case MON_DATA_SPATK_IV:
SET8(substruct3->spAttackIV);
break;
case MON_DATA_SPDEF_IV:
SET8(substruct3->spDefenseIV);
break;
case MON_DATA_IS_EGG:
SET8(substruct3->isEgg);
if (substruct3->isEgg)
boxMon->isEgg = 1;
else
boxMon->isEgg = 0;
break;
case MON_DATA_ABILITY_NUM:
SET8(substruct3->abilityNum);
break;
case MON_DATA_COOL_RIBBON:
SET8(substruct3->coolRibbon);
break;
case MON_DATA_BEAUTY_RIBBON:
SET8(substruct3->beautyRibbon);
break;
case MON_DATA_CUTE_RIBBON:
SET8(substruct3->cuteRibbon);
break;
case MON_DATA_SMART_RIBBON:
SET8(substruct3->smartRibbon);
break;
case MON_DATA_TOUGH_RIBBON:
SET8(substruct3->toughRibbon);
break;
case MON_DATA_CHAMPION_RIBBON:
SET8(substruct3->championRibbon);
break;
case MON_DATA_WINNING_RIBBON:
SET8(substruct3->winningRibbon);
break;
case MON_DATA_VICTORY_RIBBON:
SET8(substruct3->victoryRibbon);
break;
case MON_DATA_ARTIST_RIBBON:
SET8(substruct3->artistRibbon);
break;
case MON_DATA_EFFORT_RIBBON:
SET8(substruct3->effortRibbon);
break;
case MON_DATA_GIFT_RIBBON_1:
SET8(substruct3->giftRibbon1);
break;
case MON_DATA_GIFT_RIBBON_2:
SET8(substruct3->giftRibbon2);
break;
case MON_DATA_GIFT_RIBBON_3:
SET8(substruct3->giftRibbon3);
break;
case MON_DATA_GIFT_RIBBON_4:
SET8(substruct3->giftRibbon4);
break;
case MON_DATA_GIFT_RIBBON_5:
SET8(substruct3->giftRibbon5);
break;
case MON_DATA_GIFT_RIBBON_6:
SET8(substruct3->giftRibbon6);
break;
case MON_DATA_GIFT_RIBBON_7:
SET8(substruct3->giftRibbon7);
break;
case MON_DATA_FATEFUL_ENCOUNTER:
SET8(substruct3->fatefulEncounter);
break;
case MON_DATA_OBEDIENCE:
SET8(substruct3->obedient);
break;
case MON_DATA_IVS:
{
#ifdef BUGFIX_SETMONIVS
u32 ivs = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
#else
u32 ivs = *data; // Bug: Only the HP IV and the lower 3 bits of the Attack IV are read. The rest become 0.
#endif
substruct3->hpIV = ivs & 0x1F;
substruct3->attackIV = (ivs >> 5) & 0x1F;
substruct3->defenseIV = (ivs >> 10) & 0x1F;
substruct3->speedIV = (ivs >> 15) & 0x1F;
substruct3->spAttackIV = (ivs >> 20) & 0x1F;
substruct3->spDefenseIV = (ivs >> 25) & 0x1F;
break;
}
default:
break;
}
if (field > MON_DATA_10)
{
boxMon->checksum = CalculateBoxMonChecksum(boxMon);
EncryptBoxMon(boxMon);
}
}
void CopyMon(void *dest, void *src, size_t size)
{
memcpy(dest, src, size);
}
u8 GiveMonToPlayer(struct Pokemon *mon)
{
s32 i;
SetMonData(mon, MON_DATA_OT_NAME, gSaveBlock2Ptr->playerName);
SetMonData(mon, MON_DATA_OT_GENDER, &gSaveBlock2Ptr->playerGender);
SetMonData(mon, MON_DATA_OT_ID, gSaveBlock2Ptr->playerTrainerId);
for (i = 0; i < PARTY_SIZE; i++)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) == SPECIES_NONE)
break;
}
if (i >= PARTY_SIZE)
return SendMonToPC(mon);
CopyMon(&gPlayerParty[i], mon, sizeof(*mon));
gPlayerPartyCount = i + 1;
return MON_GIVEN_TO_PARTY;
}
static u8 SendMonToPC(struct Pokemon* mon)
{
s32 boxNo, boxPos;
set_unknown_box_id(VarGet(VAR_0x4037));
boxNo = StorageGetCurrentBox();
do
{
for (boxPos = 0; boxPos < 30; boxPos++)
{
struct BoxPokemon* checkingMon = GetBoxedMonPtr(boxNo, boxPos);
if (GetBoxMonData(checkingMon, MON_DATA_SPECIES, NULL) == SPECIES_NONE)
{
MonRestorePP(mon);
CopyMon(checkingMon, &mon->box, sizeof(mon->box));
gSpecialVar_MonBoxId = boxNo;
gSpecialVar_MonBoxPos = boxPos;
if (get_unknown_box_id() != boxNo)
FlagClear(FLAG_SYS_CHANGED_BOX_TO_STORE_MON);
VarSet(VAR_0x4037, boxNo);
return MON_GIVEN_TO_PC;
}
}
boxNo++;
if (boxNo == 14)
boxNo = 0;
} while (boxNo != StorageGetCurrentBox());
return MON_CANT_GIVE;
}
u8 CalculatePlayerPartyCount(void)
{
gPlayerPartyCount = 0;
while (gPlayerPartyCount < 6
&& GetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_SPECIES, NULL) != SPECIES_NONE)
{
gPlayerPartyCount++;
}
return gPlayerPartyCount;
}
u8 CalculateEnemyPartyCount(void)
{
gEnemyPartyCount = 0;
while (gEnemyPartyCount < 6
&& GetMonData(&gEnemyParty[gEnemyPartyCount], MON_DATA_SPECIES, NULL) != SPECIES_NONE)
{
gEnemyPartyCount++;
}
return gEnemyPartyCount;
}
u8 GetMonsStateToDoubles(void)
{
s32 aliveCount = 0;
s32 i;
CalculatePlayerPartyCount();
if (gPlayerPartyCount == 1)
return gPlayerPartyCount; // PLAYER_HAS_ONE_MON
for (i = 0; i < gPlayerPartyCount; i++)
{
// FRLG changed the order of these checks, but there's no point to doing that
// because of the requirement of all 3 of these checks.
if (GetMonData(&gPlayerParty[i], MON_DATA_HP, NULL) != 0
&& GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_NONE
&& GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_EGG)
aliveCount++;
}
return (aliveCount > 1) ? PLAYER_HAS_TWO_USABLE_MONS : PLAYER_HAS_ONE_USABLE_MON;
}
u8 GetAbilityBySpecies(u16 species, bool8 abilityNum)
{
if (abilityNum)
gLastUsedAbility = gBaseStats[species].abilities[1];
else
gLastUsedAbility = gBaseStats[species].abilities[0];
return gLastUsedAbility;
}
u8 GetMonAbility(struct Pokemon *mon)
{
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
u8 abilityNum = GetMonData(mon, MON_DATA_ABILITY_NUM, NULL);
return GetAbilityBySpecies(species, abilityNum);
}
static void CreateSecretBaseEnemyParty(struct SecretBaseRecord *secretBaseRecord)
{
s32 i, j;
ZeroEnemyPartyMons();
*gBattleResources->secretBase = *secretBaseRecord;
for (i = 0; i < PARTY_SIZE; i++)
{
if (gBattleResources->secretBase->party.species[i])
{
CreateMon(&gEnemyParty[i],
gBattleResources->secretBase->party.species[i],
gBattleResources->secretBase->party.levels[i],
15,
1,
gBattleResources->secretBase->party.personality[i],
2,
0);
SetMonData(&gEnemyParty[i], MON_DATA_HELD_ITEM, &gBattleResources->secretBase->party.heldItems[i]);
for (j = 0; j < 6; j++)
SetMonData(&gEnemyParty[i], MON_DATA_HP_EV + j, &gBattleResources->secretBase->party.EVs[i]);
for (j = 0; j < 4; j++)
{
SetMonData(&gEnemyParty[i], MON_DATA_MOVE1 + j, &gBattleResources->secretBase->party.moves[i * 4 + j]);
SetMonData(&gEnemyParty[i], MON_DATA_PP1 + j, &gBattleMoves[gBattleResources->secretBase->party.moves[i * 4 + j]].pp);
}
}
}
gBattleTypeFlags = 8;
gTrainerBattleOpponent_A = 0x400;
}
u8 GetSecretBaseTrainerPicIndex(void)
{
u8 facilityClass = sSecretBaseFacilityClasses[gBattleResources->secretBase->gender][gBattleResources->secretBase->trainerId[0] % 5];
return gFacilityClassToPicIndex[facilityClass];
}
u8 GetSecretBaseTrainerNameIndex(void)
{
u8 facilityClass = sSecretBaseFacilityClasses[gBattleResources->secretBase->gender][gBattleResources->secretBase->trainerId[0] % 5];
return gFacilityClassToTrainerClass[facilityClass];
}
bool8 IsPlayerPartyAndPokemonStorageFull(void)
{
s32 i;
for (i = 0; i < PARTY_SIZE; i++)
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) == SPECIES_NONE)
return FALSE;
return IsPokemonStorageFull();
}
static bool8 IsPokemonStorageFull(void)
{
s32 i, j;
for (i = 0; i < 14; i++)
for (j = 0; j < 30; j++)
if (GetBoxMonDataFromAnyBox(i, j, MON_DATA_SPECIES) == SPECIES_NONE)
return FALSE;
return TRUE;
}
void GetSpeciesName(u8 *name, u16 species)
{
s32 i;
// Hmm? FRLG has < while Ruby/Emerald has <=
for (i = 0; i < POKEMON_NAME_LENGTH; i++)
{
if (species > NUM_SPECIES)
name[i] = gSpeciesNames[0][i];
else
name[i] = gSpeciesNames[species][i];
if (name[i] == EOS)
break;
}
name[i] = EOS;
}
u8 CalculatePPWithBonus(u16 move, u8 ppBonuses, u8 moveIndex)
{
u8 basePP = gBattleMoves[move].pp;
return basePP + ((basePP * 20 * ((gPPUpGetMask[moveIndex] & ppBonuses) >> (2 * moveIndex))) / 100);
}
void RemoveMonPPBonus(struct Pokemon *mon, u8 moveIndex)
{
u8 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
ppBonuses &= gPPUpSetMask[moveIndex];
SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses);
}
void RemoveBattleMonPPBonus(struct BattlePokemon *mon, u8 moveIndex)
{
mon->ppBonuses &= gPPUpSetMask[moveIndex];
}
static void CopyPlayerPartyMonToBattleData(u8 battlerId, u8 partyIndex)
{
u16* hpSwitchout;
s32 i;
u8 nickname[POKEMON_NAME_LENGTH * 2]; // Why is the nickname array here longer in FR/LG?
gBattleMons[battlerId].species = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPECIES, NULL);
gBattleMons[battlerId].item = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HELD_ITEM, NULL);
for (i = 0; i < 4; i++)
{
gBattleMons[battlerId].moves[i] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MOVE1 + i, NULL);
gBattleMons[battlerId].pp[i] = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PP1 + i, NULL);
}
gBattleMons[battlerId].ppBonuses = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PP_BONUSES, NULL);
gBattleMons[battlerId].friendship = GetMonData(&gPlayerParty[partyIndex], MON_DATA_FRIENDSHIP, NULL);
gBattleMons[battlerId].experience = GetMonData(&gPlayerParty[partyIndex], MON_DATA_EXP, NULL);
gBattleMons[battlerId].hpIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP_IV, NULL);
gBattleMons[battlerId].attackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK_IV, NULL);
gBattleMons[battlerId].defenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF_IV, NULL);
gBattleMons[battlerId].speedIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED_IV, NULL);
gBattleMons[battlerId].spAttackIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK_IV, NULL);
gBattleMons[battlerId].spDefenseIV = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF_IV, NULL);
gBattleMons[battlerId].personality = GetMonData(&gPlayerParty[partyIndex], MON_DATA_PERSONALITY, NULL);
gBattleMons[battlerId].status1 = GetMonData(&gPlayerParty[partyIndex], MON_DATA_STATUS, NULL);
gBattleMons[battlerId].level = GetMonData(&gPlayerParty[partyIndex], MON_DATA_LEVEL, NULL);
gBattleMons[battlerId].hp = GetMonData(&gPlayerParty[partyIndex], MON_DATA_HP, NULL);
gBattleMons[battlerId].maxHP = GetMonData(&gPlayerParty[partyIndex], MON_DATA_MAX_HP, NULL);
gBattleMons[battlerId].attack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ATK, NULL);
gBattleMons[battlerId].defense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_DEF, NULL);
gBattleMons[battlerId].speed = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPEED, NULL);
gBattleMons[battlerId].spAttack = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPATK, NULL);
gBattleMons[battlerId].spDefense = GetMonData(&gPlayerParty[partyIndex], MON_DATA_SPDEF, NULL);
gBattleMons[battlerId].isEgg = GetMonData(&gPlayerParty[partyIndex], MON_DATA_IS_EGG, NULL);
gBattleMons[battlerId].abilityNum = GetMonData(&gPlayerParty[partyIndex], MON_DATA_ABILITY_NUM, NULL);
gBattleMons[battlerId].otId = GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_ID, NULL);
gBattleMons[battlerId].type1 = gBaseStats[gBattleMons[battlerId].species].type1;
gBattleMons[battlerId].type2 = gBaseStats[gBattleMons[battlerId].species].type2;
gBattleMons[battlerId].ability = GetAbilityBySpecies(gBattleMons[battlerId].species, gBattleMons[battlerId].abilityNum);
GetMonData(&gPlayerParty[partyIndex], MON_DATA_NICKNAME, nickname);
StringCopy10(gBattleMons[battlerId].nickname, nickname);
GetMonData(&gPlayerParty[partyIndex], MON_DATA_OT_NAME, gBattleMons[battlerId].otName);
hpSwitchout = &gBattleStruct->hpOnSwitchout[GetBattlerSide(battlerId)];
*hpSwitchout = gBattleMons[battlerId].hp;
for (i = 0; i < 8; i++)
gBattleMons[battlerId].statStages[i] = 6;
gBattleMons[battlerId].status2 = 0;
sub_80174B8(battlerId);
ClearTemporarySpeciesSpriteData(battlerId, FALSE);
}
bool8 ExecuteTableBasedItemEffect(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex)
{
return PokemonUseItemEffects(mon, item, partyIndex, moveIndex, 0);
}
bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex, u8 e)
{
u32 data;
s32 friendship;
s32 cmdIndex;
bool8 retVal = TRUE;
const u8 *itemEffect;
u8 sp24 = 6;
u32 sp28;
s8 sp2C = 0;
u8 holdEffect;
u8 sp34 = 4;
u16 heldItem;
u8 r10;
u32 r4;
heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, NULL);
if (heldItem == ITEM_ENIGMA_BERRY)
{
if (gMain.inBattle)
holdEffect = gEnigmaBerries[gBattlerInMenuId].holdEffect;
else
holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
}
else
{
holdEffect = ItemId_GetHoldEffect(heldItem);
}
gPotentialItemEffectBattler = gBattlerInMenuId;
if (gMain.inBattle)
{
gActiveBattler = gBattlerInMenuId;
cmdIndex = (GetBattlerSide(gActiveBattler) != 0);
while (cmdIndex < gBattlersCount)
{
if (gBattlerPartyIndexes[cmdIndex] == partyIndex)
{
sp34 = cmdIndex;
break;
}
cmdIndex += 2;
}
}
else
{
gActiveBattler = 0;
sp34 = 4;
}
if (!IS_POKEMON_ITEM(item))
return TRUE;
if (gItemEffectTable[item - 13] == NULL && item != ITEM_ENIGMA_BERRY)
return TRUE;
if (item == ITEM_ENIGMA_BERRY)
{
if (gMain.inBattle)
itemEffect = gEnigmaBerries[gActiveBattler].itemEffect;
else
itemEffect = gSaveBlock1Ptr->enigmaBerry.itemEffect;
}
else
{
itemEffect = gItemEffectTable[item - 13];
}
for (cmdIndex = 0; cmdIndex < 6; cmdIndex++)
{
switch (cmdIndex)
{
// status healing effects
case 0:
if ((itemEffect[cmdIndex] & 0x80)
&& gMain.inBattle && sp34 != 4 && (gBattleMons[sp34].status2 & STATUS2_INFATUATION))
{
gBattleMons[sp34].status2 &= ~STATUS2_INFATUATION;
retVal = FALSE;
}
if ((itemEffect[cmdIndex] & 0x30)
&& !(gBattleMons[gActiveBattler].status2 & STATUS2_FOCUS_ENERGY))
{
gBattleMons[gActiveBattler].status2 |= STATUS2_FOCUS_ENERGY;
retVal = FALSE;
}
if ((itemEffect[cmdIndex] & 0xF)
&& gBattleMons[gActiveBattler].statStages[STAT_STAGE_ATK] < 12)
{
gBattleMons[gActiveBattler].statStages[STAT_STAGE_ATK] += itemEffect[cmdIndex] & 0xF;
if (gBattleMons[gActiveBattler].statStages[STAT_STAGE_ATK] > 12)
gBattleMons[gActiveBattler].statStages[STAT_STAGE_ATK] = 12;
retVal = FALSE;
}
break;
// in-battle stat boosting effects?
case 1:
if ((itemEffect[cmdIndex] & 0xF0)
&& gBattleMons[gActiveBattler].statStages[STAT_STAGE_DEF] < 12)
{
gBattleMons[gActiveBattler].statStages[STAT_STAGE_DEF] += (itemEffect[cmdIndex] & 0xF0) >> 4;
if (gBattleMons[gActiveBattler].statStages[STAT_STAGE_DEF] > 12)
gBattleMons[gActiveBattler].statStages[STAT_STAGE_DEF] = 12;
retVal = FALSE;
}
if ((itemEffect[cmdIndex] & 0xF)
&& gBattleMons[gActiveBattler].statStages[STAT_STAGE_SPEED] < 12)
{
gBattleMons[gActiveBattler].statStages[STAT_STAGE_SPEED] += itemEffect[cmdIndex] & 0xF;
if (gBattleMons[gActiveBattler].statStages[STAT_STAGE_SPEED] > 12)
gBattleMons[gActiveBattler].statStages[STAT_STAGE_SPEED] = 12;
retVal = FALSE;
}
break;
// more stat boosting effects?
case 2:
if ((itemEffect[cmdIndex] & 0xF0)
&& gBattleMons[gActiveBattler].statStages[STAT_STAGE_ACC] < 12)
{
gBattleMons[gActiveBattler].statStages[STAT_STAGE_ACC] += (itemEffect[cmdIndex] & 0xF0) >> 4;
if (gBattleMons[gActiveBattler].statStages[STAT_STAGE_ACC] > 12)
gBattleMons[gActiveBattler].statStages[STAT_STAGE_ACC] = 12;
retVal = FALSE;
}
if ((itemEffect[cmdIndex] & 0xF)
&& gBattleMons[gActiveBattler].statStages[STAT_STAGE_SPATK] < 12)
{
gBattleMons[gActiveBattler].statStages[STAT_STAGE_SPATK] += itemEffect[cmdIndex] & 0xF;
if (gBattleMons[gActiveBattler].statStages[STAT_STAGE_SPATK] > 12)
gBattleMons[gActiveBattler].statStages[STAT_STAGE_SPATK] = 12;
retVal = FALSE;
}
break;
case 3:
if ((itemEffect[cmdIndex] & 0x80)
&& gSideTimers[GetBattlerSide(gActiveBattler)].mistTimer == 0)
{
gSideTimers[GetBattlerSide(gActiveBattler)].mistTimer = 5;
retVal = FALSE;
}
if ((itemEffect[cmdIndex] & 0x40) // raise level
&& GetMonData(mon, MON_DATA_LEVEL, NULL) != 100)
{
data = gExperienceTables[gBaseStats[GetMonData(mon, MON_DATA_SPECIES, NULL)].growthRate][GetMonData(mon, MON_DATA_LEVEL, NULL) + 1];
SetMonData(mon, MON_DATA_EXP, &data);
CalculateMonStats(mon);
retVal = FALSE;
}
if ((itemEffect[cmdIndex] & 0x20)
&& HealStatusConditions(mon, partyIndex, 7, sp34) == 0)
{
if (sp34 != 4)
gBattleMons[sp34].status2 &= ~STATUS2_NIGHTMARE;
retVal = FALSE;
}
if ((itemEffect[cmdIndex] & 0x10) && HealStatusConditions(mon, partyIndex, 0xF88, sp34) == 0)
retVal = FALSE;
if ((itemEffect[cmdIndex] & 8) && HealStatusConditions(mon, partyIndex, 16, sp34) == 0)
retVal = FALSE;
if ((itemEffect[cmdIndex] & 4) && HealStatusConditions(mon, partyIndex, 32, sp34) == 0)
retVal = FALSE;
if ((itemEffect[cmdIndex] & 2) && HealStatusConditions(mon, partyIndex, 64, sp34) == 0)
retVal = FALSE;
if ((itemEffect[cmdIndex] & 1) // heal confusion
&& gMain.inBattle && sp34 != 4 && (gBattleMons[sp34].status2 & STATUS2_CONFUSION))
{
gBattleMons[sp34].status2 &= ~STATUS2_CONFUSION;
retVal = FALSE;
}
break;
// EV, HP, and PP raising effects
case 4:
r10 = itemEffect[cmdIndex];
if (r10 & 0x20)
{
r10 &= ~0x20;
data = (GetMonData(mon, MON_DATA_PP_BONUSES, NULL) & gPPUpGetMask[moveIndex]) >> (moveIndex * 2);
sp28 = CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL), GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex);
if (data < 3 && sp28 > 4)
{
data = GetMonData(mon, MON_DATA_PP_BONUSES, NULL) + gPPUpAddMask[moveIndex];
SetMonData(mon, MON_DATA_PP_BONUSES, &data);
data = CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL), data, moveIndex) - sp28;
data = GetMonData(mon, MON_DATA_PP1 + moveIndex, NULL) + data;
SetMonData(mon, MON_DATA_PP1 + moveIndex, &data);
retVal = FALSE;
}
}
sp28 = 0;
while (r10 != 0)
{
if (r10 & 1)
{
u16 evCount;
s32 r5;
switch (sp28)
{
case 0:
case 1:
evCount = GetMonEVCount(mon);
if (evCount >= 510)
return TRUE;
data = GetMonData(mon, sGetMonDataEVConstants[sp28], NULL);
if (data < 100)
{
if (data + itemEffect[sp24] > 100)
r4 = 100 - (data + itemEffect[sp24]) + itemEffect[sp24];
else
r4 = itemEffect[sp24];
if (evCount + r4 > 510)
r4 += 510 - (evCount + r4);
data += r4;
SetMonData(mon, sGetMonDataEVConstants[sp28], &data);
CalculateMonStats(mon);
sp24++;
retVal = FALSE;
}
break;
case 2:
// revive?
if (r10 & 0x10)
{
if (GetMonData(mon, MON_DATA_HP, NULL) != 0)
{
sp24++;
break;
}
if (gMain.inBattle)
{
if (sp34 != 4)
{
gAbsentBattlerFlags &= ~gBitTable[sp34];
CopyPlayerPartyMonToBattleData(sp34, pokemon_order_func(gBattlerPartyIndexes[sp34]));
if (GetBattlerSide(gActiveBattler) == 0 && gBattleResults.numRevivesUsed < 255)
gBattleResults.numRevivesUsed++;
}
else
{
gAbsentBattlerFlags &= ~gBitTable[gActiveBattler ^ 2];
if (GetBattlerSide(gActiveBattler) == 0 && gBattleResults.numRevivesUsed < 255)
gBattleResults.numRevivesUsed++;
}
}
}
else
{
if (GetMonData(mon, MON_DATA_HP, NULL) == 0)
{
sp24++;
break;
}
}
data = itemEffect[sp24++];
switch (data)
{
case 0xFF:
data = GetMonData(mon, MON_DATA_MAX_HP, NULL) - GetMonData(mon, MON_DATA_HP, NULL);
break;
case 0xFE:
data = GetMonData(mon, MON_DATA_MAX_HP, NULL) / 2;
if (data == 0)
data = 1;
break;
case 0xFD:
data = gBattleScripting.field_23;
break;
}
if (GetMonData(mon, MON_DATA_MAX_HP, NULL) != GetMonData(mon, MON_DATA_HP, NULL))
{
if (e == 0)
{
data = GetMonData(mon, MON_DATA_HP, NULL) + data;
if (data > GetMonData(mon, MON_DATA_MAX_HP, NULL))
data = GetMonData(mon, MON_DATA_MAX_HP, NULL);
SetMonData(mon, MON_DATA_HP, &data);
if (gMain.inBattle && sp34 != 4)
{
gBattleMons[sp34].hp = data;
if (!(r10 & 0x10) && GetBattlerSide(gActiveBattler) == 0)
{
if (gBattleResults.numHealingItemsUsed < 255)
gBattleResults.numHealingItemsUsed++;
// I have to re-use this variable to match.
r5 = gActiveBattler;
gActiveBattler = sp34;
BtlController_EmitGetMonData(0, 0, 0);
MarkBattlerForControllerExec(gActiveBattler);
gActiveBattler = r5;
}
}
}
else
{
gBattleMoveDamage = -data;
}
retVal = FALSE;
}
r10 &= 0xEF;
break;
case 3:
if (!(r10 & 2))
{
for (r5 = 0; r5 < 4; r5++)
{
u16 r4;
data = GetMonData(mon, MON_DATA_PP1 + r5, NULL);
r4 = GetMonData(mon, MON_DATA_MOVE1 + r5, NULL);
if (data != CalculatePPWithBonus(r4, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), r5))
{
data += itemEffect[sp24];
r4 = GetMonData(mon, MON_DATA_MOVE1 + r5, NULL);
if (data > CalculatePPWithBonus(r4, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), r5))
{
r4 = GetMonData(mon, MON_DATA_MOVE1 + r5, NULL);
data = CalculatePPWithBonus(r4, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), r5);
}
SetMonData(mon, MON_DATA_PP1 + r5, &data);
if (gMain.inBattle
&& sp34 != 4 && !(gBattleMons[sp34].status2 & 0x200000)
&& !(gDisableStructs[sp34].mimickedMoves & gBitTable[r5]))
gBattleMons[sp34].pp[r5] = data;
retVal = FALSE;
}
}
sp24++;
}
else
{
u16 r4;
data = GetMonData(mon, MON_DATA_PP1 + moveIndex, NULL);
r4 = GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL);
if (data != CalculatePPWithBonus(r4, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex))
{
data += itemEffect[sp24++];
r4 = GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL);
if (data > CalculatePPWithBonus(r4, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex))
{
r4 = GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL);
data = CalculatePPWithBonus(r4, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex);
}
SetMonData(mon, MON_DATA_PP1 + moveIndex, &data);
if (gMain.inBattle
&& sp34 != 4 && !(gBattleMons[sp34].status2 & 0x200000)
&& !(gDisableStructs[sp34].mimickedMoves & gBitTable[moveIndex]))
gBattleMons[sp34].pp[moveIndex] = data;
retVal = FALSE;
}
}
break;
case 7:
{
u16 targetSpecies = GetEvolutionTargetSpecies(mon, 2, item);
if (targetSpecies != SPECIES_NONE)
{
BeginEvolutionScene(mon, targetSpecies, 0, partyIndex);
return FALSE;
}
}
break;
}
}
sp28++;
r10 >>= 1;
}
break;
case 5:
r10 = itemEffect[cmdIndex];
sp28 = 0;
while (r10 != 0)
{
if (r10 & 1)
{
u16 evCount;
switch (sp28)
{
case 0:
case 1:
case 2:
case 3:
evCount = GetMonEVCount(mon);
if (evCount >= 510)
return TRUE;
data = GetMonData(mon, sGetMonDataEVConstants[sp28 + 2], NULL);
if (data < 100)
{
if (data + itemEffect[sp24] > 100)
r4 = 100 - (data + itemEffect[sp24]) + itemEffect[sp24];
else
r4 = itemEffect[sp24];
if (evCount + r4 > 510)
r4 += 510 - (evCount + r4);
data += r4;
SetMonData(mon, sGetMonDataEVConstants[sp28 + 2], &data);
CalculateMonStats(mon);
retVal = FALSE;
sp24++;
}
break;
case 4:
data = (GetMonData(mon, MON_DATA_PP_BONUSES, NULL) & gPPUpGetMask[moveIndex]) >> (moveIndex * 2);
if (data < 3)
{
r4 = CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL), GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex);
data = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
data &= gPPUpSetMask[moveIndex];
data += gPPUpAddMask[moveIndex] * 3;
SetMonData(mon, MON_DATA_PP_BONUSES, &data);
data = CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL), data, moveIndex) - r4;
data = GetMonData(mon, MON_DATA_PP1 + moveIndex, NULL) + data;
SetMonData(mon, MON_DATA_PP1 + moveIndex, &data);
retVal = FALSE;
}
break;
case 5:
if (GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) < 100 && retVal == 0 && sp2C == 0)
{
sp2C = itemEffect[sp24];
friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL);
if (sp2C > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP)
friendship += 150 * sp2C / 100;
else
friendship += sp2C;
if (sp2C > 0)
{
if (GetMonData(mon, MON_DATA_POKEBALL, NULL) == 11)
friendship++;
if (GetMonData(mon, MON_DATA_MET_LOCATION, NULL) == GetCurrentRegionMapSectionId())
friendship++;
}
if (friendship < 0)
friendship = 0;
if (friendship > 255)
friendship = 255;
SetMonData(mon, MON_DATA_FRIENDSHIP, &friendship);
}
sp24++;
break;
case 6:
if (GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) >= 100 && GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) < 200
&& retVal == 0 && sp2C == 0)
{
sp2C = itemEffect[sp24];
friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL);
if (sp2C > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP)
friendship += 150 * sp2C / 100;
else
friendship += sp2C;
if (sp2C > 0)
{
if (GetMonData(mon, MON_DATA_POKEBALL, NULL) == 11)
friendship++;
if (GetMonData(mon, MON_DATA_MET_LOCATION, NULL) == GetCurrentRegionMapSectionId())
friendship++;
}
if (friendship < 0)
friendship = 0;
if (friendship > 255)
friendship = 255;
SetMonData(mon, MON_DATA_FRIENDSHIP, &friendship);
}
sp24++;
break;
case 7:
if (GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) >= 200 && retVal == 0 && sp2C == 0)
{
sp2C = itemEffect[sp24];
friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, NULL);
if (sp2C > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP)
friendship += 150 * sp2C / 100;
else
friendship += sp2C;
if (sp2C > 0)
{
if (GetMonData(mon, MON_DATA_POKEBALL, NULL) == 11)
friendship++;
if (GetMonData(mon, MON_DATA_MET_LOCATION, NULL) == GetCurrentRegionMapSectionId())
friendship++;
}
if (friendship < 0)
friendship = 0;
if (friendship > 255)
friendship = 255;
SetMonData(mon, MON_DATA_FRIENDSHIP, &friendship);
}
sp24++;
break;
}
}
sp28++;
r10 >>= 1;
}
break;
}
}
return retVal;
}
static bool8 HealStatusConditions(struct Pokemon *mon, u32 unused, u32 healMask, u8 battleId)
{
u32 status = GetMonData(mon, MON_DATA_STATUS, 0);
if (status & healMask)
{
status &= ~healMask;
SetMonData(mon, MON_DATA_STATUS, &status);
if (gMain.inBattle && battleId != 4)
gBattleMons[battleId].status1 &= ~healMask;
return FALSE;
}
else
{
return TRUE;
}
}
bool8 PokemonUseItemEffects2(struct Pokemon *mon, u16 item, u8 partyIndex, u8 moveIndex)
{
u32 data;
s32 tmp;
s32 cmdIndex;
bool8 retVal = TRUE;
const u8 *itemEffect;
u8 r10 = 6;
u32 i;
s32 sp18 = 0;
u8 holdEffect;
u8 battlerId = 4;
u16 heldItem;
u8 curEffect;
u32 curMoveId;
heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, NULL);
// you have to write as such, because otherwise gMain.inBattle will lose its u8 cast
if (heldItem == ITEM_ENIGMA_BERRY)
{
if (gMain.inBattle)
holdEffect = gEnigmaBerries[gBattlerInMenuId].holdEffect;
else
holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
}
else
{
holdEffect = ItemId_GetHoldEffect(heldItem);
}
gPotentialItemEffectBattler = gBattlerInMenuId;
if (gMain.inBattle)
{
gActiveBattler = gBattlerInMenuId;
for (cmdIndex = GetBattlerSide(gActiveBattler) != B_SIDE_PLAYER;
cmdIndex < gBattlersCount;
cmdIndex += 2)
{
if (gBattlerPartyIndexes[cmdIndex] == partyIndex)
{
battlerId = cmdIndex;
break;
}
}
}
else
{
gActiveBattler = 0;
battlerId = 4;
}
if (!IS_POKEMON_ITEM(item))
return TRUE;
if (gItemEffectTable[item - 13] == NULL && item != ITEM_ENIGMA_BERRY)
return TRUE;
if (item == ITEM_ENIGMA_BERRY)
{
if (gMain.inBattle)
itemEffect = gEnigmaBerries[gActiveBattler].itemEffect;
else
itemEffect = gSaveBlock1Ptr->enigmaBerry.itemEffect;
}
else
{
itemEffect = gItemEffectTable[item - 13];
}
for (cmdIndex = 0; cmdIndex < 6; cmdIndex++)
{
switch (cmdIndex)
{
// status healing effects
case 0:
if (itemEffect[cmdIndex] & 0x80
&& gMain.inBattle
&& battlerId != 4
&& gBattleMons[battlerId].status2 & STATUS2_INFATUATION)
retVal = FALSE;
if (itemEffect[cmdIndex] & 0x30
&& !(gBattleMons[gActiveBattler].status2 & STATUS2_FOCUS_ENERGY))
retVal = FALSE;
if ((itemEffect[cmdIndex] & 0xF)
&& gBattleMons[gActiveBattler].statStages[STAT_STAGE_ATK] < 12)
retVal = FALSE;
break;
// in-battle stat boosting effects?
case 1:
if ((itemEffect[cmdIndex] & 0xF0)
&& gBattleMons[gActiveBattler].statStages[STAT_STAGE_DEF] < 12)
retVal = FALSE;
if ((itemEffect[cmdIndex] & 0xF)
&& gBattleMons[gActiveBattler].statStages[STAT_STAGE_SPEED] < 12)
retVal = FALSE;
break;
// more stat boosting effects?
case 2:
if ((itemEffect[cmdIndex] & 0xF0)
&& gBattleMons[gActiveBattler].statStages[STAT_STAGE_ACC] < 12)
retVal = FALSE;
if ((itemEffect[cmdIndex] & 0xF)
&& gBattleMons[gActiveBattler].statStages[STAT_STAGE_SPATK] < 12)
retVal = FALSE;
break;
case 3:
if ((itemEffect[cmdIndex] & 0x80)
&& gSideTimers[GetBattlerSide(gActiveBattler)].mistTimer == 0)
retVal = FALSE;
if ((itemEffect[cmdIndex] & 0x40) // raise level
&& GetMonData(mon, MON_DATA_LEVEL, NULL) != 100)
retVal = FALSE;
if ((itemEffect[cmdIndex] & 0x20)
&& sub_8042BE8(mon, partyIndex, 7, battlerId))
retVal = FALSE;
if ((itemEffect[cmdIndex] & 0x10) && sub_8042BE8(mon, partyIndex, 0xF88, battlerId))
retVal = FALSE;
if ((itemEffect[cmdIndex] & 8) && sub_8042BE8(mon, partyIndex, 16, battlerId))
retVal = FALSE;
if ((itemEffect[cmdIndex] & 4) && sub_8042BE8(mon, partyIndex, 32, battlerId))
retVal = FALSE;
if ((itemEffect[cmdIndex] & 2) && sub_8042BE8(mon, partyIndex, 64, battlerId))
retVal = FALSE;
if (itemEffect[cmdIndex] & 1 // heal confusion
&& gMain.inBattle && battlerId != 4 && (gBattleMons[battlerId].status2 & STATUS2_CONFUSION))
retVal = FALSE;
break;
// EV, HP, and PP raising effects
case 4:
curEffect = itemEffect[cmdIndex];
if (curEffect & 0x20)
{
curEffect &= ~0x20;
data = (GetMonData(mon, MON_DATA_PP_BONUSES, NULL) & gPPUpGetMask[moveIndex]) >> (moveIndex * 2);
i = CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL), GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex);
if (data < 3 && i > 4)
retVal = FALSE;
}
i = 0;
while (curEffect) // _080428C0
{
if (curEffect & 1)
{
switch (i)
{
case 0:
case 1:
if (GetMonEVCount(mon) >= 510)
return TRUE;
data = GetMonData(mon, sGetMonDataEVConstants[i], NULL);
if (data < 100)
{
r10++;
retVal = FALSE;
}
break;
case 2:
// revive?
if (curEffect & 0x10)
{
if (GetMonData(mon, MON_DATA_HP, NULL) != 0)
{
r10++;
break;
}
}
else
{
if (GetMonData(mon, MON_DATA_HP, NULL) == 0)
{
r10++;
break;
}
}
if (GetMonData(mon, MON_DATA_MAX_HP, NULL) != GetMonData(mon, MON_DATA_HP, NULL))
retVal = FALSE;
r10++;
curEffect &= 0xEF;
break;
case 3:
if (!(curEffect & 2))
{
for (tmp = 0; tmp < MAX_MON_MOVES; tmp++)
{
data = GetMonData(mon, MON_DATA_PP1 + tmp, NULL);
if (data != CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + tmp, NULL), GetMonData(mon, MON_DATA_PP_BONUSES, NULL), tmp))
retVal = FALSE;
}
r10++;
}
else // _080429FA
{
data = GetMonData(mon, MON_DATA_PP1 + moveIndex, NULL);
curMoveId = GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL);
if (data != CalculatePPWithBonus(curMoveId, GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex))
{
r10++;
retVal = FALSE;
}
}
break;
case 7:
if (GetEvolutionTargetSpecies(mon, 2, item) != SPECIES_NONE)
return FALSE;
break;
}
}
i++;
curEffect >>= 1;
}
break;
case 5:
curEffect = itemEffect[cmdIndex];
i = 0;
while (curEffect)
{
if (curEffect & 1)
{
switch (i)
{
case 0:
case 1:
case 2:
case 3:
if (GetMonEVCount(mon) >= 510)
return TRUE;
data = GetMonData(mon, sGetMonDataEVConstants[i + 2], NULL);
if (data < 100)
{
retVal = FALSE;
r10++;
}
break;
case 4:
data = (GetMonData(mon, MON_DATA_PP_BONUSES, NULL) & gPPUpGetMask[moveIndex]) >> (moveIndex * 2);
tmp = CalculatePPWithBonus(GetMonData(mon, MON_DATA_MOVE1 + moveIndex, NULL), GetMonData(mon, MON_DATA_PP_BONUSES, NULL), moveIndex);
if (data < 3 && tmp > 4)
retVal = FALSE;
break;
case 5:
if (GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) < 100
&& retVal == FALSE
&& sp18 == 0)
sp18 = itemEffect[r10];
r10++;
break;
case 6:
if (GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) >= 100
&& GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) < 200
&& retVal == FALSE
&& sp18 == 0)
sp18 = itemEffect[r10];
r10++;
break;
case 7:\
if (GetMonData(mon, MON_DATA_FRIENDSHIP, NULL) >= 200
&& retVal == FALSE
&& sp18 == 0)
sp18 = itemEffect[r10];
r10++;
break;
}
}
i++;
curEffect >>= 1;
}
break;
}
}
return retVal;
}
static bool8 sub_8042BE8(struct Pokemon *mon, u32 unused, u32 healMask, u8 battleId)
{
if ((GetMonData(mon, MON_DATA_STATUS, NULL) & healMask) != 0)
return TRUE;
else
return FALSE;
}
u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit)
{
const u8 *temp;
const u8 *itemEffect;
u8 offset;
int i;
u8 j;
u8 val;
offset = 6;
temp = gItemEffectTable[itemId - 13];
if (!temp && itemId != ITEM_ENIGMA_BERRY)
return 0;
if (itemId == ITEM_ENIGMA_BERRY)
{
temp = gEnigmaBerries[gActiveBattler].itemEffect;
}
itemEffect = temp;
for (i = 0; i < 6; i++)
{
switch (i)
{
case 0:
case 1:
case 2:
case 3:
if (i == effectByte)
return 0;
break;
case 4:
val = itemEffect[4];
if (val & 0x20)
val &= 0xDF;
j = 0;
while (val)
{
if (val & 1)
{
switch (j)
{
case 2:
if (val & 0x10)
val &= 0xEF;
case 0:
if (i == effectByte && (val & effectBit))
return offset;
offset++;
break;
case 1:
if (i == effectByte && (val & effectBit))
return offset;
offset++;
break;
case 3:
if (i == effectByte && (val & effectBit))
return offset;
offset++;
break;
case 7:
if (i == effectByte)
return 0;
break;
}
}
j++;
val >>= 1;
if (i == effectByte)
effectBit >>= 1;
}
break;
case 5:
val = itemEffect[5];
j = 0;
while (val)
{
if (val & 1)
{
switch (j)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
if (i == effectByte && (val & effectBit))
return offset;
offset++;
break;
case 7:
if (i == effectByte)
return 0;
break;
}
}
j++;
val >>= 1;
if (i == effectByte)
effectBit >>= 1;
}
break;
}
}
return offset;
}
static void sub_8042D50(int stat)
{
gBattlerTarget = gBattlerInMenuId;
StringCopy(gBattleTextBuff1, gUnknown_83FD5D0[gUnknown_825DFF0[stat]]);
StringCopy(gBattleTextBuff2, BattleText_Rose);
BattleStringExpandPlaceholdersToDisplayedString(BattleText_UnknownString3);
}
const u8 *Battle_PrintStatBoosterEffectMessage(u16 itemId)
{
int i;
const u8 *itemEffect;
if (itemId == ITEM_ENIGMA_BERRY)
{
if (gMain.inBattle)
{
itemEffect = gEnigmaBerries[gBattlerInMenuId].itemEffect;
}
else
{
itemEffect = gSaveBlock1Ptr->enigmaBerry.itemEffect;
}
}
else
{
itemEffect = gItemEffectTable[itemId - 13];
}
gPotentialItemEffectBattler = gBattlerInMenuId;
for (i = 0; i < 3; i++)
{
if (itemEffect[i] & 0xF)
sub_8042D50(i * 2);
if (itemEffect[i] & 0xF0)
{
if (i)
{
sub_8042D50(i * 2 + 1);
}
else
{
gBattlerAttacker = gBattlerInMenuId;
BattleStringExpandPlaceholdersToDisplayedString(BattleText_GetPumped);
}
}
}
if (itemEffect[3] & 0x80)
{
gBattlerAttacker = gBattlerInMenuId;
BattleStringExpandPlaceholdersToDisplayedString(BattleText_MistShroud);
}
return gDisplayedStringBattle;
}
u8 GetNature(struct Pokemon *mon)
{
return GetMonData(mon, MON_DATA_PERSONALITY, 0) % 25;
}
static u8 GetNatureFromPersonality(u32 personality)
{
return personality % 25;
}
u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 type, u16 evolutionItem)
{
int i;
u16 targetSpecies = 0;
u16 species = GetMonData(mon, MON_DATA_SPECIES, 0);
u16 heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0);
u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
u8 level;
u16 friendship;
u8 beauty = GetMonData(mon, MON_DATA_BEAUTY, 0);
u16 upperPersonality = personality >> 16;
u8 holdEffect;
if (heldItem == ITEM_ENIGMA_BERRY)
holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
else
holdEffect = ItemId_GetHoldEffect(heldItem);
if (holdEffect == HOLD_EFFECT_PREVENT_EVOLVE && type != 3)
return 0;
switch (type)
{
case 0:
level = GetMonData(mon, MON_DATA_LEVEL, 0);
friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0);
for (i = 0; i < 5; i++)
{
switch (gEvolutionTable[species][i].method)
{
case EVO_FRIENDSHIP:
if (friendship >= 220)
targetSpecies = gEvolutionTable[species][i].targetSpecies;
break;
// FR/LG removed the time of day evolutions due to having no RTC.
case EVO_FRIENDSHIP_DAY:
/*
RtcCalcLocalTime();
if (gLocalTime.hours >= 12 && gLocalTime.hours < 24 && friendship >= 220)
targetSpecies = gEvolutionTable[species][i].targetSpecies;
*/
break;
case EVO_FRIENDSHIP_NIGHT:
/*
RtcCalcLocalTime();
if (gLocalTime.hours >= 0 && gLocalTime.hours < 12 && friendship >= 220)
targetSpecies = gEvolutionTable[species][i].targetSpecies;
*/
break;
case EVO_LEVEL:
if (gEvolutionTable[species][i].param <= level)
targetSpecies = gEvolutionTable[species][i].targetSpecies;
break;
case EVO_LEVEL_ATK_GT_DEF:
if (gEvolutionTable[species][i].param <= level)
if (GetMonData(mon, MON_DATA_ATK, 0) > GetMonData(mon, MON_DATA_DEF, 0))
targetSpecies = gEvolutionTable[species][i].targetSpecies;
break;
case EVO_LEVEL_ATK_EQ_DEF:
if (gEvolutionTable[species][i].param <= level)
if (GetMonData(mon, MON_DATA_ATK, 0) == GetMonData(mon, MON_DATA_DEF, 0))
targetSpecies = gEvolutionTable[species][i].targetSpecies;
break;
case EVO_LEVEL_ATK_LT_DEF:
if (gEvolutionTable[species][i].param <= level)
if (GetMonData(mon, MON_DATA_ATK, 0) < GetMonData(mon, MON_DATA_DEF, 0))
targetSpecies = gEvolutionTable[species][i].targetSpecies;
break;
case EVO_LEVEL_SILCOON:
if (gEvolutionTable[species][i].param <= level && (upperPersonality % 10) <= 4)
targetSpecies = gEvolutionTable[species][i].targetSpecies;
break;
case EVO_LEVEL_CASCOON:
if (gEvolutionTable[species][i].param <= level && (upperPersonality % 10) > 4)
targetSpecies = gEvolutionTable[species][i].targetSpecies;
break;
case EVO_LEVEL_NINJASK:
if (gEvolutionTable[species][i].param <= level)
targetSpecies = gEvolutionTable[species][i].targetSpecies;
break;
case EVO_BEAUTY:
if (gEvolutionTable[species][i].param <= beauty)
targetSpecies = gEvolutionTable[species][i].targetSpecies;
break;
}
}
break;
case 1:
for (i = 0; i < 5; i++)
{
switch (gEvolutionTable[species][i].method)
{
case EVO_TRADE:
targetSpecies = gEvolutionTable[species][i].targetSpecies;
break;
case EVO_TRADE_ITEM:
if (gEvolutionTable[species][i].param == heldItem)
{
targetSpecies = gEvolutionTable[species][i].targetSpecies;
if (IsNationalPokedexEnabled() || targetSpecies <= 151)
{
heldItem = 0;
SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem);
targetSpecies = gEvolutionTable[species][i].targetSpecies;
}
}
break;
}
}
break;
case 2:
case 3:
for (i = 0; i < 5; i++)
{
if (gEvolutionTable[species][i].method == EVO_ITEM
&& gEvolutionTable[species][i].param == evolutionItem)
{
targetSpecies = gEvolutionTable[species][i].targetSpecies;
break;
}
}
break;
}
return targetSpecies;
}
static u16 HoennPokedexNumToSpecies(u16 var)
{
u16 species;
if (!var)
return 0;
species = 0;
while (species < POKEMON_SLOTS_NUMBER - 1 && sSpeciesToHoennPokedexNum[species] != var)
species++;
if (species == POKEMON_SLOTS_NUMBER - 1)
return 0;
return species + 1;
}
u16 NationalPokedexNumToSpecies(u16 nationalNum)
{
u16 species;
if (!nationalNum)
return 0;
species = 0;
while (species < POKEMON_SLOTS_NUMBER - 1 && sSpeciesToNationalPokedexNum[species] != nationalNum)
species++;
if (species == POKEMON_SLOTS_NUMBER - 1)
return 0;
return species + 1;
}
static u16 NationalToHoennOrder(u16 nationalNum)
{
u16 hoennNum;
if (!nationalNum)
return 0;
hoennNum = 0;
while (hoennNum < POKEMON_SLOTS_NUMBER - 1 && sHoennToNationalOrder[hoennNum] != nationalNum)
hoennNum++;
if (hoennNum == POKEMON_SLOTS_NUMBER - 1)
return 0;
return hoennNum + 1;
}
u16 SpeciesToNationalPokedexNum(u16 species)
{
if (!species)
return 0;
return sSpeciesToNationalPokedexNum[species - 1];
}
static u16 SpeciesToHoennPokedexNum(u16 species)
{
if (!species)
return 0;
return sSpeciesToHoennPokedexNum[species - 1];
}
u16 HoennToNationalOrder(u16 hoennNum)
{
if (!hoennNum)
return 0;
return sHoennToNationalOrder[hoennNum - 1];
}
u16 SpeciesToCryId(u16 species)
{
if (species < SPECIES_OLD_UNOWN_B - 1)
return species;
if (species <= SPECIES_OLD_UNOWN_Z - 1)
return SPECIES_UNOWN - 1;
return sHoennSpeciesIdToCryId[species - ((SPECIES_OLD_UNOWN_Z + 1) - 1)];
}
static void sub_8043338(u16 species, u32 personality, u8 *dest)
{
if (species == SPECIES_SPINDA
&& dest != gMonSpritesGfxPtr->sprites[0]
&& dest != gMonSpritesGfxPtr->sprites[2])
{
int i;
for (i = 0; i < 4; i++)
{
int j;
u8 x = sSpindaSpotGraphics[i].x + ((personality & 0x0F) - 8);
u8 y = sSpindaSpotGraphics[i].y + (((personality & 0xF0) >> 4) - 8);
for (j = 0; j < 16; j++)
{
int k;
s32 row = sSpindaSpotGraphics[i].image[j];
for (k = x; k < x + 16; k++)
{
u8 *val = dest + ((k / 8) * 32) + ((k % 8) / 2) + ((y >> 3) << 8) + ((y & 7) << 2);
if (row & 1)
{
if (k & 1)
{
if ((u8)((*val & 0xF0) - 0x10) <= 0x20)
*val += 0x40;
}
else
{
if ((u8)((*val & 0xF) - 0x01) <= 0x02)
*val += 0x04;
}
}
row >>= 1;
}
y++;
}
personality >>= 8;
}
}
}
void DrawSpindaSpots(u16 species, u32 personality, u8 *dest, u8 a4)
{
if (species == SPECIES_SPINDA && a4)
{
int i;
for (i = 0; i < 4; i++)
{
int j;
u8 x = sSpindaSpotGraphics[i].x + ((personality & 0x0F) - 8);
u8 y = sSpindaSpotGraphics[i].y + (((personality & 0xF0) >> 4) - 8);
for (j = 0; j < 16; j++)
{
int k;
s32 row = sSpindaSpotGraphics[i].image[j];
for (k = x; k < x + 16; k++)
{
u8 *val = dest + ((k / 8) * 32) + ((k % 8) / 2) + ((y >> 3) << 8) + ((y & 7) << 2);
if (row & 1)
{
if (k & 1)
{
if ((u8)((*val & 0xF0) - 0x10) <= 0x20)
*val += 0x40;
}
else
{
if ((u8)((*val & 0xF) - 0x01) <= 0x02)
*val += 0x04;
}
}
row >>= 1;
}
y++;
}
personality >>= 8;
}
}
}
void EvolutionRenameMon(struct Pokemon *mon, u16 oldSpecies, u16 newSpecies)
{
u8 language;
GetMonData(mon, MON_DATA_NICKNAME, gStringVar1);
language = GetMonData(mon, MON_DATA_LANGUAGE, &language);
if (language == GAME_LANGUAGE && !StringCompare(gSpeciesNames[oldSpecies], gStringVar1))
SetMonData(mon, MON_DATA_NICKNAME, gSpeciesNames[newSpecies]);
}
bool8 sub_80435E0(void)
{
bool8 retVal = FALSE;
switch (gLinkPlayers[GetMultiplayerId()].id)
{
case 0:
case 3:
retVal = FALSE;
break;
case 1:
case 2:
retVal = TRUE;
break;
}
return retVal;
}
bool16 GetLinkTrainerFlankId(u8 linkPlayerId)
{
bool16 retVal = FALSE;
switch (gLinkPlayers[linkPlayerId].id)
{
case 0:
case 3:
retVal = FALSE;
break;
case 1:
case 2:
retVal = TRUE;
break;
}
return retVal;
}
s32 GetBattlerMultiplayerId(u16 a1)
{
s32 id;
for (id = 0; id < MAX_LINK_PLAYERS; id++)
if (gLinkPlayers[id].id == a1)
break;
return id;
}
u8 GetTrainerEncounterMusicId(u16 trainer)
{
return gTrainers[trainer].encounterMusic_gender & 0x7F;
}
static u16 ModifyStatByNature(u8 nature, u16 n, u8 statIndex)
{
if (statIndex < 1 || statIndex > 5)
{
// should just be "return n", but it wouldn't match without this
u16 retVal = n;
retVal++;
retVal--;
return retVal;
}
switch (sNatureStatTable[nature][statIndex - 1])
{
case 1:
return (u16)(n * 110) / 100;
case -1:
return (u16)(n * 90) / 100;
}
return n;
}
// TODO: Move these to constants/trainers.h
#define TRAINER_CLASS_ELITE_FOUR 0x54
#define TRAINER_CLASS_LEADER 0x57
#define TRAINER_CLASS_CHAMPION 0x5A
void AdjustFriendship(struct Pokemon *mon, u8 event)
{
u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
u16 heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0);
u8 holdEffect;
if (heldItem == ITEM_ENIGMA_BERRY)
{
if (gMain.inBattle)
holdEffect = gEnigmaBerries[0].holdEffect;
else
holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
}
else
{
holdEffect = ItemId_GetHoldEffect(heldItem);
}
if (species && species != SPECIES_EGG)
{
u8 friendshipLevel = 0;
s16 friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0);
if (friendship > 99)
friendshipLevel++;
if (friendship > 199)
friendshipLevel++;
if ((event != FRIENDSHIP_EVENT_WALKING || !(Random() & 1))
&& (event != FRIENDSHIP_EVENT_LEAGUE_BATTLE
|| ((gBattleTypeFlags & BATTLE_TYPE_TRAINER)
&& (gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_ELITE_FOUR
|| gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_LEADER
|| gTrainers[gTrainerBattleOpponent_A].trainerClass == TRAINER_CLASS_CHAMPION))))
{
s8 delta = sFriendshipEventDeltas[event][friendshipLevel];
if (delta > 0 && holdEffect == HOLD_EFFECT_HAPPINESS_UP)
delta = (150 * delta) / 100;
friendship += delta;
if (delta > 0)
{
if (GetMonData(mon, MON_DATA_POKEBALL, 0) == ITEM_LUXURY_BALL)
friendship++;
if (GetMonData(mon, MON_DATA_MET_LOCATION, 0) == GetCurrentRegionMapSectionId())
friendship++;
}
if (friendship < 0)
friendship = 0;
if (friendship > 255)
friendship = 255;
SetMonData(mon, MON_DATA_FRIENDSHIP, &friendship);
}
}
}
void MonGainEVs(struct Pokemon *mon, u16 defeatedSpecies)
{
u8 evs[NUM_STATS];
u16 evIncrease = 0;
u16 totalEVs = 0;
u16 heldItem;
u8 holdEffect;
int i;
for (i = 0; i < NUM_STATS; i++)
{
evs[i] = GetMonData(mon, MON_DATA_HP_EV + i, 0);
totalEVs += evs[i];
}
for (i = 0; i < NUM_STATS; i++)
{
u8 hasHadPokerus;
int multiplier;
if (totalEVs >= MAX_TOTAL_EVS)
break;
hasHadPokerus = CheckPartyHasHadPokerus(mon, 0);
if (hasHadPokerus)
multiplier = 2;
else
multiplier = 1;
switch (i)
{
case 0:
evIncrease = gBaseStats[defeatedSpecies].evYield_HP * multiplier;
break;
case 1:
evIncrease = gBaseStats[defeatedSpecies].evYield_Attack * multiplier;
break;
case 2:
evIncrease = gBaseStats[defeatedSpecies].evYield_Defense * multiplier;
break;
case 3:
evIncrease = gBaseStats[defeatedSpecies].evYield_Speed * multiplier;
break;
case 4:
evIncrease = gBaseStats[defeatedSpecies].evYield_SpAttack * multiplier;
break;
case 5:
evIncrease = gBaseStats[defeatedSpecies].evYield_SpDefense * multiplier;
break;
}
heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0);
if (heldItem == ITEM_ENIGMA_BERRY)
{
if (gMain.inBattle)
holdEffect = gEnigmaBerries[0].holdEffect;
else
holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
}
else
{
holdEffect = ItemId_GetHoldEffect(heldItem);
}
if (holdEffect == HOLD_EFFECT_MACHO_BRACE)
evIncrease *= 2;
if (totalEVs + (s16)evIncrease > MAX_TOTAL_EVS)
evIncrease = ((s16)evIncrease + MAX_TOTAL_EVS) - (totalEVs + evIncrease);
if (evs[i] + (s16)evIncrease > 255)
{
int val1 = (s16)evIncrease + 255;
int val2 = evs[i] + evIncrease;
evIncrease = val1 - val2;
}
evs[i] += evIncrease;
totalEVs += evIncrease;
SetMonData(mon, MON_DATA_HP_EV + i, &evs[i]);
}
}
u16 GetMonEVCount(struct Pokemon *mon)
{
int i;
u16 count = 0;
for (i = 0; i < NUM_STATS; i++)
count += GetMonData(mon, MON_DATA_HP_EV + i, 0);
return count;
}
void sub_8043A68(void)
{
u8 foo[4]; // huh?
}
u8 CheckPartyPokerus(struct Pokemon *party, u8 selection)
{
u8 retVal;
int partyIndex = 0;
unsigned curBit = 1;
retVal = 0;
if (selection)
{
do
{
if ((selection & 1) && (GetMonData(&party[partyIndex], MON_DATA_POKERUS, 0) & 0xF))
retVal |= curBit;
partyIndex++;
curBit <<= 1;
selection >>= 1;
}
while (selection);
}
else if (GetMonData(&party[0], MON_DATA_POKERUS, 0) & 0xF)
{
retVal = 1;
}
return retVal;
}
u8 CheckPartyHasHadPokerus(struct Pokemon *party, u8 selection)
{
u8 retVal;
int partyIndex = 0;
unsigned curBit = 1;
retVal = 0;
if (selection)
{
do
{
if ((selection & 1) && GetMonData(&party[partyIndex], MON_DATA_POKERUS, 0))
retVal |= curBit;
partyIndex++;
curBit <<= 1;
selection >>= 1;
}
while (selection);
}
else if (GetMonData(&party[0], MON_DATA_POKERUS, 0))
{
retVal = 1;
}
return retVal;
}
static void sub_8043B38(void)
{
u8 foo[4]; // huh?
}
void sub_8043B40(void)
{
u8 foo[4]; // huh?
}
static void SetMonExpWithMaxLevelCheck(struct Pokemon *mon, int species, u8 unused, u32 data)
{
if (data > gExperienceTables[gBaseStats[species].growthRate][100])
{
data = gExperienceTables[gBaseStats[species].growthRate][100];
SetMonData(mon, MON_DATA_EXP, &data);
}
}
bool8 TryIncrementMonLevel(struct Pokemon *mon)
{
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
u8 level = GetMonData(mon, MON_DATA_LEVEL, NULL);
u8 newLevel = level + 1;
u32 exp = GetMonData(mon, MON_DATA_EXP, NULL);
if (level < 100)
{
if (exp > gExperienceTables[gBaseStats[species].growthRate][newLevel])
{
SetMonData(mon, MON_DATA_LEVEL, &newLevel);
SetMonExpWithMaxLevelCheck(mon, species, newLevel, exp);
return TRUE;
}
else
return FALSE;
}
else
{
SetMonExpWithMaxLevelCheck(mon, species, level, exp);
return FALSE;
}
}
u32 CanMonLearnTMHM(struct Pokemon *mon, u8 tm)
{
u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
if (species == SPECIES_EGG)
{
return 0;
}
else if (tm < 32)
{
u32 mask = 1 << tm;
return sTMHMLearnsets[species][0] & mask;
}
else
{
u32 mask = 1 << (tm - 32);
return sTMHMLearnsets[species][1] & mask;
}
}
u8 GetMoveRelearnerMoves(struct Pokemon *mon, u16 *moves)
{
u16 learnedMoves[4];
u8 numMoves = 0;
u16 species = GetMonData(mon, MON_DATA_SPECIES, 0);
u8 level = GetMonData(mon, MON_DATA_LEVEL, 0);
int i, j, k;
for (i = 0; i < 4; i++)
learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0);
for (i = 0; i < 20; i++)
{
u16 moveLevel;
if (gLevelUpLearnsets[species][i] == 0xFFFF)
break;
moveLevel = gLevelUpLearnsets[species][i] & 0xFE00;
if (moveLevel <= (level << 9))
{
for (j = 0; j < 4 && learnedMoves[j] != (gLevelUpLearnsets[species][i] & 0x1FF); j++)
;
if (j == 4)
{
for (k = 0; k < numMoves && moves[k] != (gLevelUpLearnsets[species][i] & 0x1FF); k++)
;
if (k == numMoves)
moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF;
}
}
}
return numMoves;
}
u8 GetLevelUpMovesBySpecies(u16 species, u16 *moves)
{
u8 numMoves = 0;
int i;
for (i = 0; i < 20 && gLevelUpLearnsets[species][i] != 0xFFFF; i++)
moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF;
return numMoves;
}
u8 GetNumberOfRelearnableMoves(struct Pokemon *mon)
{
u16 learnedMoves[4];
u16 moves[20];
u8 numMoves = 0;
u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
u8 level = GetMonData(mon, MON_DATA_LEVEL, 0);
int i, j, k;
if (species == SPECIES_EGG)
return 0;
for (i = 0; i < 4; i++)
learnedMoves[i] = GetMonData(mon, MON_DATA_MOVE1 + i, 0);
for (i = 0; i < 20; i++)
{
u16 moveLevel;
if (gLevelUpLearnsets[species][i] == 0xFFFF)
break;
moveLevel = gLevelUpLearnsets[species][i] & 0xFE00;
if (moveLevel <= (level << 9))
{
for (j = 0; j < 4 && learnedMoves[j] != (gLevelUpLearnsets[species][i] & 0x1FF); j++)
;
if (j == 4)
{
for (k = 0; k < numMoves && moves[k] != (gLevelUpLearnsets[species][i] & 0x1FF); k++)
;
if (k == numMoves)
moves[numMoves++] = gLevelUpLearnsets[species][i] & 0x1FF;
}
}
}
return numMoves;
}
// SpeciesToPokedexNum?
u16 sub_8043F90(u16 species)
{
species = SpeciesToNationalPokedexNum(species);
if (!IsNationalPokedexEnabled() && species > 151)
return 0xFFFF;
return species;
}
void ClearBattleMonForms(void)
{
int i;
for (i = 0; i < 4; i++)
gBattleMonForms[i] = 0;
}
static u16 GetMUS_ForBattle(void)
{
if (gBattleTypeFlags & 0x1000)
return 0x12A;
if (gBattleTypeFlags & 0x4000)
return 0x10A;
if (gBattleTypeFlags & 0x2)
return 0x10A;
if (gBattleTypeFlags & 0x8)
{
switch (gTrainers[gTrainerBattleOpponent_A].trainerClass)
{
case 0x5A:
return 0x12B;
case 0x54:
case 0x57:
return 0x128;
case 0x53:
case 0x55:
case 0x56:
case 0x58:
case 0x59:
default:
return 0x129;
}
}
return 0x12A;
}
void PlayBattleBGM(void)
{
ResetMapMusic();
m4aMPlayAllStop();
PlayBGM(GetMUS_ForBattle());
}
void PlayMapChosenOrBattleBGM(u16 songId)
{
ResetMapMusic();
m4aMPlayAllStop();
if (songId)
PlayNewMapMusic(songId);
else
PlayNewMapMusic(GetMUS_ForBattle());
}
const u32 *GetMonFrontSpritePal(struct Pokemon *mon)
{
u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0);
u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
return GetMonSpritePalFromSpeciesAndPersonality(species, otId, personality);
}
const u32 *GetMonSpritePalFromSpeciesAndPersonality(u16 species, u32 otId, u32 personality)
{
u32 shinyValue;
if (species > SPECIES_EGG)
return gMonPaletteTable[0].data;
shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality);
if (shinyValue < 8)
return gMonShinyPaletteTable[species].data;
else
return gMonPaletteTable[species].data;
}
const struct CompressedSpritePalette *GetMonSpritePalStruct(struct Pokemon *mon)
{
u16 species = GetMonData(mon, MON_DATA_SPECIES2, 0);
u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0);
u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
return GetMonSpritePalStructFromOtIdPersonality(species, otId, personality);
}
const struct CompressedSpritePalette *GetMonSpritePalStructFromOtIdPersonality(u16 species, u32 otId , u32 personality)
{
u32 shinyValue;
shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality);
if (shinyValue < 8)
return &gMonShinyPaletteTable[species];
else
return &gMonPaletteTable[species];
}
bool32 IsHMMove2(u16 move)
{
int i = 0;
while (sHMMoves[i] != 0xFFFF)
{
if (sHMMoves[i++] == move)
return TRUE;
}
return FALSE;
}
bool8 IsPokeSpriteNotFlipped(u16 species)
{
return gBaseStats[species].noFlip;
}
static s8 GetMonFlavorRelation(struct Pokemon *mon, u8 flavor)
{
u8 nature = GetNature(mon);
return sPokeblockFlavorCompatibilityTable[nature * 5 + flavor];
}
s8 GetFlavorRelationByPersonality(u32 personality, u8 flavor)
{
u8 nature = GetNatureFromPersonality(personality);
return sPokeblockFlavorCompatibilityTable[nature * 5 + flavor];
}
bool8 IsTradedMon(struct Pokemon *mon)
{
u8 otName[7 + 1]; // change PLAYER_NAME_LENGTH to 7
u32 otId;
GetMonData(mon, MON_DATA_OT_NAME, otName);
otId = GetMonData(mon, MON_DATA_OT_ID, 0);
return IsOtherTrainer(otId, otName);
}
bool8 IsOtherTrainer(u32 otId, u8 *otName)
{
if (otId ==
(gSaveBlock2Ptr->playerTrainerId[0]
| (gSaveBlock2Ptr->playerTrainerId[1] << 8)
| (gSaveBlock2Ptr->playerTrainerId[2] << 16)
| (gSaveBlock2Ptr->playerTrainerId[3] << 24)))
{
int i;
for (i = 0; otName[i] != EOS; i++)
if (otName[i] != gSaveBlock2Ptr->playerName[i])
return TRUE;
return FALSE;
}
return TRUE;
}
void MonRestorePP(struct Pokemon *mon)
{
BoxMonRestorePP(&mon->box);
}
void BoxMonRestorePP(struct BoxPokemon *boxMon)
{
int i;
for (i = 0; i < 4; i++)
{
if (GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, 0))
{
u16 move = GetBoxMonData(boxMon, MON_DATA_MOVE1 + i, 0);
u16 bonus = GetBoxMonData(boxMon, MON_DATA_PP_BONUSES, 0);
u8 pp = CalculatePPWithBonus(move, bonus, i);
SetBoxMonData(boxMon, MON_DATA_PP1 + i, &pp);
}
}
}
void SetMonPreventsSwitchingString(void)
{
gLastUsedAbility = gBattleStruct -> abilityPreventingSwitchout;
gBattleTextBuff1[0] = B_BUFF_PLACEHOLDER_BEGIN;
gBattleTextBuff1[1] = B_BUFF_MON_NICK_WITH_PREFIX;
gBattleTextBuff1[2] = gBattleStruct->battlerPreventingSwitchout;
gBattleTextBuff1[4] = B_BUFF_EOS;
if (GetBattlerSide(gBattleStruct->battlerPreventingSwitchout) == B_SIDE_PLAYER)
gBattleTextBuff1[3] = pokemon_order_func(gBattlerPartyIndexes[gBattleStruct->battlerPreventingSwitchout]);
else
gBattleTextBuff1[3] = gBattlerPartyIndexes[gBattleStruct->battlerPreventingSwitchout];
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff2, gBattlerInMenuId, pokemon_order_func(gBattlerPartyIndexes[gBattlerInMenuId]))
BattleStringExpandPlaceholders(gText_PkmnsXPreventsSwitching, gStringVar4);
}
void SetWildMonHeldItem(void)
{
if (!(gBattleTypeFlags & (BATTLE_TYPE_POKEDUDE | BATTLE_TYPE_LEGENDARY | BATTLE_TYPE_TRAINER)))
{
u16 rnd = Random() % 100;
u16 species = GetMonData(&gEnemyParty[0], MON_DATA_SPECIES, 0);
if (gBaseStats[species].item1 == gBaseStats[species].item2)
{
SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item1);
return;
}
if (rnd > 44)
{
if (rnd <= 94)
SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item1);
else
SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, &gBaseStats[species].item2);
}
}
}
bool8 IsMonShiny(struct Pokemon *mon)
{
u32 otId = GetMonData(mon, MON_DATA_OT_ID, 0);
u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
return IsShinyOtIdPersonality(otId, personality);
}
static bool8 IsShinyOtIdPersonality(u32 otId, u32 personality)
{
bool8 retVal = FALSE;
u32 shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality);
if (shinyValue < 8)
retVal = TRUE;
return retVal;
}
u8 *GetTrainerPartnerName(void)
{
u8 id = GetMultiplayerId();
return gLinkPlayers[GetBattlerMultiplayerId(gLinkPlayers[id].id ^ 2)].name;
}
u8 GetPlayerPartyHighestLevel(void)
{
s32 slot;
u8 level, monLevel;
level = 1;
for (slot = 0; slot < PARTY_SIZE; ++slot)
{
if (GetMonData(&gPlayerParty[slot], MON_DATA_SANITY_HAS_SPECIES, NULL) == 1 && !GetMonData(&gPlayerParty[slot], MON_DATA_SANITY_IS_EGG, NULL))
{
monLevel = GetMonData(&gPlayerParty[slot], MON_DATA_LEVEL, NULL);
if (monLevel > level)
level = monLevel;
}
}
return level;
}
u16 FacilityClassToPicIndex(u16 facilityClass)
{
return gFacilityClassToPicIndex[facilityClass];
}
bool8 sub_804455C(u8 caseId, u8 battlerId)
{
switch (caseId)
{
case 0:
default:
return FALSE;
case 1:
if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
return FALSE;
if (!gMain.inBattle)
return FALSE;
if (gLinkPlayers[GetMultiplayerId()].id == battlerId)
return FALSE;
break;
case 2:
break;
case 3:
if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
return FALSE;
if (!gMain.inBattle)
return FALSE;
if (battlerId == 1 || battlerId == 4 || battlerId == 5)
return TRUE;
return FALSE;
case 4:
break;
case 5:
if (gBattleTypeFlags & BATTLE_TYPE_LINK)
{
if (!gMain.inBattle)
return FALSE;
if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
{
if (gLinkPlayers[GetMultiplayerId()].id == battlerId)
return FALSE;
}
else
{
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
return FALSE;
}
}
else
{
if (!gMain.inBattle)
return FALSE;
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
return FALSE;
}
break;
}
return TRUE;
}
static u16 GetDeoxysStat(struct Pokemon *mon, s32 statId)
{
s32 ivVal, evVal;
u16 statValue;
u8 nature;
if (gBattleTypeFlags & BATTLE_TYPE_20 || GetMonData(mon, MON_DATA_SPECIES, NULL) != SPECIES_DEOXYS)
{
return statValue = 0;
}
else
{
ivVal = GetMonData(mon, MON_DATA_HP_IV + statId, NULL);
evVal = GetMonData(mon, MON_DATA_HP_EV + statId, NULL);
statValue = ((sDeoxysBaseStats[statId] * 2 + ivVal + evVal / 4) * mon->level) / 100 + 5;
nature = GetNature(mon);
statValue = ModifyStatByNature(nature, statValue, (u8)statId);
}
return statValue;
}
void SetDeoxysStats(void)
{
s32 i, value;
for (i = 0; i < PARTY_SIZE; i++)
{
struct Pokemon *mon = &gPlayerParty[i];
if (GetMonData(mon, MON_DATA_SPECIES, NULL) != SPECIES_DEOXYS)
continue;
value = GetMonData(mon, MON_DATA_ATK, NULL);
SetMonData(mon, MON_DATA_ATK, &value);
value = GetMonData(mon, MON_DATA_DEF, NULL);
SetMonData(mon, MON_DATA_DEF, &value);
value = GetMonData(mon, MON_DATA_SPEED, NULL);
SetMonData(mon, MON_DATA_SPEED, &value);
value = GetMonData(mon, MON_DATA_SPATK, NULL);
SetMonData(mon, MON_DATA_SPATK, &value);
value = GetMonData(mon, MON_DATA_SPDEF, NULL);
SetMonData(mon, MON_DATA_SPDEF, &value);
}
}
u16 sub_80447AC(void)
{
u8 linkId = GetMultiplayerId() ^ 1;
u32 arrId = gLinkPlayers[linkId].trainerId & 7;
arrId |= gLinkPlayers[linkId].gender << 3;
return FacilityClassToPicIndex(gLinkPlayerFacilityClasses[arrId]);
}
u16 sub_80447F0(void)
{
u8 linkId = GetMultiplayerId() ^ 1;
u32 arrId = gLinkPlayers[linkId].trainerId & 7;
arrId |= gLinkPlayers[linkId].gender << 3;
return gFacilityClassToTrainerClass[gLinkPlayerFacilityClasses[arrId]];
}
void CreateObedientEnemyMon(void)
{
s32 species = gSpecialVar_0x8004;
s32 level = gSpecialVar_0x8005;
s32 itemId = gSpecialVar_0x8006;
ZeroEnemyPartyMons();
CreateObedientMon(&gEnemyParty[0], species, level, 32, 0, 0, 0, 0);
if (itemId)
{
u8 heldItem[2];
heldItem[0] = itemId;
heldItem[1] = itemId >> 8;
SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, heldItem);
}
}
void HandleSetPokedexFlag(u16 nationalNum, u8 caseId, u32 personality)
{
u8 getFlagCaseId = (caseId == FLAG_SET_SEEN) ? FLAG_GET_SEEN : FLAG_GET_CAUGHT;
if (!GetSetPokedexFlag(nationalNum, getFlagCaseId))
{
GetSetPokedexFlag(nationalNum, caseId);
if (NationalPokedexNumToSpecies(nationalNum) == SPECIES_UNOWN)
gSaveBlock2Ptr->pokedex.unownPersonality = personality;
if (NationalPokedexNumToSpecies(nationalNum) == SPECIES_SPINDA)
gSaveBlock2Ptr->pokedex.spindaPersonality = personality;
}
}
bool8 CheckBattleTypeGhost(struct Pokemon *mon, u8 bank)
{
u8 buffer[12];
if (gBattleTypeFlags & BATTLE_TYPE_GHOST && GetBattlerSide(bank))
{
GetMonData(mon, MON_DATA_NICKNAME, buffer);
StringGetEnd10(buffer);
if (!StringCompare(buffer, gUnknown_841D148))
return TRUE;
}
return FALSE;
}
static void OakSpeechNidoranFSetupTemplate(struct OakSpeechNidoranFStruct *structPtr, u8 battlePosition)
{
u16 i = 0, j = 0;
if (battlePosition > 3)
{
for (i = 0; i < (s8)structPtr->spriteCount; ++i)
{
structPtr->templates[i] = gUnknown_825DEF0[i];
for (j = 0; j < structPtr->frameCount; ++j)
structPtr->frameImages[i * structPtr->frameCount + j].data = &structPtr->bufferPtrs[i][j * 0x800];
structPtr->templates[i].images = &structPtr->frameImages[i * structPtr->frameCount];
}
}
else
{
const struct SpriteTemplate *template = &gUnknown_825DEF0[battlePosition];
structPtr->templates[0] = *template;
for (j = 0; j < structPtr->frameCount; ++j)
structPtr->frameImages[j].data = &structPtr->bufferPtrs[0][j * 0x800];
structPtr->templates[0].images = structPtr->frameImages;
}
}
// not used
static void OakSpeechNidoranFSetupTemplateDummy(struct OakSpeechNidoranFStruct *structPtr)
{
u16 i, j;
for (i = 0; i < (s8)structPtr->spriteCount; ++i)
{
structPtr->templates[i] = sOakSpeechNidoranFDummyTemplate;
for (j = 0; j < structPtr->frameCount; ++j)
structPtr->frameImages[i * structPtr->spriteCount + j].data = &structPtr->bufferPtrs[i][j * 0x800];
structPtr->templates[i].images = &structPtr->frameImages[i * structPtr->spriteCount]; // should be frameCount logically
structPtr->templates[i].anims = gSpriteAnimTable_82349BC;
structPtr->templates[i].paletteTag = i;
}
}
#ifdef NONMATCHING
struct OakSpeechNidoranFStruct *OakSpeechNidoranFSetup(u8 battlePosition, bool8 enable)
{
s32 size;
u8 i, flags = 0;
if (sOakSpeechNidoranResources != NULL)
{
if (sOakSpeechNidoranResources->enable == 0xA3)
return NULL;
memset(sOakSpeechNidoranResources, 0, sizeof(struct OakSpeechNidoranFStruct));
sOakSpeechNidoranResources = NULL;
}
sOakSpeechNidoranResources = AllocZeroed(0x18);
if (sOakSpeechNidoranResources == NULL)
return NULL;
switch (enable)
{
case TRUE:
if (battlePosition == 4)
{
sOakSpeechNidoranResources->spriteCount = 4;
sOakSpeechNidoranResources->battlePosition = 4;
}
else
{
if (battlePosition > 4)
battlePosition = 0;
sOakSpeechNidoranResources->spriteCount = 1;
sOakSpeechNidoranResources->battlePosition = 1;
}
sOakSpeechNidoranResources->frameCount = 4;
sOakSpeechNidoranResources->enable2 = TRUE;
break;
case FALSE:
default:
if (!battlePosition)
battlePosition = 1;
if (battlePosition > 8)
battlePosition = 8;
// The following two statements refused to cooperate.
sOakSpeechNidoranResources->spriteCount = battlePosition;
sOakSpeechNidoranResources->battlePosition = battlePosition;
sOakSpeechNidoranResources->frameCount = 4;
sOakSpeechNidoranResources->enable2 = FALSE;
break;
}
size = sOakSpeechNidoranResources->frameCount * 0x800;
sOakSpeechNidoranResources->sizePerSprite = size;
sOakSpeechNidoranResources->dataBuffer = AllocZeroed(sOakSpeechNidoranResources->spriteCount * size);
sOakSpeechNidoranResources->bufferPtrs = AllocZeroed(sOakSpeechNidoranResources->spriteCount * 0x20);
if (sOakSpeechNidoranResources->dataBuffer == NULL || sOakSpeechNidoranResources->bufferPtrs == NULL)
{
flags |= 1;
}
else
{
for (i = 0; i < (s8)sOakSpeechNidoranResources->spriteCount; ++i)
sOakSpeechNidoranResources->bufferPtrs[i] = &sOakSpeechNidoranResources->dataBuffer[sOakSpeechNidoranResources->sizePerSprite * i];
}
sOakSpeechNidoranResources->templates = AllocZeroed(sizeof(struct SpriteTemplate) * sOakSpeechNidoranResources->spriteCount);
sOakSpeechNidoranResources->frameImages = AllocZeroed(sOakSpeechNidoranResources->spriteCount * sizeof(struct SpriteFrameImage) * sOakSpeechNidoranResources->frameCount);
if (sOakSpeechNidoranResources->templates == NULL || sOakSpeechNidoranResources->frameImages == NULL)
{
flags |= 2;
}
else
{
for (i = 0; i < sOakSpeechNidoranResources->frameCount * sOakSpeechNidoranResources->spriteCount; ++i)
sOakSpeechNidoranResources->frameImages[i].size = 0x800;
switch (sOakSpeechNidoranResources->enable2)
{
case TRUE:
OakSpeechNidoranFSetupTemplate(sOakSpeechNidoranResources, battlePosition);
break;
case FALSE:
default:
OakSpeechNidoranFSetupTemplateDummy(sOakSpeechNidoranResources);
break;
}
}
if (flags & 2)
{
if (sOakSpeechNidoranResources->frameImages != NULL)
FREE_AND_SET_NULL(sOakSpeechNidoranResources->frameImages);
if (sOakSpeechNidoranResources->templates != NULL)
FREE_AND_SET_NULL(sOakSpeechNidoranResources->templates);
}
if (flags & 1)
{
if (sOakSpeechNidoranResources->bufferPtrs != NULL)
FREE_AND_SET_NULL(sOakSpeechNidoranResources->bufferPtrs);
if (sOakSpeechNidoranResources->dataBuffer != NULL)
FREE_AND_SET_NULL(sOakSpeechNidoranResources->dataBuffer);
}
if (flags)
{
memset(sOakSpeechNidoranResources, 0, sizeof(struct OakSpeechNidoranFStruct));
FREE_AND_SET_NULL(sOakSpeechNidoranResources);
}
else
{
sOakSpeechNidoranResources->enable = 0xA3;
}
return sOakSpeechNidoranResources;
}
#else
NAKED
struct OakSpeechNidoranFStruct *OakSpeechNidoranFSetup(u8 battlePosition, bool8 enable)
{
asm_unified("\n\
push {r4-r7,lr}\n\
mov r7, r8\n\
push {r7}\n\
lsls r0, 24\n\
lsrs r6, r0, 24\n\
lsls r1, 24\n\
lsrs r5, r1, 24\n\
movs r0, 0\n\
mov r8, r0\n\
ldr r4, _08044B34 @ =sOakSpeechNidoranResources\n\
ldr r1, [r4]\n\
cmp r1, 0\n\
beq _08044B1E\n\
ldrb r0, [r1, 0x2]\n\
cmp r0, 0xA3\n\
beq _08044B2E\n\
adds r0, r1, 0\n\
movs r1, 0\n\
movs r2, 0x18\n\
bl memset\n\
mov r1, r8\n\
str r1, [r4]\n\
_08044B1E:\n\
ldr r4, _08044B34 @ =sOakSpeechNidoranResources\n\
movs r0, 0x18\n\
bl AllocZeroed\n\
adds r2, r0, 0\n\
str r2, [r4]\n\
cmp r2, 0\n\
bne _08044B38\n\
_08044B2E:\n\
movs r0, 0\n\
b _08044D70\n\
.align 2, 0\n\
_08044B34: .4byte sOakSpeechNidoranResources\n\
_08044B38:\n\
cmp r5, 0\n\
beq _08044B94\n\
cmp r5, 0x1\n\
bne _08044B94\n\
cmp r6, 0x4\n\
bne _08044B5E\n\
ldrb r1, [r2]\n\
movs r0, 0x10\n\
negs r0, r0\n\
ands r0, r1\n\
movs r1, 0x4\n\
orrs r0, r1\n\
strb r0, [r2]\n\
ldr r2, [r4]\n\
ldrb r1, [r2]\n\
movs r0, 0xF\n\
ands r0, r1\n\
movs r1, 0x40\n\
b _08044B7C\n\
_08044B5E:\n\
cmp r6, 0x4\n\
bls _08044B64\n\
movs r6, 0\n\
_08044B64:\n\
ldrb r1, [r2]\n\
movs r0, 0x10\n\
negs r0, r0\n\
ands r0, r1\n\
movs r1, 0x1\n\
orrs r0, r1\n\
strb r0, [r2]\n\
ldr r2, [r4]\n\
ldrb r1, [r2]\n\
movs r0, 0xF\n\
ands r0, r1\n\
movs r1, 0x10\n\
_08044B7C:\n\
orrs r0, r1\n\
strb r0, [r2]\n\
ldr r2, _08044B90 @ =sOakSpeechNidoranResources\n\
ldr r1, [r2]\n\
movs r0, 0x4\n\
strb r0, [r1, 0x1]\n\
ldr r1, [r2]\n\
movs r0, 0x1\n\
strb r0, [r1, 0x3]\n\
b _08044BD0\n\
.align 2, 0\n\
_08044B90: .4byte sOakSpeechNidoranResources\n\
_08044B94:\n\
cmp r6, 0\n\
bne _08044B9A\n\
movs r6, 0x1\n\
_08044B9A:\n\
cmp r6, 0x8\n\
bls _08044BA0\n\
movs r6, 0x8\n\
_08044BA0:\n\
ldr r4, _08044C10 @ =sOakSpeechNidoranResources\n\
ldr r3, [r4]\n\
movs r0, 0xF\n\
adds r1, r6, 0\n\
ands r1, r0\n\
ldrb r2, [r3]\n\
movs r0, 0x10\n\
negs r0, r0\n\
ands r0, r2\n\
orrs r0, r1\n\
strb r0, [r3]\n\
ldr r2, [r4]\n\
lsls r3, r6, 4\n\
ldrb r1, [r2]\n\
movs r0, 0xF\n\
ands r0, r1\n\
orrs r0, r3\n\
strb r0, [r2]\n\
ldr r1, [r4]\n\
movs r2, 0\n\
movs r0, 0x4\n\
strb r0, [r1, 0x1]\n\
ldr r0, [r4]\n\
strb r2, [r0, 0x3]\n\
_08044BD0:\n\
ldr r5, _08044C10 @ =sOakSpeechNidoranResources\n\
ldr r0, [r5]\n\
ldrb r1, [r0, 0x1]\n\
lsls r1, 11\n\
str r1, [r0, 0x4]\n\
ldrb r0, [r0]\n\
lsls r0, 28\n\
lsrs r0, 28\n\
muls r0, r1\n\
bl AllocZeroed\n\
ldr r1, [r5]\n\
str r0, [r1, 0x8]\n\
ldrb r0, [r1]\n\
lsls r0, 28\n\
lsrs r0, 23\n\
bl AllocZeroed\n\
adds r2, r0, 0\n\
ldr r1, [r5]\n\
str r2, [r1, 0xC]\n\
ldr r0, [r1, 0x8]\n\
cmp r0, 0\n\
beq _08044C04\n\
cmp r2, 0\n\
bne _08044C14\n\
_08044C04:\n\
movs r0, 0x1\n\
mov r1, r8\n\
orrs r1, r0\n\
mov r8, r1\n\
b _08044C44\n\
.align 2, 0\n\
_08044C10: .4byte sOakSpeechNidoranResources\n\
_08044C14:\n\
ldrb r0, [r1]\n\
lsls r0, 28\n\
movs r4, 0\n\
adds r3, r5, 0\n\
cmp r0, 0\n\
beq _08044C44\n\
_08044C20:\n\
ldr r3, [r5]\n\
ldr r0, [r3, 0xC]\n\
lsls r1, r4, 2\n\
adds r1, r0\n\
ldr r0, [r3, 0x4]\n\
adds r2, r0, 0\n\
muls r2, r4\n\
ldr r0, [r3, 0x8]\n\
adds r0, r2\n\
str r0, [r1]\n\
adds r0, r4, 0x1\n\
lsls r0, 24\n\
lsrs r4, r0, 24\n\
ldrb r0, [r3]\n\
lsls r0, 28\n\
lsrs r0, 28\n\
cmp r4, r0\n\
blt _08044C20\n\
_08044C44:\n\
ldr r5, _08044C8C @ =sOakSpeechNidoranResources\n\
ldr r0, [r5]\n\
ldrb r1, [r0]\n\
lsls r1, 28\n\
lsrs r1, 28\n\
lsls r0, r1, 1\n\
adds r0, r1\n\
lsls r0, 3\n\
bl AllocZeroed\n\
ldr r2, [r5]\n\
str r0, [r2, 0x10]\n\
ldrb r1, [r2]\n\
lsls r1, 28\n\
lsrs r1, 28\n\
ldrb r0, [r2, 0x1]\n\
lsls r0, 3\n\
muls r0, r1\n\
bl AllocZeroed\n\
adds r2, r0, 0\n\
ldr r1, [r5]\n\
str r2, [r1, 0x14]\n\
ldr r0, [r1, 0x10]\n\
cmp r0, 0\n\
beq _08044C7C\n\
cmp r2, 0\n\
bne _08044C90\n\
_08044C7C:\n\
movs r0, 0x2\n\
mov r1, r8\n\
orrs r1, r0\n\
lsls r0, r1, 24\n\
lsrs r0, 24\n\
mov r8, r0\n\
b _08044CE2\n\
.align 2, 0\n\
_08044C8C: .4byte sOakSpeechNidoranResources\n\
_08044C90:\n\
movs r4, 0\n\
ldrb r0, [r1, 0x1]\n\
ldrb r1, [r1]\n\
lsls r1, 28\n\
lsrs r1, 28\n\
muls r0, r1\n\
adds r3, r5, 0\n\
cmp r4, r0\n\
bge _08044CC6\n\
adds r7, r3, 0\n\
movs r5, 0x80\n\
lsls r5, 4\n\
_08044CA8:\n\
ldr r2, [r7]\n\
ldr r1, [r2, 0x14]\n\
lsls r0, r4, 3\n\
adds r0, r1\n\
strh r5, [r0, 0x4]\n\
adds r0, r4, 0x1\n\
lsls r0, 24\n\
lsrs r4, r0, 24\n\
ldrb r1, [r2, 0x1]\n\
ldrb r0, [r2]\n\
lsls r0, 28\n\
lsrs r0, 28\n\
muls r0, r1\n\
cmp r4, r0\n\
blt _08044CA8\n\
_08044CC6:\n\
ldr r0, [r3]\n\
ldrb r4, [r0, 0x3]\n\
cmp r4, 0\n\
beq _08044CDA\n\
cmp r4, 0x1\n\
bne _08044CDA\n\
adds r1, r6, 0\n\
bl OakSpeechNidoranFSetupTemplate\n\
b _08044CE2\n\
_08044CDA:\n\
ldr r0, _08044D60 @ =sOakSpeechNidoranResources\n\
ldr r0, [r0]\n\
bl OakSpeechNidoranFSetupTemplateDummy\n\
_08044CE2:\n\
movs r0, 0x2\n\
mov r1, r8\n\
ands r0, r1\n\
cmp r0, 0\n\
beq _08044D12\n\
ldr r4, _08044D60 @ =sOakSpeechNidoranResources\n\
ldr r0, [r4]\n\
ldr r0, [r0, 0x14]\n\
cmp r0, 0\n\
beq _08044D00\n\
bl Free\n\
ldr r1, [r4]\n\
movs r0, 0\n\
str r0, [r1, 0x14]\n\
_08044D00:\n\
ldr r0, [r4]\n\
ldr r0, [r0, 0x10]\n\
cmp r0, 0\n\
beq _08044D12\n\
bl Free\n\
ldr r1, [r4]\n\
movs r0, 0\n\
str r0, [r1, 0x10]\n\
_08044D12:\n\
movs r0, 0x1\n\
mov r1, r8\n\
ands r0, r1\n\
cmp r0, 0\n\
beq _08044D42\n\
ldr r4, _08044D60 @ =sOakSpeechNidoranResources\n\
ldr r0, [r4]\n\
ldr r0, [r0, 0xC]\n\
cmp r0, 0\n\
beq _08044D30\n\
bl Free\n\
ldr r1, [r4]\n\
movs r0, 0\n\
str r0, [r1, 0xC]\n\
_08044D30:\n\
ldr r0, [r4]\n\
ldr r0, [r0, 0x8]\n\
cmp r0, 0\n\
beq _08044D42\n\
bl Free\n\
ldr r1, [r4]\n\
movs r0, 0\n\
str r0, [r1, 0x8]\n\
_08044D42:\n\
mov r0, r8\n\
cmp r0, 0\n\
beq _08044D64\n\
ldr r4, _08044D60 @ =sOakSpeechNidoranResources\n\
ldr r0, [r4]\n\
movs r1, 0\n\
movs r2, 0x18\n\
bl memset\n\
ldr r0, [r4]\n\
bl Free\n\
movs r0, 0\n\
str r0, [r4]\n\
b _08044D6C\n\
.align 2, 0\n\
_08044D60: .4byte sOakSpeechNidoranResources\n\
_08044D64:\n\
ldr r0, _08044D7C @ =sOakSpeechNidoranResources\n\
ldr r1, [r0]\n\
movs r0, 0xA3\n\
strb r0, [r1, 0x2]\n\
_08044D6C:\n\
ldr r0, _08044D7C @ =sOakSpeechNidoranResources\n\
ldr r0, [r0]\n\
_08044D70:\n\
pop {r3}\n\
mov r8, r3\n\
pop {r4-r7}\n\
pop {r1}\n\
bx r1\n\
.align 2, 0\n\
_08044D7C: .4byte sOakSpeechNidoranResources\n\
");
}
#endif
void OakSpeechNidoranFFreeResources(void)
{
if (sOakSpeechNidoranResources != NULL)
{
if (sOakSpeechNidoranResources->enable != 0xA3)
{
memset(sOakSpeechNidoranResources, 0, sizeof(struct OakSpeechNidoranFStruct));
sOakSpeechNidoranResources = NULL;
}
else
{
if (sOakSpeechNidoranResources->frameImages != NULL)
FREE_AND_SET_NULL(sOakSpeechNidoranResources->frameImages);
if (sOakSpeechNidoranResources->templates != NULL)
FREE_AND_SET_NULL(sOakSpeechNidoranResources->templates);
if (sOakSpeechNidoranResources->bufferPtrs != NULL)
FREE_AND_SET_NULL(sOakSpeechNidoranResources->bufferPtrs);
if (sOakSpeechNidoranResources->dataBuffer != NULL)
FREE_AND_SET_NULL(sOakSpeechNidoranResources->dataBuffer);
memset(sOakSpeechNidoranResources, 0, sizeof(struct OakSpeechNidoranFStruct));
FREE_AND_SET_NULL(sOakSpeechNidoranResources);
}
}
}
void *OakSpeechNidoranFGetBuffer(u8 bufferId)
{
if (sOakSpeechNidoranResources->enable != 0xA3)
{
return NULL;
}
else
{
if (bufferId >= (s8)sOakSpeechNidoranResources->spriteCount)
bufferId = 0;
return sOakSpeechNidoranResources->bufferPtrs[bufferId];
}
}