#include "global.h" #include "pokemon.h" #include "random.h" #include "main.h" #include "constants/species.h" #include "constants/abilities.h" #include "constants/items.h" #include "constants/trainers.h" #include "constants/moves.h" #include "string_util.h" #include "text.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) extern u8 sav1_map_get_name(void); // const rom data const struct SpindaSpot gSpindaSpotGraphics[] = { {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" const s8 gNatureStatTable[][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" // 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 = sav1_map_get_name(); 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].ability2) { value = personality & 1; SetBoxMonData(boxMon, MON_DATA_ALT_ABILITY, &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); } // This is only used to create Wally's Ralts. 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); } 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 temp; CreateMon(mon, species, level, fixedIV, 0, 0, 0, 0); temp = evSpread; for (i = 0; i < 6; i++) { if (temp & 1) statCount++; temp >>= 1; } evAmount = 510 / statCount; temp = 1; for (i = 0; i < 6; i++) { if (evSpread & temp) SetMonData(mon, MON_DATA_HP_EV + i, &evAmount); temp <<= 1; } CalculateMonStats(mon); } void sub_806819C(struct Pokemon *mon, struct UnknownPokemonStruct *src) { s32 i; u8 nickname[30]; u8 language; 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); SetMonData(mon, MON_DATA_FRIENDSHIP, &src->friendship); StringCopy(nickname, src->nickname); if (nickname[0] == EXT_CTRL_CODE_BEGIN && nickname[1] == EXT_CTRL_CODE_JPN) { language = LANGUAGE_JAPANESE; StripExtCtrlCodes(nickname); } else { language = GAME_LANGUAGE; } SetMonData(mon, MON_DATA_LANGUAGE, &language); SetMonData(mon, MON_DATA_NICKNAME, nickname); 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->altAbility; SetMonData(mon, MON_DATA_ALT_ABILITY, &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); MonRestorePP(mon); CalculateMonStats(mon); } u8 BattleFrontierGetOpponentLvl(u8); void sub_8068338(struct Pokemon *mon, struct UnknownPokemonStruct *src, bool8 lvl50) { s32 i; u8 nickname[30]; u8 level; u8 language; u8 value; if (gSaveBlock2Ptr->frontierChosenLvl != 0) level = BattleFrontierGetOpponentLvl(gSaveBlock2Ptr->frontierChosenLvl); else if (lvl50) level = 50; else level = src->level; CreateMon(mon, src->species, 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); SetMonData(mon, MON_DATA_FRIENDSHIP, &src->friendship); StringCopy(nickname, src->nickname); if (nickname[0] == EXT_CTRL_CODE_BEGIN && nickname[1] == EXT_CTRL_CODE_JPN) { language = LANGUAGE_JAPANESE; StripExtCtrlCodes(nickname); } else { language = GAME_LANGUAGE; } SetMonData(mon, MON_DATA_LANGUAGE, &language); SetMonData(mon, MON_DATA_NICKNAME, nickname); 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->altAbility; SetMonData(mon, MON_DATA_ALT_ABILITY, &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); MonRestorePP(mon); CalculateMonStats(mon); }