diff options
Diffstat (limited to 'src')
47 files changed, 9799 insertions, 227 deletions
diff --git a/src/apprentice.c b/src/apprentice.c index 5d636d05d..9cf8cd4b4 100644 --- a/src/apprentice.c +++ b/src/apprentice.c @@ -1080,7 +1080,7 @@ void ResetApprenticeStruct(struct Apprentice *apprentice) u8 i; for (i = 0; i < 6; i++) - apprentice->easyChatWords[i] |= 0xFFFF; + apprentice->easyChatWords[i] = 0xFFFF; apprentice->playerName[0] = EOS; apprentice->id = 16; @@ -1094,7 +1094,7 @@ void ResetAllApprenticeData(void) for (i = 0; i < 4; i++) { for (j = 0; j < 6; j++) - gSaveBlock2Ptr->apprentices[i].easyChatWords[j] |= 0xFFFF; + gSaveBlock2Ptr->apprentices[i].easyChatWords[j] = 0xFFFF; gSaveBlock2Ptr->apprentices[i].id = 16; gSaveBlock2Ptr->apprentices[i].playerName[0] = EOS; gSaveBlock2Ptr->apprentices[i].lvlMode = 0; diff --git a/src/battle_anim.c b/src/battle_anim.c index 7dd1526dd..1f4831c54 100644 --- a/src/battle_anim.c +++ b/src/battle_anim.c @@ -1450,7 +1450,7 @@ void ClearBattleAnimationVars(void) // Clear index array. for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++) - sAnimSpriteIndexArray[i] |= 0xFFFF; + sAnimSpriteIndexArray[i] = 0xFFFF; // Clear anim args. for (i = 0; i < ANIM_ARGS_COUNT; i++) @@ -1511,7 +1511,7 @@ void LaunchBattleAnimation(const u8 *const animsTable[], u16 tableId, bool8 isMo gAnimScriptCallback = RunAnimScriptCommand; for (i = 0; i < ANIM_SPRITE_INDEX_COUNT; i++) - sAnimSpriteIndexArray[i] |= 0xFFFF; + sAnimSpriteIndexArray[i] = 0xFFFF; if (isMoveAnim) { @@ -1572,7 +1572,7 @@ static void ClearSpriteIndex(u16 index) { if (sAnimSpriteIndexArray[i] == index) { - sAnimSpriteIndexArray[i] |= 0xFFFF; + sAnimSpriteIndexArray[i] = 0xFFFF; return; } } @@ -1779,7 +1779,7 @@ static void ScriptCmd_end(void) { FreeSpriteTilesByTag(gBattleAnimPicTable[sAnimSpriteIndexArray[i]].tag); FreeSpritePaletteByTag(gBattleAnimPicTable[sAnimSpriteIndexArray[i]].tag); - sAnimSpriteIndexArray[i] |= 0xFFFF; // set terminator. + sAnimSpriteIndexArray[i] = 0xFFFF; // set terminator. } } diff --git a/src/battle_dome.c b/src/battle_dome.c index efc69313e..b9e27675b 100644 --- a/src/battle_dome.c +++ b/src/battle_dome.c @@ -3548,7 +3548,7 @@ static void sub_8190400(u8 taskId) SetVBlankCallback(VblankCb0_BattleDome); sBattleDomeStruct = AllocZeroed(sizeof(*sBattleDomeStruct)); for (i = 0; i < DOME_TOURNAMENT_TRAINERS_COUNT; i++) - sBattleDomeStruct->arr[i] |= 0xFF; + sBattleDomeStruct->arr[i] = 0xFF; LoadMonIconPalettes(); i = CreateTask(sub_8190CD4, 0); gTasks[i].data[0] = 0; diff --git a/src/battle_factory.c b/src/battle_factory.c index 0445d5dea..5793c78e9 100644 --- a/src/battle_factory.c +++ b/src/battle_factory.c @@ -198,9 +198,9 @@ static void sub_81A5E94(void) gUnknown_03001288 = FALSE; for (i = 0; i < 6; i++) - gSaveBlock2Ptr->frontier.field_E70[i].monId |= 0xFFFF; + gSaveBlock2Ptr->frontier.field_E70[i].monId = 0xFFFF; for (i = 0; i < 3; i++) - gUnknown_03006298[i] |= 0xFFFF; + gUnknown_03006298[i] = 0xFFFF; SetDynamicWarp(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1); gTrainerBattleOpponent_A = 0; diff --git a/src/battle_main.c b/src/battle_main.c index 4e2a87beb..1aeaa25ca 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -5862,7 +5862,7 @@ static void HandleAction_NothingIsFainted(void) | HITMARKER_NO_PPDEDUCT | HITMARKER_IGNORE_SAFEGUARD | HITMARKER_IGNORE_ON_AIR | HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000 | HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT - | HITMARKER_x8000000 | HITMARKER_x4000000); + | HITMARKER_CHARGING | HITMARKER_x4000000); } static void HandleAction_ActionFinished(void) @@ -5875,7 +5875,7 @@ static void HandleAction_ActionFinished(void) | HITMARKER_NO_PPDEDUCT | HITMARKER_IGNORE_SAFEGUARD | HITMARKER_IGNORE_ON_AIR | HITMARKER_IGNORE_UNDERGROUND | HITMARKER_IGNORE_UNDERWATER | HITMARKER_x100000 | HITMARKER_OBEYS | HITMARKER_x10 | HITMARKER_SYNCHRONISE_EFFECT - | HITMARKER_x8000000 | HITMARKER_x4000000); + | HITMARKER_CHARGING | HITMARKER_x4000000); gCurrentMove = 0; gBattleMoveDamage = 0; diff --git a/src/battle_message.c b/src/battle_message.c index 112ab9630..7b8085219 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -16,6 +16,7 @@ #include "string_util.h" #include "strings.h" #include "text.h" +#include "trainer_hill.h" #include "window.h" #include "constants/battle_string_ids.h" #include "constants/items.h" @@ -41,10 +42,6 @@ extern u8 gUnknown_0203C7B4; extern const u8 gTrainerClassNames[][13]; extern const u16 gUnknown_08D85620[]; -extern u8 GetTrainerHillOpponentClass(u16 trainerId); // pokenav -extern void GetTrainerHillTrainerName(u8 *txtPtr, u16 trainerId); // pokenav -extern void CopyTrainerHillTrainerText(u8 arg0, u16 trainerId); // pokenav - // this file's functions static void ChooseMoveUsedParticle(u8 *textPtr); static void ChooseTypeOfMoveUsedString(u8 *dst); diff --git a/src/battle_pike.c b/src/battle_pike.c index a4b429bd5..c12038efb 100644 --- a/src/battle_pike.c +++ b/src/battle_pike.c @@ -1446,7 +1446,7 @@ static void sub_81A84B4(void) u8 i; for (i = 0; i < 14; i++) - gSaveBlock2Ptr->frontier.field_CB4[i] |= 0xFFFF; + gSaveBlock2Ptr->frontier.field_CB4[i] = 0xFFFF; } static void sub_81A84EC(void) diff --git a/src/battle_pyramid.c b/src/battle_pyramid.c index 2f0d35feb..c0ff1ecf5 100644 --- a/src/battle_pyramid.c +++ b/src/battle_pyramid.c @@ -1537,7 +1537,7 @@ void sub_81AA1D8(void) u8 var0, var1; for (i = 0; i < 8; i++) - gSaveBlock2Ptr->frontier.field_CB4[i] |= 0xFFFF; + gSaveBlock2Ptr->frontier.field_CB4[i] = 0xFFFF; id = sub_81AA9E4(); sub_81AA33C(&var0, &var1); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 2490d6e13..0995eec45 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -8459,7 +8459,7 @@ static u8 AttacksThisTurn(u8 battlerId, u16 move) // Note: returns 1 if it's a c || gBattleMoves[move].effect == EFFECT_SEMI_INVULNERABLE || gBattleMoves[move].effect == EFFECT_BIDE) { - if ((gHitMarker & HITMARKER_x8000000)) + if ((gHitMarker & HITMARKER_CHARGING)) return 1; } return 2; diff --git a/src/battle_setup.c b/src/battle_setup.c index 195af0c28..f5e9e3e9e 100644 --- a/src/battle_setup.c +++ b/src/battle_setup.c @@ -29,6 +29,7 @@ #include "field_message_box.h" #include "sound.h" #include "strings.h" +#include "trainer_hill.h" #include "secret_base.h" #include "string_util.h" #include "overworld.h" @@ -61,18 +62,9 @@ struct TrainerBattleParameter u8 ptrType; }; -extern bool32 InTrainerHill(void); extern void ClearPoisonStepCounter(void); extern void sub_808BCF4(void); extern void sub_80AF6F0(void); -extern u16 sub_81D6180(u8 localId); -extern bool8 GetTrainerHillTrainerFlag(u8 eventObjId); -extern bool8 sub_81D5C18(void); -extern void sub_81D639C(void); -extern void sub_81D6384(void); -extern void sub_81D61E8(void); -extern void sub_80982B8(void); -extern void CopyTrainerHillTrainerText(u8 a0, u16 arg1); // this file's functions static void DoBattlePikeWildBattle(void); @@ -1148,12 +1140,12 @@ const u8 *BattleSetup_ConfigureTrainerBattle(const u8 *data) { TrainerBattleLoadArgs(sOrdinaryBattleParams, data); SetMapVarsToTrainer(); - gTrainerBattleOpponent_A = sub_81D6180(gSpecialVar_LastTalked); + gTrainerBattleOpponent_A = LocalIdToHillTrainerId(gSpecialVar_LastTalked); } else { TrainerBattleLoadArgs(sTrainerBOrdinaryBattleParams, data); - gTrainerBattleOpponent_B = sub_81D6180(gSpecialVar_LastTalked); + gTrainerBattleOpponent_B = LocalIdToHillTrainerId(gSpecialVar_LastTalked); } return EventScript_TryDoNormalTrainerBattle; default: @@ -1215,7 +1207,7 @@ bool8 GetTrainerFlag(void) if (InBattlePyramid()) return GetBattlePyramidTrainerFlag(gSelectedEventObject); else if (InTrainerHill()) - return GetTrainerHillTrainerFlag(gSelectedEventObject); + return GetHillTrainerFlag(gSelectedEventObject); else return FlagGet(GetTrainerAFlag()); } @@ -1281,11 +1273,11 @@ void BattleSetup_StartTrainerBattle(void) gBattleTypeFlags |= BATTLE_TYPE_TRAINER_HILL; if (gNoOfApproachingTrainers == 2) - sub_81D639C(); + FillHillTrainersParties(); else - sub_81D6384(); + FillHillTrainerParty(); - sub_81D61E8(); + SetHillTrainerFlag(); } sNoOfPossibleTrainerRetScripts = gNoOfApproachingTrainers; @@ -1367,9 +1359,9 @@ void ShowTrainerIntroSpeech(void) else if (sub_81D5C18()) { if (gNoOfApproachingTrainers == 0 || gNoOfApproachingTrainers == 1) - CopyTrainerHillTrainerText(2, sub_81D6180(gSpecialVar_LastTalked)); + CopyTrainerHillTrainerText(2, LocalIdToHillTrainerId(gSpecialVar_LastTalked)); else - CopyTrainerHillTrainerText(2, sub_81D6180(gEventObjects[gApproachingTrainers[gApproachingTrainerId].eventObjectId].localId)); + CopyTrainerHillTrainerText(2, LocalIdToHillTrainerId(gEventObjects[gApproachingTrainers[gApproachingTrainerId].eventObjectId].localId)); sub_80982B8(); } diff --git a/src/battle_tower.c b/src/battle_tower.c index deb5acb2e..088ef7972 100644 --- a/src/battle_tower.c +++ b/src/battle_tower.c @@ -1888,7 +1888,7 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) else if (trainerId == TRAINER_EREADER) { for (i = firstMonId; i < firstMonId + 3; i++) - sub_806819C(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i - firstMonId]); + CreateBattleTowerMon(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i - firstMonId]); return; } else if (trainerId == TRAINER_FRONTIER_BRAIN) @@ -1904,7 +1904,7 @@ static void FillTrainerParty(u16 trainerId, u8 firstMonId, u8 monCount) if (gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[j].species != 0 && gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[j].level <= level) { - sub_8068338(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[j], FALSE); + CreateBattleTowerMon2(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.towerRecords[trainerId - TRAINER_RECORD_MIXING_FRIEND].party[j], FALSE); } } return; @@ -2075,7 +2075,7 @@ static void FillFactoryFrontierTrainerParty(u16 trainerId, u8 firstMonId) else if (trainerId == TRAINER_EREADER) { for (i = firstMonId; i < firstMonId + 3; i++) - sub_806819C(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i - firstMonId]); + CreateBattleTowerMon(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i - firstMonId]); return; } else if (trainerId == TRAINER_FRONTIER_BRAIN) @@ -2276,7 +2276,7 @@ void DoSpecialTrainerBattle(void) case SPECIAL_BATTLE_EREADER: ZeroEnemyPartyMons(); for (i = 0; i < 3; i++) - sub_806819C(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i]); + CreateBattleTowerMon(&gEnemyParty[i], &gSaveBlock2Ptr->frontier.ereaderTrainer.party[i]); gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_EREADER_TRAINER; gTrainerBattleOpponent_A = 0; CreateTask(Task_StartBattleAfterTransition, 1); @@ -3258,7 +3258,7 @@ static void FillPartnerParty(u16 trainerId) if (monData.nickname[0] == EXT_CTRL_CODE_BEGIN && monData.nickname[1] == EXT_CTRL_CODE_JPN) trainerName[5] = EOS; } - sub_8068338(&gPlayerParty[3 + i], &monData, TRUE); + CreateBattleTowerMon2(&gPlayerParty[3 + i], &monData, TRUE); SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_NAME, trainerName); j = IsFrontierTrainerFemale(trainerId + TRAINER_RECORD_MIXING_FRIEND); SetMonData(&gPlayerParty[3 + i], MON_DATA_OT_GENDER, &j); @@ -3663,7 +3663,7 @@ static void FillTentTrainerParty_(u16 trainerId, u8 firstMonId, u8 monCount) } } -u8 sub_81660B8(u8 facilityClass) +u8 FacilityClassToGraphicsId(u8 facilityClass) { u8 trainerObjectGfxId; u8 i; diff --git a/src/battle_util2.c b/src/battle_util2.c index 0a0f65b95..9c0d55a57 100644 --- a/src/battle_util2.c +++ b/src/battle_util2.c @@ -3,21 +3,19 @@ #include "battle_controllers.h" #include "alloc.h" #include "pokemon.h" +#include "trainer_hill.h" #include "party_menu.h" #include "event_data.h" #include "constants/abilities.h" #include "random.h" #include "battle_scripts.h" -extern void sub_81D55D0(void); -extern void sub_81D5694(void); - void AllocateBattleResources(void) { gBattleResources = gBattleResources; // something dumb needed to match if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_HILL) - sub_81D55D0(); + InitTrainerHillBattleStruct(); gBattleStruct = AllocZeroed(sizeof(*gBattleStruct)); @@ -47,7 +45,7 @@ void AllocateBattleResources(void) void FreeBattleResources(void) { if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_HILL) - sub_81D5694(); + FreeTrainerHillBattleStruct(); if (gBattleResources != NULL) { @@ -246,7 +246,7 @@ void SetTextModeAndHideBgs(void) SetGpuReg(REG_OFFSET_DISPCNT, GetGpuReg(REG_OFFSET_DISPCNT) & ~DISPCNT_ALL_BG_AND_MODE_BITS); } -static void SetBgAffineInternal(u8 bg, u32 srcCenterX, u32 srcCenterY, s16 dispCenterX, s16 dispCenterY, s16 scaleX, s16 scaleY, u16 rotationAngle) +static void SetBgAffineInternal(u8 bg, s32 srcCenterX, s32 srcCenterY, s16 dispCenterX, s16 dispCenterY, s16 scaleX, s16 scaleY, u16 rotationAngle) { struct BgAffineSrcData src; struct BgAffineDstData dest; @@ -777,7 +777,7 @@ s32 GetBgY(u8 bg) return sGpuBgConfigs2[bg].bg_y; } -void SetBgAffine(u8 bg, u32 srcCenterX, u32 srcCenterY, s16 dispCenterX, s16 dispCenterY, s16 scaleX, s16 scaleY, u16 rotationAngle) +void SetBgAffine(u8 bg, s32 srcCenterX, s32 srcCenterY, s16 dispCenterX, s16 dispCenterY, s16 scaleX, s16 scaleY, u16 rotationAngle) { SetBgAffineInternal(bg, srcCenterX, srcCenterY, dispCenterX, dispCenterY, scaleX, scaleY, rotationAngle); } diff --git a/src/cable_club.c b/src/cable_club.c index 784426d53..ce9b9db05 100644 --- a/src/cable_club.c +++ b/src/cable_club.c @@ -498,7 +498,7 @@ static void sub_80B2C30(u8 taskId) for (index = 0; index < GetLinkPlayerCount(); index++) { - sub_80C3120(&gTrainerCards[index], gBlockRecvBuffer[index], gLinkPlayers[index].version); + CopyTrainerCardData(&gTrainerCards[index], gBlockRecvBuffer[index], gLinkPlayers[index].version); } SetSuppressLinkErrorMessage(FALSE); @@ -1176,7 +1176,7 @@ static void sub_80B39A4(void) void sp02A_crash_sound(void) { - TrainerCard_ShowLinkCard(gSpecialVar_0x8006, CB2_ReturnToFieldContinueScriptPlayMapMusic); + ShowTrainerCardInLink(gSpecialVar_0x8006, CB2_ReturnToFieldContinueScriptPlayMapMusic); } bool32 sub_80B39D4(u8 linkPlayerIndex) diff --git a/src/data/battle_frontier/trainer_hill.h b/src/data/battle_frontier/trainer_hill.h new file mode 100644 index 000000000..ca0d623e9 --- /dev/null +++ b/src/data/battle_frontier/trainer_hill.h @@ -0,0 +1,4857 @@ +#define TRAINER_HILL_OTID 0x10000000 + +static const struct TrHillTag sDataTagNormal = +{ + .unkField_0 = 8, + .unused1 = 2, + .unkField_2 = 4, + .unused3 = 0, + .unused4 = 5, + .unused5 = 30, + .unused6 = 5, + .floors = + { + [0] = + { + .unk0 = 0x11, + .unk1 = 0x12, + .trainers = + { + [0] = + { + .name = _("ALAINA"), + .facilityClass = FACILITY_CLASS_HEX_MANIAC, + .unused = 0, + .speechBefore = {EC_WORD_YOU, EC_WORD_CAN, EC_WORD_CHOOSE, EC_WORD_NOT, EC_WORD_TO, EC_WORD_BELIEVE}, + .speechWin = {EC_WORD_A, EC_WORD_SUPER, EC_WORD_NATURAL, EC_WORD_POWER, EC_WORD_HAS, EC_WORD_COME}, + .speechLose = {EC_WORD_THIS, EC_WORD_MUST_BE, EC_WORD_A, EC_MOVE(NIGHTMARE), EC_WORD_EXCL, 0xFFFF}, + .speechAfter = {EC_WORD_I, EC_WORD_WILL, EC_WORD_DISAPPEAR, EC_WORD_IN, EC_WORD_THE, EC_WORD_DARK}, + .mons = + { + [0] = + { + .species = SPECIES_MISDREAVUS, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_SHADOW_BALL, MOVE_PSYCHIC, MOVE_THUNDERBOLT, MOVE_CONFUSE_RAY}, + .level = 0, + .ppBonuses = 0, + .attackEV = 155, + .speedEV = 255, + .spAttackEV = 100, + .otId = TRAINER_HILL_OTID, + .hpIV = 24, + .attackIV = 24, + .defenseIV = 24, + .speedIV = 24, + .spAttackIV = 24, + .spDefenseIV = 24, + .altAbility = 0, + .personality = 0x0, + .nickname = _("MISDREAVUS"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_SOLROCK, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_PSYCHIC, MOVE_FLAMETHROWER, MOVE_ROCK_SLIDE, MOVE_CALM_MIND}, + .level = 0, + .ppBonuses = 0, + .hpEV = 200, + .defenseEV = 100, + .spAttackEV = 110, + .spDefenseEV = 100, + .otId = TRAINER_HILL_OTID, + .hpIV = 24, + .attackIV = 24, + .defenseIV = 24, + .speedIV = 24, + .spAttackIV = 24, + .spDefenseIV = 24, + .altAbility = 0, + .personality = 0xF, + .nickname = _("SOLROCK"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_CLAYDOL, + .heldItem = ITEM_SHELL_BELL, + .moves = {MOVE_EARTHQUAKE, MOVE_PSYCHIC, MOVE_SHADOW_BALL, MOVE_ICE_BEAM}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .defenseEV = 135, + .spDefenseEV = 120, + .otId = TRAINER_HILL_OTID, + .hpIV = 24, + .attackIV = 24, + .defenseIV = 24, + .speedIV = 24, + .spAttackIV = 24, + .spDefenseIV = 24, + .altAbility = 0, + .personality = 0xC, + .nickname = _("CLAYDOL"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_WEEZING, + .heldItem = ITEM_SALAC_BERRY, + .moves = {MOVE_SLUDGE_BOMB, MOVE_SHADOW_BALL, MOVE_FRUSTRATION, MOVE_DESTINY_BOND}, + .level = 0, + .ppBonuses = 0, + .hpEV = 110, + .attackEV = 200, + .spDefenseEV = 200, + .otId = TRAINER_HILL_OTID, + .hpIV = 24, + .attackIV = 24, + .defenseIV = 24, + .speedIV = 24, + .spAttackIV = 24, + .spDefenseIV = 24, + .altAbility = 0, + .personality = 0x80, + .nickname = _("WEEZING"), + .friendship = 0, + }, + [4] = + { + .species = SPECIES_LUNATONE, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_PSYCHIC, MOVE_ICE_BEAM, MOVE_ROCK_SLIDE, MOVE_CALM_MIND}, + .level = 0, + .ppBonuses = 0, + .hpEV = 200, + .defenseEV = 100, + .spAttackEV = 110, + .spDefenseEV = 100, + .otId = TRAINER_HILL_OTID, + .hpIV = 24, + .attackIV = 24, + .defenseIV = 24, + .speedIV = 24, + .spAttackIV = 24, + .spDefenseIV = 24, + .altAbility = 0, + .personality = 0xF, + .nickname = _("LUNATONE"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_FLYGON, + .heldItem = ITEM_CHOICE_BAND, + .moves = {MOVE_EARTHQUAKE, MOVE_DRAGON_CLAW, MOVE_CRUNCH, MOVE_FLAMETHROWER}, + .level = 0, + .ppBonuses = 0, + .attackEV = 155, + .speedEV = 255, + .spAttackEV = 100, + .otId = TRAINER_HILL_OTID, + .hpIV = 24, + .attackIV = 24, + .defenseIV = 24, + .speedIV = 24, + .spAttackIV = 24, + .spDefenseIV = 24, + .altAbility = 0, + .personality = 0x83, + .nickname = _("FLYGON"), + .friendship = 255, + }, + }, + }, + [1] = + { + .name = _("ALFONSO"), + .facilityClass = FACILITY_CLASS_CYCLING_TRIATHLETE_M, + .unused = 0, + .speechBefore = {EC_WORD_I, EC_WORD_NEVER, EC_WORD_TAKE, EC_WORD_A, EC_WORD_TRAIN, 0xFFFF}, + .speechWin = {EC_WORD_I_AM, EC_WORD_FEELING, EC_MOVE2(SUPERSONIC), EC_WORD_ON, EC_WORD_MY, EC_WORD_BIKE}, + .speechLose = {EC_WORD_MY, EC_WORD_BIKE, EC_WORD_EXCL, EC_WORD_YOU_VE, EC_WORD_DESTROYED, EC_WORD_IT}, + .speechAfter = {EC_WORD_A, EC_WORD_BIKE, EC_WORD_OVER, EC_WORD_ANY, EC_WORD_TRAIN, EC_WORD_EXCL}, + .mons = + { + [0] = + { + .species = SPECIES_SEALEO, + .heldItem = ITEM_NEVER_MELT_ICE, + .moves = {MOVE_BLIZZARD, MOVE_ICE_BALL, MOVE_ENCORE, MOVE_HAIL}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xF, + .nickname = _("SEALEO"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_AMPHAROS, + .heldItem = ITEM_MAGNET, + .moves = {MOVE_THUNDER, MOVE_THUNDER_WAVE, MOVE_COTTON_SPORE, MOVE_LIGHT_SCREEN}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xF, + .nickname = _("AMPHAROS"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_MACHOKE, + .heldItem = ITEM_BLACK_BELT, + .moves = {MOVE_DYNAMIC_PUNCH, MOVE_MUD_SLAP, MOVE_COUNTER, MOVE_SCARY_FACE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .attackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x4E, + .nickname = _("MACHOKE"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_FLAREON, + .heldItem = ITEM_CHARCOAL, + .moves = {MOVE_FIRE_BLAST, MOVE_BITE, MOVE_QUICK_ATTACK, MOVE_SAND_ATTACK}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x28, + .nickname = _("FLAREON"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_MAGNETON, + .heldItem = ITEM_MAGNET, + .moves = {MOVE_ZAP_CANNON, MOVE_THUNDER_WAVE, MOVE_SCREECH, MOVE_METAL_SOUND}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x0, + .nickname = _("MAGNETON"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_PINSIR, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_GUILLOTINE, MOVE_BRICK_BREAK, MOVE_SWAGGER, MOVE_FAINT_ATTACK}, + .level = 0, + .ppBonuses = 0, + .hpEV = 200, + .defenseEV = 155, + .spDefenseEV = 155, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x85, + .nickname = _("PINSIR"), + .friendship = 255, + }, + }, + }, + }, + .data = {0x31, 0x3B, 0x35, 0x35, 0x26, 0x26, 0x1B, 0x1C, 0x1D, 0x25, 0x26, 0x3A, 0x3B, 0x35, 0x3B, 0x8, 0x31, 0x3B, 0x2C, 0x2C, 0x2C, 0x2B, 0x24, 0x24, 0x24, 0x24, 0x2C, 0x3B, 0x3B, 0x2C, 0x3B, 0x8, 0x2D, 0x3B, 0x3B, 0x3B, 0x3B, 0x2B, 0x3B, 0x3B, 0x3B, 0x3B, 0x35, 0x3B, 0x35, 0x35, 0x3B, 0x8, 0x33, 0x3B, 0x32, 0x21, 0x30, 0x2B, 0x3B, 0x32, 0x21, 0x30, 0x2B, 0x3B, 0x2C, 0x2B, 0x3B, 0x8, 0x33, 0x35, 0x3B, 0x3B, 0x3B, 0x2C, 0x35, 0x3B, 0x3B, 0x3B, 0x2B, 0x3B, 0x3B, 0x2B, 0x3B, 0x8, 0x34, 0x2C, 0x3B, 0x32, 0x21, 0x30, 0x2B, 0x32, 0x30, 0x3B, 0x2B, 0x32, 0x30, 0x2C, 0x3B, 0x8, 0x31, 0x35, 0x3B, 0x3B, 0x35, 0x3B, 0x2C, 0x3B, 0x3B, 0x35, 0x2C, 0x3B, 0x3B, 0x35, 0x35, 0x8, 0x31, 0x2C, 0x32, 0x30, 0x2B, 0x32, 0x30, 0x35, 0x3B, 0x2B, 0x32, 0x21, 0x30, 0x2C, 0x2C, 0x8, 0x31, 0x35, 0x3B, 0x3B, 0x2B, 0x3B, 0x3B, 0x2B, 0x3B, 0x2C, 0x3B, 0x35, 0x3B, 0x3B, 0x3B, 0x8, 0x31, 0x2C, 0x32, 0x30, 0x2B, 0x32, 0x30, 0x2B, 0x3B, 0x32, 0x30, 0x2B, 0x32, 0x30, 0x3B, 0x8, 0x31, 0x35, 0x35, 0x35, 0x2B, 0x3B, 0x3B, 0x2B, 0x3B, 0x3B, 0x35, 0x2B, 0x3B, 0x35, 0x35, 0x8, 0x31, 0x2B, 0x2C, 0x2C, 0x2C, 0x32, 0x30, 0x2B, 0x32, 0x30, 0x2C, 0x2C, 0x3B, 0x2C, 0x2C, 0x8, 0x31, 0x2B, 0x3B, 0x3B, 0x35, 0x3B, 0x3B, 0x2B, 0x3B, 0x3B, 0x35, 0x3B, 0x3B, 0x3B, 0x3B, 0x8, 0x31, 0x2C, 0x32, 0x30, 0x2B, 0x3B, 0x3B, 0x2C, 0x32, 0x30, 0x2C, 0x32, 0x30, 0x3B, 0x35, 0x8, 0x31, 0x3B, 0x3B, 0x3B, 0x2C, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x2C, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8}, + .unk3A0 = {0x381, 0x3FE5, 0x401, 0xBDED, 0x8425, 0xDFBD, 0x221, 0x7E7F, 0x941, 0x7F7D, 0x911, 0x7FF7, 0x4101, 0x79F9, 0x803, 0xFFFF}, + .coords = {27, 45}, + .direction = 0x21, + .range = 0x21, + }, + [1] = + { + .unk0 = 0x13, + .unk1 = 0x14, + .trainers = + { + [0] = + { + .name = _("THEODORE"), + .facilityClass = FACILITY_CLASS_BLACK_BELT, + .unused = 0, + .speechBefore = {EC_WORD_MY, EC_WORD_POWER, EC_WORD_WILL, EC_MOVE2(STOMP), EC_WORD_YOU, EC_WORD_EXCL}, + .speechWin = {EC_WORD_WAAAH, EC_WORD_HAHAHA, EC_WORD_EXCL, EC_WORD_WAAAH, EC_WORD_HAHAHA, EC_WORD_EXCL_EXCL}, + .speechLose = {EC_WORD_I, EC_WORD_WENT, EC_WORD_AT, EC_WORD_IT, EC_WORD_TOO, EC_WORD_HARD}, + .speechAfter = {EC_WORD_YES_SIR_EXCL, EC_WORD_YOU, EC_WORD_LOOK, EC_WORD_NICE, EC_WORD_AND, EC_WORD_GUTSY}, + .mons = + { + [0] = + { + .species = SPECIES_MEDITITE, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_FOCUS_PUNCH, MOVE_PROTECT, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 20, + .attackIV = 20, + .defenseIV = 20, + .speedIV = 20, + .spAttackIV = 20, + .spDefenseIV = 20, + .altAbility = 0, + .personality = 0x80, + .nickname = _("MEDITITE"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_HERACROSS, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_FOCUS_PUNCH, MOVE_PROTECT, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 20, + .attackIV = 20, + .defenseIV = 20, + .speedIV = 20, + .spAttackIV = 20, + .spDefenseIV = 20, + .altAbility = 1, + .personality = 0x80, + .nickname = _("HERACROSS"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_HITMONTOP, + .heldItem = ITEM_SHELL_BELL, + .moves = {MOVE_FOCUS_PUNCH, MOVE_PROTECT, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 20, + .attackIV = 20, + .defenseIV = 20, + .speedIV = 20, + .spAttackIV = 20, + .spDefenseIV = 20, + .altAbility = 0, + .personality = 0x3, + .nickname = _("HITMONTOP"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_MACHOP, + .heldItem = ITEM_SALAC_BERRY, + .moves = {MOVE_FOCUS_PUNCH, MOVE_REVENGE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 20, + .attackIV = 20, + .defenseIV = 20, + .speedIV = 20, + .spAttackIV = 20, + .spDefenseIV = 20, + .altAbility = 0, + .personality = 0x4E, + .nickname = _("MACHOP"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_PINSIR, + .heldItem = ITEM_SALAC_BERRY, + .moves = {MOVE_FOCUS_PUNCH, MOVE_REVENGE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 20, + .attackIV = 20, + .defenseIV = 20, + .speedIV = 20, + .spAttackIV = 20, + .spDefenseIV = 20, + .altAbility = 0, + .personality = 0x80, + .nickname = _("PINSIR"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_HITMONCHAN, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_FOCUS_PUNCH, MOVE_REVENGE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 20, + .attackIV = 20, + .defenseIV = 20, + .speedIV = 20, + .spAttackIV = 20, + .spDefenseIV = 20, + .altAbility = 0, + .personality = 0x3, + .nickname = _("HITMONCHAN"), + .friendship = 255, + }, + }, + }, + [1] = + { + .name = _("JAYDEN"), + .facilityClass = FACILITY_CLASS_POKEMON_BREEDER_F, + .unused = 0, + .speechBefore = {EC_WORD_SOME, EC_WORD_THINGS, EC_WORD_YOU, EC_WORD_CAN_T, EC_WORD_DO, EC_WORD_ALONE}, + .speechWin = {EC_WORD_YOU, EC_WORD_WIN, EC_WORD_AS, EC_WORD_A, EC_WORD_GROUP, 0xFFFF}, + .speechLose = {EC_WORD_WE, EC_WORD_COULDN_T, EC_WORD_WIN, EC_WORD_TOGETHER, EC_WORD_QUES, 0xFFFF}, + .speechAfter = {EC_WORD_MAYBE, EC_WORD_I, EC_WORD_NEED, EC_WORD_A, EC_WORD_BOY, EC_WORD_FRIEND}, + .mons = + { + [0] = + { + .species = SPECIES_VULPIX, + .heldItem = ITEM_LUM_BERRY, + .moves = {MOVE_WILL_O_WISP, MOVE_CONFUSE_RAY, MOVE_TAIL_WHIP, MOVE_OVERHEAT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xF, + .nickname = _("VULPIX"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_MINUN, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_THUNDER_WAVE, MOVE_CHARM, MOVE_ENCORE, MOVE_SPARK}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 252, + .spAttackEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x8C, + .nickname = _("MINUN"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_ROSELIA, + .heldItem = ITEM_LUM_BERRY, + .moves = {MOVE_TOXIC, MOVE_LEECH_SEED, MOVE_SWEET_SCENT, MOVE_GIGA_DRAIN}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 252, + .spAttackEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0xF, + .nickname = _("ROSELIA"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_MR_MIME, + .heldItem = ITEM_SITRUS_BERRY, + .moves = {MOVE_SAFEGUARD, MOVE_REFLECT, MOVE_LIGHT_SCREEN, MOVE_PSYCHIC}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x82, + .nickname = _("MR. MIME"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_PLUSLE, + .heldItem = ITEM_SITRUS_BERRY, + .moves = {MOVE_RAIN_DANCE, MOVE_LIGHT_SCREEN, MOVE_HELPING_HAND, MOVE_THUNDER}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x5, + .nickname = _("PLUSLE"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_TOGEPI, + .heldItem = ITEM_SITRUS_BERRY, + .moves = {MOVE_LIGHT_SCREEN, MOVE_REFLECT, MOVE_FOLLOW_ME, MOVE_METRONOME}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0x37, + .nickname = _("TOGEPI"), + .friendship = 255, + }, + }, + }, + }, + .data = {0xD1, 0xD5, 0xD5, 0xD5, 0xD9, 0xD9, 0x1B, 0x1C, 0x1D, 0xC5, 0xC6, 0xCE, 0xD5, 0xDB, 0xD5, 0x8, 0xD1, 0xCB, 0xC4, 0xC4, 0xDB, 0xDB, 0xC4, 0xC4, 0xC4, 0xCC, 0xCC, 0xCC, 0xCB, 0xDB, 0xCB, 0x8, 0xD1, 0xCB, 0xDB, 0xDB, 0x17, 0x17, 0x17, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCB, 0xDB, 0xCB, 0x8, 0xD1, 0xCB, 0xDB, 0xD5, 0x17, 0x17, 0x17, 0xD5, 0xD5, 0xD5, 0xD5, 0xDF, 0xCB, 0xDB, 0xCB, 0x8, 0xD1, 0xCB, 0xDB, 0xCB, 0x17, 0x17, 0x1F, 0xCB, 0xCB, 0xC4, 0xC4, 0xDB, 0xCB, 0xDB, 0xCB, 0x8, 0xD1, 0xCB, 0xDB, 0xCB, 0xDB, 0xDB, 0xC4, 0xCB, 0xCB, 0xDF, 0xD5, 0xD5, 0xCB, 0xDB, 0xCB, 0x8, 0xD1, 0xCB, 0xDB, 0xCB, 0xDB, 0xDB, 0xDB, 0xCB, 0xCB, 0xDB, 0xC4, 0xC4, 0xCB, 0xDB, 0xCB, 0x8, 0xD1, 0xCB, 0xDB, 0xCB, 0xDB, 0xDB, 0xDB, 0xCB, 0xCB, 0xD5, 0xD5, 0xDF, 0xCB, 0xDB, 0xCB, 0x8, 0xD1, 0xCB, 0xDB, 0xCB, 0xDB, 0xDB, 0xDB, 0xCB, 0xCB, 0xC4, 0xC4, 0xDB, 0xCB, 0xDB, 0xCB, 0x8, 0xD1, 0xCB, 0xDB, 0xCB, 0xDB, 0xDB, 0xDB, 0xCB, 0xCB, 0xDF, 0xD5, 0xD5, 0xCB, 0xDB, 0xCB, 0x8, 0xD1, 0xCB, 0xDB, 0xCB, 0xDB, 0xDB, 0xDB, 0xC4, 0xC4, 0xDB, 0xC4, 0xC4, 0xC4, 0xDB, 0xCB, 0x8, 0xD1, 0xCB, 0xDB, 0xCB, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0xDB, 0xD5, 0xD5, 0xD5, 0xCB, 0x8, 0xD1, 0xC4, 0xDB, 0xCB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x9B, 0xDB, 0xCB, 0xCB, 0xCB, 0xCB, 0x8, 0xD1, 0xDB, 0xDB, 0xCB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x9B, 0xDB, 0xCB, 0xCB, 0xCB, 0xCB, 0x8, 0xD1, 0xDB, 0xDB, 0xC4, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x9B, 0xDB, 0xC4, 0xC4, 0xC4, 0xC4, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8}, + .unk3A0 = {0x381, 0x73FB, 0x400B, 0x400B, 0x51EB, 0x538B, 0x51BB, 0x518B, 0x51EB, 0x518B, 0x51BB, 0x5003, 0x501F, 0x101F, 0x101F, 0xFFFF}, + .coords = {180, 233}, + .direction = 0x3, + .range = 0x35, + }, + [2] = + { + .unk0 = 0x15, + .unk1 = 0x16, + .trainers = + { + [0] = + { + .name = _("SALVADORE"), + .facilityClass = FACILITY_CLASS_PKMN_BREEDER_M, + .unused = 0, + .speechBefore = {EC_WORD_LET_S, EC_MOVE2(WRAP), EC_WORD_THINGS, EC_WORD_UP, EC_WORD_HERE, EC_WORD_HEY_QUES}, + .speechWin = {EC_WORD_WOULD, EC_WORD_YOU, EC_WORD_LIKE, EC_WORD_TO, EC_WORD_GO_HOME, EC_WORD_QUES}, + .speechLose = {EC_WORD_I, EC_WORD_WILL, EC_WORD_MAKE, EC_WORD_YOU, EC_WORD_SORRY, EC_WORD_FRIEND}, + .speechAfter = {EC_WORD_HAVEN_T, EC_WORD_YOU, EC_WORD_DONE, EC_WORD_ENOUGH, EC_WORD_QUES, 0xFFFF}, + .mons = + { + [0] = + { + .species = SPECIES_VAPOREON, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_HAZE, MOVE_HELPING_HAND, MOVE_TICKLE, MOVE_WATER_PULSE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 250, + .defenseEV = 130, + .spDefenseEV = 130, + .otId = TRAINER_HILL_OTID, + .hpIV = 20, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x37, + .nickname = _("VAPOREON"), + .friendship = 0, + }, + [1] = + { + .species = SPECIES_DODRIO, + .heldItem = ITEM_KINGS_ROCK, + .moves = {MOVE_HAZE, MOVE_TRI_ATTACK, MOVE_TAUNT, MOVE_TORMENT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 20, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0x8A, + .nickname = _("DODRIO"), + .friendship = 0, + }, + [2] = + { + .species = SPECIES_OMASTAR, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_HAZE, MOVE_HYDRO_PUMP, MOVE_TICKLE, MOVE_ATTRACT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 250, + .defenseEV = 130, + .spDefenseEV = 130, + .otId = TRAINER_HILL_OTID, + .hpIV = 20, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x14, + .nickname = _("OMASTAR"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_LICKITUNG, + .heldItem = ITEM_CHESTO_BERRY, + .moves = {MOVE_BELLY_DRUM, MOVE_REST, MOVE_MUD_SLAP, MOVE_SWAGGER}, + .level = 0, + .ppBonuses = 0, + .hpEV = 250, + .defenseEV = 130, + .spDefenseEV = 130, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x8, + .nickname = _("LICKITUNG"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_SLOWBRO, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_BELLY_DRUM, MOVE_MUD_SLAP, MOVE_SWAGGER, MOVE_AMNESIA}, + .level = 0, + .ppBonuses = 0, + .hpEV = 250, + .defenseEV = 130, + .spDefenseEV = 130, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0x94, + .nickname = _("SLOWBRO"), + .friendship = 0, + }, + [5] = + { + .species = SPECIES_LINOONE, + .heldItem = ITEM_LUM_BERRY, + .moves = {MOVE_BELLY_DRUM, MOVE_REST, MOVE_MUD_SLAP, MOVE_SWAGGER}, + .level = 0, + .ppBonuses = 0, + .hpEV = 250, + .defenseEV = 130, + .spDefenseEV = 130, + .otId = TRAINER_HILL_OTID, + .hpIV = 20, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x8, + .nickname = _("LINOONE"), + .friendship = 255, + }, + }, + }, + [1] = + { + .name = _("VERONICA"), + .facilityClass = FACILITY_CLASS_POKEMON_BREEDER_F, + .unused = 0, + .speechBefore = {EC_WORD_I_AM, EC_WORD_THE, EC_WORD_STRONG, EC_WORD_BEAUTY, EC_WORD_AROUND, EC_WORD_HERE}, + .speechWin = {EC_WORD_I_AM, EC_WORD_STRONG, EC_WORD_THAT_S, EC_WORD_WHY, EC_WORD_EXCL, 0xFFFF}, + .speechLose = {EC_WORD_I_AM, EC_WORD_TIRED, EC_WORD_TODAY, EC_WORD_THAT_S, EC_WORD_WHY, EC_WORD_EXCL}, + .speechAfter = {EC_WORD_WHY, EC_WORD_YES, EC_WORD_I_AM, EC_WORD_ANGRY, EC_WORD_THANK_YOU, EC_WORD_EXCL}, + .mons = + { + [0] = + { + .species = SPECIES_SKITTY, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_PSYCH_UP, MOVE_DOUBLE_EDGE, MOVE_SHADOW_BALL, MOVE_IRON_TAIL}, + .level = 0, + .ppBonuses = 0, + .attackEV = 252, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0xCB, + .nickname = _("SKITTY"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_MEDICHAM, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_PSYCH_UP, MOVE_HI_JUMP_KICK, MOVE_MEGA_KICK, MOVE_ROCK_SLIDE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 6, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xD, + .nickname = _("MEDICHAM"), + .friendship = 0, + }, + [2] = + { + .species = SPECIES_STANTLER, + .heldItem = ITEM_SHELL_BELL, + .moves = {MOVE_PSYCH_UP, MOVE_RETURN, MOVE_EARTHQUAKE, MOVE_SHADOW_BALL}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .speedEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x3, + .nickname = _("STANTLER"), + .friendship = 0, + }, + [3] = + { + .species = SPECIES_NIDOQUEEN, + .heldItem = ITEM_SALAC_BERRY, + .moves = {MOVE_SUPERPOWER, MOVE_BITE, MOVE_CHARM, MOVE_FLATTER}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 20, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x3, + .nickname = _("NIDOQUEEN"), + .friendship = 0, + }, + [4] = + { + .species = SPECIES_NINETALES, + .heldItem = ITEM_SALAC_BERRY, + .moves = {MOVE_OVERHEAT, MOVE_QUICK_ATTACK, MOVE_SPITE, MOVE_TAIL_WHIP}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xD7, + .nickname = _("NINETALES"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_CHARIZARD, + .heldItem = ITEM_SALAC_BERRY, + .moves = {MOVE_OVERHEAT, MOVE_BEAT_UP, MOVE_SCARY_FACE, MOVE_GROWL}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x28, + .nickname = _("CHARIZARD"), + .friendship = 255, + }, + }, + }, + }, + .data = {0x31, 0x35, 0x35, 0x35, 0x26, 0x26, 0x13, 0x14, 0x15, 0x38, 0x26, 0x2E, 0x35, 0x35, 0x3B, 0x8, 0x69, 0x63, 0x64, 0x64, 0x64, 0x64, 0x71, 0x71, 0x71, 0x72, 0x64, 0x64, 0x64, 0x63, 0x73, 0x8, 0x69, 0x63, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x63, 0x73, 0x8, 0x69, 0x63, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x63, 0x73, 0x8, 0x69, 0x63, 0x43, 0x41, 0x40, 0x41, 0x42, 0x41, 0x41, 0x4A, 0x42, 0x41, 0x41, 0x63, 0x73, 0x8, 0x69, 0x63, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x64, 0x73, 0x73, 0x73, 0x63, 0x73, 0x8, 0x69, 0x63, 0x41, 0x43, 0x4B, 0x43, 0x43, 0x41, 0x42, 0x42, 0x40, 0x41, 0x40, 0x63, 0x73, 0x8, 0x69, 0x63, 0x73, 0x73, 0x64, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x63, 0x73, 0x8, 0x69, 0x63, 0x41, 0x40, 0x42, 0x42, 0x41, 0x41, 0x42, 0x4A, 0x42, 0x41, 0x42, 0x63, 0x73, 0x8, 0x69, 0x63, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x64, 0x73, 0x73, 0x73, 0x63, 0x73, 0x8, 0x69, 0x63, 0x41, 0x42, 0x41, 0x43, 0x4B, 0x41, 0x41, 0x41, 0x40, 0x43, 0x41, 0x63, 0x73, 0x8, 0x69, 0x63, 0x73, 0x73, 0x73, 0x73, 0x64, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x63, 0x73, 0x8, 0x69, 0x63, 0x41, 0x40, 0x43, 0x41, 0x42, 0x42, 0x41, 0x4A, 0x42, 0x41, 0x42, 0x63, 0x73, 0x8, 0x69, 0x64, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x64, 0x73, 0x73, 0x73, 0x64, 0x73, 0x8, 0x69, 0x43, 0x43, 0x41, 0x42, 0x42, 0x41, 0x43, 0x41, 0x41, 0x40, 0x42, 0x41, 0x42, 0x73, 0x8, 0x69, 0x42, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x42, 0x73, 0x8}, + .unk3A0 = {0x381, 0x7C3D, 0x4005, 0x4005, 0x4005, 0x4045, 0x4005, 0x4805, 0x4005, 0x4045, 0x4005, 0x4205, 0x4005, 0x4045, 0x1, 0x1}, + .coords = {37, 41}, + .direction = 0x23, + .range = 0x33, + }, + [3] = + { + .unk0 = 0x17, + .unk1 = 0x18, + .trainers = + { + [0] = + { + .name = _("KEENAN"), + .facilityClass = FACILITY_CLASS_PSYCHIC_M, + .unused = 0, + .speechBefore = {EC_WORD_YOU, EC_WORD_LOOK, EC_WORD_SO, EC_WORD_HURRIED, 0xFFFF, 0xFFFF}, + .speechWin = {EC_WORD_TOO, EC_WORD_BAD, 0xFFFF, EC_WORD_TIME, EC_WORD_IS, EC_WORD_UP}, + .speechLose = {EC_WORD_DOES, EC_WORD_THE, EC_WORD_TIME, EC_WORD_WORRY, EC_WORD_YOU, EC_WORD_QUES}, + .speechAfter = {EC_WORD_YOU, EC_WORD_DON_T, EC_WORD_HAVE, EC_WORD_TIME, EC_WORD_TO, EC_WORD_CHAT}, + .mons = + { + [0] = + { + .species = SPECIES_ALAKAZAM, + .heldItem = ITEM_PETAYA_BERRY, + .moves = {MOVE_SKILL_SWAP, MOVE_FIRE_PUNCH, MOVE_ICE_PUNCH, MOVE_REFLECT}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x41, + .nickname = _("ALAKAZAM"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_BLISSEY, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_SKILL_SWAP, MOVE_EGG_BOMB, MOVE_THUNDERBOLT, MOVE_SING}, + .level = 0, + .ppBonuses = 0, + .defenseEV = 255, + .spAttackEV = 155, + .spDefenseEV = 100, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 1, + .personality = 0xF, + .nickname = _("BLISSEY"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_GRUMPIG, + .heldItem = ITEM_TWISTED_SPOON, + .moves = {MOVE_SKILL_SWAP, MOVE_PSYCHIC, MOVE_CONFUSE_RAY, MOVE_REST}, + .level = 0, + .ppBonuses = 0, + .hpEV = 110, + .defenseEV = 200, + .spAttackEV = 200, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x8C, + .nickname = _("GRUMPIG"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_GARDEVOIR, + .heldItem = ITEM_SALAC_BERRY, + .moves = {MOVE_SKILL_SWAP, MOVE_DREAM_EATER, MOVE_HYPNOSIS, MOVE_PROTECT}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 1, + .personality = 0xF, + .nickname = _("GARDEVOIR"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_VENOMOTH, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_SKILL_SWAP, MOVE_SIGNAL_BEAM, MOVE_SLEEP_POWDER, MOVE_TOXIC}, + .level = 0, + .ppBonuses = 0, + .attackEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x80, + .nickname = _("VENOMOTH"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_ESPEON, + .heldItem = ITEM_LUM_BERRY, + .moves = {MOVE_SKILL_SWAP, MOVE_PSYBEAM, MOVE_SWIFT, MOVE_ATTRACT}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0xF, + .nickname = _("ESPEON"), + .friendship = 255, + }, + }, + }, + [1] = + { + .name = _("KRISTINA"), + .facilityClass = FACILITY_CLASS_AROMA_LADY, + .unused = 0, + .speechBefore = {EC_WORD_IT_S, EC_WORD_HOT, EC_WORD_ELLIPSIS, EC_WORD_WHAT, EC_WORD_A, EC_WORD_STENCH}, + .speechWin = {EC_WORD_I, EC_WORD_REALLY, EC_WORD_LIKE, EC_WORD_AN, EC_WORD_OFFENSIVE, EC_WORD_STENCH}, + .speechLose = {EC_WORD_I, EC_MOVE2(COVET), EC_WORD_ANY, EC_WORD_STRONG, EC_WORD_STENCH, 0xFFFF}, + .speechAfter = {EC_WORD_MY, EC_WORD_SENSE, EC_WORD_OF, EC_WORD_SMELL, EC_WORD_ISN_T, EC_WORD_NORMAL}, + .mons = + { + [0] = + { + .species = SPECIES_WEEZING, + .heldItem = ITEM_POISON_BARB, + .moves = {MOVE_TOXIC, MOVE_SLUDGE_BOMB, MOVE_SMOKESCREEN, MOVE_HAZE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .attackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x3, + .nickname = _("WEEZING"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_GLOOM, + .heldItem = ITEM_MIRACLE_SEED, + .moves = {MOVE_PETAL_DANCE, MOVE_SYNTHESIS, MOVE_SUNNY_DAY, MOVE_SOLAR_BEAM}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x8C, + .nickname = _("GLOOM"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_MUK, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_SCREECH, MOVE_DISABLE, MOVE_SLUDGE_BOMB, MOVE_ACID_ARMOR}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .attackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x3, + .nickname = _("MUK"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_TROPIUS, + .heldItem = ITEM_WHITE_HERB, + .moves = {MOVE_SUNNY_DAY, MOVE_SOLAR_BEAM, MOVE_SWEET_SCENT, MOVE_AERIAL_ACE}, + .level = 0, + .ppBonuses = 0, + .attackEV = 120, + .speedEV = 255, + .spAttackEV = 135, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x83, + .nickname = _("TROPIUS"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_BELLOSSOM, + .heldItem = ITEM_MENTAL_HERB, + .moves = {MOVE_SWEET_SCENT, MOVE_PETAL_DANCE, MOVE_STUN_SPORE, MOVE_SLUDGE_BOMB}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x6, + .nickname = _("BELLOSSOM"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_MEGANIUM, + .heldItem = ITEM_MIRACLE_SEED, + .moves = {MOVE_RAZOR_LEAF, MOVE_BODY_SLAM, MOVE_LEECH_SEED, MOVE_SYNTHESIS}, + .level = 0, + .ppBonuses = 0, + .attackEV = 200, + .speedEV = 110, + .spAttackEV = 200, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x1F, + .nickname = _("MEGANIUM"), + .friendship = 255, + }, + }, + }, + }, + .data = {0x31, 0x3B, 0x3B, 0x3B, 0x39, 0x26, 0x1B, 0x1C, 0x1D, 0x25, 0x39, 0x3A, 0x3B, 0x3B, 0x3B, 0x8, 0x1F, 0x17, 0x17, 0x17, 0x17, 0x2B, 0x24, 0x24, 0x24, 0x2B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x8, 0x33, 0x17, 0x17, 0x17, 0x17, 0x2B, 0x3B, 0x3B, 0x3B, 0x2B, 0x35, 0x35, 0x3B, 0x35, 0x35, 0x8, 0x33, 0x17, 0x17, 0x17, 0x17, 0x2B, 0x3B, 0x3B, 0x3B, 0x2B, 0x2C, 0x2C, 0x3B, 0x2C, 0x2C, 0x8, 0x33, 0x17, 0x1F, 0x17, 0x17, 0x2B, 0x3B, 0x3B, 0x3B, 0x2B, 0x17, 0x17, 0x17, 0x17, 0x17, 0x8, 0x34, 0x17, 0x2C, 0x17, 0x17, 0x2B, 0x3B, 0x3B, 0x3B, 0x2C, 0x17, 0x17, 0x17, 0x17, 0x17, 0x8, 0x17, 0x17, 0x17, 0x17, 0x17, 0x2C, 0x3B, 0x3B, 0x3B, 0x3B, 0x17, 0x17, 0x17, 0x17, 0x17, 0x8, 0x1F, 0x17, 0x17, 0x17, 0x17, 0x1F, 0x17, 0x3B, 0x3B, 0x3B, 0x17, 0x17, 0x17, 0x17, 0x17, 0x8, 0x33, 0x17, 0x17, 0x17, 0x17, 0x2B, 0x3B, 0x3B, 0x3B, 0x35, 0x1F, 0x17, 0x17, 0x1F, 0x17, 0x8, 0x34, 0x17, 0x17, 0x17, 0x17, 0x2B, 0x3B, 0x3B, 0x3B, 0x2B, 0x2C, 0x3B, 0x3B, 0x2B, 0x17, 0x8, 0x17, 0x17, 0x17, 0x1F, 0x17, 0x2B, 0x3B, 0x3B, 0x3B, 0x2B, 0x17, 0x17, 0x17, 0x2C, 0x17, 0x8, 0x1F, 0x17, 0x17, 0x2C, 0x17, 0x2B, 0x3B, 0x3B, 0x3B, 0x2B, 0x17, 0x3B, 0x1F, 0x3B, 0x17, 0x8, 0x33, 0x17, 0x17, 0x17, 0x17, 0x2B, 0x3B, 0x3B, 0x3B, 0x2B, 0x17, 0x3B, 0x2B, 0x3B, 0x17, 0x8, 0x33, 0x17, 0x17, 0x17, 0x17, 0x2B, 0x35, 0x35, 0x35, 0x2B, 0x17, 0x3B, 0x2C, 0x3B, 0x17, 0x8, 0x34, 0x17, 0x17, 0x17, 0x17, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x17, 0x17, 0x17, 0x17, 0x17, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8}, + .unk3A0 = {0x381, 0x7C1, 0x8441, 0x8477, 0x8441, 0xA441, 0x401, 0x1, 0x8401, 0x8465, 0x445, 0x1441, 0x8449, 0x8449, 0x87C1, 0xFFFF}, + .coords = {71, 167}, + .direction = 0x1, + .range = 0x33, + }, + }, +}; +static const struct TrHillTag sDataTagVariety = +{ + .unkField_0 = 8, + .unused1 = 1, + .unkField_2 = 4, + .unused3 = 0, + .unused4 = 21, + .unused5 = 76, + .unused6 = 5, + .floors = + { + [0] = + { + .unk0 = 0x29, + .unk1 = 0x2A, + .trainers = + { + [0] = + { + .name = _("TERRANCE"), + .facilityClass = FACILITY_CLASS_GENTLEMAN, + .unused = 0, + .speechBefore = {EC_WORD_GOOD, EC_WORD_CHILDREN, EC_WORD_WILL, EC_WORD_GET, EC_WORD_A, EC_MOVE2(PRESENT)}, + .speechWin = {EC_WORD_THANK_YOU, EC_WORD_MY, EC_WORD_VICTORY, EC_WORD_IS, EC_WORD_YOUR, EC_MOVE2(PRESENT)}, + .speechLose = {EC_WORD_THAT_WAS, EC_WORD_MY, EC_MOVE2(PRESENT), EC_WORD_TO, EC_WORD_YOU, 0xFFFF}, + .speechAfter = {EC_WORD_WELL_THEN, EC_WORD_CONGRATS, EC_WORD_MY, EC_WORD_FRIEND, 0xFFFF, 0xFFFF}, + .mons = + { + [0] = + { + .species = SPECIES_DELIBIRD, + .heldItem = ITEM_SITRUS_BERRY, + .moves = {MOVE_PRESENT, MOVE_SPLASH, MOVE_HAIL, MOVE_PROTECT}, + .level = 0, + .ppBonuses = 0, + .attackEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0x8A, + .nickname = _("DELIBIRD"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_CLEFAIRY, + .heldItem = ITEM_SITRUS_BERRY, + .moves = {MOVE_PRESENT, MOVE_COSMIC_POWER, MOVE_LIGHT_SCREEN, MOVE_MOONLIGHT}, + .level = 0, + .ppBonuses = 0, + .attackEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xD, + .nickname = _("CLEFAIRY"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_PIKACHU, + .heldItem = ITEM_SITRUS_BERRY, + .moves = {MOVE_PRESENT, MOVE_GROWL, MOVE_TAIL_WHIP, MOVE_AGILITY}, + .level = 0, + .ppBonuses = 0, + .attackEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xD, + .nickname = _("PIKACHU"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_MARILL, + .heldItem = ITEM_SITRUS_BERRY, + .moves = {MOVE_PRESENT, MOVE_DEFENSE_CURL, MOVE_TAIL_WHIP, MOVE_ENDURE}, + .level = 0, + .ppBonuses = 0, + .attackEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0x8A, + .nickname = _("MARILL"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_JIGGLYPUFF, + .heldItem = ITEM_SITRUS_BERRY, + .moves = {MOVE_PRESENT, MOVE_SING, MOVE_DISABLE, MOVE_REST}, + .level = 0, + .ppBonuses = 0, + .attackEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xD, + .nickname = _("JIGGLYPUFF"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_TOGETIC, + .heldItem = ITEM_SITRUS_BERRY, + .moves = {MOVE_PRESENT, MOVE_CHARM, MOVE_SWEET_KISS, MOVE_WISH}, + .level = 0, + .ppBonuses = 0, + .attackEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0x26, + .nickname = _("TOGETIC"), + .friendship = 255, + }, + }, + }, + [1] = + { + .name = _("ELIZABETH"), + .facilityClass = FACILITY_CLASS_LADY, + .unused = 0, + .speechBefore = {EC_WORD_CAN, EC_WORD_YOU, EC_WORD_SENSE, EC_WORD_ME, EC_MOVE(FOCUS_ENERGY), EC_WORD_QUES}, + .speechWin = {EC_WORD_THAT_S, EC_WORD_ABOUT, EC_WORD_RIGHT, EC_WORD_I, EC_WORD_WOULD, EC_WORD_THINK}, + .speechLose = {EC_WORD_THINGS, EC_WORD_DON_T, EC_WORD_ALWAYS, EC_WORD_WORK, EC_WORD_OUT, 0xFFFF}, + .speechAfter = {EC_WORD_I_AM, EC_WORD_FEELING, EC_WORD_LONESOME, EC_WORD_AND, EC_WORD_SAD, EC_WORD_NOW}, + .mons = + { + [0] = + { + .species = SPECIES_WIGGLYTUFF, + .heldItem = ITEM_SILK_SCARF, + .moves = {MOVE_ROLLOUT, MOVE_DEFENSE_CURL, MOVE_SING, MOVE_DREAM_EATER}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0xC1, + .nickname = _("WIGGLYTUFF"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_SABLEYE, + .heldItem = ITEM_SILK_SCARF, + .moves = {MOVE_ASTONISH, MOVE_FAINT_ATTACK, MOVE_DETECT, MOVE_CONFUSE_RAY}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x87, + .nickname = _("SABLEYE"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_GRUMPIG, + .heldItem = ITEM_SILK_SCARF, + .moves = {MOVE_PSYBEAM, MOVE_MAGIC_COAT, MOVE_BOUNCE, MOVE_FUTURE_SIGHT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0xA, + .nickname = _("GRUMPIG"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_CORSOLA, + .heldItem = ITEM_SILK_SCARF, + .moves = {MOVE_BUBBLE_BEAM, MOVE_ROCK_BLAST, MOVE_REFLECT, MOVE_LIGHT_SCREEN}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x12, + .nickname = _("CORSOLA"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_CLAMPERL, + .heldItem = ITEM_SILK_SCARF, + .moves = {MOVE_WHIRLPOOL, MOVE_IRON_DEFENSE, MOVE_ENDURE, MOVE_CONFUSE_RAY}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0xA, + .nickname = _("CLAMPERL"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_STARMIE, + .heldItem = ITEM_SILK_SCARF, + .moves = {MOVE_DIVE, MOVE_ICY_WIND, MOVE_SWIFT, MOVE_SKILL_SWAP}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0xA, + .nickname = _("STARMIE"), + .friendship = 255, + }, + }, + }, + }, + .data = {0x31, 0x3B, 0x3B, 0x3B, 0x39, 0x39, 0x13, 0x14, 0x15, 0x38, 0x39, 0x3A, 0x3B, 0x3B, 0x3B, 0x8, 0x40, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x43, 0x43, 0x43, 0x43, 0x43, 0x40, 0x41, 0x41, 0x8, 0x40, 0xFB, 0x43, 0x41, 0x41, 0x41, 0x42, 0x40, 0x43, 0x41, 0x42, 0x42, 0x42, 0xFB, 0x41, 0x8, 0x40, 0x41, 0xFB, 0x41, 0x41, 0x41, 0x42, 0x40, 0x43, 0x41, 0x43, 0x43, 0xFB, 0x40, 0x41, 0x8, 0x40, 0x41, 0x41, 0xFB, 0x43, 0x41, 0x42, 0x40, 0x43, 0x43, 0x43, 0xFB, 0x41, 0x40, 0x41, 0x8, 0x40, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x40, 0x43, 0x43, 0x43, 0x41, 0x41, 0x40, 0x41, 0x8, 0x40, 0x41, 0x41, 0x41, 0xFE, 0xFE, 0xFE, 0xFB, 0xFE, 0xFE, 0xFE, 0x41, 0x41, 0x40, 0x41, 0x8, 0x40, 0x41, 0x41, 0x41, 0xFE, 0xFE, 0xFE, 0xFB, 0xFE, 0xFE, 0xFE, 0x41, 0x41, 0x40, 0x41, 0x8, 0x40, 0x41, 0x42, 0x41, 0xFE, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFE, 0x41, 0x41, 0x40, 0x41, 0x8, 0x40, 0x41, 0x41, 0x41, 0xFE, 0xFE, 0xFE, 0xFB, 0xFE, 0xFE, 0xFE, 0x41, 0x41, 0x40, 0x41, 0x8, 0x40, 0x41, 0x41, 0x41, 0xFE, 0xFE, 0xFE, 0xFB, 0xFE, 0xFE, 0xFE, 0x41, 0x41, 0x40, 0x41, 0x8, 0x40, 0x42, 0x41, 0x43, 0x43, 0x43, 0x41, 0x40, 0x42, 0x42, 0x42, 0x42, 0x41, 0x40, 0x41, 0x8, 0x40, 0x40, 0x41, 0xFB, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0xFB, 0x41, 0x40, 0x41, 0x8, 0x40, 0x40, 0xFB, 0x43, 0x43, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42, 0xFB, 0x40, 0x41, 0x8, 0x40, 0xFB, 0x43, 0x43, 0x41, 0x41, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0xFB, 0x41, 0x8, 0x40, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x8}, + .unk3A0 = {0x381, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1}, + .coords = {133, 137}, + .direction = 0x23, + .range = 0x33, + }, + [1] = + { + .unk0 = 0x2B, + .unk1 = 0x2C, + .trainers = + { + [0] = + { + .name = _("ANNABELL"), + .facilityClass = FACILITY_CLASS_PARASOL_LADY, + .unused = 0, + .speechBefore = {EC_WORD_HI, EC_WORD_ARE, EC_WORD_YOU, EC_WORD_FEELING, EC_WORD_UPBEAT, EC_WORD_QUES}, + .speechWin = {EC_WORD_AREN_T, EC_WORD_YOU, EC_WORD_FEELING, EC_WORD_WELL, EC_WORD_QUES, 0xFFFF}, + .speechLose = {EC_WORD_I, EC_WORD_CAN, EC_WORD_SEE, EC_WORD_YOU_RE, EC_WORD_FEELING, EC_WORD_GREAT}, + .speechAfter = {EC_WORD_YOUR, EC_WORD_POKEMON, EC_WORD_LOOK, EC_WORD_READY, EC_WORD_TO, EC_WORD_HUSTLE}, + .mons = + { + [0] = + { + .species = SPECIES_JIGGLYPUFF, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_SING, MOVE_HYPER_VOICE, MOVE_ATTRACT, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 85, + .attackEV = 85, + .defenseEV = 85, + .speedEV = 85, + .spAttackEV = 85, + .spDefenseEV = 85, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x0, + .nickname = _("JIGGLYPUFF"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_JYNX, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_PERISH_SONG, MOVE_FAKE_TEARS, MOVE_ATTRACT, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 85, + .attackEV = 85, + .defenseEV = 85, + .speedEV = 85, + .spAttackEV = 85, + .spDefenseEV = 85, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x0, + .nickname = _("JYNX"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_EXPLOUD, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_HOWL, MOVE_HYPER_VOICE, MOVE_ATTRACT, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 85, + .attackEV = 85, + .defenseEV = 85, + .speedEV = 85, + .spAttackEV = 85, + .spDefenseEV = 85, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x96, + .nickname = _("EXPLOUD"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_ABSOL, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_SWORDS_DANCE, MOVE_SLASH, MOVE_ATTRACT, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 85, + .attackEV = 85, + .defenseEV = 85, + .speedEV = 85, + .spAttackEV = 85, + .spDefenseEV = 85, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x96, + .nickname = _("ABSOL"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_PIDGEOTTO, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_FEATHER_DANCE, MOVE_AERIAL_ACE, MOVE_ATTRACT, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 85, + .attackEV = 85, + .defenseEV = 85, + .speedEV = 85, + .spAttackEV = 85, + .spDefenseEV = 85, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x96, + .nickname = _("PIDGEOTTO"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_ALTARIA, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_DRAGON_DANCE, MOVE_AERIAL_ACE, MOVE_ATTRACT, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 85, + .attackEV = 85, + .defenseEV = 85, + .speedEV = 85, + .spAttackEV = 85, + .spDefenseEV = 85, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x0, + .nickname = _("ALTARIA"), + .friendship = 255, + }, + }, + }, + [1] = + { + .name = _("COLEMAN"), + .facilityClass = FACILITY_CLASS_COLLECTOR, + .unused = 0, + .speechBefore = {EC_WORD_I, EC_WORD_SEEK, EC_WORD_SOMEONE, EC_WORD_AS, EC_WORD_MY, EC_WORD_IDOL}, + .speechWin = {EC_WORD_DID, EC_WORD_MY, EC_WORD_IDOL, EC_WORD_SEE, EC_WORD_THAT, EC_WORD_QUES}, + .speechLose = {EC_WORD_YOU_RE, EC_WORD_LIKE, EC_WORD_A, EC_MOVE(HEAL_BELL), EC_WORD_TO_ME, EC_WORD_EXCL}, + .speechAfter = {EC_WORD_I_VE, EC_WORD_DECIDED, EC_WORD_I_CHOOSE_YOU, EC_WORD_AS, EC_WORD_MY, EC_WORD_IDOL}, + .mons = + { + [0] = + { + .species = SPECIES_CHIMECHO, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_UPROAR, MOVE_ATTRACT, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .attackEV = 252, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0xD, + .nickname = _("CHIMECHO"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_WHISMUR, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_UPROAR, MOVE_ATTRACT, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .attackEV = 252, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0xD, + .nickname = _("WHISMUR"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_YANMA, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_UPROAR, MOVE_ATTRACT, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .attackEV = 252, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x8A, + .nickname = _("YANMA"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_ILLUMISE, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_ENCORE, MOVE_ATTRACT, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 6, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0xA, + .nickname = _("ILLUMISE"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_SPHEAL, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_ENCORE, MOVE_ATTRACT, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0xA, + .nickname = _("SPHEAL"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_VIGOROTH, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_ENCORE, MOVE_ATTRACT, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 6, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x87, + .nickname = _("VIGOROTH"), + .friendship = 255, + }, + }, + }, + }, + .data = {0x31, 0x3B, 0x3B, 0x3B, 0x39, 0x39, 0x13, 0x14, 0x15, 0x38, 0x39, 0x3A, 0x3B, 0x3B, 0x3B, 0x8, 0x91, 0x9B, 0x9C, 0x96, 0x40, 0x40, 0x96, 0x9B, 0x96, 0x40, 0x40, 0x96, 0x9B, 0x9C, 0x9B, 0x8, 0x9C, 0x9B, 0x96, 0x40, 0xDB, 0xDB, 0x40, 0x96, 0x40, 0xDB, 0xDB, 0x42, 0x96, 0x9B, 0x9B, 0x8, 0x91, 0x96, 0x40, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x42, 0x96, 0x9C, 0x8, 0x91, 0x42, 0xDB, 0xDB, 0xD6, 0xD6, 0xD6, 0xDB, 0xD6, 0xD6, 0xD6, 0xDB, 0xDB, 0x42, 0x9B, 0x8, 0x96, 0x42, 0xDB, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xDB, 0x42, 0x96, 0x8, 0x96, 0x42, 0xDB, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xDB, 0x42, 0x96, 0x8, 0x96, 0x42, 0xDB, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xDB, 0x42, 0x96, 0x8, 0x96, 0x42, 0xDB, 0xDB, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xDB, 0xDB, 0x42, 0x96, 0x8, 0x91, 0x96, 0x42, 0xDB, 0xDB, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, 0xDB, 0xDB, 0x42, 0x96, 0x9B, 0x8, 0x91, 0x9B, 0x96, 0x42, 0xDB, 0xDB, 0xD6, 0xD6, 0xD6, 0xDB, 0xDB, 0x42, 0x96, 0x9B, 0x9C, 0x8, 0x9C, 0x9B, 0x9B, 0x96, 0x42, 0xDB, 0xDB, 0xD6, 0xDB, 0xDB, 0x42, 0x96, 0x9B, 0x9B, 0x9B, 0x8, 0x96, 0x9B, 0x9B, 0x9B, 0x96, 0x41, 0xDB, 0xDB, 0xDB, 0x42, 0x96, 0x9B, 0x9B, 0x9C, 0x96, 0x8, 0xD6, 0x96, 0x9C, 0x9B, 0x9B, 0x96, 0x41, 0xDB, 0x42, 0x96, 0x9B, 0x9B, 0x9B, 0x96, 0xD6, 0x8, 0x9C, 0xD6, 0x96, 0x9B, 0x9C, 0x9B, 0x96, 0x40, 0x96, 0x9B, 0x9C, 0x9B, 0x96, 0xD6, 0x9C, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8}, + .unk3A0 = {0x381, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0xFFFF}, + .coords = {131, 139}, + .direction = 0x23, + .range = 0x77, + }, + [2] = + { + .unk0 = 0x2D, + .unk1 = 0x2E, + .trainers = + { + [0] = + { + .name = _("ENRIQUE"), + .facilityClass = FACILITY_CLASS_RICH_BOY, + .unused = 0, + .speechBefore = {EC_WORD_GET, EC_WORD_READY, EC_WORD_FOR, EC_WORD_AN, EC_WORD_AWESOME, EC_WORD_TIME}, + .speechWin = {EC_WORD_HEY, EC_WORD_HEY, EC_WORD_EXCL, EC_WORD_WHAT_S_UP_QUES, 0xFFFF, 0xFFFF}, + .speechLose = {EC_WORD_AWW, EC_WORD_COULDN_T, EC_WORD_YOU, EC_WORD_LET_ME_WIN, EC_WORD_QUES, 0xFFFF}, + .speechAfter = {EC_WORD_DID, EC_WORD_YOU, EC_WORD_SEE, EC_WORD_MY, EC_WORD_SKILL, EC_WORD_QUES}, + .mons = + { + [0] = + { + .species = SPECIES_WOOPER, + .heldItem = ITEM_FIGY_BERRY, + .moves = {MOVE_RAIN_DANCE, MOVE_YAWN, MOVE_SURF, MOVE_HAZE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 6, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x8C, + .nickname = _("WOOPER"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_POLIWAG, + .heldItem = ITEM_WIKI_BERRY, + .moves = {MOVE_SURF, MOVE_ICE_BEAM, MOVE_MIST, MOVE_HYPNOSIS}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 6, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0x3, + .nickname = _("POLIWAG"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_PSYDUCK, + .heldItem = ITEM_AGUAV_BERRY, + .moves = {MOVE_HYPNOSIS, MOVE_SURF, MOVE_DISABLE, MOVE_SEISMIC_TOSS}, + .level = 0, + .ppBonuses = 0, + .hpEV = 250, + .defenseEV = 130, + .spDefenseEV = 130, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x3, + .nickname = _("PSYDUCK"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_RHYDON, + .heldItem = ITEM_SOFT_SAND, + .moves = {MOVE_EARTHQUAKE, MOVE_MAGNITUDE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .speedEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x96, + .nickname = _("RHYDON"), + .friendship = 0, + }, + [4] = + { + .species = SPECIES_RHYHORN, + .heldItem = ITEM_SOFT_SAND, + .moves = {MOVE_EARTHQUAKE, MOVE_MAGNITUDE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .attackEV = 252, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x3, + .nickname = _("RHYHORN"), + .friendship = 0, + }, + [5] = + { + .species = SPECIES_CUBONE, + .heldItem = ITEM_SOFT_SAND, + .moves = {MOVE_EARTHQUAKE, MOVE_NONE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .attackEV = 252, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0x80, + .nickname = _("CUBONE"), + .friendship = 0, + }, + }, + }, + [1] = + { + .name = _("COLLEEN"), + .facilityClass = FACILITY_CLASS_LADY, + .unused = 0, + .speechBefore = {EC_WORD_I, EC_WORD_WOULD, EC_WORD_LIKE, EC_WORD_TO, EC_WORD_ROCK, EC_WORD_OUT}, + .speechWin = {EC_WORD_I, EC_WORD_LIKE, EC_WORD_THIS, EC_WORD_ROCK, EC_WORD_THING, EC_WORD_EXCL}, + .speechLose = {EC_WORD_GO_AHEAD, EC_WORD_AND, EC_WORD_CRUSH, EC_WORD_MY, EC_WORD_DREAM, EC_WORD_ELLIPSIS}, + .speechAfter = {EC_WORD_I, EC_WORD_WANT, EC_WORD_TO, EC_WORD_GO, EC_WORD_WILD, EC_WORD_SOMETIME}, + .mons = + { + [0] = + { + .species = SPECIES_MAGNEMITE, + .heldItem = ITEM_MAGNET, + .moves = {MOVE_THUNDER, MOVE_ZAP_CANNON, MOVE_SPARK, MOVE_THUNDER_SHOCK}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x8C, + .nickname = _("MAGNEMITE"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_ELECTABUZZ, + .heldItem = ITEM_MAGNET, + .moves = {MOVE_THUNDER, MOVE_THUNDERBOLT, MOVE_THUNDER_PUNCH, MOVE_SHOCK_WAVE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x41, + .nickname = _("ELECTABUZZ"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_FLAAFFY, + .heldItem = ITEM_MAGNET, + .moves = {MOVE_THUNDER, MOVE_THUNDERBOLT, MOVE_SHOCK_WAVE, MOVE_THUNDER_SHOCK}, + .level = 0, + .ppBonuses = 0, + .hpEV = 250, + .spAttackEV = 130, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x0, + .nickname = _("FLAAFFY"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_BALTOY, + .heldItem = ITEM_SILK_SCARF, + .moves = {MOVE_EXPLOSION, MOVE_SELF_DESTRUCT, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .attackEV = 252, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x3, + .nickname = _("BALTOY"), + .friendship = 0, + }, + [4] = + { + .species = SPECIES_PINECO, + .heldItem = ITEM_SILK_SCARF, + .moves = {MOVE_EXPLOSION, MOVE_SELF_DESTRUCT, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .speedEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x3, + .nickname = _("PINECO"), + .friendship = 0, + }, + [5] = + { + .species = SPECIES_VOLTORB, + .heldItem = ITEM_SILK_SCARF, + .moves = {MOVE_EXPLOSION, MOVE_SELF_DESTRUCT, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .attackEV = 252, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x80, + .nickname = _("VOLTORB"), + .friendship = 0, + }, + }, + }, + }, + .data = {0x31, 0x3B, 0x3B, 0x3B, 0x39, 0x39, 0x1B, 0x1C, 0x1D, 0x38, 0x39, 0x3A, 0x3B, 0x3B, 0x3B, 0x8, 0x91, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x84, 0x84, 0x84, 0x9A, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x8, 0x17, 0xB2, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xB0, 0x17, 0xB2, 0xA1, 0x8, 0x17, 0xBB, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0xBB, 0x17, 0x17, 0x17, 0x8, 0x17, 0xB2, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xB0, 0x17, 0xB2, 0xA1, 0x8, 0x17, 0x17, 0x17, 0xBB, 0x17, 0x17, 0x17, 0x17, 0x17, 0xBB, 0x17, 0x17, 0x17, 0x17, 0x17, 0x8, 0x17, 0xB2, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xB0, 0x17, 0xB2, 0xA1, 0x8, 0x17, 0x17, 0xBB, 0x17, 0x17, 0x17, 0x17, 0xBB, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x8, 0x17, 0xB2, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xB0, 0x17, 0xB2, 0xA1, 0x8, 0x17, 0x17, 0x17, 0x17, 0x17, 0xBB, 0x17, 0x17, 0x17, 0x17, 0xBB, 0x17, 0x17, 0x17, 0x17, 0x8, 0x17, 0xB2, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xB0, 0x17, 0xB2, 0xA1, 0x8, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0xBB, 0x17, 0x17, 0xBB, 0x17, 0x17, 0x8, 0x17, 0xB2, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xB0, 0x17, 0xB2, 0xA1, 0x8, 0x17, 0x17, 0x17, 0x17, 0xBB, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x8, 0x17, 0xB2, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xA1, 0xB0, 0x17, 0xB2, 0xA1, 0x8, 0x17, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x17, 0xBB, 0xBB, 0x8}, + .unk3A0 = {0x381, 0x381, 0x7FF7, 0x1, 0x7FF7, 0x1, 0x7FF7, 0x1, 0x7FF7, 0x1, 0x7FF7, 0x1, 0x7FF7, 0x1, 0x7FF7, 0x1}, + .coords = {25, 30}, + .direction = 0x23, + .range = 0x44, + }, + [3] = + { + .unk0 = 0x2F, + .unk1 = 0x30, + .trainers = + { + [0] = + { + .name = _("KIMBERLY"), + .facilityClass = FACILITY_CLASS_POKEFAN_F, + .unused = 0, + .speechBefore = {EC_WORD_I, EC_WORD_LIKE, EC_WORD_WORKING, EC_WORD_AT, EC_WORD_MY, EC_WORD_OWN_TEMPO}, + .speechWin = {EC_WORD_I_AM, EC_WORD_NOT, EC_WORD_BAD, EC_WORD_YOU, EC_WORD_THINK, EC_WORD_QUES}, + .speechLose = {EC_WORD_YOU_RE, EC_WORD_A, EC_WORD_MEAN, EC_WORD_KID, EC_WORD_IT, EC_WORD_SEEMS}, + .speechAfter = {EC_WORD_MY, EC_WORD_OWN_TEMPO, EC_WORD_IS, EC_WORD_RIGHT, EC_WORD_FOR, EC_WORD_ME}, + .mons = + { + [0] = + { + .species = SPECIES_UNOWN, + .heldItem = ITEM_MIRACLE_SEED, + .moves = {MOVE_HIDDEN_POWER, MOVE_NONE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 30, + .attackIV = 31, + .defenseIV = 30, + .speedIV = 31, + .spAttackIV = 30, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x202, + .nickname = _("UNOWN"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_UNOWN, + .heldItem = ITEM_MYSTIC_WATER, + .moves = {MOVE_HIDDEN_POWER, MOVE_NONE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 30, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 30, + .spAttackIV = 30, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x10001, + .nickname = _("UNOWN"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_UNOWN, + .heldItem = ITEM_BLACK_BELT, + .moves = {MOVE_HIDDEN_POWER, MOVE_NONE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 30, + .attackIV = 30, + .defenseIV = 30, + .speedIV = 30, + .spAttackIV = 30, + .spDefenseIV = 30, + .altAbility = 0, + .personality = 0x102, + .nickname = _("UNOWN"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_SPINDA, + .heldItem = ITEM_LUM_BERRY, + .moves = {MOVE_TEETER_DANCE, MOVE_DIZZY_PUNCH, MOVE_CALM_MIND, MOVE_BATON_PASS}, + .level = 0, + .ppBonuses = 0, + .hpEV = 110, + .defenseEV = 200, + .spDefenseEV = 200, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x88FE980F, + .nickname = _("SPINDA"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_PLUSLE, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_HELPING_HAND, MOVE_THUNDERBOLT, MOVE_AGILITY, MOVE_BATON_PASS}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xF, + .nickname = _("PLUSLE"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_VOLBEAT, + .heldItem = ITEM_SITRUS_BERRY, + .moves = {MOVE_HELPING_HAND, MOVE_SIGNAL_BEAM, MOVE_SOLAR_BEAM, MOVE_MOONLIGHT}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0xF, + .nickname = _("VOLBEAT"), + .friendship = 255, + }, + }, + }, + [1] = + { + .name = _("FRANCISCO"), + .facilityClass = FACILITY_CLASS_POKEFAN_M, + .unused = 0, + .speechBefore = {EC_WORD_I, EC_WORD_STUDY, EC_WORD_EVERY, EC_WORD_DAY, EC_WORD_TOO, 0xFFFF}, + .speechWin = {EC_WORD_SO, EC_WORD_THAT_S, EC_WORD_HOW, EC_WORD_YOU, EC_WORD_LOSE, 0xFFFF}, + .speechLose = {EC_WORD_NO, EC_WORD_WONDER, EC_WORD_I, EC_WORD_COULDN_T, EC_WORD_BEAT, EC_WORD_YOU}, + .speechAfter = {EC_WORD_YES, EC_WORD_ELLIPSIS, 0xFFFF, EC_WORD_THANK_YOU, 0xFFFF, 0xFFFF}, + .mons = + { + [0] = + { + .species = SPECIES_SPINDA, + .heldItem = ITEM_LUM_BERRY, + .moves = {MOVE_TEETER_DANCE, MOVE_DIZZY_PUNCH, MOVE_CALM_MIND, MOVE_BATON_PASS}, + .level = 0, + .ppBonuses = 0, + .hpEV = 110, + .defenseEV = 200, + .spDefenseEV = 200, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xE2880098, + .nickname = _("SPINDA"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_MINUN, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_HELPING_HAND, MOVE_THUNDERBOLT, MOVE_AGILITY, MOVE_BATON_PASS}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x8C, + .nickname = _("MINUN"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_ILLUMISE, + .heldItem = ITEM_SITRUS_BERRY, + .moves = {MOVE_HELPING_HAND, MOVE_WISH, MOVE_THUNDERBOLT, MOVE_MOONLIGHT}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xF, + .nickname = _("ILLUMISE"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_UNOWN, + .heldItem = ITEM_CHARCOAL, + .moves = {MOVE_HIDDEN_POWER, MOVE_NONE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 30, + .attackIV = 31, + .defenseIV = 30, + .speedIV = 30, + .spAttackIV = 30, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x302, + .nickname = _("UNOWN"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_UNOWN, + .heldItem = ITEM_SOFT_SAND, + .moves = {MOVE_HIDDEN_POWER, MOVE_NONE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .attackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 30, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 30, + .spDefenseIV = 30, + .altAbility = 0, + .personality = 0x203, + .nickname = _("UNOWN"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_UNOWN, + .heldItem = ITEM_TWISTED_SPOON, + .moves = {MOVE_HIDDEN_POWER, MOVE_NONE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 30, + .speedIV = 30, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x301, + .nickname = _("UNOWN"), + .friendship = 255, + }, + }, + }, + }, + .data = {0x31, 0x3B, 0x3B, 0x3B, 0x39, 0x39, 0x13, 0x14, 0x15, 0x38, 0x39, 0x3A, 0x3B, 0x3B, 0x3B, 0x8, 0x69, 0x40, 0x6D, 0x41, 0x73, 0x41, 0x5E, 0x41, 0x71, 0x42, 0x45, 0x45, 0x45, 0x45, 0x45, 0x8, 0x43, 0x73, 0x64, 0x73, 0x43, 0x73, 0x64, 0x73, 0x41, 0x73, 0x45, 0x45, 0x45, 0x45, 0x45, 0x8, 0x65, 0x40, 0x73, 0x42, 0x6D, 0x42, 0x73, 0x42, 0x6D, 0x42, 0x45, 0x45, 0x45, 0x45, 0x45, 0x8, 0x6C, 0x73, 0x41, 0x73, 0x64, 0x73, 0x40, 0x73, 0x64, 0x73, 0x40, 0x73, 0x42, 0x73, 0x41, 0x8, 0x69, 0x40, 0x6D, 0x41, 0x73, 0x40, 0x6D, 0x43, 0x73, 0x43, 0x6D, 0x42, 0x73, 0x42, 0x6D, 0x8, 0x40, 0x73, 0x64, 0x73, 0x43, 0x73, 0x64, 0x73, 0x41, 0x73, 0x64, 0x73, 0x41, 0x73, 0x64, 0x8, 0x65, 0x42, 0x73, 0x42, 0x6D, 0x41, 0x73, 0x40, 0x6D, 0x42, 0x73, 0x41, 0x6D, 0x42, 0x73, 0x8, 0x6C, 0x73, 0x41, 0x73, 0x64, 0x73, 0x42, 0x73, 0x64, 0x73, 0x42, 0x73, 0x64, 0x73, 0x42, 0x8, 0x69, 0x40, 0x6D, 0x41, 0x73, 0x41, 0x6D, 0x42, 0x73, 0x43, 0x6D, 0x41, 0x73, 0x43, 0x6D, 0x8, 0x40, 0x73, 0x64, 0x73, 0x43, 0x73, 0x64, 0x73, 0x43, 0x73, 0x64, 0x73, 0x42, 0x73, 0x64, 0x8, 0x65, 0x42, 0x73, 0x42, 0x6D, 0x43, 0x73, 0x42, 0x6D, 0x42, 0x73, 0x41, 0x6D, 0x40, 0x73, 0x8, 0x6C, 0x73, 0x40, 0x73, 0x64, 0x73, 0x41, 0x73, 0x64, 0x73, 0x42, 0x73, 0x64, 0x73, 0x42, 0x8, 0x69, 0x40, 0x6D, 0x42, 0x73, 0x42, 0x6D, 0x43, 0x73, 0x40, 0x6D, 0x41, 0x73, 0x40, 0x6D, 0x8, 0x40, 0x73, 0x64, 0x73, 0x40, 0x73, 0x64, 0x73, 0x40, 0x73, 0x64, 0x73, 0x43, 0x73, 0x64, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8}, + .unk3A0 = {0x381, 0x1, 0x2201, 0x1, 0x8881, 0x1, 0x2223, 0x1, 0x8889, 0x1, 0x2223, 0x1, 0x8889, 0x1, 0x2223, 0xFFFF}, + .coords = {42, 46}, + .direction = 0x23, + .range = 0x33, + }, + }, +}; +static const struct TrHillTag sDataTagUnique = +{ + .unkField_0 = 8, + .unused1 = 3, + .unkField_2 = 4, + .unused3 = 0, + .unused4 = 243, + .unused5 = 82, + .unused6 = 6, + .floors = + { + [0] = + { + .unk0 = 0x31, + .unk1 = 0x32, + .trainers = + { + [0] = + { + .name = _("MEREDITH"), + .facilityClass = FACILITY_CLASS_PKMN_RANGER_F, + .unused = 0, + .speechBefore = {EC_WORD_UM, EC_WORD_ELLIPSIS, 0xFFFF, EC_WORD_I, EC_WORD_ELLIPSIS, 0xFFFF}, + .speechWin = {EC_WORD_OH, EC_WORD_EXCL, 0xFFFF, EC_WORD_UM, EC_WORD_ELLIPSIS, EC_WORD_YAY}, + .speechLose = {EC_WORD_UM, EC_WORD_ELLIPSIS, 0xFFFF, EC_WORD_WAAAH, EC_WORD_ELLIPSIS, 0xFFFF}, + .speechAfter = {EC_WORD_UM, EC_WORD_ELLIPSIS, 0xFFFF, EC_WORD_I_AM, EC_WORD_SAD, EC_WORD_ELLIPSIS}, + .mons = + { + [0] = + { + .species = SPECIES_SUNFLORA, + .heldItem = ITEM_PERSIM_BERRY, + .moves = {MOVE_PETAL_DANCE, MOVE_GRASS_WHISTLE, MOVE_LIGHT_SCREEN, MOVE_SUNNY_DAY}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .defenseEV = 155, + .spDefenseEV = 100, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x0, + .nickname = _("SUNFLORA"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_TANGELA, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_GIGA_DRAIN, MOVE_SLEEP_POWDER, MOVE_AMNESIA, MOVE_SUNNY_DAY}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .spDefenseEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x91, + .nickname = _("TANGELA"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_VENUSAUR, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_SOLAR_BEAM, MOVE_EARTHQUAKE, MOVE_SYNTHESIS, MOVE_SUNNY_DAY}, + .level = 0, + .ppBonuses = 0, + .hpEV = 100, + .attackEV = 110, + .defenseEV = 100, + .spAttackEV = 100, + .spDefenseEV = 100, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x1F, + .nickname = _("VENUSAUR"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_LANTURN, + .heldItem = ITEM_PERSIM_BERRY, + .moves = {MOVE_SPARK, MOVE_WATER_PULSE, MOVE_CONFUSE_RAY, MOVE_RAIN_DANCE}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xF, + .nickname = _("LANTURN"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_MANECTRIC, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_THUNDERBOLT, MOVE_HEADBUTT, MOVE_BITE, MOVE_RAIN_DANCE}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0xF, + .nickname = _("MANECTRIC"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_RAIKOU, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_THUNDER, MOVE_CRUNCH, MOVE_ROAR, MOVE_RAIN_DANCE}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xF, + .nickname = _("RAIKOU"), + .friendship = 255, + }, + }, + }, + [1] = + { + .name = _("BERNARD"), + .facilityClass = FACILITY_CLASS_KINDLER, + .unused = 0, + .speechBefore = {EC_WORD_I, EC_WORD_CAN_T, EC_WORD_LOSE, EC_WORD_THIS, EC_WORD_HOT, EC_WORD_BATTLE}, + .speechWin = {EC_WORD_DID, EC_WORD_I, EC_WORD_COOL, EC_WORD_YOU, EC_WORD_DOWN, EC_WORD_QUES}, + .speechLose = {EC_WORD_AIYEEH, EC_WORD_EXCL, EC_WORD_YOU_RE, EC_WORD_A, EC_WORD_TERRIBLE, EC_WORD_PERSON}, + .speechAfter = {EC_WORD_YOUR, EC_WORD_HEART, EC_WORD_MUST_BE, EC_WORD_ICE, EC_WORD_COLD, EC_WORD_ELLIPSIS}, + .mons = + { + [0] = + { + .species = SPECIES_RELICANTH, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_ANCIENT_POWER, MOVE_WATER_PULSE, MOVE_MUD_SPORT, MOVE_RAIN_DANCE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 155, + .defenseEV = 100, + .spDefenseEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x2F, + .nickname = _("RELICANTH"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_GOLDUCK, + .heldItem = ITEM_LAX_INCENSE, + .moves = {MOVE_SURF, MOVE_PSYBEAM, MOVE_BRICK_BREAK, MOVE_RAIN_DANCE}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xF, + .nickname = _("GOLDUCK"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_BLASTOISE, + .heldItem = ITEM_SHELL_BELL, + .moves = {MOVE_HYDRO_PUMP, MOVE_BITE, MOVE_MIRROR_COAT, MOVE_RAIN_DANCE}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x28, + .nickname = _("BLASTOISE"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_MAGCARGO, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_HEAT_WAVE, MOVE_ROCK_SLIDE, MOVE_PROTECT, MOVE_SUNNY_DAY}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .spDefenseEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0x93, + .nickname = _("MAGCARGO"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_RAPIDASH, + .heldItem = ITEM_KINGS_ROCK, + .moves = {MOVE_FIRE_BLAST, MOVE_BOUNCE, MOVE_QUICK_ATTACK, MOVE_SUNNY_DAY}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0xF, + .nickname = _("RAPIDASH"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_MOLTRES, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_SKY_ATTACK, MOVE_AERIAL_ACE, MOVE_ROAR, MOVE_SUNNY_DAY}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xF, + .nickname = _("MOLTRES"), + .friendship = 255, + }, + }, + }, + }, + .data = {0xF1, 0xF5, 0xFB, 0xF5, 0xE6, 0xE6, 0x1B, 0x14, 0x15, 0xF8, 0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0x8, 0xF1, 0xEB, 0xFB, 0xEB, 0xEC, 0xEC, 0xEC, 0xF9, 0xE6, 0xEE, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0x8, 0xF1, 0xEB, 0xFB, 0xEB, 0xFB, 0x9B, 0x9B, 0xFB, 0xEB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0x8, 0xF1, 0xEB, 0xFB, 0xEB, 0x9B, 0xDB, 0xDB, 0x9B, 0xEC, 0xFB, 0xF5, 0xF5, 0xF5, 0xFB, 0xEB, 0x8, 0xF1, 0xEB, 0xFB, 0xEB, 0xF5, 0x95, 0x95, 0xF5, 0xF5, 0xF5, 0xEB, 0xEC, 0xEB, 0xFB, 0xEB, 0x8, 0xED, 0xEB, 0xFB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0x8, 0xF4, 0xEB, 0xFB, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0x8, 0xF1, 0xEB, 0xFB, 0xEB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xFB, 0xEB, 0xFB, 0xEC, 0x8, 0xF1, 0xEB, 0xFB, 0xEB, 0xFB, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xEB, 0xF5, 0xFB, 0x8, 0xF1, 0xEC, 0xFB, 0xEB, 0xFB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xFB, 0x8, 0xF1, 0xF5, 0xF5, 0xEB, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xFB, 0xEB, 0xFB, 0x8, 0xF1, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xFB, 0xEB, 0xFB, 0x8, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xEB, 0xFB, 0xEB, 0xFB, 0x8, 0xF1, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xFB, 0xEC, 0xFB, 0x8, 0xF1, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8}, + .unk3A0 = {0x381, 0x5E01, 0x50FF, 0x5083, 0x503B, 0x5FEB, 0xC02B, 0x5FEB, 0x5009, 0x57FD, 0x1005, 0x7FF5, 0x15, 0x7FF5, 0x1, 0xFFFF}, + .coords = {52, 55}, + .direction = 0x23, + .range = 0x22, + }, + [1] = + { + .unk0 = 0x33, + .unk1 = 0x34, + .trainers = + { + [0] = + { + .name = _("ABRAHAM"), + .facilityClass = FACILITY_CLASS_RUIN_MANIAC, + .unused = 0, + .speechBefore = {EC_WORD_I, EC_WORD_LIKE, EC_WORD_THIS, EC_WORD_POKEMON, EC_WORD_THE, EC_WORD_BEST}, + .speechWin = {EC_WORD_WHAT, EC_WORD_A, EC_WORD_GREAT, EC_WORD_POKEMON, EC_WORD_IT, EC_WORD_IS}, + .speechLose = {EC_WORD_I, EC_WORD_CONFUSED, EC_WORD_A, EC_WORD_MOVE, EC_WORD_WITH, EC_WORD_ANOTHER}, + .speechAfter = {EC_WORD_I, EC_WORD_WANT, EC_WORD_A, EC_MOVE(SKETCH), EC_WORD_OF, EC_WORD_YOU}, + .mons = + { + [0] = + { + .species = SPECIES_SMEARGLE, + .heldItem = ITEM_SCOPE_LENS, + .moves = {MOVE_EARTHQUAKE, MOVE_SHADOW_BALL, MOVE_AERIAL_ACE, MOVE_IMPRISON}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 6, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x8A, + .nickname = _("SMEARGLE"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_SMEARGLE, + .heldItem = ITEM_CHESTO_BERRY, + .moves = {MOVE_REST, MOVE_THUNDER_WAVE, MOVE_FLAMETHROWER, MOVE_IMPRISON}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 252, + .spAttackEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x87, + .nickname = _("SMEARGLE"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_SMEARGLE, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_TEETER_DANCE, MOVE_LOCK_ON, MOVE_SHEER_COLD, MOVE_EXPLOSION}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 6, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xD, + .nickname = _("SMEARGLE"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_SMEARGLE, + .heldItem = ITEM_SCOPE_LENS, + .moves = {MOVE_PSYCHIC, MOVE_SURF, MOVE_THUNDERBOLT, MOVE_IMPRISON}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 252, + .spAttackEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xA, + .nickname = _("SMEARGLE"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_SMEARGLE, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_TOXIC, MOVE_PROTECT, MOVE_WILL_O_WISP, MOVE_IMPRISON}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 6, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xA, + .nickname = _("SMEARGLE"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_SMEARGLE, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_TEETER_DANCE, MOVE_LOCK_ON, MOVE_SHEER_COLD, MOVE_DESTINY_BOND}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 6, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x8A, + .nickname = _("SMEARGLE"), + .friendship = 255, + }, + }, + }, + [1] = + { + .name = _("LUC"), + .facilityClass = FACILITY_CLASS_TUBER_M, + .unused = 0, + .speechBefore = {EC_WORD_I, EC_WORD_HAVE, EC_WORD_A, EC_WORD_COOL, EC_WORD_RARE, EC_WORD_MOVE}, + .speechWin = {EC_WORD_MY, EC_WORD_RARE, EC_WORD_MOVE, EC_WORD_IS, EC_WORD_COOL, EC_WORD_ISN_T_IT_QUES}, + .speechLose = {EC_WORD_DIDN_T, EC_WORD_YOU, EC_WORD_SEE, EC_WORD_MY, EC_WORD_MOVE, EC_WORD_QUES}, + .speechAfter = {EC_WORD_I_AM, EC_WORD_SMART, EC_WORD_BUT, EC_WORD_ALSO, EC_WORD_WEAK, EC_WORD_ELLIPSIS}, + .mons = + { + [0] = + { + .species = SPECIES_STARYU, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_CAMOUFLAGE, MOVE_NONE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 252, + .spAttackEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 1, + .personality = 0xA, + .nickname = _("STARYU"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_MEOWTH, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_PAY_DAY, MOVE_NONE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 252, + .spAttackEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0xD, + .nickname = _("MEOWTH"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_BLAZIKEN, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_BLAZE_KICK, MOVE_NONE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x28, + .nickname = _("BLAZIKEN"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_CUBONE, + .heldItem = ITEM_THICK_CLUB, + .moves = {MOVE_BONEMERANG, MOVE_NONE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 6, + .spDefenseEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 1, + .personality = 0x16, + .nickname = _("CUBONE"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_BEEDRILL, + .heldItem = ITEM_SHELL_BELL, + .moves = {MOVE_TWINEEDLE, MOVE_NONE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 0, + .personality = 0x8A, + .nickname = _("BEEDRILL"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_RATICATE, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_SUPER_FANG, MOVE_NONE, MOVE_NONE, MOVE_NONE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 6, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 5, + .attackIV = 5, + .defenseIV = 5, + .speedIV = 5, + .spAttackIV = 5, + .spDefenseIV = 5, + .altAbility = 1, + .personality = 0xD, + .nickname = _("RATICATE"), + .friendship = 255, + }, + }, + }, + }, + .data = {0x31, 0x3B, 0x3B, 0x3B, 0x39, 0x26, 0x1B, 0x1C, 0x1D, 0x25, 0x39, 0x3A, 0x3B, 0x3B, 0x3B, 0x8, 0x2D, 0x3B, 0x3B, 0x3B, 0x35, 0x2C, 0x23, 0x24, 0x23, 0x2C, 0x35, 0x3B, 0x3B, 0x3B, 0x3B, 0x8, 0x94, 0x87, 0x9B, 0x87, 0x8C, 0x87, 0x8B, 0x87, 0x8C, 0x87, 0x8C, 0x87, 0x95, 0x87, 0x9B, 0x8, 0x91, 0x8F, 0x9B, 0x8F, 0x9B, 0x8F, 0x8C, 0x8F, 0x9B, 0x8F, 0x9B, 0x8F, 0x8C, 0x8F, 0x95, 0x8, 0x8D, 0x97, 0x95, 0x97, 0x9B, 0x97, 0x95, 0x97, 0x95, 0x97, 0x9B, 0x97, 0x9B, 0x97, 0x8C, 0x8, 0x94, 0x87, 0x8C, 0x87, 0x9B, 0x87, 0x8C, 0x87, 0x8B, 0x87, 0x9B, 0x9B, 0x9B, 0x87, 0x9B, 0x8, 0x91, 0x8F, 0x9B, 0x8F, 0x95, 0x8F, 0x9B, 0x8F, 0x8C, 0x8F, 0x95, 0x9B, 0x95, 0x8F, 0x9B, 0x8, 0x91, 0x97, 0x95, 0x97, 0x8C, 0x97, 0x95, 0x97, 0x95, 0x97, 0x8C, 0x9B, 0x8C, 0x97, 0x95, 0x8, 0x91, 0x87, 0x8C, 0x87, 0x9B, 0x87, 0x8C, 0x87, 0x8B, 0x87, 0x9B, 0x87, 0x95, 0x87, 0x8C, 0x8, 0x8D, 0x8F, 0x9B, 0x8F, 0x95, 0x8F, 0x9B, 0x8F, 0x8C, 0x8F, 0x9B, 0x8F, 0x8C, 0x8F, 0x9B, 0x8, 0x94, 0x97, 0x95, 0x97, 0x8C, 0x97, 0x9B, 0x97, 0x95, 0x97, 0x95, 0x97, 0x9B, 0x97, 0x9B, 0x8, 0x91, 0x87, 0x8C, 0x87, 0x95, 0x87, 0x95, 0x87, 0x8B, 0x87, 0x8C, 0x87, 0x9B, 0x87, 0x9B, 0x8, 0x91, 0x8F, 0x95, 0x8F, 0x8B, 0x8F, 0x8C, 0x8F, 0x8C, 0x8F, 0x9B, 0x8F, 0x95, 0x8F, 0x9B, 0x8, 0x91, 0x97, 0x8C, 0x97, 0x8C, 0x97, 0x9B, 0x97, 0x9B, 0x97, 0x9B, 0x97, 0x8B, 0x97, 0x9B, 0x8, 0x91, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x8C, 0x9B, 0x9B, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8}, + .unk3A0 = {0x381, 0x7C1, 0x8AA1, 0x209, 0x5557, 0xA281, 0x81, 0x5D6D, 0x2283, 0x89, 0xDD55, 0x20A1, 0xA81, 0x7D5D, 0x9, 0xFFFF}, + .coords = {105, 109}, + .direction = 0x23, + .range = 0x33, + }, + [2] = + { + .unk0 = 0x35, + .unk1 = 0x36, + .trainers = + { + [0] = + { + .name = _("BREYDEN"), + .facilityClass = FACILITY_CLASS_YOUNGSTER, + .unused = 0, + .speechBefore = {EC_WORD_I, EC_WORD_CARE, EC_WORD_FOR, EC_WORD_MY, EC_WORD_POKEMON, EC_WORD_A_LOT}, + .speechWin = {EC_WORD_MY, EC_WORD_POKEMON, EC_WORD_CAN, EC_WORD_DO, EC_WORD_IT, EC_WORD_ALL}, + .speechLose = {EC_WORD_IT_S, EC_WORD_NOT, EC_WORD_LIKE, EC_WORD_WE, EC_WORD_ALWAYS, EC_WORD_WIN}, + .speechAfter = {EC_WORD_I, EC_WORD_LIKE, EC_WORD_THE, EC_WORD_BEGINNING, EC_WORD_POKEMON, EC_WORD_BEST}, + .mons = + { + [0] = + { + .species = SPECIES_CHARMELEON, + .heldItem = ITEM_CHARCOAL, + .moves = {MOVE_FIRE_SPIN, MOVE_DRAGON_RAGE, MOVE_FLAMETHROWER, MOVE_SLASH}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 252, + .spAttackEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 25, + .attackIV = 25, + .defenseIV = 25, + .speedIV = 25, + .spAttackIV = 25, + .spDefenseIV = 25, + .altAbility = 0, + .personality = 0x32, + .nickname = _("CHARMELEON"), + .friendship = 100, + }, + [1] = + { + .species = SPECIES_WARTORTLE, + .heldItem = ITEM_MYSTIC_WATER, + .moves = {MOVE_HYDRO_PUMP, MOVE_SKULL_BASH, MOVE_RAIN_DANCE, MOVE_PROTECT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 250, + .defenseEV = 130, + .otId = TRAINER_HILL_OTID, + .hpIV = 25, + .attackIV = 25, + .defenseIV = 25, + .speedIV = 25, + .spAttackIV = 25, + .spDefenseIV = 25, + .altAbility = 0, + .personality = 0x0, + .nickname = _("WARTORTLE"), + .friendship = 100, + }, + [2] = + { + .species = SPECIES_IVYSAUR, + .heldItem = ITEM_MIRACLE_SEED, + .moves = {MOVE_SOLAR_BEAM, MOVE_SYNTHESIS, MOVE_GROWTH, MOVE_SWEET_SCENT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 6, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 25, + .attackIV = 25, + .defenseIV = 25, + .speedIV = 25, + .spAttackIV = 25, + .spDefenseIV = 25, + .altAbility = 0, + .personality = 0x0, + .nickname = _("IVYSAUR"), + .friendship = 100, + }, + [3] = + { + .species = SPECIES_BAYLEEF, + .heldItem = ITEM_MIRACLE_SEED, + .moves = {MOVE_SOLAR_BEAM, MOVE_SAFEGUARD, MOVE_LIGHT_SCREEN, MOVE_BODY_SLAM}, + .level = 0, + .ppBonuses = 0, + .hpEV = 250, + .attackEV = 130, + .spAttackEV = 130, + .otId = TRAINER_HILL_OTID, + .hpIV = 25, + .attackIV = 25, + .defenseIV = 25, + .speedIV = 25, + .spAttackIV = 25, + .spDefenseIV = 25, + .altAbility = 0, + .personality = 0x32, + .nickname = _("BAYLEEF"), + .friendship = 100, + }, + [4] = + { + .species = SPECIES_CROCONAW, + .heldItem = ITEM_MYSTIC_WATER, + .moves = {MOVE_SCARY_FACE, MOVE_SLASH, MOVE_HYDRO_PUMP, MOVE_SCREECH}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .speedEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 25, + .attackIV = 25, + .defenseIV = 25, + .speedIV = 25, + .spAttackIV = 25, + .spDefenseIV = 25, + .altAbility = 0, + .personality = 0x3, + .nickname = _("CROCONAW"), + .friendship = 100, + }, + [5] = + { + .species = SPECIES_QUILAVA, + .heldItem = ITEM_CHARCOAL, + .moves = {MOVE_QUICK_ATTACK, MOVE_FLAMETHROWER, MOVE_FLAME_WHEEL, MOVE_SWIFT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x28, + .nickname = _("QUILAVA"), + .friendship = 100, + }, + }, + }, + [1] = + { + .name = _("ANIYA"), + .facilityClass = FACILITY_CLASS_TUBER_F, + .unused = 0, + .speechBefore = {EC_WORD_SOMEONE, EC_WORD_GOT, EC_WORD_ME, EC_WORD_A_LITTLE, EC_WORD_POKEMON, EC_WORD_EGG}, + .speechWin = {EC_WORD_I_AM, EC_WORD_NOT, EC_WORD_NEW, EC_WORD_AT, EC_WORD_THIS, EC_WORD_EXCL}, + .speechLose = {EC_WORD_OH, EC_WORD_BUT, EC_WORD_ELLIPSIS, EC_WORD_WHY, EC_WORD_WHY, EC_WORD_QUES_EXCL}, + .speechAfter = {EC_WORD_YOU_RE, EC_WORD_BUSY, EC_WORD_QUES, EC_WORD_DON_T, EC_WORD_GIVE_UP, EC_WORD_EXCL}, + .mons = + { + [0] = + { + .species = SPECIES_SMOOCHUM, + .heldItem = ITEM_PETAYA_BERRY, + .moves = {MOVE_ICE_BEAM, MOVE_PSYCHIC, MOVE_SWEET_KISS, MOVE_FAKE_TEARS}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x32, + .nickname = _("SMOOCHUM"), + .friendship = 50, + }, + [1] = + { + .species = SPECIES_AZURILL, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_SURF, MOVE_SING, MOVE_RAIN_DANCE, MOVE_BLIZZARD}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0xC8, + .nickname = _("AZURILL"), + .friendship = 50, + }, + [2] = + { + .species = SPECIES_ELEKID, + .heldItem = ITEM_KINGS_ROCK, + .moves = {MOVE_FIRE_PUNCH, MOVE_THUNDER, MOVE_ICE_PUNCH, MOVE_THUNDER_WAVE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x0, + .nickname = _("ELEKID"), + .friendship = 50, + }, + [3] = + { + .species = SPECIES_CLEFFA, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_MEGA_KICK, MOVE_SWEET_KISS, MOVE_SING, MOVE_METRONOME}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .attackEV = 252, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x0, + .nickname = _("CLEFFA"), + .friendship = 50, + }, + [4] = + { + .species = SPECIES_WYNAUT, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_ENCORE, MOVE_COUNTER, MOVE_MIRROR_COAT, MOVE_DESTINY_BOND}, + .level = 0, + .ppBonuses = 0, + .hpEV = 250, + .defenseEV = 130, + .spDefenseEV = 130, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x84, + .nickname = _("WYNAUT"), + .friendship = 50, + }, + [5] = + { + .species = SPECIES_MAGBY, + .heldItem = ITEM_SCOPE_LENS, + .moves = {MOVE_FIRE_BLAST, MOVE_CONFUSE_RAY, MOVE_THUNDER_PUNCH, MOVE_BARRIER}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0xF, + .nickname = _("MAGBY"), + .friendship = 50, + }, + }, + }, + }, + .data = {0x31, 0x3B, 0x3B, 0x3B, 0x39, 0x39, 0x13, 0x14, 0x15, 0x38, 0x39, 0x3A, 0x3B, 0x3B, 0x3B, 0x8, 0x69, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x7C, 0x46, 0x8, 0x69, 0x46, 0x7A, 0x73, 0x73, 0x73, 0x79, 0x73, 0x73, 0x73, 0x7D, 0x73, 0x73, 0x73, 0x46, 0x8, 0x69, 0x46, 0x73, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x8, 0x69, 0x46, 0x73, 0x73, 0x7B, 0x73, 0x7C, 0x73, 0x7B, 0x73, 0x7A, 0x73, 0x73, 0x73, 0x46, 0x8, 0x69, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x7A, 0x46, 0x8, 0x69, 0x46, 0x73, 0x73, 0x73, 0x73, 0x73, 0x7D, 0x7C, 0x73, 0x7C, 0x73, 0x7B, 0x73, 0x46, 0x8, 0x69, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x7C, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x8, 0x91, 0x46, 0x9B, 0x9B, 0x9B, 0x46, 0x3B, 0x3B, 0x3B, 0x46, 0x9B, 0x9B, 0x9B, 0x9B, 0x46, 0x8, 0x91, 0x46, 0x9B, 0x9B, 0x9B, 0x46, 0x3B, 0x3B, 0x3B, 0x46, 0x9B, 0x9B, 0x9B, 0x9B, 0x46, 0x8, 0x91, 0x46, 0x9B, 0x9B, 0x9B, 0x46, 0x3B, 0x3B, 0x3B, 0x46, 0x9B, 0x9B, 0x9B, 0x9B, 0x46, 0x8, 0xF1, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x78, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x8, 0xF1, 0x46, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0x7A, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0x7C, 0x8, 0xF1, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0xFB, 0x8, 0x7C, 0xFB, 0x7B, 0xFB, 0x7A, 0xFB, 0x79, 0xFB, 0xB3, 0xFB, 0x7D, 0xFB, 0x7E, 0xFB, 0x7D, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8}, + .unk3A0 = {0x381, 0x7FFB, 0x4003, 0x5FFF, 0x4003, 0x7FFB, 0x4003, 0x7EFF, 0x4443, 0x4443, 0x4443, 0x7EFF, 0x4001, 0x7FFD, 0x1, 0xFFFF}, + .coords = {150, 152}, + .direction = 0x23, + .range = 0x11, + }, + [3] = + { + .unk0 = 0x38, + .unk1 = 0x37, + .trainers = + { + [0] = + { + .name = _("DANE"), + .facilityClass = FACILITY_CLASS_BIRD_KEEPER, + .unused = 0, + .speechBefore = {EC_WORD_I, EC_WORD_GOT, EC_WORD_MY, EC_WORD_POKEMON, EC_WORD_ON, EC_WORD_VACATION}, + .speechWin = {EC_WORD_IT_S, EC_WORD_GREAT, EC_WORD_TO, EC_WORD_TRAVEL, EC_WORD_AND, EC_WORD_BATTLE}, + .speechLose = {EC_WORD_WAAAH, EC_WORD_EXCL, EC_WORD_MY, EC_WORD_RARE, EC_WORD_POKEMON, EC_WORD_EXCL}, + .speechAfter = {EC_WORD_OFF, EC_WORD_ON, EC_WORD_ANOTHER, EC_WORD_VACATION, EC_WORD_I, EC_WORD_GO}, + .mons = + { + [0] = + { + .species = SPECIES_SUDOWOODO, + .heldItem = ITEM_SITRUS_BERRY, + .moves = {MOVE_ROCK_SLIDE, MOVE_BLOCK, MOVE_TOXIC, MOVE_EXPLOSION}, + .level = 0, + .ppBonuses = 0, + .hpEV = 100, + .attackEV = 255, + .spDefenseEV = 155, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x80, + .nickname = _("SUDOWOODO"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_SLOWKING, + .heldItem = ITEM_SCOPE_LENS, + .moves = {MOVE_SURF, MOVE_PSYCHIC, MOVE_BLIZZARD, MOVE_DISABLE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .defenseEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0x8C, + .nickname = _("SLOWKING"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_ENTEI, + .heldItem = ITEM_PETAYA_BERRY, + .moves = {MOVE_FLAMETHROWER, MOVE_CALM_MIND, MOVE_FIRE_SPIN, MOVE_ROAR}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xF, + .nickname = _("ENTEI"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_HITMONCHAN, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_MEGA_PUNCH, MOVE_DETECT, MOVE_COUNTER, MOVE_SKY_UPPERCUT}, + .level = 0, + .ppBonuses = 0, + .attackEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x3, + .nickname = _("HITMONCHAN"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_MANTINE, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_SURF, MOVE_CONFUSE_RAY, MOVE_ATTRACT, MOVE_AERIAL_ACE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .defenseEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0x6, + .nickname = _("MANTINE"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_ZAPDOS, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_THUNDERBOLT, MOVE_DRILL_PECK, MOVE_THUNDER_WAVE, MOVE_AGILITY}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x18, + .nickname = _("ZAPDOS"), + .friendship = 255, + }, + }, + }, + [1] = + { + .name = _("STEPHANIE"), + .facilityClass = FACILITY_CLASS_SWIMMING_TRIATHLETE_F, + .unused = 0, + .speechBefore = {EC_WORD_THIS, EC_WORD_IS, EC_WORD_HOW, EC_WORD_YOU, EC_WORD_WIN, EC_WORD_EXCL}, + .speechWin = {EC_WORD_DO, EC_WORD_YOU, EC_WORD_UNDERSTAND, EC_WORD_HOW, EC_WORD_NOW, EC_WORD_QUES}, + .speechLose = {EC_WORD_YES, EC_WORD_THAT_S, EC_WORD_HOW, EC_WORD_YOU, EC_WORD_DO, EC_WORD_IT}, + .speechAfter = {EC_WORD_YOU, EC_WORD_BEAT, EC_WORD_ME, EC_WORD_GOOD, EC_WORD_FOR, EC_WORD_YOU}, + .mons = + { + [0] = + { + .species = SPECIES_HITMONLEE, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_MEGA_KICK, MOVE_MIND_READER, MOVE_FOCUS_ENERGY, MOVE_HI_JUMP_KICK}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .attackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x3, + .nickname = _("HITMONLEE"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_PORYGON2, + .heldItem = ITEM_SCOPE_LENS, + .moves = {MOVE_LOCK_ON, MOVE_BLIZZARD, MOVE_CONVERSION_2, MOVE_PSYCHIC}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xF, + .nickname = _("PORYGON2"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_SUICUNE, + .heldItem = ITEM_PETAYA_BERRY, + .moves = {MOVE_SURF, MOVE_CALM_MIND, MOVE_MIRROR_COAT, MOVE_MIST}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xF, + .nickname = _("SUICUNE"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_HOUNDOOM, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_FLAMETHROWER, MOVE_CRUNCH, MOVE_ROAR, MOVE_WILL_O_WISP}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 1, + .personality = 0xF, + .nickname = _("HOUNDOOM"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_STANTLER, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_CONFUSE_RAY, MOVE_SWAGGER, MOVE_PSYCH_UP, MOVE_TAKE_DOWN}, + .level = 0, + .ppBonuses = 0, + .attackEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0x3, + .nickname = _("STANTLER"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_ARTICUNO, + .heldItem = ITEM_NEVER_MELT_ICE, + .moves = {MOVE_BLIZZARD, MOVE_SHEER_COLD, MOVE_MIST, MOVE_AERIAL_ACE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 15, + .attackIV = 15, + .defenseIV = 15, + .speedIV = 15, + .spAttackIV = 15, + .spDefenseIV = 15, + .altAbility = 0, + .personality = 0xF, + .nickname = _("ARTICUNO"), + .friendship = 255, + }, + }, + }, + }, + .data = {0xF1, 0xFB, 0xFB, 0xFB, 0xF9, 0xF9, 0x1B, 0x1C, 0x1D, 0xE5, 0xE6, 0xEE, 0xF5, 0xFB, 0xFB, 0x8, 0xED, 0xF5, 0xF5, 0xF5, 0xFB, 0xFB, 0xEC, 0xEC, 0xEC, 0xEB, 0xEC, 0xEC, 0xEC, 0xFB, 0xFB, 0x8, 0xF4, 0xEC, 0xEC, 0xEC, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xEB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0x8, 0xF1, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xFB, 0xEB, 0xFB, 0xF5, 0xF5, 0xF5, 0xF5, 0x8, 0xF1, 0xEB, 0xEC, 0xEC, 0xEC, 0xEB, 0xEC, 0xEC, 0xFB, 0xEC, 0xFB, 0xEC, 0xEC, 0xEC, 0xEC, 0x8, 0xF1, 0xEB, 0xFB, 0xFB, 0xFB, 0xEB, 0xFB, 0xF5, 0xFB, 0xF5, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0x8, 0xF1, 0xEB, 0xFB, 0xF5, 0xFB, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xF5, 0xF5, 0xF5, 0xFB, 0xFB, 0x8, 0xF1, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xEC, 0xEC, 0xEC, 0xFB, 0xFB, 0x8, 0xF1, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xFB, 0xF5, 0xF5, 0xF5, 0xF5, 0x8, 0xF1, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xFB, 0xEC, 0xEC, 0xEC, 0xEC, 0x8, 0xF1, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0x8, 0xF1, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xFB, 0xEB, 0xF5, 0xF5, 0xF5, 0xF5, 0xFB, 0x8, 0xF1, 0xEC, 0xFB, 0xEB, 0xFB, 0xEC, 0xFB, 0xEB, 0xFB, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xFB, 0x8, 0xF1, 0xFB, 0xFB, 0xEB, 0xFB, 0xFB, 0xFB, 0xEB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0x8, 0xF1, 0xFB, 0xFB, 0xEC, 0xFB, 0xFB, 0xFB, 0xEC, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8}, + .unk3A0 = {0x381, 0x3F9, 0xF041, 0x41, 0x7F5F, 0x4401, 0x4541, 0x5579, 0x5541, 0x555F, 0x5541, 0x5541, 0x557D, 0x1101, 0x1101, 0xFFFF}, + .coords = {40, 91}, + .direction = 0x21, + .range = 0x33, + }, + }, +}; +static const struct TrHillTag sDataTagExpert = +{ + .unkField_0 = 8, + .unused1 = 1, + .unkField_2 = 4, + .unused3 = 0, + .unused4 = 63, + .unused5 = 31, + .unused6 = 6, + .floors = + { + [0] = + { + .unk0 = 0x39, + .unk1 = 0x3A, + .trainers = + { + [0] = + { + .name = _("ALFRED"), + .facilityClass = FACILITY_CLASS_COOLTRAINER_M, + .unused = 0, + .speechBefore = {EC_WORD_WE, EC_WORD_CAN, EC_WORD_TAKE, EC_WORD_ON, EC_WORD_ANY, EC_WORD_TYPE}, + .speechWin = {EC_WORD_WE, EC_WORD_DID, EC_WORD_BETTER, EC_WORD_THAN, EC_WORD_OKAY, EC_WORD_EXCL}, + .speechLose = {EC_WORD_OUR, EC_WORD_STRATEGY, EC_WORD_ISN_T, EC_WORD_ANY, EC_WORD_GOOD, EC_WORD_ELLIPSIS}, + .speechAfter = {EC_WORD_WE, EC_WORD_NEED, EC_WORD_TO, EC_WORD_TRAIN, EC_WORD_A_LOT, EC_WORD_MORE}, + .mons = + { + [0] = + { + .species = SPECIES_SNORLAX, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_MEGA_KICK, MOVE_SHADOW_BALL, MOVE_BRICK_BREAK, MOVE_EARTHQUAKE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .attackEV = 252, + .defenseEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x35, + .nickname = _("SNORLAX"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_MILTANK, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_DOUBLE_EDGE, MOVE_SHADOW_BALL, MOVE_ATTRACT, MOVE_MILK_DRINK}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .attackEV = 252, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x3, + .nickname = _("MILTANK"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_URSARING, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_DOUBLE_EDGE, MOVE_CRUNCH, MOVE_BRICK_BREAK, MOVE_AERIAL_ACE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .spAttackEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x7F, + .nickname = _("URSARING"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_SLAKING, + .heldItem = ITEM_CHESTO_BERRY, + .moves = {MOVE_HYPER_BEAM, MOVE_SHADOW_BALL, MOVE_BRICK_BREAK, MOVE_REST}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .attackEV = 252, + .spDefenseEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x80, + .nickname = _("SLAKING"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_KANGASKHAN, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_MEGA_KICK, MOVE_SHADOW_BALL, MOVE_ATTRACT, MOVE_FAKE_OUT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .attackEV = 252, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x3, + .nickname = _("KANGASKHAN"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_ZANGOOSE, + .heldItem = ITEM_SCOPE_LENS, + .moves = {MOVE_CRUSH_CLAW, MOVE_SHADOW_BALL, MOVE_BRICK_BREAK, MOVE_ROAR}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .attackEV = 252, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x80, + .nickname = _("ZANGOOSE"), + .friendship = 255, + }, + }, + }, + [1] = + { + .name = _("EDIE"), + .facilityClass = FACILITY_CLASS_PSYCHIC_F, + .unused = 0, + .speechBefore = {EC_WORD_WE, EC_WORD_WILL_BE_HERE, EC_WORD_FOR, EC_WORD_ANY, EC_WORD_TRAINER, EC_WORD_CHALLENGE}, + .speechWin = {EC_WORD_MY, EC_WORD_STRATEGY, EC_WORD_WORKS, EC_WORD_TO, EC_WORD_PERFECTION, EC_WORD_EXCL}, + .speechLose = {EC_WORD_NO, EC_WORD_NO, EC_WORD_ELLIPSIS, EC_WORD_THAT, EC_WORD_WON_T, EC_WORD_DO}, + .speechAfter = {EC_WORD_THERE, EC_WORD_SHOULD, EC_WORD_BE, EC_WORD_A, EC_WORD_TRAINER, EC_WORD_SCHOOL}, + .mons = + { + [0] = + { + .species = SPECIES_SLOWKING, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_PSYCHIC, MOVE_SURF, MOVE_ICE_BEAM, MOVE_SKILL_SWAP}, + .level = 0, + .ppBonuses = 0, + .hpEV = 200, + .defenseEV = 110, + .spAttackEV = 200, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 1, + .personality = 0xF, + .nickname = _("SLOWKING"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_ESPEON, + .heldItem = ITEM_LUM_BERRY, + .moves = {MOVE_PSYCHIC, MOVE_BITE, MOVE_CALM_MIND, MOVE_REFLECT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x28, + .nickname = _("ESPEON"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_STARMIE, + .heldItem = ITEM_SHELL_BELL, + .moves = {MOVE_PSYCHIC, MOVE_SURF, MOVE_THUNDERBOLT, MOVE_ICE_BEAM}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 1, + .personality = 0xF, + .nickname = _("STARMIE"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_GENGAR, + .heldItem = ITEM_LUM_BERRY, + .moves = {MOVE_PSYCHIC, MOVE_THUNDERBOLT, MOVE_FIRE_PUNCH, MOVE_ICE_PUNCH}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0xF, + .nickname = _("GENGAR"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_GARDEVOIR, + .heldItem = ITEM_SALAC_BERRY, + .moves = {MOVE_PSYCHIC, MOVE_THUNDERBOLT, MOVE_MAGICAL_LEAF, MOVE_DESTINY_BOND}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0xF, + .nickname = _("GARDEVOIR"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_ALAKAZAM, + .heldItem = ITEM_LUM_BERRY, + .moves = {MOVE_PSYCHIC, MOVE_RECOVER, MOVE_THUNDER_WAVE, MOVE_ATTRACT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0xF, + .nickname = _("ALAKAZAM"), + .friendship = 255, + }, + }, + }, + }, + .data = {0x31, 0x3B, 0x3B, 0x3B, 0x39, 0x39, 0x1B, 0x14, 0x15, 0x38, 0x39, 0x3A, 0x3B, 0x3B, 0x3B, 0x8, 0x31, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x2C, 0x39, 0x39, 0x3A, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x8, 0x31, 0x3B, 0x8, 0x8, 0x8, 0x8, 0x8, 0x3B, 0x8, 0x8, 0x8, 0x8, 0x8, 0x3B, 0x3B, 0x8, 0x69, 0x73, 0x8, 0x4D, 0x4D, 0x4D, 0x4D, 0xD1, 0x4D, 0x4D, 0x4D, 0x4D, 0x8, 0x69, 0x73, 0x8, 0x40, 0x3B, 0x8, 0x55, 0x55, 0x55, 0x55, 0xD1, 0x55, 0x55, 0x55, 0x55, 0x8, 0x31, 0x41, 0x8, 0x69, 0x41, 0x8, 0xC5, 0xD9, 0xD9, 0xD9, 0x9A, 0xD9, 0xD9, 0xD9, 0xC6, 0x8, 0x41, 0x73, 0x8, 0x69, 0x3B, 0x8, 0xD4, 0xDB, 0x9B, 0x73, 0x73, 0x73, 0x9B, 0xDB, 0xCC, 0x8, 0x31, 0x73, 0x8, 0x69, 0x3B, 0x8, 0xCD, 0x9B, 0x73, 0x73, 0x44, 0x73, 0x73, 0x9B, 0xD5, 0x8, 0x31, 0x73, 0x8, 0x69, 0x3B, 0x8, 0xD4, 0xDB, 0x9B, 0x73, 0x73, 0x73, 0x9B, 0xDB, 0xCC, 0x8, 0x31, 0x73, 0x8, 0x69, 0x41, 0x8, 0xD1, 0xDB, 0xDB, 0xDB, 0x9B, 0xDB, 0xDB, 0xDB, 0xDB, 0x8, 0x41, 0x73, 0x8, 0x40, 0x3B, 0x8, 0x8, 0xC7, 0xC7, 0xDB, 0xDB, 0xDB, 0xC7, 0xC7, 0x8, 0x8, 0x31, 0x41, 0x8, 0x69, 0x3B, 0x4D, 0x4D, 0x67, 0x67, 0xDB, 0xDB, 0xDB, 0x67, 0x67, 0x4D, 0x4D, 0x31, 0x73, 0x8, 0x69, 0x3B, 0x55, 0x55, 0xD7, 0xD7, 0xD1, 0xDB, 0xDB, 0xD7, 0xD7, 0x55, 0x55, 0x31, 0x73, 0x8, 0x69, 0x3B, 0x39, 0x39, 0x39, 0x39, 0x3A, 0x3B, 0x3B, 0x39, 0x39, 0x39, 0x39, 0x3A, 0x73, 0x8, 0x69, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8}, + .unk3A0 = {0x381, 0x201, 0x3EF9, 0x3EF9, 0x3EF9, 0x2009, 0x3019, 0x2009, 0x3019, 0x2009, 0x3019, 0x3019, 0x3C79, 0x1, 0x1, 0xFFFF}, + .coords = {116, 122}, + .direction = 0x23, + .range = 0x55, + }, + [1] = + { + .unk0 = 0x3B, + .unk1 = 0x3C, + .trainers = + { + [0] = + { + .name = _("RODERICK"), + .facilityClass = FACILITY_CLASS_COOLTRAINER_M, + .unused = 0, + .speechBefore = {EC_WORD_I, EC_WORD_CAN, EC_WORD_WIN, EC_WORD_WITHOUT, EC_WORD_A, EC_MOVE2(HELPING_HAND)}, + .speechWin = {EC_WORD_IT_S, EC_WORD_ONLY, EC_WORD_NATURAL, EC_WORD_THAT, EC_WORD_I, EC_WORD_WIN}, + .speechLose = {EC_WORD_LOSING, EC_WORD_HAS, EC_WORD_ME, EC_WORD_FEELING, EC_WORD_SMALL, EC_WORD_ELLIPSIS}, + .speechAfter = {EC_WORD_YOU, EC_WORD_HAVE, EC_WORD_A, EC_WORD_GOOD, EC_WORD_TEACHER, EC_WORD_QUES}, + .mons = + { + [0] = + { + .species = SPECIES_SWELLOW, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_AERIAL_ACE, MOVE_AGILITY, MOVE_FACADE, MOVE_ATTRACT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x3, + .nickname = _("SWELLOW"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_MACHAMP, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_LOW_KICK, MOVE_ROCK_SLIDE, MOVE_FACADE, MOVE_ATTRACT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x3, + .nickname = _("MACHAMP"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_URSARING, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_PROTECT, MOVE_ROCK_SLIDE, MOVE_FACADE, MOVE_ATTRACT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x3, + .nickname = _("URSARING"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_KINGLER, + .heldItem = ITEM_PERSIM_BERRY, + .moves = {MOVE_RETURN, MOVE_PROTECT, MOVE_CRABHAMMER, MOVE_ATTRACT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x80, + .nickname = _("KINGLER"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_TYRANITAR, + .heldItem = ITEM_PERSIM_BERRY, + .moves = {MOVE_ROCK_SLIDE, MOVE_CRUNCH, MOVE_EARTHQUAKE, MOVE_ATTRACT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .defenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x80, + .nickname = _("TYRANITAR"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_DRAGONITE, + .heldItem = ITEM_PERSIM_BERRY, + .moves = {MOVE_BODY_SLAM, MOVE_THUNDER_WAVE, MOVE_EARTHQUAKE, MOVE_ATTRACT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .attackEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x80, + .nickname = _("DRAGONITE"), + .friendship = 255, + }, + }, + }, + [1] = + { + .name = _("ALICIA"), + .facilityClass = FACILITY_CLASS_COOLTRAINER_F, + .unused = 0, + .speechBefore = {EC_WORD_I, EC_WORD_DON_T, EC_WORD_NEED, EC_WORD_A, EC_MOVE2(HELPING_HAND), EC_WORD_EXCL}, + .speechWin = {EC_WORD_SORRY, EC_WORD_EXCL, EC_WORD_TOO, EC_WORD_BAD, EC_WORD_FOR, EC_WORD_YOU}, + .speechLose = {EC_WORD_WHAT, EC_WORD_AN, EC_WORD_UNBELIEVABLE, EC_MOVE2(STRUGGLE), EC_WORD_THAT_WAS, EC_WORD_EXCL}, + .speechAfter = {EC_WORD_I, EC_WORD_CAN, EC_WORD_BE, EC_WORD_YOUR, EC_WORD_POKEMON, EC_WORD_TEACHER}, + .mons = + { + [0] = + { + .species = SPECIES_JOLTEON, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_THUNDERBOLT, MOVE_THUNDER_WAVE, MOVE_ATTRACT, MOVE_SWAGGER}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0xA, + .nickname = _("JOLTEON"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_ALAKAZAM, + .heldItem = ITEM_KINGS_ROCK, + .moves = {MOVE_PSYCHIC, MOVE_ICE_PUNCH, MOVE_ATTRACT, MOVE_SWAGGER}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0xA, + .nickname = _("ALAKAZAM"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_STARMIE, + .heldItem = ITEM_SCOPE_LENS, + .moves = {MOVE_SURF, MOVE_PSYCHIC, MOVE_CONFUSE_RAY, MOVE_SWAGGER}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 1, + .personality = 0xA, + .nickname = _("STARMIE"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_DUSCLOPS, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_PURSUIT, MOVE_PROTECT, MOVE_ATTRACT, MOVE_WILL_O_WISP}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x82, + .nickname = _("DUSCLOPS"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_NINETALES, + .heldItem = ITEM_WHITE_HERB, + .moves = {MOVE_OVERHEAT, MOVE_CONFUSE_RAY, MOVE_WILL_O_WISP, MOVE_ATTRACT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .speedEV = 252, + .spAttackEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0xD2, + .nickname = _("NINETALES"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_BANETTE, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_SHADOW_BALL, MOVE_FAINT_ATTACK, MOVE_ATTRACT, MOVE_WILL_O_WISP}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x85, + .nickname = _("BANETTE"), + .friendship = 255, + }, + }, + }, + }, + .data = {0x31, 0x3B, 0x3B, 0x3B, 0x39, 0x39, 0x13, 0x14, 0x15, 0x38, 0x39, 0x3A, 0x3B, 0x3B, 0x3B, 0x8, 0x91, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x78, 0x8, 0x91, 0x46, 0x9B, 0x7C, 0x9B, 0x9B, 0x9B, 0x7D, 0x9B, 0x7C, 0x9B, 0x7B, 0x9B, 0x7A, 0x9B, 0x8, 0x91, 0x46, 0x7D, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x8, 0x91, 0x46, 0x9B, 0x7E, 0x9B, 0x9B, 0x9B, 0x7D, 0x9B, 0x7E, 0x9B, 0xB3, 0x9B, 0x9B, 0x9B, 0x8, 0x91, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x9B, 0x8, 0x91, 0x46, 0x9B, 0x7D, 0x9B, 0x7C, 0x9B, 0x7B, 0x9B, 0x7A, 0x9B, 0x7C, 0x9B, 0x9B, 0x9B, 0x8, 0x91, 0x46, 0x9B, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x8, 0x91, 0x46, 0x9B, 0x7C, 0x9B, 0x7D, 0x9B, 0x7E, 0x9B, 0x9B, 0x9B, 0x7D, 0x9B, 0x7E, 0x9B, 0x8, 0x91, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0xB3, 0x8, 0x91, 0xD6, 0x96, 0x9B, 0x9B, 0x96, 0xD6, 0xDB, 0xD6, 0x96, 0x9B, 0x9B, 0x96, 0xD6, 0x9B, 0x8, 0xD6, 0x96, 0x9B, 0x9B, 0x96, 0xD6, 0xDB, 0xDB, 0xDB, 0xD6, 0x96, 0x9B, 0x9B, 0x96, 0xD6, 0x8, 0x96, 0x9B, 0x9B, 0x96, 0xD6, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xD6, 0x96, 0x9B, 0x9B, 0x96, 0x8, 0xD6, 0x96, 0x9B, 0x9B, 0x96, 0xD6, 0xDB, 0xDB, 0xDB, 0xD6, 0x96, 0x9B, 0x9B, 0x96, 0xD6, 0x8, 0x91, 0xD6, 0x96, 0x9B, 0x9B, 0x96, 0xD6, 0xDB, 0xD6, 0x96, 0x9B, 0x9B, 0x96, 0xD6, 0x9B, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8}, + .unk3A0 = {0x381, 0x7FFD, 0x4001, 0x5FFF, 0x4001, 0x7FFD, 0x4001, 0x5FFF, 0x4001, 0x7FFD, 0x1, 0x1, 0x1, 0x1, 0x1, 0xFFFF}, + .coords = {167, 231}, + .direction = 0x1, + .range = 0x33, + }, + [2] = + { + .unk0 = 0x3D, + .unk1 = 0x3E, + .trainers = + { + [0] = + { + .name = _("TERRENCE"), + .facilityClass = FACILITY_CLASS_EXPERT_M, + .unused = 0, + .speechBefore = {EC_WORD_OH_DEAR, EC_WORD_THIS, EC_WORD_MATCH, EC_WORD_IS, EC_WORD_FOR, EC_WORD_YOU}, + .speechWin = {EC_WORD_OH_DEAR, EC_WORD_DID, EC_WORD_YOU, EC_WORD_SEE, EC_WORD_THAT, EC_WORD_QUES}, + .speechLose = {EC_WORD_OH_DEAR, EC_WORD_I_AM, EC_WORD_SO, EC_WORD_SORRY, 0xFFFF, 0xFFFF}, + .speechAfter = {EC_WORD_IS, EC_WORD_YOUR, EC_WORD_GRANDMOTHER, EC_WORD_STRONG, EC_WORD_QUES, 0xFFFF}, + .mons = + { + [0] = + { + .species = SPECIES_WOBBUFFET, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_MIRROR_COAT, MOVE_COUNTER, MOVE_SAFEGUARD, MOVE_ENCORE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 250, + .defenseEV = 130, + .spDefenseEV = 130, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x94, + .nickname = _("WOBBUFFET"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_EXPLOUD, + .heldItem = ITEM_CHESTO_BERRY, + .moves = {MOVE_HYPER_VOICE, MOVE_COUNTER, MOVE_REST, MOVE_ROCK_SLIDE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 250, + .defenseEV = 130, + .spDefenseEV = 130, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x85, + .nickname = _("EXPLOUD"), + .friendship = 0, + }, + [2] = + { + .species = SPECIES_CROBAT, + .heldItem = ITEM_KINGS_ROCK, + .moves = {MOVE_MEAN_LOOK, MOVE_CONFUSE_RAY, MOVE_AERIAL_ACE, MOVE_TOXIC}, + .level = 0, + .ppBonuses = 0, + .hpEV = 250, + .defenseEV = 130, + .spDefenseEV = 130, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x0, + .nickname = _("CROBAT"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_DUGTRIO, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_DOUBLE_TEAM, MOVE_PROTECT, MOVE_RETURN, MOVE_SLUDGE_BOMB}, + .level = 0, + .ppBonuses = 0, + .hpEV = 6, + .attackEV = 252, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 1, + .personality = 0xD, + .nickname = _("DUGTRIO"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_ELECTRODE, + .heldItem = ITEM_PETAYA_BERRY, + .moves = {MOVE_TORMENT, MOVE_MIRROR_COAT, MOVE_THUNDERBOLT, MOVE_LIGHT_SCREEN}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 252, + .spAttackEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x5, + .nickname = _("ELECTRODE"), + .friendship = 0, + }, + [5] = + { + .species = SPECIES_GENGAR, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_CONFUSE_RAY, MOVE_MEAN_LOOK, MOVE_GIGA_DRAIN, MOVE_WILL_O_WISP}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 252, + .spDefenseEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x14, + .nickname = _("GENGAR"), + .friendship = 255, + }, + }, + }, + [1] = + { + .name = _("CARLOTTA"), + .facilityClass = FACILITY_CLASS_EXPERT_F, + .unused = 0, + .speechBefore = {EC_WORD_OH_DEAR, EC_WORD_I, EC_WORD_WILL, EC_WORD_WIN, EC_WORD_FOR, EC_WORD_YOU}, + .speechWin = {EC_WORD_OH_DEAR, EC_WORD_WE, EC_WORD_HAVE, EC_WORD_A, EC_WORD_PARTY, EC_WORD_LATER}, + .speechLose = {EC_WORD_OH_DEAR, EC_WORD_I_AM, EC_WORD_SORRY, EC_WORD_TO, EC_WORD_DISAPPOINT, EC_WORD_YOU}, + .speechAfter = {EC_WORD_IS, EC_WORD_YOUR, EC_WORD_GRANDFATHER, EC_WORD_COOL, EC_WORD_QUES, 0xFFFF}, + .mons = + { + [0] = + { + .species = SPECIES_LAPRAS, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_SURF, MOVE_ICE_BEAM, MOVE_PERISH_SONG, MOVE_SING}, + .level = 0, + .ppBonuses = 0, + .hpEV = 250, + .defenseEV = 130, + .spDefenseEV = 130, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x82, + .nickname = _("LAPRAS"), + .friendship = 0, + }, + [1] = + { + .species = SPECIES_ABSOL, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_PERISH_SONG, MOVE_DOUBLE_EDGE, MOVE_PROTECT, MOVE_TORMENT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .defenseEV = 6, + .speedEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x8A, + .nickname = _("ABSOL"), + .friendship = 0, + }, + [2] = + { + .species = SPECIES_ALTARIA, + .heldItem = ITEM_KINGS_ROCK, + .moves = {MOVE_PERISH_SONG, MOVE_PROTECT, MOVE_DRAGON_CLAW, MOVE_FIRE_BLAST}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .spAttackEV = 6, + .spDefenseEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x0, + .nickname = _("ALTARIA"), + .friendship = 0, + }, + [3] = + { + .species = SPECIES_DEWGONG, + .heldItem = ITEM_CHESTO_BERRY, + .moves = {MOVE_ICE_BEAM, MOVE_SIGNAL_BEAM, MOVE_REST, MOVE_PERISH_SONG}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 252, + .spAttackEV = 6, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x14, + .nickname = _("DEWGONG"), + .friendship = 0, + }, + [4] = + { + .species = SPECIES_POLITOED, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_HYDRO_PUMP, MOVE_BLIZZARD, MOVE_MIND_READER, MOVE_PERISH_SONG}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .spAttackEV = 6, + .spDefenseEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 1, + .personality = 0x14, + .nickname = _("POLITOED"), + .friendship = 0, + }, + [5] = + { + .species = SPECIES_MAROWAK, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_PERISH_SONG, MOVE_EARTHQUAKE, MOVE_COUNTER, MOVE_PROTECT}, + .level = 0, + .ppBonuses = 0, + .hpEV = 252, + .speedEV = 6, + .spDefenseEV = 252, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 1, + .personality = 0x17, + .nickname = _("MAROWAK"), + .friendship = 0, + }, + }, + }, + }, + .data = {0xD1, 0xDB, 0xDB, 0xDB, 0xD9, 0xD9, 0x1B, 0x14, 0x15, 0x98, 0x99, 0x9A, 0x9B, 0x9B, 0x9B, 0x8, 0xD1, 0xDB, 0xDB, 0xDB, 0xD5, 0xD5, 0xC3, 0xF9, 0x86, 0x8E, 0x95, 0x9B, 0x9B, 0x9B, 0x9B, 0x8, 0xD1, 0xDB, 0xDB, 0xD5, 0xCB, 0xCB, 0xCB, 0xFB, 0x8B, 0x8B, 0x8B, 0x95, 0x9B, 0x9B, 0x9B, 0x8, 0xD1, 0xDB, 0xD5, 0xCB, 0xCB, 0xCB, 0xCB, 0xFB, 0x8B, 0x8B, 0x8B, 0x8B, 0x95, 0x9B, 0x9B, 0x8, 0xD1, 0xDB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xFB, 0x8B, 0x8B, 0x8B, 0x8B, 0x8B, 0x9B, 0x9B, 0x8, 0xD1, 0xD5, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xFB, 0x8C, 0x8B, 0x8B, 0x8B, 0x8B, 0x95, 0x9B, 0x8, 0xD1, 0xCB, 0xCB, 0xCB, 0xCB, 0xCC, 0xCC, 0xFB, 0xFB, 0x8C, 0x8B, 0x8B, 0x8B, 0x8B, 0x9B, 0x8, 0xD1, 0xCC, 0xCC, 0xCC, 0xCC, 0xFB, 0xF5, 0xFB, 0xF5, 0xFB, 0x8B, 0x8B, 0x8B, 0x8B, 0x9B, 0x8, 0xD1, 0xD5, 0xD5, 0xD5, 0xD5, 0xFB, 0xEC, 0xFB, 0xEC, 0xFB, 0x8B, 0x8B, 0x8B, 0x8B, 0x9B, 0x8, 0xD1, 0xCB, 0xCB, 0xCB, 0xCB, 0xF5, 0xF5, 0xFB, 0xFB, 0xF5, 0x8B, 0x8B, 0x8B, 0x8B, 0x9B, 0x8, 0xD1, 0xCC, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xFB, 0xFB, 0x8B, 0x8B, 0x8B, 0x8B, 0x8C, 0x9B, 0x8, 0xD1, 0xDB, 0xCB, 0xCB, 0xCB, 0xCB, 0xCB, 0xFB, 0xF5, 0x8B, 0x8B, 0x8B, 0x8B, 0x9B, 0x9B, 0x8, 0xD1, 0xDB, 0xCC, 0xCB, 0xCB, 0xCB, 0xCB, 0xFB, 0x8B, 0x8B, 0x8B, 0x8B, 0x8C, 0x9B, 0x9B, 0x8, 0xD1, 0xDB, 0xDB, 0xCC, 0xCB, 0xCB, 0xCB, 0xFB, 0x8B, 0x8B, 0x8B, 0x8C, 0x9B, 0x9B, 0x9B, 0x8, 0xD1, 0xDB, 0xDB, 0xDB, 0xCC, 0xCC, 0xCB, 0xFB, 0x8C, 0x8C, 0x8C, 0x9B, 0x9B, 0x9B, 0x9B, 0x8, 0xD1, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xCC, 0xFB, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x9B, 0x8}, + .unk3A0 = {0x381, 0x201, 0xEE1, 0x1EF1, 0x3EF9, 0x3EF9, 0x7E7D, 0x783D, 0x2BD, 0x783D, 0x7E7D, 0x3E79, 0x3EF9, 0x1EF1, 0xEE1, 0x201}, + .coords = {103, 167}, + .direction = 0x1, + .range = 0x33, + }, + [3] = + { + .unk0 = 0x3F, + .unk1 = 0x40, + .trainers = + { + [0] = + { + .name = _("NORA"), + .facilityClass = FACILITY_CLASS_PKMN_RANGER_F, + .unused = 0, + .speechBefore = {EC_WORD_WAAAH, EC_WORD_THIS, EC_WORD_IS, EC_WORD_SO, EC_WORD_EXCITING, EC_WORD_EXCL}, + .speechWin = {EC_WORD_WAAAH, EC_WORD_I_AM, EC_WORD_SO, EC_WORD_HAPPY, EC_WORD_I, EC_WORD_WON}, + .speechLose = {EC_WORD_WAAAH, EC_WORD_I_AM, EC_WORD_SO, EC_WORD_SAD, EC_WORD_I, EC_WORD_LOST}, + .speechAfter = {EC_WORD_WAAAH, EC_WORD_EXCL, 0xFFFF, EC_WORD_GO, EC_WORD_AWAY, EC_WORD_EXCL}, + .mons = + { + [0] = + { + .species = SPECIES_FORRETRESS, + .heldItem = ITEM_QUICK_CLAW, + .moves = {MOVE_EXPLOSION, MOVE_EARTHQUAKE, MOVE_ATTRACT, MOVE_SPIKES}, + .level = 0, + .ppBonuses = 0, + .hpEV = 110, + .attackEV = 200, + .spDefenseEV = 200, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x3, + .nickname = _("FORRETRESS"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_ELECTRODE, + .heldItem = ITEM_SALAC_BERRY, + .moves = {MOVE_EXPLOSION, MOVE_THUNDERBOLT, MOVE_SWIFT, MOVE_LIGHT_SCREEN}, + .level = 0, + .ppBonuses = 0, + .attackEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 1, + .personality = 0xC, + .nickname = _("ELECTRODE"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_EXEGGUTOR, + .heldItem = ITEM_SHELL_BELL, + .moves = {MOVE_EXPLOSION, MOVE_HYPNOSIS, MOVE_PSYCHIC, MOVE_SOLAR_BEAM}, + .level = 0, + .ppBonuses = 0, + .attackEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x7F, + .nickname = _("EXEGGUTOR"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_DUSCLOPS, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_IMPRISON, MOVE_PROTECT, MOVE_ICE_BEAM, MOVE_EARTHQUAKE}, + .level = 0, + .ppBonuses = 0, + .hpEV = 110, + .defenseEV = 200, + .spDefenseEV = 200, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x93, + .nickname = _("DUSCLOPS"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_NINETALES, + .heldItem = ITEM_WHITE_HERB, + .moves = {MOVE_IMPRISON, MOVE_PROTECT, MOVE_OVERHEAT, MOVE_CONFUSE_RAY}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0xF, + .nickname = _("NINETALES"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_BANETTE, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_IMPRISON, MOVE_PROTECT, MOVE_THUNDERBOLT, MOVE_THUNDER}, + .level = 0, + .ppBonuses = 0, + .hpEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x96, + .nickname = _("BANETTE"), + .friendship = 255, + }, + }, + }, + [1] = + { + .name = _("GAV"), + .facilityClass = FACILITY_CLASS_PKMN_RANGER_M, + .unused = 0, + .speechBefore = {EC_WORD_WAHAHAHA, EC_WORD_YOU, EC_WORD_CAN_T, EC_WORD_STOP, EC_WORD_ME, EC_WORD_EXCL}, + .speechWin = {EC_WORD_WOWEE, EC_WORD_EXCL, 0xFFFF, EC_WORD_I_AM, EC_WORD_AWESOME, EC_WORD_COOL}, + .speechLose = {EC_WORD_I_AM, EC_WORD_NOT, EC_WORD_COOL, EC_WORD_AT, EC_WORD_ALL, EC_WORD_EXCL}, + .speechAfter = {EC_WORD_HEHEHE, EC_WORD_THAT_WAS, EC_WORD_AN, EC_WORD_AWESOME, EC_WORD_BATTLE, EC_WORD_EXCL}, + .mons = + { + [0] = + { + .species = SPECIES_SALAMENCE, + .heldItem = ITEM_SHELL_BELL, + .moves = {MOVE_ROCK_SLIDE, MOVE_FLAMETHROWER, MOVE_DRAGON_CLAW, MOVE_AERIAL_ACE}, + .level = 0, + .ppBonuses = 0, + .attackEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x95, + .nickname = _("SALAMENCE"), + .friendship = 255, + }, + [1] = + { + .species = SPECIES_GENGAR, + .heldItem = ITEM_LUM_BERRY, + .moves = {MOVE_PSYCHIC, MOVE_GIGA_DRAIN, MOVE_WILL_O_WISP, MOVE_DESTINY_BOND}, + .level = 0, + .ppBonuses = 0, + .speedEV = 255, + .spAttackEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x8C, + .nickname = _("GENGAR"), + .friendship = 255, + }, + [2] = + { + .species = SPECIES_GYARADOS, + .heldItem = ITEM_BRIGHT_POWDER, + .moves = {MOVE_DRAGON_DANCE, MOVE_HYPER_BEAM, MOVE_BITE, MOVE_EARTHQUAKE}, + .level = 0, + .ppBonuses = 0, + .attackEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x3, + .nickname = _("GYARADOS"), + .friendship = 255, + }, + [3] = + { + .species = SPECIES_GENGAR, + .heldItem = ITEM_SALAC_BERRY, + .moves = {MOVE_EXPLOSION, MOVE_MEAN_LOOK, MOVE_SHADOW_BALL, MOVE_CONFUSE_RAY}, + .level = 0, + .ppBonuses = 0, + .attackEV = 255, + .speedEV = 255, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x3, + .nickname = _("GENGAR"), + .friendship = 255, + }, + [4] = + { + .species = SPECIES_DUSCLOPS, + .heldItem = ITEM_LEFTOVERS, + .moves = {MOVE_MEAN_LOOK, MOVE_CONFUSE_RAY, MOVE_WILL_O_WISP, MOVE_SHADOW_BALL}, + .level = 0, + .ppBonuses = 0, + .hpEV = 110, + .defenseEV = 200, + .spDefenseEV = 200, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x14, + .nickname = _("DUSCLOPS"), + .friendship = 255, + }, + [5] = + { + .species = SPECIES_MISDREAVUS, + .heldItem = ITEM_FOCUS_BAND, + .moves = {MOVE_MEAN_LOOK, MOVE_CONFUSE_RAY, MOVE_PERISH_SONG, MOVE_SHADOW_BALL}, + .level = 0, + .ppBonuses = 0, + .hpEV = 180, + .defenseEV = 180, + .spDefenseEV = 150, + .otId = TRAINER_HILL_OTID, + .hpIV = 31, + .attackIV = 31, + .defenseIV = 31, + .speedIV = 31, + .spAttackIV = 31, + .spDefenseIV = 31, + .altAbility = 0, + .personality = 0x85, + .nickname = _("MISDREAVUS"), + .friendship = 255, + }, + }, + }, + }, + .data = {0x31, 0x3B, 0x3B, 0x3B, 0x39, 0x39, 0x13, 0x14, 0x15, 0x39, 0x39, 0x3A, 0x3B, 0x3B, 0x3B, 0x8, 0x96, 0xFB, 0xF6, 0xFD, 0xF6, 0xF6, 0xFB, 0x46, 0xFB, 0xF6, 0xF6, 0xFD, 0xF6, 0xFB, 0x9B, 0x8, 0xFB, 0x9B, 0xFB, 0xF6, 0xFB, 0xFB, 0xFB, 0x46, 0xFB, 0xFB, 0xFB, 0xF6, 0xFB, 0x9B, 0xFB, 0x8, 0xF6, 0xFB, 0x9B, 0xFB, 0xFB, 0x46, 0x46, 0x9B, 0x46, 0x46, 0xFB, 0xFB, 0x9B, 0xFB, 0xF6, 0x8, 0xFD, 0xF6, 0xFB, 0x9B, 0x46, 0x36, 0x36, 0x9B, 0x36, 0x36, 0x46, 0x9B, 0xFB, 0xF6, 0xFD, 0x8, 0xF6, 0xFB, 0xFB, 0x46, 0x9B, 0x46, 0x46, 0xDB, 0x46, 0x46, 0x9B, 0x46, 0xFB, 0xFB, 0xF6, 0x8, 0xF6, 0xFB, 0x46, 0x36, 0x46, 0x9B, 0xDB, 0xD6, 0xDB, 0x9B, 0x46, 0x36, 0x46, 0xFB, 0xF6, 0x8, 0xFB, 0xFB, 0x46, 0x36, 0x9B, 0xDB, 0xD6, 0xD6, 0xD6, 0xDB, 0x9B, 0x36, 0x46, 0xFB, 0xFB, 0x8, 0x96, 0x9B, 0x9B, 0x9B, 0x9B, 0xD6, 0xD6, 0x96, 0xD6, 0xD6, 0xDB, 0x9B, 0x9B, 0x9B, 0x96, 0x8, 0xFB, 0xFB, 0x46, 0x36, 0x9B, 0xDB, 0xD6, 0xD6, 0xD6, 0xDB, 0x9B, 0x36, 0x46, 0xFB, 0xFB, 0x8, 0xF6, 0xFB, 0x46, 0x36, 0x46, 0x9B, 0xDB, 0xD6, 0xDB, 0x9B, 0x46, 0x36, 0x46, 0xFB, 0xF6, 0x8, 0xF6, 0xFB, 0xFB, 0x46, 0x9B, 0x46, 0x46, 0xDB, 0x46, 0x46, 0x9B, 0x46, 0xFB, 0xFB, 0xF6, 0x8, 0xFD, 0xF6, 0xFB, 0x9B, 0x46, 0x36, 0x36, 0x9B, 0x36, 0x36, 0x46, 0x9B, 0xFB, 0xF6, 0xFD, 0x8, 0xF6, 0xFB, 0x9B, 0xFB, 0xFB, 0x46, 0x46, 0x9B, 0x46, 0x46, 0xFB, 0xFB, 0x9B, 0xFB, 0xF6, 0x8, 0xFB, 0x9B, 0xFB, 0xF6, 0xFB, 0xFB, 0xFB, 0x46, 0xFB, 0xFB, 0xFB, 0xF6, 0xFB, 0x9B, 0xFB, 0x8, 0x96, 0xFB, 0xF6, 0xFD, 0xF6, 0xF6, 0xFB, 0x46, 0xFB, 0xF6, 0xF6, 0xFD, 0xF6, 0xFB, 0x9B, 0x8}, + .unk3A0 = {0x381, 0x101, 0x101, 0x6C1, 0x821, 0x16D1, 0x2829, 0x2009, 0x1, 0x2009, 0x2829, 0x16D1, 0x821, 0x6C1, 0x101, 0x101}, + .coords = {103, 167}, + .direction = 0x1, + .range = 0x33, + }, + }, +}; diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 7cee717bf..6e1bae31e 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -20,6 +20,7 @@ #include "sprite.h" #include "task.h" #include "trainer_see.h" +#include "trainer_hill.h" #include "util.h" #include "constants/event_object_movement_constants.h" #include "constants/event_objects.h" diff --git a/src/field_control_avatar.c b/src/field_control_avatar.c index 4f6f5acdf..00dce4c7d 100644 --- a/src/field_control_avatar.c +++ b/src/field_control_avatar.c @@ -25,6 +25,7 @@ #include "sound.h" #include "start_menu.h" #include "trainer_see.h" +#include "trainer_hill.h" #include "wild_encounter.h" #include "constants/bg_event_constants.h" #include "constants/event_objects.h" diff --git a/src/field_poison.c b/src/field_poison.c index fac17dea9..89cd02728 100644 --- a/src/field_poison.c +++ b/src/field_poison.c @@ -13,6 +13,7 @@ #include "string_util.h" #include "strings.h" #include "task.h" +#include "trainer_hill.h" #include "constants/species.h" static bool32 IsMonValidSpecies(struct Pokemon *pokemon) diff --git a/src/fieldmap.c b/src/fieldmap.c index d2ff34b1c..f67f61ede 100644 --- a/src/fieldmap.c +++ b/src/fieldmap.c @@ -11,6 +11,7 @@ #include "pokenav.h" #include "script.h" #include "secret_base.h" +#include "trainer_hill.h" #include "tv.h" #include "constants/rgb.h" diff --git a/src/frontier_pass.c b/src/frontier_pass.c new file mode 100644 index 000000000..0db546c4d --- /dev/null +++ b/src/frontier_pass.c @@ -0,0 +1,1709 @@ +#include "global.h" +#include "gpu_regs.h" +#include "main.h" +#include "trainer_card.h" +#include "battle_anim.h" +#include "event_data.h" +#include "recorded_battle.h" +#include "alloc.h" +#include "sprite.h" +#include "scanline_effect.h" +#include "text_window.h" +#include "task.h" +#include "graphics.h" +#include "strings.h" +#include "frontier_pass.h" +#include "international_string_util.h" +#include "palette.h" +#include "window.h" +#include "decompress.h" +#include "menu_helpers.h" +#include "menu.h" +#include "bg.h" +#include "sound.h" +#include "string_util.h" +#include "battle_pyramid.h" +#include "overworld.h" +#include "math_util.h" +#include "constants/battle_frontier.h" +#include "constants/maps.h" +#include "constants/rgb.h" +#include "constants/region_map_sections.h" +#include "constants/songs.h" + +// All windows displayed in the frontier pass. +enum +{ + WINDOW_EARNED_SYMBOLS, + WINDOW_BATTLE_RECORD, + WINDOW_BATTLE_POINTS, + WINDOW_DESCRIPTION, + WINDOW_4, + WINDOW_COUNT +}; + +// Windows displayed in the facilities map view. +enum +{ + MAP_WINDOW_0, + MAP_WINDOW_NAME, + MAP_WINDOW_DESCRIPTION, + MAP_WINDOW_COUNT +}; + +enum +{ + CURSOR_AREA_NOTHING, + CURSOR_AREA_MAP, + CURSOR_AREA_CARD, + CURSOR_AREA_RECORD, + CURSOR_AREA_CANCEL, + CURSOR_AREA_POINTS, + CURSOR_AREA_EARNED_SYMBOLS, // The window. + CURSOR_AREA_SYMBOL, // All 7 symbols. + CURSOR_AREA_COUNT = CURSOR_AREA_SYMBOL + NUM_FRONTIER_FACILITIES, +}; + +struct FrontierPassData +{ + void (*callback)(void); + u16 state; + u16 battlePoints; + s16 cursorX; + s16 cursorY; + u8 cursorArea; + u8 previousCursorArea; + u8 hasBattleRecord:1; + u8 unkE:3; + u8 trainerStars:4; + u8 facilitySymbols[NUM_FRONTIER_FACILITIES]; +}; + +struct FrontierPassGfx +{ + struct Sprite *cursorSprite; + struct Sprite *symbolSprites[NUM_FRONTIER_FACILITIES]; + u8 *unk20; + u8 *unk24; + u8 *unk28; + bool8 setAffine; + s16 unk2E; + s16 unk30; + u8 tilemapBuff1[0x1000]; + u8 tilemapBuff2[0x1000]; + u8 tilemapBuff3[0x400]; +}; + +struct FrontierPassSaved +{ + void (*callback)(void); + s16 cursorX; + s16 cursorY; +}; + +struct FrontierMapData +{ + void (*callback)(void); + struct Sprite *cursorSprite; + struct Sprite *playerHeadSprite; + struct Sprite *mapIndicatorSprite; + u8 cursorPos; + u8 unused; + u8 tilemapBuff0[0x1000]; + u8 tilemapBuff1[0x1000]; + u8 tilemapBuff2[0x1000]; +}; + +static EWRAM_DATA struct FrontierPassData *sPassData = NULL; +static EWRAM_DATA struct FrontierPassGfx *sPassGfx = NULL; +static EWRAM_DATA struct FrontierMapData *sMapData = NULL; +static EWRAM_DATA struct FrontierPassSaved sSavedPassData = {0}; + +// This file's functions. +static u32 AllocateFrontierPassData(void (*callback)(void)); +static void ShowFrontierMap(void (*callback)(void)); +static void CB2_InitFrontierPass(void); +static void sub_80C629C(void); +static void FreeCursorAndSymbolSprites(void); +static void LoadCursorAndSymbolSprites(void); +static u32 FreeFrontierPassData(void); +static bool32 InitFrontierPass(void); +static bool32 HideFrontierPass(void); +static void Task_HandleFrontierPassInput(u8 taskId); +static void Task_DoFadeEffect(u8 taskId); +static void sub_80C6104(u8 cursorArea, u8 previousCursorArea); +static void PrintAreaDescription(u8 cursorArea); +static void sub_80C5F58(bool8 arg0, bool8 arg1); +static void SpriteCb_Dummy(struct Sprite *sprite); + +// Const rom data. +static const u16 sMaleHeadPalette[] = INCBIN_U16("graphics/frontier_pass/map_heads.gbapal"); +static const u16 sFemaleHeadPalette[] = INCBIN_U16("graphics/frontier_pass/map_heads_female.gbapal"); +static const u32 gUnknown_0856FBBC[] = INCBIN_U32("graphics/frontier_pass/map_screen.4bpp.lz"); +static const u32 sCursorGfx[] = INCBIN_U32("graphics/frontier_pass/cursor.4bpp.lz"); +static const u32 sHeadsGfx[] = INCBIN_U32("graphics/frontier_pass/map_heads.4bpp.lz"); +static const u32 sMapCursorGfx[] = INCBIN_U32("graphics/frontier_pass/map_cursor.4bpp.lz"); +static const u32 gUnknown_08570E00[] = INCBIN_U32("graphics/frontier_pass/map_screen.bin.lz"); +static const u32 gUnknown_08571060[] = INCBIN_U32("graphics/frontier_pass/small_map_and_card.bin.lz"); +static const u32 gUnknown_08571298[] = INCBIN_U32("graphics/frontier_pass/unknown_571298.bin"); +static const u32 gUnknown_085712C0[] = INCBIN_U32("graphics/frontier_pass/record_frame.bin.lz"); +static const u32 gUnknown_085712F8[] = INCBIN_U32("graphics/frontier_pass/small_map_and_card_affine.bin.lz"); + +static const s16 gUnknown_085713E0[][2] = {{216, 32}, {216, 128}}; + +static const struct BgTemplate sPassBgTemplates[] = +{ + { + .bg = 0, + .charBaseIndex = 2, + .mapBaseIndex = 31, + .screenSize = 0, + .paletteMode = 0, + .priority = 1, + .baseTile = 0 + }, + { + .bg = 1, + .charBaseIndex = 0, + .mapBaseIndex = 30, + .screenSize = 0, + .paletteMode = 0, + .priority = 2, + .baseTile = 0 + }, + { + .bg = 2, + .charBaseIndex = 1, + .mapBaseIndex = 29, + .screenSize = 1, + .paletteMode = 1, + .priority = 0, + .baseTile = 0 + }, +}; + +static const struct BgTemplate sMapBgTemplates[] = +{ + { + .bg = 0, + .charBaseIndex = 2, + .mapBaseIndex = 31, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0 + }, + { + .bg = 1, + .charBaseIndex = 0, + .mapBaseIndex = 30, + .screenSize = 0, + .paletteMode = 0, + .priority = 1, + .baseTile = 0 + }, + { + .bg = 2, + .charBaseIndex = 0, + .mapBaseIndex = 29, + .screenSize = 0, + .paletteMode = 0, + .priority = 2, + .baseTile = 0 + }, +}; + +static const struct WindowTemplate sPassWindowTemplates[] = +{ + { + .bg = 0, + .tilemapLeft = 2, + .tilemapTop = 3, + .width = 12, + .height = 3, + .paletteNum = 15, + .baseBlock = 0x1, + }, + { + .bg = 0, + .tilemapLeft = 2, + .tilemapTop = 10, + .width = 12, + .height = 3, + .paletteNum = 15, + .baseBlock = 0x26, + }, + { + .bg = 0, + .tilemapLeft = 2, + .tilemapTop = 13, + .width = 12, + .height = 4, + .paletteNum = 15, + .baseBlock = 0x4B, + }, + { + .bg = 0, + .tilemapLeft = 0, + .tilemapTop = 18, + .width = 30, + .height = 3, + .paletteNum = 15, + .baseBlock = 0x7C, + }, + DUMMY_WIN_TEMPLATE +}; + +static const struct WindowTemplate sMapWindowTemplates[] = +{ + { + .bg = 0, + .tilemapLeft = 0, + .tilemapTop = 1, + .width = 15, + .height = 5, + .paletteNum = 15, + .baseBlock = 0x1, + }, + { + .bg = 0, + .tilemapLeft = 20, + .tilemapTop = 1, + .width = 10, + .height = 14, + .paletteNum = 15, + .baseBlock = 0x4D, + }, + { + .bg = 0, + .tilemapLeft = 2, + .tilemapTop = 16, + .width = 26, + .height = 4, + .paletteNum = 15, + .baseBlock = 0xDA, + }, + DUMMY_WIN_TEMPLATE +}; + +static const u8 sTextColors[][3] = +{ + {0, 2, 3}, + {0, 1, 9}, + {0, 4, 5}, +}; + +struct +{ + s16 yStart; + s16 yEnd; + s16 xStart; + s16 xEnd; +} +static const sPassAreasLayout[] = +{ + {28, 76, 132, 220}, + {84, 132, 132, 220}, + {80, 102, 20, 108}, + {0, 16, 152, 240}, + {108, 134, 20, 108}, + {24, 48, 20, 108}, + {50, 66, 20, 36}, + {66, 82, 32, 48}, + {50, 66, 44, 60}, + {66, 82, 56, 72}, + {50, 66, 68, 84}, + {66, 82, 80, 96}, + {50, 66, 92, 108}, +}; + +static const struct CompressedSpriteSheet sCursorSpriteSheets[] = +{ + {sCursorGfx, 0x100, 0}, + {sMapCursorGfx, 0x400, 1}, + {gFrontierPassMedals_Gfx, 0x380, 2}, +}; + +static const struct CompressedSpriteSheet sHeadsSpriteSheet[] = +{ + {sHeadsGfx, 0x100, 4}, + {} +}; + +static const struct SpritePalette sSpritePalettes[] = +{ + {gFrontierPassCursor_Pal, 0}, + {gFrontierPassMapCursor_Pal, 1}, + {gFrontierPassMedalsSilver_Pal, 2}, + {gFrontierPassMedalsGold_Pal, 3}, + {sMaleHeadPalette, 4}, + {sFemaleHeadPalette, 5}, + {} +}; + +static const union AnimCmd sSpriteAnim_857151C[] = +{ + ANIMCMD_FRAME(0, 0), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8571524[] = +{ + ANIMCMD_FRAME(0, 0), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_857152C[] = +{ + ANIMCMD_FRAME(4, 0), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8571534[] = +{ + ANIMCMD_FRAME(8, 0), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_857153C[] = +{ + ANIMCMD_FRAME(12, 0), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8571544[] = +{ + ANIMCMD_FRAME(16, 0), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_857154C[] = +{ + ANIMCMD_FRAME(20, 0), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_8571554[] = +{ + ANIMCMD_FRAME(24, 0), + ANIMCMD_END +}; + +static const union AnimCmd sSpriteAnim_857155C[] = +{ + ANIMCMD_FRAME(0, 45), + ANIMCMD_FRAME(8, 45), + ANIMCMD_JUMP(0) +}; + +static const union AnimCmd sSpriteAnim_8571568[] = +{ + ANIMCMD_FRAME(16, 45), + ANIMCMD_FRAME(24, 45), + ANIMCMD_JUMP(0) +}; + +static const union AnimCmd *const sSpriteAnimTable_8571574[] = +{ + sSpriteAnim_8571524, + sSpriteAnim_857152C +}; + +static const union AnimCmd *const sSpriteAnimTable_857157C[] = +{ + sSpriteAnim_8571524, + sSpriteAnim_857152C, + sSpriteAnim_8571534, + sSpriteAnim_857153C, + sSpriteAnim_8571544, + sSpriteAnim_857154C, + sSpriteAnim_8571554 +}; + +static const union AnimCmd *const sSpriteAnimTable_8571598[] = +{ + sSpriteAnim_857155C, + sSpriteAnim_8571568 +}; + +static const union AffineAnimCmd sSpriteAffineAnim_85715A0[] = +{ + AFFINEANIMCMD_FRAME(256, 256, 0, 0), + AFFINEANIMCMD_END +}; + +static const union AffineAnimCmd *const sSpriteAffineAnimTable_85715B0[] = +{ + sSpriteAffineAnim_85715A0 +}; + +static const struct SpriteTemplate sSpriteTemplates_Cursors[] = +{ + { + .tileTag = 0, + .paletteTag = 0, + .oam = &gUnknown_0852490C, + .anims = sSpriteAnimTable_8571574, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, + { + .tileTag = 1, + .paletteTag = 1, + .oam = &gUnknown_08524934, + .anims = sSpriteAnimTable_8571598, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, + }, +}; + +static const struct SpriteTemplate sSpriteTemplate_Medal = +{ + .tileTag = 2, + .paletteTag = 2, + .oam = &gUnknown_0852490C, + .anims = sSpriteAnimTable_857157C, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy, +}; + +static const struct SpriteTemplate sSpriteTemplate_Head = +{ + .tileTag = 4, + .paletteTag = 4, + .oam = &gUnknown_0852490C, + .anims = sSpriteAnimTable_8571574, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCb_Dummy, +}; + +static const u8 *const sPassAreaDescriptions[] = +{ + gUnknown_085EDA96, + gUnknown_085ED932, + gUnknown_085ED94D, + gUnknown_085ED961, + gUnknown_085ED977, + gUnknown_085ED993, + gUnknown_085ED9AF, + gUnknown_085ED9C7, + gUnknown_085ED9E5, + gUnknown_085EDA02, + gUnknown_085EDA21, + gUnknown_085EDA3C, + gUnknown_085EDA5E, + gUnknown_085EDA78, + gUnknown_085ED931, +}; + +struct +{ + const u8 *name; + const u8 *description; + s16 x; + s16 y; + u8 animNum; +} static const sMapLandmarks[] = +{ + {gUnknown_085EDAB1, gUnknown_085EDB0F, 0x59, 0x28, 1}, + {gUnknown_085EDABE, gUnknown_085EDB4E, 0x21, 0x2A, 1}, + {gUnknown_085EDACA, gUnknown_085EDB8B, 0x78, 0x56, 0}, + {gUnknown_085EDAD8, gUnknown_085EDBC2, 0x72, 0x3B, 0}, + {gUnknown_085EDAE5, gUnknown_085EDC00, 0x19, 0x43, 0}, + {gUnknown_085EDAF4, gUnknown_085EDC45, 0x39, 0x39, 1}, + {gUnknown_085EDB00, gUnknown_085EDC84, 0x86, 0x29, 1}, +}; + +// code +static void ResetGpuRegsAndBgs(void) +{ + SetGpuReg(REG_OFFSET_DISPCNT, 0); + SetGpuReg(REG_OFFSET_BG3CNT, 0); + SetGpuReg(REG_OFFSET_BG2CNT, 0); + SetGpuReg(REG_OFFSET_BG1CNT, 0); + SetGpuReg(REG_OFFSET_BG0CNT, 0); + ChangeBgX(0, 0, 0); + ChangeBgY(0, 0, 0); + ChangeBgX(1, 0, 0); + ChangeBgY(1, 0, 0); + ChangeBgX(2, 0, 0); + ChangeBgY(2, 0, 0); + ChangeBgX(3, 0, 0); + ChangeBgY(3, 0, 0); + SetGpuReg(REG_OFFSET_BLDCNT, 0); + SetGpuReg(REG_OFFSET_BLDY, 0); + SetGpuReg(REG_OFFSET_BLDALPHA, 0); + SetGpuReg(REG_OFFSET_WIN0H, 0); + SetGpuReg(REG_OFFSET_WIN0V, 0); + SetGpuReg(REG_OFFSET_WIN1H, 0); + SetGpuReg(REG_OFFSET_WIN1V, 0); + SetGpuReg(REG_OFFSET_WININ, 0); + SetGpuReg(REG_OFFSET_WINOUT, 0); + CpuFill16(0, (void *)VRAM, VRAM_SIZE); + CpuFill32(0, (void *)OAM, OAM_SIZE); +} + +void ShowFrontierPass(void (*callback)(void)) +{ + AllocateFrontierPassData(callback); + SetMainCallback2(CB2_InitFrontierPass); +} + +static void LeaveFrontierPass(void) +{ + SetMainCallback2(sPassData->callback); + FreeFrontierPassData(); +} + +static u32 AllocateFrontierPassData(void (*callback)(void)) +{ + u8 i; + + if (sPassData != NULL) + return 1; + + sPassData = AllocZeroed(sizeof(*sPassData)); + if (sPassData == NULL) + return 2; + + sPassData->callback = callback; + i = GetCurrentRegionMapSectionId(); + if (i != MAPSEC_BATTLE_FRONTIER && i != MAPSEC_ARTISAN_CAVE) + { + sPassData->cursorX = 176; + sPassData->cursorY = 104; + } + else + { + sPassData->cursorX = 176; + sPassData->cursorY = 48; + } + + sPassData->battlePoints = gSaveBlock2Ptr->frontier.battlePoints; + sPassData->hasBattleRecord = CanCopyRecordedBattleSaveData(); + sPassData->unkE = 0; + sPassData->trainerStars = CountPlayerTrainerStars(); + for (i = 0; i < 7; i++) + { + if (FlagGet(FLAG_SYS_TOWER_SILVER + i * 2)) + sPassData->facilitySymbols[i]++; + if (FlagGet(FLAG_SYS_TOWER_GOLD + i * 2)) + sPassData->facilitySymbols[i]++; + } + + return 0; +} + +static u32 FreeFrontierPassData(void) +{ + if (sPassData == NULL) + return 1; + + memset(sPassData, 0, sizeof(*sPassData)); // Why clear data, if it's going to be freed anyway? + FREE_AND_SET_NULL(sPassData); + return 0; +} + +static u32 AllocateFrontierPassGfx(void) +{ + if (sPassGfx != NULL) + return 1; + + sPassGfx = AllocZeroed(sizeof(*sPassGfx)); + if (sPassGfx == NULL) + return 2; + + return 0; +} + +static u32 FreeFrontierPassGfx(void) +{ + FreeAllWindowBuffers(); + if (sPassGfx == NULL) + return 1; + + if (sPassGfx->unk28 != NULL) + FREE_AND_SET_NULL(sPassGfx->unk28); + if (sPassGfx->unk24 != NULL) + FREE_AND_SET_NULL(sPassGfx->unk24); + if (sPassGfx->unk20 != NULL) + FREE_AND_SET_NULL(sPassGfx->unk20); + + memset(sPassGfx, 0, sizeof(*sPassGfx)); // Why clear data, if it's going to be freed anyway? + FREE_AND_SET_NULL(sPassGfx); + return 0; +} + +static void VblankCb_FrontierPass(void) +{ + if (sPassGfx->setAffine) + { + SetBgAffine(2, + gUnknown_085713E0[sPassData->unkE - 1][0] << 8, + gUnknown_085713E0[sPassData->unkE - 1][1] << 8, + gUnknown_085713E0[sPassData->unkE - 1][0], + gUnknown_085713E0[sPassData->unkE - 1][1], + sPassGfx->unk2E, + sPassGfx->unk30, + 0); + } + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void CB2_FrontierPass(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); +} + +static void CB2_InitFrontierPass(void) +{ + if (InitFrontierPass()) + { + CreateTask(Task_HandleFrontierPassInput, 0); + SetMainCallback2(CB2_FrontierPass); + } +} + +static void CB2_HideFrontierPass(void) +{ + if (HideFrontierPass()) + LeaveFrontierPass(); +} + +static bool32 InitFrontierPass(void) +{ + u32 sizeOut = 0; + + switch (sPassData->state) + { + case 0: + SetVBlankCallback(NULL); + ScanlineEffect_Stop(); + SetVBlankHBlankCallbacksToNull(); + DisableInterrupts(INTR_FLAG_HBLANK); + break; + case 1: + ResetGpuRegsAndBgs(); + break; + case 2: + ResetTasks(); + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetPaletteFade(); + reset_temp_tile_data_buffers(); + break; + case 3: + AllocateFrontierPassGfx(); + break; + case 4: + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(1, sPassBgTemplates, ARRAY_COUNT(sPassBgTemplates)); + SetBgTilemapBuffer(1, sPassGfx->tilemapBuff1); + SetBgTilemapBuffer(2, sPassGfx->tilemapBuff2); + SetBgTilemapBuffer(3, sPassGfx->tilemapBuff3); + SetBgAttribute(2, BG_ATTR_WRAPAROUND, 1); + break; + case 5: + InitWindows(sPassWindowTemplates); + DeactivateAllTextPrinters(); + break; + case 6: + sPassGfx->unk20 = malloc_and_decompress(gUnknown_085712F8, &sizeOut); + sPassGfx->unk24 = malloc_and_decompress(gUnknown_08571060, &sizeOut); + sPassGfx->unk28 = malloc_and_decompress(gUnknown_085712C0, &sizeOut); + decompress_and_copy_tile_data_to_vram(1, gUnknown_08DE08C8, 0, 0, 0); + decompress_and_copy_tile_data_to_vram(2, gUnknown_08DE2084, 0, 0, 0); + break; + case 7: + if (free_temp_tile_data_buffers_if_possible()) + return FALSE; + FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 30, 20); + FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 30, 20); + FillBgTilemapBufferRect_Palette0(2, 0, 0, 0, 30, 20); + CopyBgTilemapBufferToVram(0); + CopyBgTilemapBufferToVram(1); + CopyBgTilemapBufferToVram(2); + break; + case 8: + LoadPalette(gUnknown_08DE07C8[0], 0, 0x1A0); + LoadPalette(gUnknown_08DE07C8[1 + sPassData->trainerStars], 0x10, 0x20); + LoadPalette(stdpal_get(0), 0xF0, 0x20); + sub_80C629C(); + sub_80C6104(sPassData->cursorArea, sPassData->previousCursorArea); + if (sPassData->unkE == 1 || sPassData->unkE == 2) + { + sPassData->state = 0; + return TRUE; + } + break; + case 9: + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + ShowBg(0); + ShowBg(1); + ShowBg(2); + LoadCursorAndSymbolSprites(); + SetVBlankCallback(VblankCb_FrontierPass); + BlendPalettes(0xFFFFFFFF, 0x10, RGB_BLACK); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_BLACK); + break; + case 10: + AnimateSprites(); + BuildOamBuffer(); + if (UpdatePaletteFade()) + return FALSE; + + sPassData->state = 0; + return TRUE; + } + + sPassData->state++; + return FALSE; +} + +static bool32 HideFrontierPass(void) +{ + switch (sPassData->state) + { + case 0: + if (sPassData->unkE != 1 && sPassData->unkE != 2) + { + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK); + } + else + { + sPassData->state = 2; + return FALSE; + } + break; + case 1: + if (UpdatePaletteFade()) + return FALSE; + break; + case 2: + SetGpuReg(REG_OFFSET_DISPCNT, 0); + HideBg(0); + HideBg(1); + HideBg(2); + SetVBlankCallback(NULL); + ScanlineEffect_Stop(); + SetVBlankHBlankCallbacksToNull(); + break; + case 3: + FreeCursorAndSymbolSprites(); + break; + case 4: + ResetGpuRegsAndBgs(); + ResetTasks(); + ResetSpriteData(); + FreeAllSpritePalettes(); + break; + case 5: + UnsetBgTilemapBuffer(0); + UnsetBgTilemapBuffer(1); + UnsetBgTilemapBuffer(2); + FreeFrontierPassGfx(); + sPassData->state = 0; + return TRUE; + } + + sPassData->state++; + return FALSE; +} + +static u8 GetCursorAreaFromCoords(s16 x, s16 y) +{ + u8 i; + + // Minus/Plus 1, because the table doesn't take into account the nothing field. + for (i = 0; i < CURSOR_AREA_COUNT - 1; i++) + { + if (sPassAreasLayout[i].yStart <= y && sPassAreasLayout[i].yEnd >= y + && sPassAreasLayout[i].xStart <= x && sPassAreasLayout[i].xEnd >= x) + { + if (i >= CURSOR_AREA_SYMBOL - 1 && sPassData->facilitySymbols[i - CURSOR_AREA_SYMBOL + 1] == 0) + break; + + return i + 1; + } + } + + return 0; +} + +void CB2_ReshowFrontierPass(void) +{ + u8 taskId; + + if (!InitFrontierPass()) + return; + + switch (sPassData->unkE) + { + case 1: + case 2: + taskId = CreateTask(Task_DoFadeEffect, 0); + gTasks[taskId].data[0] = TRUE; + break; + case 3: + default: + sPassData->unkE = 0; + taskId = CreateTask(Task_HandleFrontierPassInput, 0); + break; + } + + SetMainCallback2(CB2_FrontierPass); +} + +static void CB2_ReturnFromRecord(void) +{ + AllocateFrontierPassData(sSavedPassData.callback); + sPassData->cursorX = sSavedPassData.cursorX; + sPassData->cursorY = sSavedPassData.cursorY; + memset(&sSavedPassData, 0, sizeof(sSavedPassData)); + switch (InBattlePyramid()) + { + case 1: + PlayBGM(MUS_PYRAMID); + break; + case 2: + PlayBGM(MUS_PYRAMID_TOP); + break; + default: + Overworld_PlaySpecialMapMusic(); + break; + } + + SetMainCallback2(CB2_ReshowFrontierPass); +} + +static void CB2_ShowFrontierPassFeature(void) +{ + if (!HideFrontierPass()) + return; + + switch (sPassData->unkE) + { + case 1: + ShowFrontierMap(CB2_ReshowFrontierPass); + break; + case 3: + sSavedPassData.callback = sPassData->callback; + sSavedPassData.cursorX = sPassData->cursorX; + sSavedPassData.cursorY = sPassData->cursorY; + FreeFrontierPassData(); + PlayRecordedBattle(CB2_ReturnFromRecord); + break; + case 2: + ShowPlayerTrainerCard(CB2_ReshowFrontierPass); + break; + } +} + +static bool32 TryCallPassAreaFunction(u8 taskId, u8 cursorArea) +{ + switch (cursorArea) + { + case CURSOR_AREA_RECORD: + if (!sPassData->hasBattleRecord) + return FALSE; + sPassData->unkE = 3; + DestroyTask(taskId); + SetMainCallback2(CB2_ShowFrontierPassFeature); + break; + case CURSOR_AREA_MAP: + case CURSOR_AREA_CARD: + sPassData->unkE = cursorArea; + gTasks[taskId].func = Task_DoFadeEffect; + gTasks[taskId].data[0] = FALSE; + break; + default: + return FALSE; + } + + sPassData->cursorX = sPassGfx->cursorSprite->pos1.x; + sPassData->cursorY = sPassGfx->cursorSprite->pos1.y; + return TRUE; +} + +static void Task_HandleFrontierPassInput(u8 taskId) +{ + u8 var = FALSE; // Reused, first informs whether the cursor moves, then used as the new cursor area. + + if (gMain.heldKeys & DPAD_UP && sPassGfx->cursorSprite->pos1.y >= 9) + { + sPassGfx->cursorSprite->pos1.y -= 2; + if (sPassGfx->cursorSprite->pos1.y <= 7) + sPassGfx->cursorSprite->pos1.y = 2; + var = TRUE; + } + if (gMain.heldKeys & DPAD_DOWN && sPassGfx->cursorSprite->pos1.y <= 135) + { + sPassGfx->cursorSprite->pos1.y += 2; + if (sPassGfx->cursorSprite->pos1.y >= 137) + sPassGfx->cursorSprite->pos1.y = 136; + var = TRUE; + } + + if (gMain.heldKeys & DPAD_LEFT && sPassGfx->cursorSprite->pos1.x >= 6) + { + sPassGfx->cursorSprite->pos1.x -= 2; + if (sPassGfx->cursorSprite->pos1.x <= 4) + sPassGfx->cursorSprite->pos1.x = 5; + var = TRUE; + } + if (gMain.heldKeys & DPAD_RIGHT && sPassGfx->cursorSprite->pos1.x <= 231) + { + sPassGfx->cursorSprite->pos1.x += 2; + if (sPassGfx->cursorSprite->pos1.x >= 233) + sPassGfx->cursorSprite->pos1.x = 232; + var = TRUE; + } + + if (!var) // Cursor did not change. + { + if (sPassData->cursorArea != CURSOR_AREA_NOTHING && gMain.newKeys & A_BUTTON) + { + if (sPassData->cursorArea <= CURSOR_AREA_RECORD) // Map, Card, Record + { + PlaySE(SE_SELECT); + if (TryCallPassAreaFunction(taskId, sPassData->cursorArea)) + return; + } + else if (sPassData->cursorArea == CURSOR_AREA_CANCEL) + { + PlaySE(SE_PC_OFF); + SetMainCallback2(CB2_HideFrontierPass); + DestroyTask(taskId); + // BUG. The function should return here. Otherwise, it can play the same sound twice and destroy the same task twice. + } + } + + if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_PC_OFF); + SetMainCallback2(CB2_HideFrontierPass); + DestroyTask(taskId); + } + } + else + { + var = GetCursorAreaFromCoords(sPassGfx->cursorSprite->pos1.x - 5, sPassGfx->cursorSprite->pos1.y + 5); + if (sPassData->cursorArea != var) + { + PrintAreaDescription(var); + sPassData->previousCursorArea = sPassData->cursorArea; + sPassData->cursorArea = var; + sub_80C6104(sPassData->cursorArea, sPassData->previousCursorArea); + } + } +} + +static void Task_DoFadeEffect(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + + switch (sPassData->state) + { + case 0: + if (!data[0]) + { + sub_80C5F58(TRUE, FALSE); + data[1] = 0x100; + data[2] = 0x100; + data[3] = 0x15; + data[4] = 0x15; + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_WHITE); + } + else + { + data[1] = 0x1FC; + data[2] = 0x1FC; + data[3] = -0x15; + data[4] = -0x15; + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + ShowBg(0); + ShowBg(1); + ShowBg(2); + LoadCursorAndSymbolSprites(); + SetVBlankCallback(VblankCb_FrontierPass); + BlendPalettes(0xFFFFFFFF, 0x10, RGB_WHITE); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_WHITE); + } + sPassGfx->setAffine = TRUE; + sPassGfx->unk2E = sub_8151624(data[1]); + sPassGfx->unk30 = sub_8151624(data[2]); + break; + case 1: + UpdatePaletteFade(); + data[1] += data[3]; + data[2] += data[4]; + sPassGfx->unk2E = sub_8151624(data[1]); + sPassGfx->unk30 = sub_8151624(data[2]); + if (!data[0]) + { + if (data[1] <= 0x1FC) + return; + } + else + { + if (data[1] != 0x100) + return; + } + break; + case 2: + if (sPassGfx->setAffine) // Nonsensical check. + sPassGfx->setAffine = FALSE; + if (UpdatePaletteFade()) + return; + if (!data[0]) + { + DestroyTask(taskId); + SetMainCallback2(CB2_ShowFrontierPassFeature); + } + else + { + sub_80C5F58(FALSE, FALSE); + sPassData->unkE = 0; + gTasks[taskId].func = Task_HandleFrontierPassInput; + } + SetBgAttribute(2, BG_ATTR_WRAPAROUND, 0); + sPassData->state = 0; + return; + } + + sPassData->state++; +} + +static void ShowAndPrintWindows(void) +{ + s32 x; + u8 i; + + for (i = 0; i < WINDOW_COUNT; i++) + { + PutWindowTilemap(i); + FillWindowPixelBuffer(i, 0); + } + + x = GetStringCenterAlignXOffset(1, gText_SymbolsEarned, 96); + AddTextPrinterParameterized3(WINDOW_EARNED_SYMBOLS, 1, x, 5, sTextColors[0], 0, gText_SymbolsEarned); + + x = GetStringCenterAlignXOffset(1, gText_BattleRecord, 96); + AddTextPrinterParameterized3(WINDOW_BATTLE_RECORD, 1, x, 5, sTextColors[0], 0, gText_BattleRecord); + + AddTextPrinterParameterized3(WINDOW_BATTLE_POINTS, 8, 5, 4, sTextColors[0], 0, gText_BattlePoints); + ConvertIntToDecimalStringN(gStringVar4, sPassData->battlePoints, STR_CONV_MODE_LEFT_ALIGN, 5); + x = GetStringRightAlignXOffset(8, gStringVar4, 91); + AddTextPrinterParameterized3(WINDOW_BATTLE_POINTS, 8, x, 16, sTextColors[0], 0, gStringVar4); + + sPassData->cursorArea = GetCursorAreaFromCoords(sPassData->cursorX - 5, sPassData->cursorY + 5); + sPassData->previousCursorArea = CURSOR_AREA_NOTHING; + PrintAreaDescription(sPassData->cursorArea); + + for (i = 0; i < WINDOW_COUNT; i++) + CopyWindowToVram(i, 3); + + CopyBgTilemapBufferToVram(0); +} + +static void PrintAreaDescription(u8 cursorArea) +{ + FillWindowPixelBuffer(WINDOW_DESCRIPTION, 0); + if (cursorArea == CURSOR_AREA_RECORD && !sPassData->hasBattleRecord) + AddTextPrinterParameterized3(WINDOW_DESCRIPTION, 1, 2, 0, sTextColors[1], 0, sPassAreaDescriptions[0]); + else if (cursorArea != CURSOR_AREA_NOTHING) + AddTextPrinterParameterized3(WINDOW_DESCRIPTION, 1, 2, 0, sTextColors[1], 0, sPassAreaDescriptions[cursorArea]); + + CopyWindowToVram(WINDOW_DESCRIPTION, 3); + CopyBgTilemapBufferToVram(0); +} + +static void sub_80C5F58(bool8 arg0, bool8 arg1) +{ + switch (sPassData->unkE) + { + case 1: + if (arg0) + CopyToBgTilemapBufferRect_ChangePalette(2, sPassGfx->unk20, 16, 3, 12, 7, 16); + else + FillBgTilemapBufferRect(2, 0, 16, 3, 12, 7, 16); + break; + case 2: + if (arg0) + CopyToBgTilemapBufferRect_ChangePalette(2, sPassGfx->unk20 + 84, 16, 10, 12, 7, 16); + else + FillBgTilemapBufferRect(2, 0, 16, 10, 12, 7, 16); + break; + default: + return; + } + + CopyBgTilemapBufferToVram(2); + if (arg1) + { + SetBgAffine(2, + gUnknown_085713E0[sPassData->unkE - 1][0] << 8, + gUnknown_085713E0[sPassData->unkE - 1][1] << 8, + gUnknown_085713E0[sPassData->unkE - 1][0], + gUnknown_085713E0[sPassData->unkE - 1][1], + sub_8151624(0x1FC), + sub_8151624(0x1FC), + 0); + } + else + { + SetBgAffine(2, + gUnknown_085713E0[sPassData->unkE - 1][0] << 8, + gUnknown_085713E0[sPassData->unkE - 1][1] << 8, + gUnknown_085713E0[sPassData->unkE - 1][0], + gUnknown_085713E0[sPassData->unkE - 1][1], + sub_8151624(0x100), + sub_8151624(0x100), + 0); + } +} + +static void sub_80C6104(u8 cursorArea, u8 previousCursorArea) +{ + bool32 var; + + switch (previousCursorArea) + { + case CURSOR_AREA_MAP: + CopyToBgTilemapBufferRect_ChangePalette(1, sPassGfx->unk24, 16, 3, 12, 7, 17); + var = TRUE; + break; + case CURSOR_AREA_CARD: + CopyToBgTilemapBufferRect_ChangePalette(1, sPassGfx->unk24 + 336, 16, 10, 12, 7, 17); + var = TRUE; + break; + case CURSOR_AREA_RECORD: + if (!sPassData->hasBattleRecord) + { + var = FALSE; + } + else + { + CopyToBgTilemapBufferRect_ChangePalette(1, sPassGfx->unk28, 2, 10, 12, 3, 17); + var = TRUE; + } + break; + case CURSOR_AREA_CANCEL: + CopyToBgTilemapBufferRect_ChangePalette(1, gUnknown_08DE3350, 21, 0, 9, 2, 17); + var = TRUE; + break; + default: + var = FALSE; + break; + } + + if (!var) + { + if (cursorArea == CURSOR_AREA_NOTHING || cursorArea > CURSOR_AREA_CANCEL) + return; + } + + switch (cursorArea) + { + case CURSOR_AREA_MAP: + CopyToBgTilemapBufferRect_ChangePalette(1, sPassGfx->unk24 + 168, 16, 3, 12, 7, 17); + var = TRUE; + break; + case CURSOR_AREA_CARD: + CopyToBgTilemapBufferRect_ChangePalette(1, sPassGfx->unk24 + 504, 16, 10, 12, 7, 17); + var = TRUE; + break; + case CURSOR_AREA_RECORD: + if (!sPassData->hasBattleRecord) + return; + + CopyToBgTilemapBufferRect_ChangePalette(1, sPassGfx->unk28 + 72, 2, 10, 12, 3, 17); + var = TRUE; + break; + case CURSOR_AREA_CANCEL: + CopyToBgTilemapBufferRect_ChangePalette(1, gUnknown_08DE3374, 21, 0, 9, 2, 17); + var = TRUE; + break; + default: + var = FALSE; + break; + } + + if (!var) + { + asm("":::"r4"); + if (previousCursorArea == CURSOR_AREA_NOTHING || previousCursorArea > CURSOR_AREA_CANCEL) + return; + } + + CopyBgTilemapBufferToVram(1); +} + +static void sub_80C629C(void) +{ + CopyToBgTilemapBuffer(1, gUnknown_08DE3060, 0, 0); + sub_80C6104(sPassData->cursorArea, sPassData->previousCursorArea); + sub_80C5F58(TRUE, sPassData->unkE); + ShowAndPrintWindows(); + CopyBgTilemapBufferToVram(1); +} + +static void LoadCursorAndSymbolSprites(void) +{ + u8 spriteId; + u8 i = 0; + + FreeAllSpritePalettes(); + ResetAffineAnimData(); + LoadSpritePalettes(sSpritePalettes); + LoadCompressedSpriteSheet(&sCursorSpriteSheets[0]); + LoadCompressedSpriteSheet(&sCursorSpriteSheets[2]); + spriteId = CreateSprite(&sSpriteTemplates_Cursors[0], sPassData->cursorX, sPassData->cursorY, 0); + sPassGfx->cursorSprite = &gSprites[spriteId]; + sPassGfx->cursorSprite->oam.priority = 0; + + for (i = 0; i < NUM_FRONTIER_FACILITIES; i++) + { + if (sPassData->facilitySymbols[i] != 0) + { + struct SpriteTemplate sprite = sSpriteTemplate_Medal; + + sprite.paletteTag += sPassData->facilitySymbols[i] - 1; + spriteId = CreateSprite(&sprite, sPassAreasLayout[i + CURSOR_AREA_SYMBOL - 1].xStart + 8, sPassAreasLayout[i + CURSOR_AREA_SYMBOL - 1].yStart + 6, i + 1); + sPassGfx->symbolSprites[i] = &gSprites[spriteId]; + sPassGfx->symbolSprites[i]->oam.priority = 2; + StartSpriteAnim(sPassGfx->symbolSprites[i], i); + } + } +} + +static void FreeCursorAndSymbolSprites(void) +{ + u8 i = 0; + + DestroySprite(sPassGfx->cursorSprite); + sPassGfx->cursorSprite = NULL; + for (i = 0; i < NUM_FRONTIER_FACILITIES; i++) + { + if (sPassGfx->symbolSprites[i] != NULL) + { + DestroySprite(sPassGfx->symbolSprites[i]); + sPassGfx->symbolSprites[i] = NULL; + } + } + FreeAllSpritePalettes(); + FreeSpriteTilesByTag(2); + FreeSpriteTilesByTag(0); +} + +static void SpriteCb_Dummy(struct Sprite *sprite) +{ + +} + +// Frontier Map code. + +// Forward declarations. +static void Task_HandleFrontierMap(u8 taskId); +static void PrintOnFrontierMap(void); +static void InitFrontierMapSprites(void); +static void HandleFrontierMapCursorMove(u8 direction); + +static void ShowFrontierMap(void (*callback)(void)) +{ + if (sMapData != NULL) + SetMainCallback2(callback); // This line doesn't make sense at all, since it gets overwritten later anyway. + + sMapData = AllocZeroed(sizeof(*sMapData)); + sMapData->callback = callback; + ResetTasks(); + CreateTask(Task_HandleFrontierMap, 0); + SetMainCallback2(CB2_FrontierPass); +} + +static void FreeFrontierMap(void) +{ + ResetTasks(); + SetMainCallback2(sMapData->callback); + memset(sMapData, 0, sizeof(*sMapData)); // Pointless memory clear. + FREE_AND_SET_NULL(sMapData); +} + +static bool32 InitFrontierMap(void) +{ + switch (sPassData->state) + { + case 0: + SetVBlankCallback(NULL); + ScanlineEffect_Stop(); + SetVBlankHBlankCallbacksToNull(); + break; + case 1: + ResetGpuRegsAndBgs(); + break; + case 2: + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetPaletteFade(); + reset_temp_tile_data_buffers(); + break; + case 3: + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, sMapBgTemplates, ARRAY_COUNT(sMapBgTemplates)); + SetBgTilemapBuffer(0, sMapData->tilemapBuff0); + SetBgTilemapBuffer(1, sMapData->tilemapBuff1); + SetBgTilemapBuffer(2, sMapData->tilemapBuff2); + FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 30, 20); + FillBgTilemapBufferRect_Palette0(1, 0, 0, 0, 30, 20); + FillBgTilemapBufferRect_Palette0(2, 0, 0, 0, 30, 20); + CopyBgTilemapBufferToVram(0); + CopyBgTilemapBufferToVram(1); + CopyBgTilemapBufferToVram(2); + break; + case 4: + InitWindows(sMapWindowTemplates); + DeactivateAllTextPrinters(); + PrintOnFrontierMap(); + decompress_and_copy_tile_data_to_vram(1, gUnknown_0856FBBC, 0, 0, 0); + break; + case 5: + if (free_temp_tile_data_buffers_if_possible()) + return FALSE; + LoadPalette(gUnknown_08DE07C8[0], 0, 0x1A0); + LoadPalette(stdpal_get(0), 0xF0, 0x20); + CopyToBgTilemapBuffer(2, gUnknown_08570E00, 0, 0); + CopyBgTilemapBufferToVram(2); + break; + case 6: + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + ShowBg(0); + ShowBg(1); + ShowBg(2); + InitFrontierMapSprites(); + SetVBlankCallback(VblankCb_FrontierPass); + BlendPalettes(0xFFFFFFFF, 0x10, RGB_WHITE); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0x10, 0, RGB_WHITE); + break; + case 7: + if (UpdatePaletteFade()) + return FALSE; + sPassData->state = 0; + return TRUE; + } + + sPassData->state++; + return FALSE; +} + +static bool32 ExitFrontierMap(void) +{ + switch (sPassData->state) + { + case 0: + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_WHITE); + break; + case 1: + if (UpdatePaletteFade()) + return FALSE; + SetGpuReg(REG_OFFSET_DISPCNT, 0); + HideBg(0); + HideBg(1); + HideBg(2); + break; + case 2: + SetVBlankCallback(NULL); + ScanlineEffect_Stop(); + SetVBlankHBlankCallbacksToNull(); + break; + case 3: + if (sMapData->cursorSprite != NULL) + { + DestroySprite(sMapData->cursorSprite); + FreeSpriteTilesByTag(0); + } + if (sMapData->mapIndicatorSprite != NULL) + { + DestroySprite(sMapData->mapIndicatorSprite); + FreeSpriteTilesByTag(1); + } + if (sMapData->playerHeadSprite != NULL) + { + DestroySprite(sMapData->playerHeadSprite); + FreeSpriteTilesByTag(4); + } + FreeAllWindowBuffers(); + break; + case 4: + ResetGpuRegsAndBgs(); + ResetSpriteData(); + FreeAllSpritePalettes(); + break; + case 5: + UnsetBgTilemapBuffer(0); + UnsetBgTilemapBuffer(1); + UnsetBgTilemapBuffer(2); + sPassData->state = 0; + return TRUE; + } + + sPassData->state++; + return FALSE; +} + +static void Task_HandleFrontierMap(u8 taskId) +{ + s16 *data = gTasks[taskId].data; + + switch (data[0]) + { + case 0: + if (InitFrontierMap()) + break; + return; + case 1: + if (gMain.newKeys & B_BUTTON) + { + PlaySE(SE_PC_OFF); + data[0] = 4; + } + else if (gMain.newKeys & DPAD_DOWN) + { + if (sMapData->cursorPos >= NUM_FRONTIER_FACILITIES - 1) + HandleFrontierMapCursorMove(0); + else + data[0] = 2; + } + else if (gMain.newKeys & DPAD_UP) + { + if (sMapData->cursorPos == 0) + HandleFrontierMapCursorMove(1); + else + data[0] = 3; + } + return; + case 2: + if (data[1] > 3) + { + HandleFrontierMapCursorMove(0); + data[1] = 0; + data[0] = 1; + } + else + { + sMapData->cursorSprite->pos1.y += 4; + data[1]++; + } + return; + case 3: + if (data[1] > 3) + { + HandleFrontierMapCursorMove(1); + data[1] = 0; + data[0] = 1; + } + else + { + sMapData->cursorSprite->pos1.y -= 4; + data[1]++; + } + return; + case 4: + if (ExitFrontierMap()) + break; + return; + case 5: + DestroyTask(taskId); + FreeFrontierMap(); + return; + } + + data[0]++; +} + +static u8 MapNumToFrontierFacilityId(u16 mapNum) // id + 1, zero means not a frontier map number +{ + if ((mapNum >= MAP_NUM(BATTLE_FRONTIER_BATTLE_TOWER_LOBBY) && mapNum <= MAP_NUM(BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM)) + || (mapNum >= MAP_NUM(BATTLE_FRONTIER_BATTLE_TOWER_MULTI_BATTLE_ROOM) && mapNum <= MAP_NUM(BATTLE_FRONTIER_BATTLE_TOWER_BATTLE_ROOM2))) + return FRONTIER_FACILITY_TOWER + 1; + else if (mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_DOME_LOBBY) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_DOME_CORRIDOR) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_DOME_PRE_BATTLE_ROOM) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_DOME_BATTLE_ROOM)) + return FRONTIER_FACILITY_DOME + 1; + else if (mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_PALACE_LOBBY) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_PALACE_CORRIDOR) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_PALACE_BATTLE_ROOM)) + return FRONTIER_FACILITY_PALACE + 1; + else if (mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_ARENA_LOBBY) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_ARENA_CORRIDOR) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_ARENA_BATTLE_ROOM)) + return FRONTIER_FACILITY_ARENA + 1; + else if (mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_FACTORY_LOBBY) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_FACTORY_PRE_BATTLE_ROOM) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_FACTORY_BATTLE_ROOM)) + return FRONTIER_FACILITY_FACTORY + 1; + else if (mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_PIKE_LOBBY) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_PIKE_CORRIDOR) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_PIKE_THREE_PATH_ROOM) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_PIKE_RANDOM_ROOM1) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_PIKE_RANDOM_ROOM2) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_PIKE_RANDOM_ROOM3)) + return FRONTIER_FACILITY_PIKE + 1; + else if (mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_PYRAMID_LOBBY) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_PYRAMID_EMPTY_SQUARE) + || mapNum == MAP_NUM(BATTLE_FRONTIER_BATTLE_PYRAMID_TOP)) + return FRONTIER_FACILITY_PYRAMID + 1; + else + return 0; +} + +static void InitFrontierMapSprites(void) +{ + struct SpriteTemplate sprite; + u8 spriteId; + u8 id; + s16 x = 0, y; + + FreeAllSpritePalettes(); + LoadSpritePalettes(sSpritePalettes); + + LoadCompressedSpriteSheet(&sCursorSpriteSheets[0]); + spriteId = CreateSprite(&sSpriteTemplates_Cursors[0], 155, (sMapData->cursorPos * 16) + 8, 2); + sMapData->cursorSprite = &gSprites[spriteId]; + sMapData->cursorSprite->oam.priority = 0; + sMapData->cursorSprite->hFlip = TRUE; + StartSpriteAnim(sMapData->cursorSprite, 1); + + LoadCompressedSpriteSheet(&sCursorSpriteSheets[1]); + spriteId = CreateSprite(&sSpriteTemplates_Cursors[1], sMapLandmarks[sMapData->cursorPos].x, sMapLandmarks[sMapData->cursorPos].y, 1); + sMapData->mapIndicatorSprite = &gSprites[spriteId]; + sMapData->mapIndicatorSprite->oam.priority = 0; + StartSpriteAnim(sMapData->mapIndicatorSprite, sMapLandmarks[sMapData->cursorPos].animNum); + + // Create player indicator head sprite only if it's in vicinity of battle frontier. + id = GetCurrentRegionMapSectionId(); + if (id == MAPSEC_BATTLE_FRONTIER || id == MAPSEC_ARTISAN_CAVE) + { + s8 mapNum = gSaveBlock1Ptr->location.mapNum; + + if (mapNum == MAP_NUM(BATTLE_FRONTIER_OUTSIDE_WEST) + || (mapNum == MAP_NUM(BATTLE_FRONTIER_OUTSIDE_EAST) && (x = 55))) + { + x += gSaveBlock1Ptr->pos.x; + y = gSaveBlock1Ptr->pos.y; + + x /= 8; + y /= 8; + + id = 0; + } + else + { + id = MapNumToFrontierFacilityId(mapNum); + if (id != 0) + { + x = sMapLandmarks[id - 1].x; + y = sMapLandmarks[id - 1].y; + } + else + { + // Handle Artisan Cave. + if (gSaveBlock1Ptr->escapeWarp.mapNum == MAP_NUM(BATTLE_FRONTIER_OUTSIDE_EAST)) + x = gSaveBlock1Ptr->escapeWarp.x + 55; + else + x = gSaveBlock1Ptr->escapeWarp.x; + + y = gSaveBlock1Ptr->escapeWarp.y; + + x /= 8; + y /= 8; + } + } + + LoadCompressedSpriteSheet(sHeadsSpriteSheet); + sprite = sSpriteTemplate_Head; + sprite.paletteTag = gSaveBlock2Ptr->playerGender + 4; + if (id != 0) + { + spriteId = CreateSprite(&sprite, x, y, 0); + } + else + { + x *= 8; + y *= 8; + spriteId = CreateSprite(&sprite, x + 20, y + 36, 0); + } + + sMapData->playerHeadSprite = &gSprites[spriteId]; + sMapData->playerHeadSprite->oam.priority = 0; + if (gSaveBlock2Ptr->playerGender != MALE) + StartSpriteAnim(sMapData->playerHeadSprite, 1); + } +} + +static void PrintOnFrontierMap(void) +{ + u8 i; + + for (i = 0; i < MAP_WINDOW_COUNT; i++) + { + PutWindowTilemap(i); + FillWindowPixelBuffer(i, 0); + } + + for (i = 0; i < NUM_FRONTIER_FACILITIES; i++) + { + if (i == sMapData->cursorPos) + AddTextPrinterParameterized3(MAP_WINDOW_NAME, 7, 4, (i * 16) + 1, sTextColors[2], 0, sMapLandmarks[i].name); + else + AddTextPrinterParameterized3(MAP_WINDOW_NAME, 7, 4, (i * 16) + 1, sTextColors[1], 0, sMapLandmarks[i].name); + } + + AddTextPrinterParameterized3(MAP_WINDOW_DESCRIPTION, 1, 4, 0, sTextColors[0], 0, sMapLandmarks[sMapData->cursorPos].description); + + for (i = 0; i < MAP_WINDOW_COUNT; i++) + CopyWindowToVram(i, 3); + + CopyBgTilemapBufferToVram(0); +} + +static void HandleFrontierMapCursorMove(u8 direction) +{ + u8 oldCursorPos, i; + + if (direction) + { + oldCursorPos = sMapData->cursorPos; + sMapData->cursorPos = (oldCursorPos + 6) % NUM_FRONTIER_FACILITIES; + } + else + { + oldCursorPos = sMapData->cursorPos; + sMapData->cursorPos = (oldCursorPos + 1) % NUM_FRONTIER_FACILITIES; + } + + AddTextPrinterParameterized3(MAP_WINDOW_NAME, 7, 4, (oldCursorPos * 16) + 1, sTextColors[1], 0, sMapLandmarks[oldCursorPos].name); + AddTextPrinterParameterized3(MAP_WINDOW_NAME, 7, 4, (sMapData->cursorPos * 16) + 1, sTextColors[2], 0, sMapLandmarks[sMapData->cursorPos].name); + + sMapData->cursorSprite->pos1.y = (sMapData->cursorPos * 16) + 8; + + StartSpriteAnim(sMapData->mapIndicatorSprite, sMapLandmarks[sMapData->cursorPos].animNum); + sMapData->mapIndicatorSprite->pos1.x = sMapLandmarks[sMapData->cursorPos].x; + sMapData->mapIndicatorSprite->pos1.y = sMapLandmarks[sMapData->cursorPos].y; + FillWindowPixelBuffer(MAP_WINDOW_DESCRIPTION, 0); + AddTextPrinterParameterized3(MAP_WINDOW_DESCRIPTION, 1, 4, 0, sTextColors[0], 0, sMapLandmarks[sMapData->cursorPos].description); + + for (i = 0; i < 3; i++) + CopyWindowToVram(i, 3); + + CopyBgTilemapBufferToVram(0); + PlaySE(SE_Z_SCROLL); +} diff --git a/src/frontier_util.c b/src/frontier_util.c index 40b1edbe3..742b73858 100644 --- a/src/frontier_util.c +++ b/src/frontier_util.c @@ -1827,7 +1827,7 @@ void sub_81A3ACC(void) s32 i; for (i = 0; i < 20; i++) - gSaveBlock2Ptr->frontier.field_CB4[i] |= 0xFFFF; + gSaveBlock2Ptr->frontier.field_CB4[i] = 0xFFFF; } static void sub_81A3B00(void) diff --git a/src/graphics.c b/src/graphics.c index 4786f1f22..90b705d2f 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -1590,7 +1590,7 @@ const u32 gUnknown_08DE0644[] = INCBIN_U32("graphics/title_screen/title_screen2. // more trainer card stuff -const u16 gUnknown_08DE07C8[] = INCBIN_U16("graphics/frontier_pass/tiles.gbapal");// size in LoadPalette calls is reported as 0xD0 << 1, which is 0x1A0, but palette is only 0x100 bytes long so it loads garbage as well +const u16 gUnknown_08DE07C8[][16] = INCBIN_U16("graphics/frontier_pass/tiles.gbapal");// size in LoadPalette calls is reported as 0xD0 << 1, which is 0x1A0, but palette is only 0x100 bytes long so it loads garbage as well const u32 gUnknown_08DE08C8[] = INCBIN_U32("graphics/frontier_pass/tiles.4bpp.lz"); const u32 gUnknown_08DE2084[] = INCBIN_U32("graphics/frontier_pass/tiles2.8bpp.lz"); const u32 gUnknown_08DE3060[] = INCBIN_U32("graphics/frontier_pass/tiles.bin.lz"); diff --git a/src/link_rfu.c b/src/link_rfu.c index 0f997591f..ebfc802e0 100644 --- a/src/link_rfu.c +++ b/src/link_rfu.c @@ -4524,7 +4524,7 @@ void sub_80115EC(s32 a0) if ((a0 >> i) & 1) { gUnknown_03005000.unk_cea[i] = 0; - gUnknown_03005000.unk_cee[i] |= 0xFF; + gUnknown_03005000.unk_cee[i] = 0xFF; } } } diff --git a/src/load_save.c b/src/load_save.c index a7593d007..0d19c6dae 100644 --- a/src/load_save.c +++ b/src/load_save.c @@ -8,13 +8,12 @@ #include "pokemon_storage_system.h" #include "random.h" #include "save_location.h" +#include "trainer_hill.h" #include "gba/flash_internal.h" #include "decoration_inventory.h" static void ApplyNewEncryptionKeyToAllEncryptedData(u32 encryptionKey); -extern void* gUnknown_0203CF5C; - extern bool16 IdentifyFlash(void); extern void ApplyNewEncryptionKeyToBerryPowder(u32 key); diff --git a/src/main.c b/src/main.c index c4962286c..61c5e3386 100644 --- a/src/main.c +++ b/src/main.c @@ -22,10 +22,10 @@ #include "text.h" #include "intro.h" #include "main.h" +#include "trainer_hill.h" extern void sub_800B9B8(void); extern u8 gUnknown_03002748; -extern u32 *gUnknown_0203CF5C; static void VBlankIntr(void); static void HBlankIntr(void); diff --git a/src/map_name_popup.c b/src/map_name_popup.c index ab52cb37e..c13747006 100644 --- a/src/map_name_popup.c +++ b/src/map_name_popup.c @@ -157,22 +157,22 @@ static const u8 gRegionMapSectionId_To_PopUpThemeIdMapping[] = [MAPSEC_SKY_PILLAR] = MAPPOPUP_THEME_STONE, [MAPSEC_SECRET_BASE] = MAPPOPUP_THEME_STONE, [MAPSEC_DYNAMIC] = MAPPOPUP_THEME_MARBLE, - [MAPSEC_AQUA_HIDEOUT - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_STONE, - [MAPSEC_MAGMA_HIDEOUT - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_STONE, - [MAPSEC_MIRAGE_TOWER - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_STONE, - [MAPSEC_BIRTH_ISLAND_2 - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_WOOD, - [MAPSEC_FARAWAY_ISLAND - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_WOOD, - [MAPSEC_ARTISAN_CAVE - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_STONE, - [MAPSEC_MARINE_CAVE - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_STONE, - [MAPSEC_UNDERWATER_MARINE_CAVE - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_STONE2, - [MAPSEC_TERRA_CAVE - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_STONE, - [MAPSEC_UNDERWATER_TERRA_CAVE - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_STONE2, - [MAPSEC_UNDERWATER_UNK1 - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_STONE2, - [MAPSEC_UNDERWATER_129 - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_STONE2, - [MAPSEC_DESERT_UNDERPASS - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_STONE, - [MAPSEC_ALTERING_CAVE_2 - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_STONE, - [MAPSEC_NAVEL_ROCK2 - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_STONE, - [MAPSEC_TRAINER_HILL - MAPSEC_SUBTRACT_KANTO] = MAPPOPUP_THEME_MARBLE + [MAPSEC_AQUA_HIDEOUT - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_STONE, + [MAPSEC_MAGMA_HIDEOUT - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_STONE, + [MAPSEC_MIRAGE_TOWER - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_STONE, + [MAPSEC_BIRTH_ISLAND_2 - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_WOOD, + [MAPSEC_FARAWAY_ISLAND - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_WOOD, + [MAPSEC_ARTISAN_CAVE - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_STONE, + [MAPSEC_MARINE_CAVE - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_STONE, + [MAPSEC_UNDERWATER_MARINE_CAVE - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_STONE2, + [MAPSEC_TERRA_CAVE - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_STONE, + [MAPSEC_UNDERWATER_TERRA_CAVE - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_STONE2, + [MAPSEC_UNDERWATER_UNK1 - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_STONE2, + [MAPSEC_UNDERWATER_129 - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_STONE2, + [MAPSEC_DESERT_UNDERPASS - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_STONE, + [MAPSEC_ALTERING_CAVE_2 - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_STONE, + [MAPSEC_NAVEL_ROCK2 - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_STONE, + [MAPSEC_TRAINER_HILL - KANTO_MAPSEC_COUNT] = MAPPOPUP_THEME_MARBLE }; static const u8 gText_PyramidFloor1[] = _("PYRAMID FLOOR 1"); diff --git a/src/new_game.c b/src/new_game.c index 1b3fa2b00..158120245 100644 --- a/src/new_game.c +++ b/src/new_game.c @@ -17,6 +17,7 @@ #include "easy_chat.h" #include "event_data.h" #include "money.h" +#include "trainer_hill.h" #include "tv.h" #include "coins.h" #include "text.h" @@ -49,7 +50,6 @@ extern void copy_strings_to_sav1(void); extern void InitMatchCallCounters(void); extern void sub_801AFD8(void); extern void sub_800E5AC(void); -extern void sub_81D54BC(void); extern void ResetContestLinkResults(void); extern void ResetPokeJumpResults(void); extern void SetBerryPowder(u32* powder, u32 newValue); @@ -212,7 +212,7 @@ void NewGameInitData(void) InitMatchCallCounters(); sub_801AFD8(); sub_800E5AC(); - sub_81D54BC(); + ResetTrainerHillResults(); ResetContestLinkResults(); } diff --git a/src/overworld.c b/src/overworld.c index 9df69e360..a67b4b68f 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -19,7 +19,6 @@ #include "field_tasks.h" #include "field_weather.h" #include "fieldmap.h" -// #include "fldeff_flash.h" #include "gpu_regs.h" #include "heal_location.h" #include "link.h" @@ -50,6 +49,7 @@ #include "task.h" // #include "tileset_anim.h" #include "time_events.h" +#include "trainer_hill.h" #include "tv.h" #include "scanline_effect.h" #include "wild_encounter.h" @@ -106,7 +106,6 @@ extern void apply_map_tileset2_palette(const struct MapLayout *); extern void copy_map_tileset2_to_vram_2(const struct MapLayout *); extern void RestartWildEncounterImmunitySteps(void); extern void ShowMapNamePopup(void); -extern bool32 InTrainerHill(void); extern bool32 sub_808651C(void); extern bool8 sub_80AF6A4(void); extern bool8 sub_80E909C(void); @@ -129,14 +128,11 @@ extern void WriteFlashScanlineEffectBuffer(u8); extern void sub_81AA2F8(void); extern void InitMatchCallCounters(void); extern void sub_80EDB44(void); -extern void sub_81D64C0(void); extern void InitFieldMessageBox(void); extern void copy_map_tileset1_to_vram(const struct MapLayout *); extern void copy_map_tileset2_to_vram(const struct MapLayout *); extern void FieldUpdateBgTilemapScroll(void); extern void TransferTilesetAnimsBuffer(void); -extern bool32 sub_81D5F48(void); -extern u8 GetCurrentTrainerHillMapId(void); extern bool8 warp0_in_pokecenter(void); extern void ResetAllPicSprites(void); extern void FieldEffectActiveListClear(void); diff --git a/src/party_menu.c b/src/party_menu.c index 241df1c91..a8c98faec 100755 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -1563,7 +1563,7 @@ static void InitPartyMenu(u8 a, u8 b, u8 c, u8 d, u8 e, TaskFunc task, MainCallb for (i = 0; i <= 15; i++) gUnknown_0203CEC4->data[i] = 0; for (i = 0; i < 3; i++) - gUnknown_0203CEC4->unkC[i] |= 0xFF; + gUnknown_0203CEC4->unkC[i] = 0xFF; if (d == 0) gUnknown_0203CEC8.unk9 = 0; @@ -1851,10 +1851,10 @@ static void PartyMenuInitHelperStructs(u8 a) gUnknown_0203CEDC[i].unk0 = &gUnknown_086156C4[1]; gUnknown_0203CEDC[i].unk4 = gUnknown_08615704[a][i]; gUnknown_0203CEDC[i].windowId = i; - gUnknown_0203CEDC[i].unk9 |= 0xFF; - gUnknown_0203CEDC[i].unkA |= 0xFF; - gUnknown_0203CEDC[i].unkB |= 0xFF; - gUnknown_0203CEDC[i].unkC |= 0xFF; + gUnknown_0203CEDC[i].unk9 = 0xFF; + gUnknown_0203CEDC[i].unkA = 0xFF; + gUnknown_0203CEDC[i].unkB = 0xFF; + gUnknown_0203CEDC[i].unkC = 0xFF; } gUnknown_0203CEDC[0].unk0 = &gUnknown_086156C4[0]; if (a == 3) diff --git a/src/pokedex.c b/src/pokedex.c index 755a46821..f99a8226a 100644 --- a/src/pokedex.c +++ b/src/pokedex.c @@ -1264,7 +1264,7 @@ static void ResetPokedexView(struct PokedexView *pokedexView) for (i = 0; i < NATIONAL_DEX_COUNT; i++) { - pokedexView->pokedexList[i].dexNum |= 0xFFFF; + pokedexView->pokedexList[i].dexNum = 0xFFFF; pokedexView->pokedexList[i].seen = 0; pokedexView->pokedexList[i].owned = 0; } @@ -1281,7 +1281,7 @@ static void ResetPokedexView(struct PokedexView *pokedexView) pokedexView->seenCount = 0; pokedexView->ownCount = 0; for (i = 0; i < 4; i++) - pokedexView->unk61E[i] |= 0xFFFF; + pokedexView->unk61E[i] = 0xFFFF; pokedexView->unk628 = 0; pokedexView->unk62A = 0; pokedexView->unk62C = 0; @@ -2030,7 +2030,7 @@ void sub_80BC8D4(u8 dexMode, u8 sortMode) for (i = sPokedexView->pokemonListCount; i < NATIONAL_DEX_COUNT; i++) { - sPokedexView->pokedexList[i].dexNum |= 0xFFFF; + sPokedexView->pokedexList[i].dexNum = 0xFFFF; sPokedexView->pokedexList[i].seen = FALSE; sPokedexView->pokedexList[i].owned = FALSE; } @@ -2437,7 +2437,7 @@ u8 sub_80BDA40(void) if (sPokedexView->unk61E[i] != 0xFFFF) { FreeAndDestroyMonPicSprite(sPokedexView->unk61E[i]); - sPokedexView->unk61E[i] |= 0xFFFF; + sPokedexView->unk61E[i] = 0xFFFF; } } return FALSE; @@ -4271,46 +4271,46 @@ s8 GetSetPokedexFlag(u16 nationalDexNo, u8 caseID) retVal = 0; switch (caseID) { - case FLAG_GET_SEEN: - if (gSaveBlock2Ptr->pokedex.seen[index] & mask) + case FLAG_GET_SEEN: + if (gSaveBlock2Ptr->pokedex.seen[index] & mask) + { + if ((gSaveBlock2Ptr->pokedex.seen[index] & mask) == (gSaveBlock1Ptr->seen1[index] & mask) + && (gSaveBlock2Ptr->pokedex.seen[index] & mask) == (gSaveBlock1Ptr->seen2[index] & mask)) + retVal = 1; + else { - if ((gSaveBlock2Ptr->pokedex.seen[index] & mask) == (gSaveBlock1Ptr->seen1[index] & mask) - && (gSaveBlock2Ptr->pokedex.seen[index] & mask) == (gSaveBlock1Ptr->seen2[index] & mask)) - retVal = 1; - else - { - gSaveBlock2Ptr->pokedex.seen[index] &= ~mask; - gSaveBlock1Ptr->seen1[index] &= ~mask; - gSaveBlock1Ptr->seen2[index] &= ~mask; - retVal = 0; - } + gSaveBlock2Ptr->pokedex.seen[index] &= ~mask; + gSaveBlock1Ptr->seen1[index] &= ~mask; + gSaveBlock1Ptr->seen2[index] &= ~mask; + retVal = 0; } - break; - case FLAG_GET_CAUGHT: - if (gSaveBlock2Ptr->pokedex.owned[index] & mask) + } + break; + case FLAG_GET_CAUGHT: + if (gSaveBlock2Ptr->pokedex.owned[index] & mask) + { + if ((gSaveBlock2Ptr->pokedex.owned[index] & mask) == (gSaveBlock2Ptr->pokedex.seen[index] & mask) + && (gSaveBlock2Ptr->pokedex.owned[index] & mask) == (gSaveBlock1Ptr->seen1[index] & mask) + && (gSaveBlock2Ptr->pokedex.owned[index] & mask) == (gSaveBlock1Ptr->seen2[index] & mask)) + retVal = 1; + else { - if ((gSaveBlock2Ptr->pokedex.owned[index] & mask) == (gSaveBlock2Ptr->pokedex.seen[index] & mask) - && (gSaveBlock2Ptr->pokedex.owned[index] & mask) == (gSaveBlock1Ptr->seen1[index] & mask) - && (gSaveBlock2Ptr->pokedex.owned[index] & mask) == (gSaveBlock1Ptr->seen2[index] & mask)) - retVal = 1; - else - { - gSaveBlock2Ptr->pokedex.owned[index] &= ~mask; - gSaveBlock2Ptr->pokedex.seen[index] &= ~mask; - gSaveBlock1Ptr->seen1[index] &= ~mask; - gSaveBlock1Ptr->seen2[index] &= ~mask; - retVal = 0; - } + gSaveBlock2Ptr->pokedex.owned[index] &= ~mask; + gSaveBlock2Ptr->pokedex.seen[index] &= ~mask; + gSaveBlock1Ptr->seen1[index] &= ~mask; + gSaveBlock1Ptr->seen2[index] &= ~mask; + retVal = 0; } - break; - case FLAG_SET_SEEN: - gSaveBlock2Ptr->pokedex.seen[index] |= mask; - gSaveBlock1Ptr->seen1[index] |= mask; - gSaveBlock1Ptr->seen2[index] |= mask; - break; - case FLAG_SET_CAUGHT: - gSaveBlock2Ptr->pokedex.owned[index] |= mask; - break; + } + break; + case FLAG_SET_SEEN: + gSaveBlock2Ptr->pokedex.seen[index] |= mask; + gSaveBlock1Ptr->seen1[index] |= mask; + gSaveBlock1Ptr->seen2[index] |= mask; + break; + case FLAG_SET_CAUGHT: + gSaveBlock2Ptr->pokedex.owned[index] |= mask; + break; } return retVal; } @@ -4324,14 +4324,14 @@ u16 GetNationalPokedexCount(u8 caseID) { switch (caseID) { - case FLAG_GET_SEEN: - if (GetSetPokedexFlag(i + 1, FLAG_GET_SEEN)) - count++; - break; - case FLAG_GET_CAUGHT: - if (GetSetPokedexFlag(i + 1, FLAG_GET_CAUGHT)) - count++; - break; + case FLAG_GET_SEEN: + if (GetSetPokedexFlag(i + 1, FLAG_GET_SEEN)) + count++; + break; + case FLAG_GET_CAUGHT: + if (GetSetPokedexFlag(i + 1, FLAG_GET_CAUGHT)) + count++; + break; } } return count; @@ -4346,14 +4346,14 @@ u16 GetHoennPokedexCount(u8 caseID) { switch (caseID) { - case FLAG_GET_SEEN: - if (GetSetPokedexFlag(HoennToNationalOrder(i + 1), FLAG_GET_SEEN)) - count++; - break; - case FLAG_GET_CAUGHT: - if (GetSetPokedexFlag(HoennToNationalOrder(i + 1), FLAG_GET_CAUGHT)) - count++; - break; + case FLAG_GET_SEEN: + if (GetSetPokedexFlag(HoennToNationalOrder(i + 1), FLAG_GET_SEEN)) + count++; + break; + case FLAG_GET_CAUGHT: + if (GetSetPokedexFlag(HoennToNationalOrder(i + 1), FLAG_GET_CAUGHT)) + count++; + break; } } return count; @@ -4381,7 +4381,7 @@ u16 sub_80C089C(u8 caseID) return count; } -bool8 sub_80C08E4(void) +bool16 HasAllHoennMons(void) { u16 i; diff --git a/src/pokemon.c b/src/pokemon.c index 580216b2c..174f7ae66 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -22,7 +22,6 @@ #include "pokemon_animation.h" #include "pokemon_summary_screen.h" #include "pokemon_storage_system.h" -#include "pokenav.h" #include "random.h" #include "recorded_battle.h" #include "rtc.h" @@ -31,6 +30,7 @@ #include "strings.h" #include "task.h" #include "text.h" +#include "trainer_hill.h" #include "util.h" #include "constants/abilities.h" #include "constants/battle_frontier.h" @@ -74,7 +74,6 @@ extern const u8 gTrainerClassNames[][13]; extern u16 get_unknown_box_id(void); extern void set_unknown_box_id(u8); extern bool8 sub_806F104(void); -extern u8 sub_81D63C8(u16 trainerOpponentId); // this file's functions static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon); @@ -2745,7 +2744,7 @@ void CreateMonWithEVSpread(struct Pokemon *mon, u16 species, u8 level, u8 fixedI CalculateMonStats(mon); } -void sub_806819C(struct Pokemon *mon, struct BattleTowerPokemon *src) +void CreateBattleTowerMon(struct Pokemon *mon, struct BattleTowerPokemon *src) { s32 i; u8 nickname[30]; @@ -2799,7 +2798,7 @@ void sub_806819C(struct Pokemon *mon, struct BattleTowerPokemon *src) CalculateMonStats(mon); } -void sub_8068338(struct Pokemon *mon, struct BattleTowerPokemon *src, bool8 lvl50) +void CreateBattleTowerMon2(struct Pokemon *mon, struct BattleTowerPokemon *src, bool8 lvl50) { s32 i; u8 nickname[30]; @@ -6083,7 +6082,7 @@ u8 GetTrainerEncounterMusicId(u16 trainerOpponentId) if (InBattlePyramid()) return GetTrainerEncounterMusicIdInBattlePyramind(trainerOpponentId); else if (sub_81D5C18()) - return sub_81D63C8(trainerOpponentId); + return GetTrainerEncounterMusicIdInTrainerHill(trainerOpponentId); else return TRAINER_ENCOUNTER_MUSIC(trainerOpponentId); } diff --git a/src/pokemon_storage_system.c b/src/pokemon_storage_system.c index 36ed78a54..78fec2fc5 100644 --- a/src/pokemon_storage_system.c +++ b/src/pokemon_storage_system.c @@ -463,8 +463,6 @@ EWRAM_DATA static u8 sMovingMonOrigBoxId = 0; EWRAM_DATA static u8 sMovingMonOrigBoxPos = 0; EWRAM_DATA static bool8 sCanOnlyMove = 0; -extern void sub_80C6D80(u8 *arg0, void *arg1, u8 arg2, u8 arg3, s32 arg4); - extern const struct CompressedSpriteSheet gMonFrontPicTable[]; // This file's functions. @@ -1543,6 +1541,76 @@ static const u8 gHandCursorTiles[] = INCBIN_U8("graphics/pokemon_storage/hand_cu static const u8 gHandCursorShadowTiles[] = INCBIN_U8("graphics/pokemon_storage/hand_cursor_shadow.4bpp"); // code +void sub_80C6D80(const u8 *string, void *dst, u8 arg2, u8 arg3, s32 arg4) +{ + s32 i, val, val2; + u16 windowId; + u8 txtColor[3]; + u8 *tileData1, *tileData2; + struct WindowTemplate winTemplate = {0}; + + winTemplate.width = 24; + winTemplate.height = 2; + windowId = AddWindow(&winTemplate); + FillWindowPixelBuffer(windowId, (arg3 << 4) | arg3); + tileData1 = (u8*) GetWindowAttribute(windowId, WINDOW_TILE_DATA); + tileData2 = (winTemplate.width * 32) + tileData1; + + if (!arg2) + txtColor[0] = 0; + else + txtColor[0] = arg3; + txtColor[1] = 0xF; + txtColor[2] = 0xE; + AddTextPrinterParameterized4(windowId, 1, 0, 1, 0, 0, txtColor, -1, string); + + val = arg4; + if (val > 6u) + val = 6; + val2 = arg4 - 6; + if (val > 0) + { + for (i = val; i != 0; i--) + { + CpuCopy16(tileData1, dst, 0x80); + CpuCopy16(tileData2, dst + 0x80, 0x80); + tileData1 += 0x80; + tileData2 += 0x80; + dst += 0x100; + } + } + + if (val2 > 0) + CpuFill16((arg3 << 4) | arg3, dst, (u32)(val2) * 0x100); + + RemoveWindow(windowId); +} + +// Unused +void sub_80C6EAC(const u8 *string, void *dst, u16 arg2, u8 arg3, u8 clr2, u8 clr3) +{ + u32 var; + u8 windowId; + u8 txtColor[3]; + u8 *tileData1, *tileData2; + struct WindowTemplate winTemplate = {0}; + + winTemplate.width = StringLength_Multibyte(string); + winTemplate.height = 2; + var = winTemplate.width * 32; + windowId = AddWindow(&winTemplate); + FillWindowPixelBuffer(windowId, (arg3 << 4) | arg3); + tileData1 = (u8*) GetWindowAttribute(windowId, WINDOW_TILE_DATA); + tileData2 = (winTemplate.width * 32) + tileData1; + txtColor[0] = arg3; + txtColor[1] = clr2; + txtColor[2] = clr3; + AddTextPrinterParameterized4(windowId, 1, 0, 2, 0, 0, txtColor, -1, string); + CpuCopy16(tileData1, dst, var); + CpuCopy16(tileData2, dst + arg2, var); + RemoveWindow(windowId); +} + u8 CountMonsInBox(u8 boxId) { u16 i, count; diff --git a/src/pokemon_summary_screen.c b/src/pokemon_summary_screen.c index 14d5aa9dc..14bfba4ad 100644 --- a/src/pokemon_summary_screen.c +++ b/src/pokemon_summary_screen.c @@ -3048,11 +3048,11 @@ static void BufferMonTrainerMemo(void) else text = (sum->metLocation >= MAPSEC_NONE) ? gText_XNatureMetSomewhereAt : gText_XNatureMetAtYZ; } - else if (sum->metLocation == MAPSEC_FATEFUL_ENCOUNTER) + else if (sum->metLocation == METLOC_FATEFUL_ENCOUNTER) { text = gText_XNatureFatefulEncounter; } - else if (sum->metLocation != MAPSEC_IN_GAME_TRADE && DidMonComeFromGBAGames()) + else if (sum->metLocation != METLOC_IN_GAME_TRADE && DidMonComeFromGBAGames()) { text = (sum->metLocation >= MAPSEC_NONE) ? gText_XNatureObtainedInTrade : gText_XNatureProbablyMetAt; } @@ -3183,11 +3183,11 @@ static void PrintEggMemo(void) if (pssData->summary.sanity != 1) { - if (sum->metLocation == MAPSEC_FATEFUL_ENCOUNTER) + if (sum->metLocation == METLOC_FATEFUL_ENCOUNTER) text = gText_PeculiarEggNicePlace; else if (DidMonComeFromGBAGames() == FALSE || DoesMonOTMatchOwner() == FALSE) text = gText_PeculiarEggTrade; - else if (sum->metLocation == MAPSEC_SPECIAL_EGG) + else if (sum->metLocation == METLOC_SPECIAL_EGG) text = (DidMonComeFromRSE() == TRUE) ? gText_EggFromHotSprings : gText_EggFromTraveler; else text = gText_OddEggFoundByCouple; diff --git a/src/recorded_battle.c b/src/recorded_battle.c index 03823dd45..0dae76f02 100644 --- a/src/recorded_battle.c +++ b/src/recorded_battle.c @@ -124,7 +124,7 @@ void sub_8184DA4(u8 arg0) { for (j = 0; j < BATTLER_RECORD_SIZE; j++) { - sBattleRecords[i][j] |= 0xFF; + sBattleRecords[i][j] = 0xFF; } sBattleFlags = gBattleTypeFlags; sAI_Scripts = gBattleResources->ai->aiFlags; @@ -206,7 +206,7 @@ void RecordedBattle_ClearBattlerAction(u8 battlerId, u8 bytesToClear) for (i = 0; i < bytesToClear; i++) { sRecordedBytesNo[battlerId]--; - sBattleRecords[battlerId][sRecordedBytesNo[battlerId]] |= 0xFF; + sBattleRecords[battlerId][sRecordedBytesNo[battlerId]] = 0xFF; if (sRecordedBytesNo[battlerId] == 0) break; } diff --git a/src/rom_8011DC0.c b/src/rom_8011DC0.c index 813d143d2..41f7eeee7 100644 --- a/src/rom_8011DC0.c +++ b/src/rom_8011DC0.c @@ -1577,7 +1577,7 @@ void sub_80140E0(u8 taskId) for (i = 0; i < GetLinkPlayerCount(); i++) { recvBuff = gBlockRecvBuffer[i]; - sub_80C3120(&gTrainerCards[i], recvBuff, gLinkPlayers[i].version); + CopyTrainerCardData(&gTrainerCards[i], recvBuff, gLinkPlayers[i].version); } if (GetLinkPlayerCount() == 2) @@ -1607,7 +1607,7 @@ void sub_80141A4(void) break; case 1: if (!FuncIsActiveTask(sub_80140E0)) - TrainerCard_ShowLinkCard(GetMultiplayerId() ^ 1, CB2_ReturnToField); + ShowTrainerCardInLink(GetMultiplayerId() ^ 1, CB2_ReturnToField); break; } diff --git a/src/rom_8034C54.c b/src/rom_8034C54.c index cc875bd3f..a3707017e 100644 --- a/src/rom_8034C54.c +++ b/src/rom_8034C54.c @@ -82,7 +82,7 @@ bool32 sub_8034C54(u32 count) for (i = 0; i < count; i++) { gUnknown_02022E10->array[i].isActive = FALSE; - gUnknown_02022E10->array[i].firstOamId |= 0xFF; + gUnknown_02022E10->array[i].firstOamId = 0xFF; } return TRUE; diff --git a/src/save.c b/src/save.c index cfbe5b848..a22e20f0b 100644 --- a/src/save.c +++ b/src/save.c @@ -7,6 +7,7 @@ #include "overworld.h" #include "pokemon_storage_system.h" #include "main.h" +#include "trainer_hill.h" #include "constants/game_stat.h" static u16 CalculateChecksum(void *data, u16 size); @@ -17,10 +18,6 @@ static u8 ClearSaveData_2(u16 a1, const struct SaveSectionLocation *location); static u8 TryWriteSector(u8 sector, u8 *data); static u8 HandleWriteSector(u16 a1, const struct SaveSectionLocation *location); -// for the chunk declarations - -extern u32 gUnknown_0203CF5C; - // Divide save blocks into individual chunks to be written to flash sectors // Each 4 KiB flash sector contains 3968 bytes of actual data followed by a 128 byte footer @@ -662,10 +659,10 @@ static void UpdateSaveAddresses(void) u8 HandleSavingData(u8 saveType) { u8 i; - u32 backupVar = gUnknown_0203CF5C; + u32 *backupVar = gUnknown_0203CF5C; u8 *tempAddr; - gUnknown_0203CF5C = 0; + gUnknown_0203CF5C = NULL; UpdateSaveAddresses(); switch (saveType) { diff --git a/src/script_menu.c b/src/script_menu.c index d415d65a9..a4f4c6086 100644 --- a/src/script_menu.c +++ b/src/script_menu.c @@ -782,10 +782,10 @@ const struct MenuAction MultichoiceList_112[] = const struct MenuAction MultichoiceList_113[] = { - {gUnknown_085EB32D, NULL}, - {gUnknown_085EB33E, NULL}, - {gUnknown_085EB350, NULL}, - {gUnknown_085EB361, NULL}, + {gText_NormalTagMatch, NULL}, + {gText_VarietyTagMatch, NULL}, + {gText_UniqueTagMatch, NULL}, + {gText_ExpertTagMatch, NULL}, {gText_Exit, NULL}, }; @@ -1407,7 +1407,7 @@ static void sub_80E2578(void) for (i = 0; i < ARRAY_COUNT(gUnknown_03001124); i++) { - gUnknown_03001124[i] |= 0xFF; + gUnknown_03001124[i] = 0xFF; } GetFontAttribute(1, FONTATTR_MAX_LETTER_WIDTH); diff --git a/src/script_pokemon_util_80F87D8.c b/src/script_pokemon_util_80F87D8.c index f3eaa7161..cade00b50 100755 --- a/src/script_pokemon_util_80F87D8.c +++ b/src/script_pokemon_util_80F87D8.c @@ -128,18 +128,18 @@ void sub_80F88E8(void) } } -u8 sub_80F8940(void) +u8 CountPlayerContestPaintings(void) { int i; - u8 var0 = 0; + u8 count = 0; for (i = 0; i < 5; i++) { if (gSaveBlock1Ptr->contestWinners[8 + i].species) - var0++; + count++; } - return var0; + return count; } void sub_80F8970(void) diff --git a/src/start_menu.c b/src/start_menu.c index 0f608b1d2..5c7e5365d 100644 --- a/src/start_menu.c +++ b/src/start_menu.c @@ -9,6 +9,8 @@ #include "strings.h" #include "bg.h" #include "field_effect.h" +#include "party_menu.h" +#include "frontier_pass.h" #include "task.h" #include "overworld.h" #include "link.h" @@ -30,6 +32,7 @@ #include "scanline_effect.h" #include "text_window.h" #include "load_save.h" +#include "trainer_card.h" #include "international_string_util.h" #include "constants/songs.h" #include "field_player_avatar.h" @@ -89,11 +92,7 @@ extern void var_800D_set_xB(void); extern void sub_808B864(void); extern void CB2_Pokedex(void); extern void PlayRainSoundEffect(void); -extern void CB2_PartyMenuFromStartMenu(void); extern void CB2_PokeNav(void); -extern void sub_80C4DDC(void (*)(void)); -extern void sub_80C51C4(void (*)(void)); -extern void TrainerCard_ShowLinkCard(u8, void (*)(void)); extern void ScriptUnfreezeEventObjects(void); extern void sub_81A9EC8(void); extern void save_serialize_map(void); @@ -422,16 +421,19 @@ static bool32 PrintStartMenuActions(s8 *pIndex, u32 count) do { - if (sStartMenuItems[sCurrentStartMenuActions[index]].func.u8_void == StartMenuPlayerNameCallback) { + if (sStartMenuItems[sCurrentStartMenuActions[index]].func.u8_void == StartMenuPlayerNameCallback) + { PrintPlayerNameOnWindow(GetStartMenuWindowId(), sStartMenuItems[sCurrentStartMenuActions[index]].text, 8, (index << 4) + 9); } - else { + else + { StringExpandPlaceholders(gStringVar4, sStartMenuItems[sCurrentStartMenuActions[index]].text); AddTextPrinterParameterized(GetStartMenuWindowId(), 1, gStringVar4, 8, (index << 4) + 9, 0xFF, NULL); } index++; - if (index >= sNumStartMenuActions) { + if (index >= sNumStartMenuActions) + { *pIndex = index; return TRUE; } @@ -465,21 +467,14 @@ static bool32 InitStartMenuStep(void) break; case 3: if (GetSafariZoneFlag()) - { ShowSafariBallsWindow(); - } if (InBattlePyramid()) - { ShowPyramidFloorWindow(); - } sUnknown_02037619[0]++; break; case 4: - if (!PrintStartMenuActions(&sUnknown_02037619[1], 2)) - { - break; - } - sUnknown_02037619[0]++; + if (PrintStartMenuActions(&sUnknown_02037619[1], 2)) + sUnknown_02037619[0]++; break; case 5: sStartMenuCursorPos = sub_81983AC(GetStartMenuWindowId(), 1, 0, 9, 16, sNumStartMenuActions, sStartMenuCursorPos); @@ -494,15 +489,14 @@ static void InitStartMenu(void) { sUnknown_02037619[0] = 0; sUnknown_02037619[1] = 0; - while (!InitStartMenuStep()); + while (!InitStartMenuStep()) + ; } static void StartMenuTask(u8 taskId) { if (InitStartMenuStep() == TRUE) - { SwitchTaskToFollowupFunc(taskId); - } } static void CreateStartMenuTask(TaskFunc followupFunc) @@ -541,18 +535,14 @@ void sub_809FA34(u8 taskId) // Referenced in field_screen.s and rom_8011DC0.s { case 0: if (InUnionRoom() == TRUE) - { var_800D_set_xB(); - } gMenuCallback = HandleStartMenuInput; task->data[0]++; break; case 1: if (gMenuCallback() == TRUE) - { DestroyTask(taskId); - } break; } } @@ -588,9 +578,8 @@ static bool8 HandleStartMenuInput(void) PlaySE(SE_SELECT); if (sStartMenuItems[sCurrentStartMenuActions[sStartMenuCursorPos]].func.u8_void == StartMenuPokedexCallback) { - if (GetNationalPokedexCount(0) == 0) { + if (GetNationalPokedexCount(0) == 0) return FALSE; - } } gMenuCallback = sStartMenuItems[sCurrentStartMenuActions[sStartMenuCursorPos]].func.u8_void; @@ -686,17 +675,11 @@ static bool8 StartMenuPlayerNameCallback(void) CleanupOverworldWindowsAndTilemaps(); if (is_c1_link_related_active() || InUnionRoom()) - { - sub_80C4DDC(CB2_ReturnToFieldWithOpenMenu); // Display trainer card - } + ShowPlayerTrainerCard(CB2_ReturnToFieldWithOpenMenu); // Display trainer card else if (FlagGet(FLAG_SYS_FRONTIER_PASS)) - { - sub_80C51C4(CB2_ReturnToFieldWithOpenMenu); // Display frontier pass - } + ShowFrontierPass(CB2_ReturnToFieldWithOpenMenu); // Display frontier pass else - { - sub_80C4DDC(CB2_ReturnToFieldWithOpenMenu); // Display trainer card - } + ShowPlayerTrainerCard(CB2_ReturnToFieldWithOpenMenu); // Display trainer card return TRUE; } @@ -707,9 +690,7 @@ static bool8 StartMenuPlayerNameCallback(void) static bool8 StartMenuSaveCallback(void) { if (InBattlePyramid()) - { RemoveExtraStartMenuWindows(); - } gMenuCallback = SaveStartCallback; // Display save menu @@ -755,7 +736,7 @@ static bool8 StartMenuLinkModePlayerNameCallback(void) { PlayRainSoundEffect(); CleanupOverworldWindowsAndTilemaps(); - TrainerCard_ShowLinkCard(gUnknown_03005DB4, CB2_ReturnToFieldWithOpenMenu); + ShowTrainerCardInLink(gUnknown_03005DB4, CB2_ReturnToFieldWithOpenMenu); return TRUE; } diff --git a/src/string_util.c b/src/string_util.c index 8ce9a97ed..39d235ab8 100644 --- a/src/string_util.c +++ b/src/string_util.c @@ -587,7 +587,7 @@ u8 *StringCopyN_Multibyte(u8 *dest, u8 *src, u32 n) return dest; } -u32 StringLength_Multibyte(u8 *str) +u32 StringLength_Multibyte(const u8 *str) { u32 length = 0; diff --git a/src/strings.c b/src/strings.c index 7b2b5ca4c..b0eb048ba 100644 --- a/src/strings.c +++ b/src/strings.c @@ -252,7 +252,7 @@ const u8 gText_ThePokemonList[] = _("the POKéMON LIST"); const u8 gText_TheShop[] = _("the shop"); const u8 gText_ThePC[] = _("the PC"); -const u8 *const gReturnToXStringsTable[] = +const u8 *const gReturnToXStringsTable[] = { gText_TheField, gText_TheBattle, @@ -268,7 +268,7 @@ const u8 *const gReturnToXStringsTable[] = gText_ThePC }; -const u8 *const gReturnToXStringsTable2[] = +const u8 *const gReturnToXStringsTable2[] = { gText_TheField, gText_TheBattle, @@ -283,7 +283,7 @@ const u8 gText_TMHMPocket[] = _("TMs & HMs"); const u8 gText_BerriesPocket[] = _("BERRIES"); const u8 gText_KeyItemsPocket[] = _("KEY ITEMS"); -const u8 *const gPocketNamesStringsTable[] = +const u8 *const gPocketNamesStringsTable[] = { gText_ItemsPocket, gText_PokeBallsPocket, @@ -749,10 +749,10 @@ const u8 gUnknown_085EB2FF[] = _("I'll battle now!"); const u8 gUnknown_085EB310[] = _("I won!"); const u8 gUnknown_085EB317[] = _("I lost!"); const u8 gUnknown_085EB31F[] = _("I won't tell."); -const u8 gUnknown_085EB32D[] = _("NORMAL TAG MATCH"); -const u8 gUnknown_085EB33E[] = _("VARIETY TAG MATCH"); -const u8 gUnknown_085EB350[] = _("UNIQUE TAG MATCH"); -const u8 gUnknown_085EB361[] = _("EXPERT TAG MATCH"); +const u8 gText_NormalTagMatch[] = _("NORMAL TAG MATCH"); +const u8 gText_VarietyTagMatch[] = _("VARIETY TAG MATCH"); +const u8 gText_UniqueTagMatch[] = _("UNIQUE TAG MATCH"); +const u8 gText_ExpertTagMatch[] = _("EXPERT TAG MATCH"); const u8 gUnknown_085EB372[] = _("TRADE CENTER"); const u8 gUnknown_085EB37F[] = _("COLOSSEUM"); const u8 gUnknown_085EB389[] = _("RECORD CORNER"); @@ -1737,10 +1737,10 @@ const u8 gText_Lv[] = _("{LV}"); const u8 gText_TimeBoard[] = _("TIME BOARD"); const u8 gText_TimeCleared[] = _("TIME CLEARED "); const u8 gText_XMinYDotZSec[] = _("{STR_VAR_1} min. {STR_VAR_2}.{STR_VAR_3} sec."); -const u8 gUnknown_085EF8B6[] = _("1F"); -const u8 gUnknown_085EF8B9[] = _("2F"); -const u8 gUnknown_085EF8BC[] = _("3F"); -const u8 gUnknown_085EF8BF[] = _("4F"); +const u8 gText_TrainerHill1F[] = _("1F"); +const u8 gText_TrainerHill2F[] = _("2F"); +const u8 gText_TrainerHill3F[] = _("3F"); +const u8 gText_TrainerHill4F[] = _("4F"); const u8 gText_TeachWhichMoveToPkmn[] = _("Teach which move to {STR_VAR_1}?"); const u8 gText_TeachX[] = _("Teach {STR_VAR_2}?"); const u8 gText_PkmnLearnedMove4[] = _("{STR_VAR_1} learned\n{STR_VAR_2}!"); diff --git a/src/trade.c b/src/trade.c index 7af1e19c9..70b57fbc7 100644 --- a/src/trade.c +++ b/src/trade.c @@ -26,6 +26,7 @@ #include "pokedex.h" #include "pokemon_icon.h" #include "pokemon_summary_screen.h" +#include "pokemon_storage_system.h" #include "random.h" #include "rom_8011DC0.h" #include "save.h" diff --git a/src/trainer_card.c b/src/trainer_card.c new file mode 100755 index 000000000..b7bd5cc1d --- /dev/null +++ b/src/trainer_card.c @@ -0,0 +1,1856 @@ +#include "global.h" +#include "scanline_effect.h" +#include "palette.h" +#include "task.h" +#include "main.h" +#include "window.h" +#include "alloc.h" +#include "link.h" +#include "bg.h" +#include "sound.h" +#include "frontier_pass.h" +#include "overworld.h" +#include "menu.h" +#include "text.h" +#include "event_data.h" +#include "easy_chat.h" +#include "money.h" +#include "strings.h" +#include "string_util.h" +#include "trainer_card.h" +#include "gpu_regs.h" +#include "international_string_util.h" +#include "pokedex.h" +#include "graphics.h" +#include "pokemon_icon.h" +#include "trainer_pokemon_sprites.h" +#include "script_pokemon_util_80F87D8.h" +#include "constants/songs.h" +#include "constants/flags.h" +#include "constants/game_stat.h" +#include "constants/battle_frontier.h" + +enum +{ + CARD_TYPE_FRLG, + CARD_TYPE_RS, + CARD_TYPE_EMERALD, +}; + +struct TrainerCardData +{ + u8 var_0; + u8 printState; + u8 gfxLoadState; + u8 bgPalLoadState; + u8 var_4; + bool8 isLink; + u8 var_6; + u8 var_7; + u8 var_8; + bool8 allowDMACopy; + bool8 hasPokedex; + bool8 hasHofResult; + bool8 hasLinkResults; + bool8 hasBattleTowerWins; + u8 var_E; + u8 var_F; + bool8 hasTrades; + u8 badgeCount[8]; + u8 var_19[4][0xD]; + u8 var_4D[0x46]; + u8 var_93[0x46]; + u8 var_D9[0x8C]; + u8 var_165[0x46]; + u8 var_1AB[0x8C]; + u8 var_237[0x8C]; + u8 var_2C3[0x8C]; + u8 var_34F[0x46]; + u8 var_395[0x46]; + u8 var_3DB[0x46]; + u8 var_421[0x46]; + u16 var_468[0x60]; + s8 var_528; + u8 var_529; + u8 cardType; + bool8 isHoenn; + u16 var_52C; + void (*callback2)(void); + struct TrainerCard trainerCard; + u16 var_598[0x4B0 / 2]; + u16 var_A48[0x4B0 / 2]; + u16 var_EF8[0x4B0 / 2]; + u8 var_13A8[0x400]; + u8 var_17A8[0x200]; + u8 var_19A8[0x2300]; + u16 var_3CA8[0x2000 / 2]; + u16 var_5CA8[0x2000 / 2]; + u16 var_7CA8; + u8 language; +}; + +//external functions +extern u8 sub_80D30A0(u16); + +// EWRAM +EWRAM_DATA static struct TrainerCardData *sData = NULL; + +//this file's functions +static void VblankCb_TrainerCard(void); +static void HblankCb_TrainerCard(void); +static void sub_80C48C8(void); +static void CB2_TrainerCard(void); +static void CloseTrainerCard(u8 task); +static bool8 PrintAllOnCardPage1(void); +static void sub_80C438C(u8); +static void sub_80C4FF0(void); +static void sub_80C4550(u16*); +static void sub_80C45C0(u16*); +static void sub_80C4630(void); +static void PrintTimeOnCard(void); +static void sub_80C4918(void); +static bool8 sub_80C4940(void); +static bool8 LoadCardGfx(void); +static void CB2_InitTrainerCard(void); +static u32 GetCappedGameStat(u8 statId, u32 maxValue); +static bool8 HasAllFrontierSymbols(void); +static u8 GetRubyTrainerStars(struct TrainerCard*); +static u16 GetCaughtMonsCount(void); +static void SetPlayerCardData(struct TrainerCard*, u8); +static void sub_80C3020(struct TrainerCard*); +static u8 VersionToCardType(u8); +static void SetDataFromTrainerCard(void); +static void HandleGpuRegs(void); +static void ResetGpuRegs(void); +static void InitBgsAndWindows(void); +static void SetTrainerCardCb2(void); +static void sub_80C3414(void); +static void sub_80C4EE4(void); +static u8 GetSetCardType(void); +static void PrintNameOnCard(void); +static void PrintIdOnCard(void); +static void PrintMoneyOnCard(void); +static void PrintPokedexOnCard(void); +static void PrintProfilePhraseOnCard(void); +static bool8 PrintStringsOnCardPage2(void); +static void sub_80C3B50(void); +static void PrintHofDebutStringOnCard(void); +static void PrintWinsLossesStringOnCard(void); +static void PrintTradesStringOnCard(void); +static void PrintBerryCrushStringOnCard(void); +static void PrintPokeblockStringOnCard(void); +static void PrintUnionStringOnCard(void); +static void PrintContestStringOnCard(void); +static void sub_80C4140(void); +static void PrintBattleFacilityStringOnCard(void); +static void sub_80C42A4(void); +static void PrintAllVariableNumsOnCardPage2(void); +static void PrintNameOnCard2(void); +static void PrintHofTimeOnCard(void); +static void PrintLinkResultsNumsOnCard(void); +static void PrintTradesNumOnCard(void); +static void PrintBerryCrushNumOnCard(void); +static void PrintUnionNumOnCard(void); +static void PrintPokeblocksNumOnCard(void); +static void PrintContestNumOnCard(void); +static void PrintBattleFacilityNumsOnCard(void); +static void PrintString(u8 top, const u8* str1, u8* str2, const u8* color); +static void sub_80C4330(void); +static u8 SetCardBgsAndPals(void); +static void sub_80C474C(void); +static void sub_80C4960(u8); +static bool8 sub_80C4998(struct Task* task); +static bool8 sub_80C49D8(struct Task* task); +static bool8 sub_80C4B08(struct Task* task); +static bool8 sub_80C4C1C(struct Task* task); +static bool8 sub_80C4C84(struct Task* task); +static bool8 sub_80C4DB0(struct Task* task); +static void sub_80C32EC(u16); +static void sub_80C41D8(void); + +// const rom data +static const u32 gUnknown_0856F018[] = INCBIN_U32("graphics/trainer_card/stickers_fr.4bpp.lz"); +static const u16 gUnknown_0856F18C[] = INCBIN_U16("graphics/trainer_card/unknown_56F18C.gbapal"); +static const u16 gEmeraldTrainerCard1Star_Pal[] = INCBIN_U16("graphics/trainer_card/one_star.gbapal"); +static const u16 gFireRedTrainerCard1Star_Pal[] = INCBIN_U16("graphics/trainer_card/one_star_fr.gbapal"); +static const u16 gEmeraldTrainerCard2Star_Pal[] = INCBIN_U16("graphics/trainer_card/two_stars.gbapal"); +static const u16 gFireRedTrainerCard2Star_Pal[] = INCBIN_U16("graphics/trainer_card/two_stars_fr.gbapal"); +static const u16 gEmeraldTrainerCard3Star_Pal[] = INCBIN_U16("graphics/trainer_card/three_stars.gbapal"); +static const u16 gFireRedTrainerCard3Star_Pal[] = INCBIN_U16("graphics/trainer_card/three_stars_fr.gbapal"); +static const u16 gEmeraldTrainerCard4Star_Pal[] = INCBIN_U16("graphics/trainer_card/four_stars.gbapal"); +static const u16 gFireRedTrainerCard4Star_Pal[] = INCBIN_U16("graphics/trainer_card/four_stars_fr.gbapal"); +static const u16 gUnknown_0856F4AC[] = INCBIN_U16("graphics/trainer_card/female_bg.gbapal"); +static const u16 gUnknown_0856F4CC[] = INCBIN_U16("graphics/trainer_card/female_bg_fr.gbapal"); +static const u16 gUnknown_0856F4EC[] = INCBIN_U16("graphics/trainer_card/badges.gbapal"); +static const u16 gUnknown_0856F50C[] = INCBIN_U16("graphics/trainer_card/badges_fr.gbapal"); +static const u16 gUnknown_0856F52C[] = INCBIN_U16("graphics/trainer_card/gold.gbapal"); +static const u16 gUnknown_0856F54C[] = INCBIN_U16("graphics/trainer_card/stickers_fr1.gbapal"); +static const u16 gUnknown_0856F56C[] = INCBIN_U16("graphics/trainer_card/stickers_fr2.gbapal"); +static const u16 gUnknown_0856F58C[] = INCBIN_U16("graphics/trainer_card/stickers_fr3.gbapal"); +static const u16 gUnknown_0856F5AC[] = INCBIN_U16("graphics/trainer_card/stickers_fr4.gbapal"); +static const u32 gUnknown_0856F5CC[] = INCBIN_U32("graphics/trainer_card/badges.4bpp.lz"); +static const u32 gUnknown_0856F814[] = INCBIN_U32("graphics/trainer_card/badges_fr.4bpp.lz"); + +static const struct BgTemplate gUnknown_0856FAB4[4] = +{ + { + .bg = 0, + .charBaseIndex = 0, + .mapBaseIndex = 27, + .screenSize = 2, + .paletteMode = 0, + .priority = 2, + .baseTile = 0 + }, + { + .bg = 1, + .charBaseIndex = 2, + .mapBaseIndex = 29, + .screenSize = 0, + .paletteMode = 0, + .priority = 0, + .baseTile = 0 + }, + { + .bg = 2, + .charBaseIndex = 0, + .mapBaseIndex = 30, + .screenSize = 0, + .paletteMode = 0, + .priority = 3, + .baseTile = 0 + }, + { + .bg = 3, + .charBaseIndex = 0, + .mapBaseIndex = 31, + .screenSize = 0, + .paletteMode = 0, + .priority = 1, + .baseTile = 192 + }, +}; + +static const struct WindowTemplate gUnknown_0856FAC4[] = +{ + { + .bg = 1, + .tilemapLeft = 2, + .tilemapTop = 15, + .width = 27, + .height = 4, + .paletteNum = 15, + .baseBlock = 0x253, + }, + { + .bg = 1, + .tilemapLeft = 1, + .tilemapTop = 1, + .width = 28, + .height = 18, + .paletteNum = 15, + .baseBlock = 0x1, + }, + { + .bg = 3, + .tilemapLeft = 19, + .tilemapTop = 5, + .width = 9, + .height = 10, + .paletteNum = 8, + .baseBlock = 0x150, + }, + DUMMY_WIN_TEMPLATE +}; + +static const u16 *const gEmeraldTrainerCardStarPals[] = +{ + gEmeraldTrainerCard0Star_Pal, + gEmeraldTrainerCard1Star_Pal, + gEmeraldTrainerCard2Star_Pal, + gEmeraldTrainerCard3Star_Pal, + gEmeraldTrainerCard4Star_Pal, +}; + +static const u16 *const gFireRedTrainerCardStarPals[] = +{ + gFireRedTrainerCard0Star_Pal, + gFireRedTrainerCard1Star_Pal, + gFireRedTrainerCard2Star_Pal, + gFireRedTrainerCard3Star_Pal, + gFireRedTrainerCard4Star_Pal, +}; + +static const u8 gUnknown_0856FB0C[] = {0, 2, 3}; +static const u8 gUnknown_0856FB0F[] = {0, 4, 5}; +static const u8 gUnknown_0856FB12[6] = {0}; + +static const u8 gUnknown_0856FB18[][2][2] = +{ + {{0xD, 4}, {0xD, 4}}, + {{1, 0}, {1, 0}}, +}; + +static const u8 gUnknown_0856FB20[][2] = {{0x4E, 0x4F}, {0x50, 0x51}, {0x3C, 0x3F}}; + +static bool8 (*const gUnknown_0856FB28[])(struct Task *) = +{ + sub_80C4998, + sub_80C49D8, + sub_80C4B08, + sub_80C4C1C, + sub_80C4C84, + sub_80C4DB0, +}; + +// code +static void VblankCb_TrainerCard(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); + sub_80C48C8(); + if (sData->allowDMACopy) + DmaCopy16(3, &gScanlineEffectRegBuffers[0], &gScanlineEffectRegBuffers[1], 0x140); +} + +static void HblankCb_TrainerCard(void) +{ + u16 backup; + u16 bgVOffset; + + backup = REG_IME; + REG_IME = 0; + bgVOffset = gScanlineEffectRegBuffers[1][REG_VCOUNT & 0xFF]; + REG_BG0VOFS = bgVOffset; + REG_IME = backup; +} + +static void CB2_TrainerCard(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} + +static void CloseTrainerCard(u8 taskId) +{ + SetMainCallback2(sData->callback2); + FreeAllWindowBuffers(); + FREE_AND_SET_NULL(sData); + DestroyTask(taskId); +} + +static void sub_80C2760(u8 taskId) +{ + switch (sData->var_0) + { + case 0: + if (!IsDma3ManagerBusyWithBgCopy()) + { + FillWindowPixelBuffer(1, 0); + sData->var_0++; + } + break; + case 1: + if (PrintAllOnCardPage1()) + sData->var_0++; + break; + case 2: + sub_80C438C(1); + sData->var_0++; + break; + case 3: + FillWindowPixelBuffer(2, 0); + sub_80C4FF0(); + sub_80C438C(2); + sData->var_0++; + break; + case 4: + sub_80C4550(sData->var_EF8); + sData->var_0++; + break; + case 5: + sub_80C45C0(sData->var_598); + sData->var_0++; + break; + case 6: + sub_80C4630(); + sData->var_0++; + break; + case 7: + if (gWirelessCommType == 1 && gReceivedRemoteLinkPlayers == TRUE) + { + sub_800E0E8(); + CreateWirelessStatusIndicatorSprite(230, 150); + } + BlendPalettes(0xFFFFFFFF, 16, sData->var_52C); + BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, sData->var_52C); + SetVBlankCallback(VblankCb_TrainerCard); + sData->var_0++; + break; + case 8: + if (!UpdatePaletteFade() && !IsDma3ManagerBusyWithBgCopy()) + { + PlaySE(SE_RG_CARD3); + sData->var_0 = 10; + } + break; + case 9: + if (!IsSEPlaying()) + sData->var_0++; + break; + case 10: + if (!gReceivedRemoteLinkPlayers && sData->var_529) + { + PrintTimeOnCard(); + sub_80C438C(1); + sData->var_529 = 0; + } + if (gMain.newKeys & A_BUTTON) + { + sub_80C4918(); + PlaySE(SE_RG_CARD1); + sData->var_0 = 12; + } + else if (gMain.newKeys & B_BUTTON) + { + if (gReceivedRemoteLinkPlayers && sData->isLink && InUnionRoom() == TRUE) + { + sData->var_0 = 15; + } + else + { + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, sData->var_52C); + sData->var_0 = 14; + } + } + break; + case 12: + if (sub_80C4940() && sub_8087598() != TRUE) + { + PlaySE(SE_RG_CARD3); + sData->var_0 = 11; + } + break; + case 11: + if (gMain.newKeys & B_BUTTON) + { + if (gReceivedRemoteLinkPlayers && sData->isLink && InUnionRoom() == TRUE) + { + sData->var_0 = 15; + } + else if (gReceivedRemoteLinkPlayers) + { + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, sData->var_52C); + sData->var_0 = 14; + } + else + { + sub_80C4918(); + sData->var_0 = 13; + PlaySE(SE_RG_CARD1); + } + } + else if (gMain.newKeys & A_BUTTON) + { + if (gReceivedRemoteLinkPlayers && sData->isLink && InUnionRoom() == TRUE) + { + sData->var_0 = 15; + } + else + { + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, sData->var_52C); + sData->var_0 = 14; + } + } + break; + case 15: + sub_800AC34(); + NewMenuHelpers_DrawDialogueFrame(0, 1); + AddTextPrinterParameterized(0, 1, gText_WaitingTrainerFinishReading, 0, 1, 255, 0); + CopyWindowToVram(0, 3); + sData->var_0 = 16; + break; + case 16: + if (!gReceivedRemoteLinkPlayers) + { + BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 16, sData->var_52C); + sData->var_0 = 14; + } + break; + case 14: + if (!UpdatePaletteFade()) + CloseTrainerCard(taskId); + break; + case 13: + if (sub_80C4940() && sub_8087598() != TRUE) + { + sData->var_0 = 10; + PlaySE(SE_RG_CARD3); + } + break; + } +} + +static bool8 LoadCardGfx(void) +{ + switch (sData->gfxLoadState) + { + case 0: + if (sData->cardType != CARD_TYPE_FRLG) + LZ77UnCompWram(gUnknown_08DD1F78, sData->var_EF8); + else + LZ77UnCompWram(gUnknown_08DD2AE0, sData->var_EF8); + break; + case 1: + if (sData->cardType != CARD_TYPE_FRLG) + LZ77UnCompWram(gUnknown_08DD21B0, sData->var_A48); + else + LZ77UnCompWram(gUnknown_08DD2D30, sData->var_A48); + break; + case 2: + if (!sData->isLink) + { + if (sData->cardType != CARD_TYPE_FRLG) + LZ77UnCompWram(gUnknown_08DD2010, sData->var_598); + else + LZ77UnCompWram(gUnknown_08DD2B78, sData->var_598); + } + else + { + if (sData->cardType != CARD_TYPE_FRLG) + LZ77UnCompWram(gUnknown_08DD228C, sData->var_598); + else + LZ77UnCompWram(gUnknown_08DD2E5C, sData->var_598); + } + break; + case 3: + if (sData->cardType != CARD_TYPE_FRLG) + LZ77UnCompWram(gUnknown_0856F5CC, sData->var_13A8); + else + LZ77UnCompWram(gUnknown_0856F814, sData->var_13A8); + break; + case 4: + if (sData->cardType != CARD_TYPE_FRLG) + LZ77UnCompWram(gEmeraldTrainerCard_Gfx, sData->var_19A8); + else + LZ77UnCompWram(gFireRedTrainerCard_Gfx, sData->var_19A8); + break; + case 5: + if (sData->cardType == CARD_TYPE_FRLG) + LZ77UnCompWram(gUnknown_0856F018, sData->var_17A8); + break; + default: + sData->gfxLoadState = 0; + return TRUE; + } + sData->gfxLoadState++; + return FALSE; +} + +static void CB2_InitTrainerCard(void) +{ + switch (gMain.state) + { + case 0: + ResetGpuRegs(); + sub_80C3414(); + gMain.state++; + break; + case 1: + DmaClear32(3, (void *)OAM, OAM_SIZE); + gMain.state++; + break; + case 2: + if (!sData->var_52C) + DmaClear16(3, (void *)PLTT, PLTT_SIZE); + gMain.state++; + break; + case 3: + ResetSpriteData(); + FreeAllSpritePalettes(); + ResetPaletteFade(); + gMain.state++; + case 4: + InitBgsAndWindows(); + gMain.state++; + break; + case 5: + sub_80C41D8(); + gMain.state++; + break; + case 6: + if (LoadCardGfx() == TRUE) + gMain.state++; + break; + case 7: + sub_80C4330(); + gMain.state++; + break; + case 8: + HandleGpuRegs(); + gMain.state++; + break; + case 9: + PrintAllVariableNumsOnCardPage2(); + gMain.state++; + break; + case 10: + if (SetCardBgsAndPals() == TRUE) + gMain.state++; + break; + default: + SetTrainerCardCb2(); + break; + } +} + +static u32 GetCappedGameStat(u8 statId, u32 maxValue) +{ + u32 statValue = GetGameStat(statId); + + return min(maxValue, statValue); +} + +static bool8 HasAllFrontierSymbols(void) +{ + u8 i; + for (i = 0; i < NUM_FRONTIER_FACILITIES; i++) + { + if (!FlagGet(FLAG_SYS_TOWER_SILVER + 2 * i) || !FlagGet(FLAG_SYS_TOWER_GOLD + 2 * i)) + return FALSE; + } + return TRUE; +} + +u32 CountPlayerTrainerStars(void) +{ + u8 stars = 0; + + if (GetGameStat(GAME_STAT_ENTERED_HOF)) + stars++; + if (HasAllHoennMons()) + stars++; + if (CountPlayerContestPaintings() > 4) + stars++; + if (HasAllFrontierSymbols()) + stars++; + + return stars; +} + +static u8 GetRubyTrainerStars(struct TrainerCard *trainerCard) +{ + u8 stars = 0; + + if (trainerCard->hofDebutHours || trainerCard->hofDebutMinutes || trainerCard->hofDebutSeconds) + stars++; + if (trainerCard->caughtAllHoenn) + stars++; + if (trainerCard->battleTowerStraightWins > 49) + stars++; + if (trainerCard->hasAllPaintings) + stars++; + + return stars; +} + +static void SetPlayerCardData(struct TrainerCard *trainerCard, u8 cardType) +{ + u32 playTime; + u8 i; + + trainerCard->gender = gSaveBlock2Ptr->playerGender; + trainerCard->playTimeHours = gSaveBlock2Ptr->playTimeHours; + trainerCard->playTimeMinutes = gSaveBlock2Ptr->playTimeMinutes; + + playTime = GetGameStat(GAME_STAT_FIRST_HOF_PLAY_TIME); + if (!GetGameStat(GAME_STAT_ENTERED_HOF)) + playTime = 0; + + trainerCard->hofDebutHours = playTime >> 16; + trainerCard->hofDebutMinutes = (playTime >> 8) & 0xFF; + trainerCard->hofDebutSeconds = playTime & 0xFF; + if ((playTime >> 16) > 999) + { + trainerCard->hofDebutHours = 999; + trainerCard->hofDebutMinutes = 59; + trainerCard->hofDebutSeconds = 59; + } + + trainerCard->hasPokedex = FlagGet(FLAG_SYS_POKEDEX_GET); + trainerCard->caughtAllHoenn = HasAllHoennMons(); + trainerCard->caughtMonsCount = GetCaughtMonsCount(); + + trainerCard->trainerId = (gSaveBlock2Ptr->playerTrainerId[1] << 8) | gSaveBlock2Ptr->playerTrainerId[0]; + + trainerCard->linkBattleWins = GetCappedGameStat(GAME_STAT_LINK_BATTLE_WINS, 9999); + trainerCard->linkBattleLosses = GetCappedGameStat(GAME_STAT_LINK_BATTLE_LOSSES, 9999); + + trainerCard->pokemonTrades = GetCappedGameStat(GAME_STAT_POKEMON_TRADES, 0xFFFF); + + trainerCard->money = GetMoney(&gSaveBlock1Ptr->money); + + for (i = 0; i < 4; i++) + trainerCard->var_28[i] = gSaveBlock1Ptr->unk2BB0[i]; + + StringCopy(trainerCard->playerName, gSaveBlock2Ptr->playerName); + + switch (cardType) + { + case CARD_TYPE_EMERALD: + trainerCard->battleTowerWins = 0; + trainerCard->battleTowerStraightWins = 0; + // Seems like GF got CARD_TYPE_FRLG and CARD_TYPE_RS wrong. + case CARD_TYPE_FRLG: + trainerCard->contestsWithFriends = GetCappedGameStat(GAME_STAT_WON_LINK_CONTEST, 999); + trainerCard->pokeblocksWithFriends = GetCappedGameStat(GAME_STAT_POKEBLOCKS_WITH_FRIENDS, 0xFFFF); + if (CountPlayerContestPaintings() > 4) + trainerCard->hasAllPaintings = TRUE; + trainerCard->stars = GetRubyTrainerStars(trainerCard); + break; + case CARD_TYPE_RS: + trainerCard->battleTowerWins = 0; + trainerCard->battleTowerStraightWins = 0; + trainerCard->contestsWithFriends = 0; + trainerCard->pokeblocksWithFriends = 0; + trainerCard->hasAllPaintings = 0; + trainerCard->stars = 0; + break; + } +} + +static void sub_80C3020(struct TrainerCard *trainerCard) +{ + memset(trainerCard, 0, sizeof(struct TrainerCard)); + trainerCard->version = GAME_VERSION; + SetPlayerCardData(trainerCard, CARD_TYPE_EMERALD); + trainerCard->hasAllSymbols = HasAllFrontierSymbols(); + trainerCard->frontierBP = gSaveBlock2Ptr->frontier.field_EBA; + if (trainerCard->hasAllSymbols) + trainerCard->stars++; + + if (trainerCard->gender == FEMALE) + trainerCard->var_4F = gUnknown_08329D54[(trainerCard->trainerId % 8) + 8]; + else + trainerCard->var_4F = gUnknown_08329D54[trainerCard->trainerId % 8]; +} + +void TrainerCard_GenerateCardForPlayer(struct TrainerCard *trainerCard) +{ + memset(trainerCard, 0, 0x60); + trainerCard->version = GAME_VERSION; + SetPlayerCardData(trainerCard, CARD_TYPE_EMERALD); + trainerCard->var_3A = HasAllFrontierSymbols(); + *((u16*)&trainerCard->berryCrushPoints) = gSaveBlock2Ptr->frontier.field_EBA; + if (trainerCard->var_3A) + trainerCard->stars++; + + if (trainerCard->gender == FEMALE) + trainerCard->var_4F = gUnknown_08329D54[(trainerCard->trainerId % 8) + 8]; + else + trainerCard->var_4F = gUnknown_08329D54[trainerCard->trainerId % 8]; +} + +void CopyTrainerCardData(struct TrainerCard *dst, u16 *src, u8 gameVersion) +{ + memset(dst, 0, sizeof(struct TrainerCard)); + dst->version = gameVersion; + + switch (VersionToCardType(gameVersion)) + { + case CARD_TYPE_FRLG: + memcpy(dst, src, 0x60); + break; + case CARD_TYPE_RS: + memcpy(dst, src, 0x38); + break; + case CARD_TYPE_EMERALD: + memcpy(dst, src, 0x60); + dst->berryCrushPoints = 0; + dst->hasAllSymbols = src[29]; + dst->frontierBP = src[30]; + break; + } +} + +static void SetDataFromTrainerCard(void) +{ + u8 i; + u32 badgeFlag; + + sData->hasPokedex = FALSE; + sData->hasHofResult = FALSE; + sData->hasLinkResults = FALSE; + sData->hasBattleTowerWins = FALSE; + sData->var_E = 0; + sData->var_F = 0; + sData->hasTrades = FALSE; + memset(sData->badgeCount, 0, sizeof(sData->badgeCount)); + if (sData->trainerCard.hasPokedex) + sData->hasPokedex++; + + if (sData->trainerCard.hofDebutHours + || sData->trainerCard.hofDebutMinutes + || sData->trainerCard.hofDebutSeconds) + sData->hasHofResult++; + + if (sData->trainerCard.linkBattleWins || sData->trainerCard.linkBattleLosses) + sData->hasLinkResults++; + if (sData->trainerCard.pokemonTrades) + sData->hasTrades++; + if (sData->trainerCard.battleTowerWins || sData->trainerCard.battleTowerStraightWins) + sData->hasBattleTowerWins++; + + for (i = 0, badgeFlag = FLAG_BADGE01_GET; badgeFlag <= FLAG_BADGE08_GET; badgeFlag++, i++) + { + if (FlagGet(badgeFlag)) + sData->badgeCount[i]++; + } +} + +static void HandleGpuRegs(void) +{ + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON | DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP); + ShowBg(0); + ShowBg(1); + ShowBg(2); + ShowBg(3); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_DARKEN); + SetGpuReg(REG_OFFSET_BLDY, 0); + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR); + SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ); + SetGpuReg(REG_OFFSET_WIN0V, 160); + SetGpuReg(REG_OFFSET_WIN0H, 240); + if (gReceivedRemoteLinkPlayers) + EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_HBLANK | INTR_FLAG_VCOUNT | INTR_FLAG_TIMER3 | INTR_FLAG_SERIAL); + else + EnableInterrupts(INTR_FLAG_VBLANK | INTR_FLAG_HBLANK); +} + +static void sub_80C32EC(u16 arg0) +{ + s8 quotient = (arg0 + 40) / 10; + + if (quotient <= 4) + quotient = 0; + sData->var_528 = quotient; + SetGpuReg(REG_OFFSET_BLDY, sData->var_528); + SetGpuReg(REG_OFFSET_WIN0V, (sData->var_7CA8 * 256) | (160 - sData->var_7CA8)); +} + +static void ResetGpuRegs(void) +{ + SetVBlankCallback(NULL); + SetHBlankCallback(NULL); + SetGpuReg(REG_OFFSET_DISPCNT, 0); + SetGpuReg(REG_OFFSET_BG0CNT, 0); + SetGpuReg(REG_OFFSET_BG1CNT, 0); + SetGpuReg(REG_OFFSET_BG2CNT, 0); + SetGpuReg(REG_OFFSET_BG3CNT, 0); +} + +static void InitBgsAndWindows(void) +{ + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, gUnknown_0856FAB4, ARRAY_COUNT(gUnknown_0856FAB4)); + ChangeBgX(0, 0, 0); + ChangeBgY(0, 0, 0); + ChangeBgX(1, 0, 0); + ChangeBgY(1, 0, 0); + ChangeBgX(2, 0, 0); + ChangeBgY(2, 0, 0); + ChangeBgX(3, 0, 0); + ChangeBgY(3, 0, 0); + InitWindows(gUnknown_0856FAC4); + DeactivateAllTextPrinters(); + sub_81973A4(); +} + +static void SetTrainerCardCb2(void) +{ + SetMainCallback2(CB2_TrainerCard); +} + +static void sub_80C3414(void) +{ + ResetTasks(); + ScanlineEffect_Stop(); + CreateTask(sub_80C2760, 0); + sub_80C4EE4(); + SetDataFromTrainerCard(); +} + +static bool8 PrintAllOnCardPage1(void) +{ + switch (sData->printState) + { + case 0: + PrintNameOnCard(); + break; + case 1: + PrintIdOnCard(); + break; + case 2: + PrintMoneyOnCard(); + break; + case 3: + PrintPokedexOnCard(); + break; + case 4: + PrintTimeOnCard(); + break; + case 5: + PrintProfilePhraseOnCard(); + break; + default: + sData->printState = 0; + return TRUE; + } + sData->printState++; + return FALSE; +} + +static bool8 PrintStringsOnCardPage2(void) +{ + switch (sData->printState) + { + case 0: + sub_80C3B50(); + break; + case 1: + PrintHofDebutStringOnCard(); + break; + case 2: + PrintWinsLossesStringOnCard(); + break; + case 3: + PrintTradesStringOnCard(); + break; + case 4: + PrintBerryCrushStringOnCard(); + PrintPokeblockStringOnCard(); + break; + case 5: + PrintUnionStringOnCard(); + PrintContestStringOnCard(); + break; + case 6: + sub_80C4140(); + PrintBattleFacilityStringOnCard(); + break; + case 7: + sub_80C42A4(); + break; + default: + sData->printState = 0; + return TRUE; + } + sData->printState++; + return FALSE; +} + +static void PrintAllVariableNumsOnCardPage2(void) +{ + PrintNameOnCard2(); + PrintHofTimeOnCard(); + PrintLinkResultsNumsOnCard(); + PrintTradesNumOnCard(); + PrintBerryCrushNumOnCard(); + PrintUnionNumOnCard(); + PrintPokeblocksNumOnCard(); + PrintContestNumOnCard(); + PrintBattleFacilityNumsOnCard(); +} + +static void PrintNameOnCard(void) +{ + u8 buffer[32]; + u8* txtPtr; + txtPtr = StringCopy(buffer, gText_TrainerCardName); + StringCopy(txtPtr, sData->trainerCard.playerName); + ConvertInternationalString(txtPtr, sData->language); + if (sData->cardType == CARD_TYPE_FRLG) + AddTextPrinterParameterized3(1, 1, 20, 28, gUnknown_0856FB0C, TEXT_SPEED_FF, buffer); + else + AddTextPrinterParameterized3(1, 1, 16, 33, gUnknown_0856FB0C, TEXT_SPEED_FF, buffer); +} + +static void PrintIdOnCard(void) +{ + u8 buffer[32]; + u8* txtPtr; + s32 xPos; + u32 top; + txtPtr = StringCopy(buffer, gText_TrainerCardIDNo); + ConvertIntToDecimalStringN(txtPtr, sData->trainerCard.trainerId, STR_CONV_MODE_LEADING_ZEROS, 5); + if (sData->cardType == CARD_TYPE_FRLG) + { + xPos = GetStringCenterAlignXOffset(1, buffer, 80) + 132; + top = 9; + } + else + { + xPos = GetStringCenterAlignXOffset(1, buffer, 96) + 120; + top = 9; + } + + AddTextPrinterParameterized3(1, 1, xPos, top, gUnknown_0856FB0C, TEXT_SPEED_FF, buffer); +} + +static void PrintMoneyOnCard(void) +{ + s32 xOffset; + u8 top; + + if (!sData->isHoenn) + AddTextPrinterParameterized3(1, 1, 20, 56, gUnknown_0856FB0C, TEXT_SPEED_FF, gText_TrainerCardMoney); + else + AddTextPrinterParameterized3(1, 1, 16, 57, gUnknown_0856FB0C, TEXT_SPEED_FF, gText_TrainerCardMoney); + + ConvertIntToDecimalStringN(gStringVar1, sData->trainerCard.money, 0, 6); + StringExpandPlaceholders(gStringVar4, gText_PokedollarVar1); + if (!sData->isHoenn) + { + xOffset = GetStringRightAlignXOffset(1, gStringVar4, 144); + top = 56; + } + else + { + xOffset = GetStringRightAlignXOffset(1, gStringVar4, 128); + top = 57; + } + AddTextPrinterParameterized3(1, 1, xOffset, top, gUnknown_0856FB0C, TEXT_SPEED_FF, gStringVar4); +} + +static u16 GetCaughtMonsCount(void) +{ + if (IsNationalPokedexEnabled()) + return GetNationalPokedexCount(FLAG_GET_CAUGHT); + else + return GetHoennPokedexCount(FLAG_GET_CAUGHT); +} + +static void PrintPokedexOnCard(void) +{ + s32 xOffset; + u8 top; + if (FlagGet(FLAG_SYS_POKEDEX_GET)) + { + if (!sData->isHoenn) + AddTextPrinterParameterized3(1, 1, 20, 72, gUnknown_0856FB0C, TEXT_SPEED_FF, gText_TrainerCardPokedex); + else + AddTextPrinterParameterized3(1, 1, 16, 73, gUnknown_0856FB0C, TEXT_SPEED_FF, gText_TrainerCardPokedex); + StringCopy(ConvertIntToDecimalStringN(gStringVar4, sData->trainerCard.caughtMonsCount, 0, 3), gText_EmptyString6); + if (!sData->isHoenn) + { + xOffset = GetStringRightAlignXOffset(1, gStringVar4, 144); + top = 72; + } + else + { + xOffset = GetStringRightAlignXOffset(1, gStringVar4, 128); + top = 73; + } + AddTextPrinterParameterized3(1, 1, xOffset, top, gUnknown_0856FB0C, TEXT_SPEED_FF, gStringVar4); + } +} + +static const u8 *const gUnknown_0856FB40[] = {gUnknown_0856FB0C, gUnknown_0856FB12}; + +static void PrintTimeOnCard(void) +{ + u16 hours; + u16 minutes; + s32 width; + u32 r7, r4, r10; + + if (!sData->isHoenn) + AddTextPrinterParameterized3(1, 1, 20, 88, gUnknown_0856FB0C, TEXT_SPEED_FF, gText_TrainerCardTime); + else + AddTextPrinterParameterized3(1, 1, 16, 89, gUnknown_0856FB0C, TEXT_SPEED_FF, gText_TrainerCardTime); + + if (sData->isLink) + { + hours = sData->trainerCard.playTimeHours; + minutes = sData->trainerCard.playTimeMinutes; + } + else + { + hours = gSaveBlock2Ptr->playTimeHours; + minutes = gSaveBlock2Ptr->playTimeMinutes; + } + + if (hours > 999) + hours = 999; + if (minutes > 59) + minutes = 59; + width = GetStringWidth(1, gText_Colon2, 0); + + if (!sData->isHoenn) + { + r7 = 144; + r4 = 88; + } + else + { + r7 = 128; + r4 = 89; + } + r10 = width + 30; + r7 -= r10; + + FillWindowPixelRect(1, 0, r7, r4, r10, 15); + ConvertIntToDecimalStringN(gStringVar4, hours, 1, 3); + AddTextPrinterParameterized3(1, 1, r7, r4, gUnknown_0856FB0C, TEXT_SPEED_FF, gStringVar4); + r7 += 18; + AddTextPrinterParameterized3(1, 1, r7, r4, gUnknown_0856FB40[sData->var_7], TEXT_SPEED_FF, gText_Colon2); + r7 += width; + ConvertIntToDecimalStringN(gStringVar4, minutes, 2, 2); + AddTextPrinterParameterized3(1, 1, r7, r4, gUnknown_0856FB0C, TEXT_SPEED_FF, gStringVar4); +} + +static const u8 gUnknown_0856FB48[] = {0x71, 0x68}; +static const u8 gUnknown_0856FB4A[] = {0x81, 0x78}; + +static void PrintProfilePhraseOnCard(void) +{ + if (sData->isLink) + { + AddTextPrinterParameterized3(1, 1, 8, gUnknown_0856FB48[sData->isHoenn], gUnknown_0856FB0C, TEXT_SPEED_FF, sData->var_19[0]); + AddTextPrinterParameterized3(1, 1, GetStringWidth(1, sData->var_19[0], 0) + 14, gUnknown_0856FB48[sData->isHoenn], gUnknown_0856FB0C, TEXT_SPEED_FF, sData->var_19[1]); + AddTextPrinterParameterized3(1, 1, 8, gUnknown_0856FB4A[sData->isHoenn], gUnknown_0856FB0C, TEXT_SPEED_FF, sData->var_19[2]); + AddTextPrinterParameterized3(1, 1, GetStringWidth(1, sData->var_19[2], 0) + 14, gUnknown_0856FB4A[sData->isHoenn], gUnknown_0856FB0C, TEXT_SPEED_FF, sData->var_19[3]); + } +} + +static void PrintNameOnCard2(void) +{ + StringCopy(sData->var_4D, sData->trainerCard.playerName); + ConvertInternationalString(sData->var_4D, sData->language); + if (sData->cardType != CARD_TYPE_FRLG) + { + StringCopy(gStringVar1, sData->var_4D); + StringExpandPlaceholders(sData->var_4D, gText_Var1sTrainerCard); + } +} + +static void sub_80C3B50(void) +{ + if (!sData->isHoenn) + AddTextPrinterParameterized3(1, 1, 136, 9, gUnknown_0856FB0C, TEXT_SPEED_FF, sData->var_4D); + else + AddTextPrinterParameterized3(1, 1, GetStringRightAlignXOffset(1, sData->var_4D, 216), 9, gUnknown_0856FB0C, TEXT_SPEED_FF, sData->var_4D); +} + +static const u8 gUnknown_0856FB4C[] = {0xfd, 0x02, 0xf0, 0xfd, 0x03, 0xf0, 0xfd, 0x04, 0xff}; + +static void PrintHofTimeOnCard(void) +{ + if (sData->hasHofResult) + { + ConvertIntToDecimalStringN(gStringVar1, sData->trainerCard.hofDebutHours, 1, 3); + ConvertIntToDecimalStringN(gStringVar2, sData->trainerCard.hofDebutMinutes, 2, 2); + ConvertIntToDecimalStringN(gStringVar3, sData->trainerCard.hofDebutSeconds, 2, 2); + StringExpandPlaceholders(sData->var_93, gUnknown_0856FB4C); + } +} + +static const u8 gUnknown_0856FB55[] = {0x08, 0x10}; +static const u8 gUnknown_0856FB57[] = {0xd8, 0xd8}; + +static void PrintString(u8 top, const u8* str1, u8* str2, const u8* color) +{ + AddTextPrinterParameterized3(1, 1, gUnknown_0856FB55[sData->isHoenn], top * 16 + 33, gUnknown_0856FB0C, TEXT_SPEED_FF, str1); + AddTextPrinterParameterized3(1, 1, GetStringRightAlignXOffset(1, str2, gUnknown_0856FB57[sData->isHoenn]), top * 16 + 33, color, TEXT_SPEED_FF, str2); +} + +static void PrintHofDebutStringOnCard(void) +{ + if (sData->hasHofResult) + PrintString(0, gText_HallOfFameDebut, sData->var_93, gUnknown_0856FB0F); +} + +static const u8 *const gUnknown_0856FB5C[] = {gText_LinkBattles, gText_LinkCableBattles, gText_LinkBattles}; + +static void PrintLinkResultsNumsOnCard(void) +{ + if (sData->hasLinkResults) + { + StringCopy(sData->var_D9, gUnknown_0856FB5C[sData->cardType]); + ConvertIntToDecimalStringN(sData->var_165, sData->trainerCard.linkBattleWins, 0, 4); + ConvertIntToDecimalStringN(sData->var_1AB, sData->trainerCard.linkBattleLosses, 0, 4); + } +} + +static void PrintWinsLossesStringOnCard(void) +{ + if (sData->hasLinkResults) + { + StringCopy(gStringVar1, sData->var_165); + StringCopy(gStringVar2, sData->var_1AB); + StringExpandPlaceholders(gStringVar4, gText_WinsLosses); + PrintString(1, sData->var_D9, gStringVar4, gUnknown_0856FB0C); + } +} + +static void PrintTradesNumOnCard(void) +{ + if (sData->hasTrades) + ConvertIntToDecimalStringN(sData->var_237, sData->trainerCard.pokemonTrades, 1, 5); +} + +static void PrintTradesStringOnCard(void) +{ + if (sData->hasTrades) + PrintString(2, gText_PokemonTrades, sData->var_237, gUnknown_0856FB0F); +} + +static void PrintBerryCrushNumOnCard(void) +{ + if (sData->cardType == CARD_TYPE_FRLG && sData->trainerCard.berryCrushPoints) + ConvertIntToDecimalStringN(sData->var_2C3, sData->trainerCard.berryCrushPoints, 1, 5); +} + +static void PrintBerryCrushStringOnCard(void) +{ + if (sData->cardType == CARD_TYPE_FRLG && sData->trainerCard.berryCrushPoints) + PrintString(4, gText_BerryCrush, sData->var_2C3, gUnknown_0856FB0F); +} + +static void PrintUnionNumOnCard(void) +{ + if (sData->cardType == CARD_TYPE_FRLG && sData->trainerCard.unionRoomNum) + ConvertIntToDecimalStringN(sData->var_34F, sData->trainerCard.unionRoomNum, 1, 5); +} + +static void PrintUnionStringOnCard(void) +{ + if (sData->cardType == CARD_TYPE_FRLG && sData->trainerCard.unionRoomNum) + PrintString(3, gText_UnionTradesAndBattles, sData->var_34F, gUnknown_0856FB0F); +} + +static void PrintPokeblocksNumOnCard(void) +{ + if (sData->cardType != CARD_TYPE_FRLG && sData->trainerCard.pokeblocksWithFriends) + { + ConvertIntToDecimalStringN(gStringVar1, sData->trainerCard.pokeblocksWithFriends, 1, 5); + StringExpandPlaceholders(sData->var_395, gText_Var1DarkGreyShadowLightGrey); + } +} + +static void PrintPokeblockStringOnCard(void) +{ + if (sData->cardType != CARD_TYPE_FRLG && sData->trainerCard.pokeblocksWithFriends) + PrintString(3, gText_PokeblocksWithFriends, sData->var_395, gUnknown_0856FB0F); +} + +static void PrintContestNumOnCard(void) +{ + if (sData->cardType != CARD_TYPE_FRLG && sData->trainerCard.contestsWithFriends) + ConvertIntToDecimalStringN(sData->var_3DB, sData->trainerCard.contestsWithFriends, 1, 5); +} + +static void PrintContestStringOnCard(void) +{ + if (sData->cardType != CARD_TYPE_FRLG && sData->trainerCard.contestsWithFriends) + PrintString(4, gText_WonContestsWFriends, sData->var_3DB, gUnknown_0856FB0F); +} + +static void PrintBattleFacilityNumsOnCard(void) +{ + switch (sData->cardType) + { + case CARD_TYPE_RS: + if (sData->hasBattleTowerWins) + { + ConvertIntToDecimalStringN(gStringVar1, sData->trainerCard.battleTowerWins, 1, 4); + ConvertIntToDecimalStringN(gStringVar2, sData->trainerCard.battleTowerStraightWins, 1, 4); + StringExpandPlaceholders(sData->var_421, gText_WSlashStraightSlash); + } + break; + case CARD_TYPE_EMERALD: + if (sData->trainerCard.frontierBP) + { + ConvertIntToDecimalStringN(gStringVar1, sData->trainerCard.frontierBP, 1, 5); + StringExpandPlaceholders(sData->var_421, gText_Var1DarkLightGreyBP); + } + break; + case CARD_TYPE_FRLG: + break; + } +} + +static void PrintBattleFacilityStringOnCard(void) +{ + switch (sData->cardType) + { + case CARD_TYPE_RS: + if (sData->hasBattleTowerWins) + PrintString(5, gText_BattleTower, sData->var_421, gUnknown_0856FB0C); + break; + case CARD_TYPE_EMERALD: + if (sData->trainerCard.frontierBP) + PrintString(5, gText_BattlePtsWon, sData->var_421, gUnknown_0856FB0F); + break; + case CARD_TYPE_FRLG: + break; + } +} + +static void sub_80C4140(void) +{ + u8 i; + u8 buffer[] = {0x05, 0x06, 0x07, 0x08, 0x09, 0x0a}; + u8 buffer2[] = {0x00, 0x04, 0x08, 0x0c, 0x10, 0x14}; + + if (sData->cardType == CARD_TYPE_FRLG) + { + for (i = 0; i < 6; i++) + { + if (sData->trainerCard.monSpecies[i]) + { + u8 monSpecies = sub_80D30A0(sData->trainerCard.monSpecies[i]); + WriteSequenceToBgTilemapBuffer(3, 16 * i + 224, buffer2[i] + 3, 15, 4, 4, buffer[monSpecies], 1); + } + } + } +} + +static void sub_80C41D8(void) +{ + u8 i; + + CpuSet(gMonIconPalettes, sData->var_468, 0x60); + switch (sData->trainerCard.var_4E) + { + case 0: + break; + case 1: + TintPalette_CustomTone(sData->var_468, 96, 0, 0, 0); + break; + case 2: + TintPalette_CustomTone(sData->var_468, 96, 500, 330, 310); + break; + case 3: + TintPalette_SepiaTone(sData->var_468, 96); + break; + } + LoadPalette(sData->var_468, 80, 192); + + for (i = 0; i < 6; i++) + { + if (sData->trainerCard.monSpecies[i]) + LoadBgTiles(3, GetMonIconTiles(sData->trainerCard.monSpecies[i], 0), 512, 16 * i + 32); + } +} + +static void sub_80C42A4(void) +{ + u8 i; + u8 buffer[4] = {0x0b, 0x0c, 0x0d, 0x0e}; + + if (sData->cardType == CARD_TYPE_FRLG && sData->trainerCard.var_4C == 1) + { + for (i = 0; i < 3; i++) + { + u8 var_50 = sData->trainerCard.var_50[i]; + if (sData->trainerCard.var_50[i]) + WriteSequenceToBgTilemapBuffer(3, i * 4 + 320, i * 3 + 2, 2, 2, 2, buffer[var_50 - 1], 1); + } + } +} + +static void sub_80C4330(void) +{ + LoadPalette(gUnknown_0856F54C, 176, 32); + LoadPalette(gUnknown_0856F56C, 192, 32); + LoadPalette(gUnknown_0856F58C, 208, 32); + LoadPalette(gUnknown_0856F5AC, 224, 32); + LoadBgTiles(3, sData->var_17A8, 1024, 128); +} + +static void sub_80C438C(u8 windowId) +{ + PutWindowTilemap(windowId); + CopyWindowToVram(windowId, 3); +} + +static u8 SetCardBgsAndPals(void) +{ + switch (sData->bgPalLoadState) + { + case 0: + LoadBgTiles(3, sData->var_13A8, 1024, 0); + break; + case 1: + LoadBgTiles(0, sData->var_19A8, 6144, 0); + break; + case 2: + if (sData->cardType != CARD_TYPE_FRLG) + { + LoadPalette(gEmeraldTrainerCardStarPals[sData->trainerCard.stars], 0, 96); + LoadPalette(gUnknown_0856F4EC, 48, 32); + if (sData->trainerCard.gender) + LoadPalette(gUnknown_0856F4AC, 16, 32); + } + else + { + LoadPalette(gFireRedTrainerCardStarPals[sData->trainerCard.stars], 0, 96); + LoadPalette(gUnknown_0856F50C, 48, 32); + if (sData->trainerCard.gender) + LoadPalette(gUnknown_0856F4CC, 16, 32); + } + LoadPalette(gUnknown_0856F52C, 64, 32); + break; + case 3: + SetBgTilemapBuffer(0, sData->var_3CA8); + SetBgTilemapBuffer(2, sData->var_5CA8); + break; + case 4: + FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 32, 32); + FillBgTilemapBufferRect_Palette0(2, 0, 0, 0, 32, 32); + FillBgTilemapBufferRect_Palette0(3, 0, 0, 0, 32, 32); + default: + return 1; + } + sData->bgPalLoadState++; + return 0; +} + +static void sub_80C4550(u16 *ptr) +{ + s16 i, j; + u16 *dst = sData->var_5CA8; + + for (i = 0; i < 20; i++) + { + for (j = 0; j < 32; j++) + { + if (j < 30) + dst[32 * i + j] = ptr[30 * i + j]; + else + dst[32 * i + j] = ptr[0]; + } + } + CopyBgTilemapBufferToVram(2); +} + +static void sub_80C45C0(u16* ptr) +{ + s16 i, j; + u16 *dst = sData->var_3CA8; + + for (i = 0; i < 20; i++) + { + for (j = 0; j < 32; j++) + { + if (j < 30) + dst[32 * i + j] = ptr[30 * i + j]; + else + dst[32 * i + j] = ptr[0]; + } + } + CopyBgTilemapBufferToVram(0); +} + +static const u8 gUnknown_0856FB78[] = {7, 7}; + +static void sub_80C4630(void) +{ + s16 i, x; + u16 tileNum = 192; + u8 palNum = 3; + + FillBgTilemapBufferRect(3, 143, 15, gUnknown_0856FB78[sData->isHoenn], sData->trainerCard.stars, 1, 4); + if (!sData->isLink) + { + x = 4; + for (i = 0; i < 8; i++, tileNum += 2, x += 3) + { + if (sData->badgeCount[i]) + { + FillBgTilemapBufferRect(3, tileNum, x, 15, 1, 1, palNum); + FillBgTilemapBufferRect(3, tileNum + 1, x + 1, 15, 1, 1, palNum); + FillBgTilemapBufferRect(3, tileNum + 16, x, 16, 1, 1, palNum); + FillBgTilemapBufferRect(3, tileNum + 17, x + 1, 16, 1, 1, palNum); + } + } + } + CopyBgTilemapBufferToVram(3); +} + +static void sub_80C474C(void) +{ + if (sData->cardType == CARD_TYPE_FRLG) + { + if (sData->hasTrades) + { + FillBgTilemapBufferRect(3, 141, 27, 9, 1, 1, 1); + FillBgTilemapBufferRect(3, 157, 27, 10, 1, 1, 1); + } + if (sData->trainerCard.berryCrushPoints) + { + FillBgTilemapBufferRect(3, 141, 21, 13, 1, 1, 1); + FillBgTilemapBufferRect(3, 157, 21, 14, 1, 1, 1); + } + if (sData->trainerCard.unionRoomNum) + { + FillBgTilemapBufferRect(3, 141, 27, 11, 1, 1, 1); + FillBgTilemapBufferRect(3, 157, 27, 12, 1, 1, 1); + } + } + else + { + if (sData->hasTrades) + { + FillBgTilemapBufferRect(3, 141, 27, 9, 1, 1, 0); + FillBgTilemapBufferRect(3, 157, 27, 10, 1, 1, 0); + } + if (sData->trainerCard.contestsWithFriends) + { + FillBgTilemapBufferRect(3, 141, 27, 13, 1, 1, 0); + FillBgTilemapBufferRect(3, 157, 27, 14, 1, 1, 0); + } + if (sData->hasBattleTowerWins) + { + FillBgTilemapBufferRect(3, 141, 17, 15, 1, 1, 0); + FillBgTilemapBufferRect(3, 157, 17, 16, 1, 1, 0); + FillBgTilemapBufferRect(3, 140, 27, 15, 1, 1, 0); + FillBgTilemapBufferRect(3, 156, 27, 16, 1, 1, 0); + } + } + CopyBgTilemapBufferToVram(3); +} + +static void sub_80C48C8(void) +{ + if (++sData->var_6 > 60) + { + sData->var_6 = 0; + sData->var_7 ^= 1; + sData->var_529 = 1; + } +} + +u8 sub_80C4904(u8 cardId) +{ + struct TrainerCard* trainerCards = gTrainerCards; + return trainerCards[cardId].stars; +} + +static void sub_80C4918(void) +{ + u8 taskId = CreateTask(sub_80C4960, 0); + sub_80C4960(taskId); + SetHBlankCallback(HblankCb_TrainerCard); +} + +static bool8 sub_80C4940(void) +{ + if (FindTaskIdByFunc(sub_80C4960) == 0xFF) + return TRUE; + else + return FALSE; +} + +static void sub_80C4960(u8 taskId) +{ + while(gUnknown_0856FB28[gTasks[taskId].data[0]](&gTasks[taskId])) + ; +} + +static bool8 sub_80C4998(struct Task* task) +{ + u32 i; + + HideBg(1); + HideBg(3); + ScanlineEffect_Stop(); + ScanlineEffect_Clear(); + for (i = 0; i < 160; i++) + gScanlineEffectRegBuffers[1][i] = 0; + task->data[0]++; + return FALSE; +} + +static bool8 sub_80C49D8(struct Task* task) +{ + u32 r4, r5, r10, r7, r6, var_24, r9, var; + s16 i; + + sData->allowDMACopy = FALSE; + if (task->data[1] >= 77) + task->data[1] = 77; + else + task->data[1] += 7; + + sData->var_7CA8 = task->data[1]; + sub_80C32EC(task->data[1]); + + // ??? + r7 = task->data[1]; + r9 = 160 - r7; + r4 = r9 - r7; + r6 = -r7 << 16; + r5 = 0xA00000 / r4; + r5 += 0xFFFF0000; + var_24 = r6; + var_24 += r5 * r4; + r10 = r5 / r4; + r5 *= 2; + + for (i = 0; i < r7; i++) + gScanlineEffectRegBuffers[0][i] = -i; + for (; i < (s16)(r9); i++) + { + var = r6 >> 16; + r6 += r5; + r5 -= r10; + gScanlineEffectRegBuffers[0][i] = var; + } + var = var_24 >> 16; + for (; i < 160; i++) + gScanlineEffectRegBuffers[0][i] = var; + + sData->allowDMACopy = TRUE; + if (task->data[1] >= 77) + task->data[0]++; + + return FALSE; +} + +static bool8 sub_80C4B08(struct Task* task) +{ + sData->allowDMACopy = FALSE; + if (sub_8087598() == TRUE) + return FALSE; + + do + { + switch (sData->var_4) + { + case 0: + FillWindowPixelBuffer(1, 0); + FillBgTilemapBufferRect_Palette0(3, 0, 0, 0, 0x20, 0x20); + break; + case 1: + if (!sData->var_8) + { + if (!PrintStringsOnCardPage2()) + return FALSE; + } + else + { + if (!PrintAllOnCardPage1()) + return FALSE; + } + break; + case 2: + if (!sData->var_8) + sub_80C45C0(sData->var_A48); + else + sub_80C438C(1); + break; + case 3: + if (!sData->var_8) + sub_80C474C(); + else + FillWindowPixelBuffer(2, 0); + break; + case 4: + if (sData->var_8) + sub_80C4FF0(); + break; + default: + task->data[0]++; + sData->allowDMACopy = TRUE; + sData->var_4 = 0; + return FALSE; + } + sData->var_4++; + } while (gReceivedRemoteLinkPlayers == 0); + + return FALSE; +} + +static bool8 sub_80C4C1C(struct Task* task) +{ + sData->allowDMACopy = FALSE; + if (sData->var_8) + { + sub_80C438C(2); + sub_80C4550(sData->var_EF8); + sub_80C45C0(sData->var_598); + sub_80C4630(); + } + sub_80C438C(1); + sData->var_8 ^= 1; + task->data[0]++; + sData->allowDMACopy = TRUE; + PlaySE(SE_RG_CARD2); + return FALSE; +} + +static bool8 sub_80C4C84(struct Task* task) +{ + u32 r4, r5, r10, r7, r6, var_24, r9, var; + s16 i; + + sData->allowDMACopy = FALSE; + if (task->data[1] <= 5) + task->data[1] = 0; + else + task->data[1] -= 5; + + sData->var_7CA8 = task->data[1]; + sub_80C32EC(task->data[1]); + + // ??? + r7 = task->data[1]; + r9 = 160 - r7; + r4 = r9 - r7; + r6 = -r7 << 16; + r5 = 0xA00000 / r4; + r5 += 0xFFFF0000; + var_24 = r6; + var_24 += r5 * r4; + r10 = r5 / r4; + r5 /= 2; + + for (i = 0; i < r7; i++) + gScanlineEffectRegBuffers[0][i] = -i; + for (; i < (s16)(r9); i++) + { + var = r6 >> 16; + r6 += r5; + r5 += r10; + gScanlineEffectRegBuffers[0][i] = var; + } + var = var_24 >> 16; + for (; i < 160; i++) + gScanlineEffectRegBuffers[0][i] = var; + + sData->allowDMACopy = TRUE; + if (task->data[1] <= 0) + task->data[0]++; + + return FALSE; +} + +static bool8 sub_80C4DB0(struct Task *task) +{ + ShowBg(1); + ShowBg(3); + SetHBlankCallback(NULL); + DestroyTask(FindTaskIdByFunc(sub_80C4960)); + return FALSE; +} + +void ShowPlayerTrainerCard(void (*callback)(void)) +{ + sData = AllocZeroed(sizeof(*sData)); + sData->callback2 = callback; + if (callback == CB2_ReshowFrontierPass) + sData->var_52C = 0x7FFF; + else + sData->var_52C = 0; + + if (InUnionRoom() == TRUE) + sData->isLink = TRUE; + else + sData->isLink = FALSE; + + sData->language = GAME_LANGUAGE; + sub_80C3020(&sData->trainerCard); + SetMainCallback2(CB2_InitTrainerCard); +} + +void ShowTrainerCardInLink(u8 cardId, void (*callback)(void)) +{ + sData = AllocZeroed(sizeof(*sData)); + sData->callback2 = callback; + sData->isLink = TRUE; + sData->trainerCard = gTrainerCards[cardId]; + sData->language = gLinkPlayers[cardId].language; + SetMainCallback2(CB2_InitTrainerCard); +} + +static void sub_80C4EE4(void) +{ + u8 i; + + sData->var_0 = 0; + sData->var_6 = gSaveBlock2Ptr->playTimeVBlanks; + sData->var_7 = 0; + sData->var_8 = 0; + sData->var_528 = 0; + sData->cardType = GetSetCardType(); + for (i = 0; i < 4; i++) + CopyEasyChatWord(sData->var_19[i], sData->trainerCard.var_28[i]); +} + +static u8 GetSetCardType(void) +{ + if (sData == NULL) + { + if (gGameVersion == VERSION_FIRE_RED || gGameVersion == VERSION_LEAF_GREEN) + return CARD_TYPE_FRLG; + else if (gGameVersion == VERSION_EMERALD) + return CARD_TYPE_EMERALD; + else + return CARD_TYPE_RS; + } + else + { + if (sData->trainerCard.version == VERSION_FIRE_RED || sData->trainerCard.version == VERSION_LEAF_GREEN) + { + sData->isHoenn = FALSE; + return CARD_TYPE_FRLG; + } + else if (sData->trainerCard.version == VERSION_EMERALD) + { + sData->isHoenn = TRUE; + return CARD_TYPE_EMERALD; + } + else + { + sData->isHoenn = TRUE; + return CARD_TYPE_RS; + } + } +} + +static u8 VersionToCardType(u8 version) +{ + if (version == VERSION_FIRE_RED || version == VERSION_LEAF_GREEN) + return CARD_TYPE_FRLG; + else if (version == VERSION_EMERALD) + return CARD_TYPE_EMERALD; + else + return CARD_TYPE_RS; +} + +static void sub_80C4FF0(void) +{ + if (InUnionRoom() == TRUE && gReceivedRemoteLinkPlayers == 1) + { + sub_818D938(FacilityClassToPicIndex(sData->trainerCard.var_4F), + TRUE, + gUnknown_0856FB18[sData->isHoenn][sData->trainerCard.gender][0], + gUnknown_0856FB18[sData->isHoenn][sData->trainerCard.gender][1], + 8, + 2); + } + else + { + sub_818D938(FacilityClassToPicIndex(gUnknown_0856FB20[sData->cardType][sData->trainerCard.gender]), + TRUE, + gUnknown_0856FB18[sData->isHoenn][sData->trainerCard.gender][0], + gUnknown_0856FB18[sData->isHoenn][sData->trainerCard.gender][1], + 8, + 2); + } +} diff --git a/src/trainer_hill.c b/src/trainer_hill.c new file mode 100644 index 000000000..e0a236286 --- /dev/null +++ b/src/trainer_hill.c @@ -0,0 +1,1120 @@ +#include "global.h" +#include "alloc.h" +#include "battle.h" +#include "battle_tower.h" +#include "battle_setup.h" +#include "event_data.h" +#include "event_scripts.h" +#include "fieldmap.h" +#include "field_message_box.h" +#include "international_string_util.h" +#include "item.h" +#include "main.h" +#include "menu.h" +#include "overworld.h" +#include "palette.h" +#include "pokemon.h" +#include "script.h" +#include "string_util.h" +#include "strings.h" +#include "text.h" +#include "trainer_hill.h" +#include "window.h" +#include "util.h" +#include "constants/event_object_movement_constants.h" +#include "constants/event_objects.h" +#include "constants/items.h" +#include "constants/moves.h" +#include "constants/maps.h" +#include "constants/species.h" +#include "constants/trainers.h" +#include "constants/easy_chat.h" + +extern bool32 sub_81D3B34(void); + +#define HILL_TAG_NORMAL 0 +#define HILL_TAG_VARIETY 1 +#define HILL_TAG_UNIQUE 2 +#define HILL_TAG_EXPERT 3 + +#define HILL_TRAINER_NAME_LENGTH 11 +#define HILL_MAX_TIME 215999 // 60 * 60 * 60 - 1 + +struct TrHillRoomTrainers +{ + u8 name[2][HILL_TRAINER_NAME_LENGTH]; + u8 facilityClass[2]; +}; + +struct TrainerHillTrainer +{ + u8 name[HILL_TRAINER_NAME_LENGTH]; + u8 facilityClass; + u32 unused; + u16 speechBefore[6]; + u16 speechWin[6]; + u16 speechLose[6]; + u16 speechAfter[6]; + struct BattleTowerPokemon mons[PARTY_SIZE]; +}; + +struct TrHillFloor +{ + u8 unk0; + u8 unk1; + struct TrainerHillTrainer trainers[2]; + u8 data[0x100]; + u16 unk3A0[16]; + u8 coords[2]; // x first 4 bits, y last 4 bits + u8 direction; // array of 4 bits for each trainer + u8 range; // array of 4 bits for each trainer +}; + +struct TrHillTag +{ + u8 unkField_0; + u8 unused1; + u8 unkField_2; + u8 unused3; + u8 unused4; + u8 unused5; + u8 unused6; + struct TrHillFloor floors[4]; +}; + +struct TrHillStruct2 +{ + u8 floorId; + struct TrHillTag tag; +}; + +// EWRAM +static EWRAM_DATA struct TrHillStruct2 *sHillData = NULL; +static EWRAM_DATA struct TrHillRoomTrainers *sRoomTrainers = NULL; +EWRAM_DATA u32 *gUnknown_0203CF5C = NULL; + +// This file's functions. +static void sub_81D581C(void); +static void sub_81D58D8(void); +static void sub_81D5924(void); +static void sub_81D59D0(void); +static void sub_81D5A70(void); +static void sub_81D5AB4(void); +static void sub_81D5AD0(void); +static void sub_81D5B2C(void); +static void sub_81D5BBC(void); +static void sub_81D5C00(void); +static void sub_81D5C5C(void); +static void sub_81D62B4(void); +static void sub_81D64AC(void); +static void sub_81D64DC(void); +static void sub_81D64FC(void); +static void sub_81D6518(void); +static void sub_81D6568(void); +static void sub_81D65A0(void); +static void SetUpDataStruct(void); +static void FreeDataStruct(void); +static void nullsub_2(void); +static void SetTimerValue(u32 *dst, u32 val); +static u32 GetTimerValue(u32 *src); +static void sub_81D642C(struct Pokemon *mon, u8 level); +static u16 sub_81D6640(void); + +// const data +#include "data/battle_frontier/trainer_hill.h" + +struct +{ + u8 trainerClass; + u8 musicId; +} static const gUnknown_0862A3B4[] = +{ + {TRAINER_CLASS_TEAM_AQUA, TRAINER_ENCOUNTER_MUSIC_AQUA}, + {TRAINER_CLASS_AQUA_ADMIN, TRAINER_ENCOUNTER_MUSIC_AQUA}, + {TRAINER_CLASS_AQUA_LEADER, TRAINER_ENCOUNTER_MUSIC_AQUA}, + {TRAINER_CLASS_AROMA_LADY, TRAINER_ENCOUNTER_MUSIC_FEMALE}, + {TRAINER_CLASS_BATTLE_GIRL, TRAINER_ENCOUNTER_MUSIC_INTENSE}, + {TRAINER_CLASS_SWIMMER_F, TRAINER_ENCOUNTER_MUSIC_FEMALE}, + {TRAINER_CLASS_POKEFAN, TRAINER_ENCOUNTER_MUSIC_TWINS}, + {TRAINER_CLASS_DRAGON_TAMER, TRAINER_ENCOUNTER_MUSIC_INTENSE}, + {TRAINER_CLASS_COOLTRAINER, TRAINER_ENCOUNTER_MUSIC_COOL}, + {TRAINER_CLASS_GUITARIST, TRAINER_ENCOUNTER_MUSIC_INTENSE}, + {TRAINER_CLASS_SAILOR, TRAINER_ENCOUNTER_MUSIC_MALE}, + {TRAINER_CLASS_TWINS, TRAINER_ENCOUNTER_MUSIC_TWINS}, + {TRAINER_CLASS_INTERVIEWER, TRAINER_ENCOUNTER_MUSIC_INTERVIEWER}, + {TRAINER_CLASS_RUIN_MANIAC, TRAINER_ENCOUNTER_MUSIC_HIKER}, + {TRAINER_CLASS_GENTLEMAN, TRAINER_ENCOUNTER_MUSIC_RICH}, + {TRAINER_CLASS_SWIMMER_M, TRAINER_ENCOUNTER_MUSIC_FEMALE}, + {TRAINER_CLASS_POKEMANIAC, TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS}, + {TRAINER_CLASS_BLACK_BELT, TRAINER_ENCOUNTER_MUSIC_INTENSE}, + {TRAINER_CLASS_OLD_COUPLE, TRAINER_ENCOUNTER_MUSIC_INTENSE}, + {TRAINER_CLASS_BUG_MANIAC, TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS}, + {TRAINER_CLASS_CAMPER, TRAINER_ENCOUNTER_MUSIC_MALE}, + {TRAINER_CLASS_KINDLER, TRAINER_ENCOUNTER_MUSIC_HIKER}, + {TRAINER_CLASS_TEAM_MAGMA, TRAINER_ENCOUNTER_MUSIC_MAGMA}, + {TRAINER_CLASS_MAGMA_ADMIN, TRAINER_ENCOUNTER_MUSIC_MAGMA}, + {TRAINER_CLASS_MAGMA_LEADER, TRAINER_ENCOUNTER_MUSIC_MAGMA}, + {TRAINER_CLASS_LASS, TRAINER_ENCOUNTER_MUSIC_FEMALE}, + {TRAINER_CLASS_BUG_CATCHER, TRAINER_ENCOUNTER_MUSIC_MALE}, + {TRAINER_CLASS_NINJA_BOY, TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS}, + {TRAINER_CLASS_RICH_BOY, TRAINER_ENCOUNTER_MUSIC_RICH}, + {TRAINER_CLASS_HEX_MANIAC, TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS}, + {TRAINER_CLASS_BEAUTY, TRAINER_ENCOUNTER_MUSIC_FEMALE}, + {TRAINER_CLASS_LADY, TRAINER_ENCOUNTER_MUSIC_FEMALE}, + {TRAINER_CLASS_PARASOL_LADY, TRAINER_ENCOUNTER_MUSIC_FEMALE}, + {TRAINER_CLASS_PICNICKER, TRAINER_ENCOUNTER_MUSIC_GIRL}, + {TRAINER_CLASS_PKMN_BREEDER, TRAINER_ENCOUNTER_MUSIC_FEMALE}, + {TRAINER_CLASS_COLLECTOR, TRAINER_ENCOUNTER_MUSIC_SUSPICIOUS}, + {TRAINER_CLASS_PKMN_RANGER, TRAINER_ENCOUNTER_MUSIC_COOL}, + {TRAINER_CLASS_PKMN_TRAINER_3, TRAINER_ENCOUNTER_MUSIC_MALE}, + {TRAINER_CLASS_YOUNG_COUPLE, TRAINER_ENCOUNTER_MUSIC_GIRL}, + {TRAINER_CLASS_PSYCHIC, TRAINER_ENCOUNTER_MUSIC_INTENSE}, + {TRAINER_CLASS_SR_AND_JR, TRAINER_ENCOUNTER_MUSIC_TWINS}, + {TRAINER_CLASS_ELITE_FOUR, TRAINER_ENCOUNTER_MUSIC_FEMALE}, + {TRAINER_CLASS_YOUNGSTER, TRAINER_ENCOUNTER_MUSIC_MALE}, + {TRAINER_CLASS_EXPERT, TRAINER_ENCOUNTER_MUSIC_INTENSE}, + {TRAINER_CLASS_TRIATHLETE, TRAINER_ENCOUNTER_MUSIC_MALE}, + {TRAINER_CLASS_BIRD_KEEPER, TRAINER_ENCOUNTER_MUSIC_COOL}, + {TRAINER_CLASS_FISHERMAN, TRAINER_ENCOUNTER_MUSIC_HIKER}, + {TRAINER_CLASS_CHAMPION, TRAINER_ENCOUNTER_MUSIC_MALE}, + {TRAINER_CLASS_TUBER_M, TRAINER_ENCOUNTER_MUSIC_MALE}, + {TRAINER_CLASS_TUBER_F, TRAINER_ENCOUNTER_MUSIC_GIRL}, + {TRAINER_CLASS_SIS_AND_BRO, TRAINER_ENCOUNTER_MUSIC_SWIMMER}, + {TRAINER_CLASS_HIKER, TRAINER_ENCOUNTER_MUSIC_HIKER}, + {TRAINER_CLASS_LEADER, TRAINER_ENCOUNTER_MUSIC_FEMALE}, + {TRAINER_CLASS_SCHOOL_KID, TRAINER_ENCOUNTER_MUSIC_MALE}, +}; + +static const u16 gUnknown_0862A48C[] = {ITEM_RARE_CANDY, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A498[] = {ITEM_LUXURY_BALL, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A4A4[] = {ITEM_MAX_REVIVE, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A4B0[] = {ITEM_MAX_ETHER, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A4BC[] = {ITEM_ELIXIR, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A4C8[] = {ITEM_TM05_ROAR, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A4D4[] = {ITEM_TM36_SLUDGE_BOMB, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A4E0[] = {ITEM_TM06_TOXIC, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A4EC[] = {ITEM_TM11_SUNNY_DAY, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A4F8[] = {ITEM_TM26_EARTHQUAKE, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A504[] = {ITEM_RARE_CANDY, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A510[] = {ITEM_LUXURY_BALL, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A51C[] = {ITEM_MAX_REVIVE, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A528[] = {ITEM_MAX_ETHER, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A534[] = {ITEM_ELIXIR, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A540[] = {ITEM_TM31_BRICK_BREAK, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A54C[] = {ITEM_TM41_TORMENT, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A558[] = {ITEM_TM48_SKILL_SWAP, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A564[] = {ITEM_TM19_GIGA_DRAIN, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; +static const u16 gUnknown_0862A570[] = {ITEM_TM45_ATTRACT, ITEM_ETHER, ITEM_MAX_POTION, ITEM_REVIVE, ITEM_FLUFFY_TAIL, ITEM_GREAT_BALL}; + +static const u16 *const gUnknown_0862A57C[] = +{ + gUnknown_0862A48C, + gUnknown_0862A498, + gUnknown_0862A4A4, + gUnknown_0862A4B0, + gUnknown_0862A4BC, + gUnknown_0862A4C8, + gUnknown_0862A4D4, + gUnknown_0862A4E0, + gUnknown_0862A4EC, + gUnknown_0862A4F8 +}; + +static const u16 *const gUnknown_0862A5A4[] = +{ + gUnknown_0862A504, + gUnknown_0862A510, + gUnknown_0862A51C, + gUnknown_0862A528, + gUnknown_0862A534, + gUnknown_0862A540, + gUnknown_0862A54C, + gUnknown_0862A558, + gUnknown_0862A564, + gUnknown_0862A570 +}; + +static const u16 *const *const gUnknown_0862A5CC[] = +{ + gUnknown_0862A57C, + gUnknown_0862A5A4 +}; + +static const u16 gUnknown_0862A5D4[] = INCBIN_U16("graphics/pokenav/862A5D4.gbapal"); +static const u8 sRecordWinColors[] = {0, 2, 3}; + +static const struct TrHillTag *const sDataPerTag[] = +{ + &sDataTagNormal, + &sDataTagVariety, + &sDataTagUnique, + &sDataTagExpert, +}; + +// Unused. +static const u8 *const sFloorStrings[] = +{ + gText_TrainerHill1F, + gText_TrainerHill2F, + gText_TrainerHill3F, + gText_TrainerHill4F, +}; + +static void (* const sHillFunctions[])(void) = +{ + sub_81D581C, + sub_81D58D8, + sub_81D5924, + sub_81D59D0, + sub_81D5A70, + sub_81D5AB4, + sub_81D5AD0, + sub_81D5B2C, + sub_81D5BBC, + sub_81D5C00, + sub_81D5C5C, + sub_81D62B4, + sub_81D64AC, + sub_81D64DC, + sub_81D64FC, + sub_81D6518, + sub_81D6568, + sub_81D65A0, +}; + +static const u8 *const sTagMatchStrings[] = +{ + gText_NormalTagMatch, + gText_VarietyTagMatch, + gText_UniqueTagMatch, + gText_ExpertTagMatch, +}; + +static const struct EventObjectTemplate gUnknown_0862A670 = +{ + .graphicsId = EVENT_OBJ_GFX_RIVAL_BRENDAN_NORMAL, + .elevation = 3, + .movementType = MOVEMENT_TYPE_LOOK_AROUND, + .movementRangeX = 1, + .movementRangeY = 1, + .trainerType = 1, +}; + +static const u32 gUnknown_0862A688[] = {MAP_NUM(TRAINER_HILL_2F), MAP_NUM(TRAINER_HILL_3F), MAP_NUM(TRAINER_HILL_4F), MAP_NUM(TRAINER_HILL_ROOF)}; +static const u8 gUnknown_0862A698[][3] = {{0, 1, 2}, {3, 4, 5}}; + +// code +void CallTrainerHillFunction(void) +{ + SetUpDataStruct(); + sHillFunctions[gSpecialVar_0x8004](); + FreeDataStruct(); +} + +void ResetTrainerHillResults(void) +{ + s32 i; + + gSaveBlock2Ptr->frontier.field_EF9_1 = 0; + gSaveBlock2Ptr->frontier.field_EF9_0 = 0; + gSaveBlock1Ptr->trainerHill.field_3D68 = 0; + for (i = 0; i < 4; i++) + SetTimerValue(&gSaveBlock1Ptr->trainerHillTimes[i], HILL_MAX_TIME); +} + +static u8 GetFloorId(void) +{ + return gMapHeader.mapLayoutId - 159; +} + +u8 GetTrainerHillOpponentClass(u16 trainerId) +{ + u8 id = trainerId - 1; + + return gFacilityClassToTrainerClass[sRoomTrainers->facilityClass[id]]; +} + +void GetTrainerHillTrainerName(u8 *dst, u16 trainerId) +{ + s32 i; + u8 id = trainerId - 1; + + for (i = 0; i < HILL_TRAINER_NAME_LENGTH; i++) + dst[i] = sRoomTrainers->name[id][i]; +} + +u8 GetTrainerHillTrainerFrontSpriteId(u16 trainerId) +{ + u8 id, facilityClass; + + SetUpDataStruct(); + id = trainerId - 1; + facilityClass = sHillData->tag.floors[sHillData->floorId].trainers[id].facilityClass; + FreeDataStruct(); + + return gFacilityClassToPicIndex[facilityClass]; +} + +void InitTrainerHillBattleStruct(void) +{ + s32 i, j; + + SetUpDataStruct(); + sRoomTrainers = AllocZeroed(sizeof(*sRoomTrainers)); + + for (i = 0; i < 2; i++) + { + for (j = 0; j < HILL_TRAINER_NAME_LENGTH; j++) + { + sRoomTrainers->name[i][j] = sHillData->tag.floors[sHillData->floorId].trainers[i].name[j]; + } + sRoomTrainers->facilityClass[i] = sHillData->tag.floors[sHillData->floorId].trainers[i].facilityClass; + } + sub_80008DC(&gSaveBlock1Ptr->trainerHill.field_3D64); + FreeDataStruct(); +} + +void FreeTrainerHillBattleStruct(void) +{ + if (sRoomTrainers != NULL) + FREE_AND_SET_NULL(sRoomTrainers); +} + +static void SetUpDataStruct(void) +{ + if (sHillData == NULL) + { + sHillData = AllocZeroed(sizeof(*sHillData)); + sHillData->floorId = gMapHeader.mapLayoutId - 159; + CpuCopy32(sDataPerTag[gSaveBlock1Ptr->trainerHill.tag], &sHillData->tag, sizeof(sHillData->tag)); + nullsub_2(); + } +} + +static void FreeDataStruct(void) +{ + if (sHillData != NULL) + FREE_AND_SET_NULL(sHillData); +} + +void CopyTrainerHillTrainerText(u8 which, u16 trainerId) +{ + u8 id, floorId; + + SetUpDataStruct(); + floorId = GetFloorId(); + id = trainerId - 1; + + switch (which) + { + case 2: + FrontierSpeechToString(sHillData->tag.floors[floorId].trainers[id].speechBefore); + break; + case 3: + FrontierSpeechToString(sHillData->tag.floors[floorId].trainers[id].speechWin); + break; + case 4: + FrontierSpeechToString(sHillData->tag.floors[floorId].trainers[id].speechLose); + break; + case 5: + FrontierSpeechToString(sHillData->tag.floors[floorId].trainers[id].speechAfter); + break; + } + + FreeDataStruct(); +} + +static void sub_81D581C(void) +{ + nullsub_2(); + if (!sub_81D3B34()) + gSaveBlock1Ptr->trainerHill.field_3D6E_0f = 1; + else + gSaveBlock1Ptr->trainerHill.field_3D6E_0f = 0; + + gSaveBlock1Ptr->trainerHill.field_3D6C = 0; + sub_80008DC(&gSaveBlock1Ptr->trainerHill.field_3D64); + gSaveBlock1Ptr->trainerHill.field_3D64 = 0; + gSaveBlock1Ptr->trainerHill.field_3D6E_0c = 0; + gSaveBlock1Ptr->trainerHill.field_3D6E_0b = 0; + gSaveBlock1Ptr->trainerHill.field_3D6E_0e = 0; + gSaveBlock2Ptr->frontier.field_EE0 = 0; + gBattleOutcome = 0; + gSaveBlock1Ptr->trainerHill.field_3D6E_0a = 0; +} + +static void sub_81D58D8(void) +{ + sub_80008E8(); + gSpecialVar_Result = 0; + if (gSaveBlock1Ptr->trainerHill.field_3D6E_0c) + gSpecialVar_Result++; + if (gSaveBlock1Ptr->trainerHill.field_3D6E_0a && gSaveBlock1Ptr->trainerHill.field_3D6E_0b) + gSpecialVar_Result++; + + gSaveBlock1Ptr->trainerHill.field_3D6E_0c = 1; +} + +static void sub_81D5924(void) +{ + u16 itemId = sub_81D6640(); + + if (sHillData->tag.unkField_2 != 4 || gSaveBlock1Ptr->trainerHill.field_3D6E_0a) + { + gSpecialVar_Result = 2; + } + else if (AddBagItem(itemId, 1) == TRUE) + { + CopyItemName(itemId, gStringVar2); + gSaveBlock1Ptr->trainerHill.field_3D6E_0a = 1; + gSaveBlock2Ptr->frontier.field_EF9_0 = 0; + gSpecialVar_Result = 0; + } + else + { + gSpecialVar_Result = 1; + } +} + +static void sub_81D59D0(void) +{ + if (gSaveBlock1Ptr->trainerHill.field_3D6E_0b) + { + gSpecialVar_Result = 2; + } + else if (GetTimerValue(&gSaveBlock1Ptr->trainerHill.field_3D68) > gSaveBlock1Ptr->trainerHill.field_3D64) + { + SetTimerValue(&gSaveBlock1Ptr->trainerHill.field_3D68, gSaveBlock1Ptr->trainerHill.field_3D64); + gSaveBlock1Ptr->trainerHillTimes[gSaveBlock1Ptr->trainerHill.tag] = gSaveBlock1Ptr->trainerHill.field_3D68; + gSpecialVar_Result = 0; + } + else + { + gSpecialVar_Result = 1; + } + + gSaveBlock1Ptr->trainerHill.field_3D6E_0b = 1; +} + +static void sub_81D5A70(void) +{ + if (!gSaveBlock1Ptr->trainerHill.field_3D6E_0c) + { + if (gSaveBlock1Ptr->trainerHill.field_3D64 >= HILL_MAX_TIME) + gSaveBlock1Ptr->trainerHill.field_3D64 = HILL_MAX_TIME; + else + sub_80008DC(&gSaveBlock1Ptr->trainerHill.field_3D64); + } +} + +static void sub_81D5AB4(void) +{ + gSaveBlock1Ptr->trainerHill.field_3D6E_0d = 1; +} + +static void sub_81D5AD0(void) +{ + if (gSaveBlock1Ptr->trainerHill.field_3D6E_0d) + { + gSaveBlock1Ptr->trainerHill.field_3D6E_0d = 0; + gSpecialVar_Result = 0; + } + else if (gSaveBlock1Ptr->trainerHill.field_3D6E_0e) + { + gSaveBlock1Ptr->trainerHill.field_3D6E_0e = 0; + gSpecialVar_Result = 1; + } + else + { + gSpecialVar_Result = 2; + } +} + +static void sub_81D5B2C(void) +{ + s32 total, minutes, secondsWhole, secondsFraction; + + total = gSaveBlock1Ptr->trainerHill.field_3D64; + if (total >= HILL_MAX_TIME) + total = HILL_MAX_TIME; + + minutes = total / (60 * 60); + total %= (60 * 60); + secondsWhole = total / 60; + total %= 60; + secondsFraction = (total * 168) / 100; + + ConvertIntToDecimalStringN(gStringVar1, minutes, STR_CONV_MODE_RIGHT_ALIGN, 2); + ConvertIntToDecimalStringN(gStringVar2, secondsWhole, STR_CONV_MODE_RIGHT_ALIGN, 2); + ConvertIntToDecimalStringN(gStringVar3, secondsFraction, STR_CONV_MODE_LEADING_ZEROS, 2); +} + +static void sub_81D5BBC(void) +{ + SetUpDataStruct(); + if (sHillData->tag.unkField_2 != 4) + { + ConvertIntToDecimalStringN(gStringVar1, sHillData->tag.unkField_2, STR_CONV_MODE_LEFT_ALIGN, 1); + gSpecialVar_Result = 0; + } + else + { + gSpecialVar_Result = 1; + } + + FreeDataStruct(); +} + +static void sub_81D5C00(void) +{ + SetUpDataStruct(); + gSpecialVar_Result = 0; + FreeDataStruct(); +} + +bool8 sub_81D5C18(void) +{ + if (VarGet(VAR_0x40D6) == 0) + return FALSE; + else if (gSaveBlock1Ptr->trainerHill.field_3D6E_0c) + return FALSE; + else if (GetCurrentTrainerHillMapId() != 0) + return TRUE; + else + return FALSE; +} + +static void sub_81D5C5C(void) +{ + if (!sub_81D5C18()) + gSpecialVar_Result = 0; + else + gSpecialVar_Result = 1; +} + +void nullsub_129(void) +{ + +} + +static void nullsub_2(void) +{ + +} + +void PrintOnTrainerHillRecordsWindow(void) +{ + s32 i, x, y; + u32 total, minutes, secondsWhole, secondsFraction; + + SetUpDataStruct(); + FillWindowPixelBuffer(0, 0); + x = GetStringCenterAlignXOffset(1, gText_TimeBoard, 0xD0); + AddTextPrinterParameterized3(0, 1, x, 2, sRecordWinColors, TEXT_SPEED_FF, gText_TimeBoard); + + y = 18; + for (i = 0; i < 4; i++) + { + AddTextPrinterParameterized3(0, 1, 0, y, sRecordWinColors, TEXT_SPEED_FF, sTagMatchStrings[i]); + y += 15; + total = GetTimerValue(&gSaveBlock1Ptr->trainerHillTimes[i]); + minutes = total / (60 * 60); + total %= (60 * 60); + ConvertIntToDecimalStringN(gStringVar1, minutes, STR_CONV_MODE_RIGHT_ALIGN, 2); + secondsWhole = total / 60; + total %= 60; + ConvertIntToDecimalStringN(gStringVar2, secondsWhole, STR_CONV_MODE_RIGHT_ALIGN, 2); + secondsFraction = (total * 168) / 100; + ConvertIntToDecimalStringN(gStringVar3, secondsFraction, STR_CONV_MODE_LEADING_ZEROS, 2); + StringExpandPlaceholders(StringCopy(gStringVar4, gText_TimeCleared), gText_XMinYDotZSec); + x = GetStringRightAlignXOffset(1, gStringVar4, 0xD0); + AddTextPrinterParameterized3(0, 1, x, y, sRecordWinColors, TEXT_SPEED_FF, gStringVar4); + y += 17; + } + + PutWindowTilemap(0); + CopyWindowToVram(0, 3); + FreeDataStruct(); +} + +// Leftover from Fire Red / Leaf Green as in these games, +// the timer had to be xored by the encryption key in Sav2. +static u32 GetTimerValue(u32 *src) +{ + return *src; +} + +static void SetTimerValue(u32 *dst, u32 val) +{ + *dst = val; +} + +void sub_81D5DF8(void) +{ + u8 i, floorId; + struct EventObjectTemplate *eventTemplates = gSaveBlock1Ptr->eventObjectTemplates; + + if (!sub_81D5F48()) + return; + + SetUpDataStruct(); + for (i = 0; i < 2; i++) + gSaveBlock2Ptr->frontier.field_CB4[i] = 0xFFFF; + CpuFill32(0, gSaveBlock1Ptr->eventObjectTemplates, sizeof(gSaveBlock1Ptr->eventObjectTemplates)); + + floorId = GetFloorId(); + for (i = 0; i < 2; i++) + { + u8 bits; + + eventTemplates[i] = gUnknown_0862A670; + eventTemplates[i].localId = i + 1; + eventTemplates[i].graphicsId = FacilityClassToGraphicsId(sHillData->tag.floors[floorId].trainers[i].facilityClass); + eventTemplates[i].x = sHillData->tag.floors[floorId].coords[i] & 0xF; + eventTemplates[i].y = ((sHillData->tag.floors[floorId].coords[i] >> 4) & 0xF) + 5; + bits = i << 2; + eventTemplates[i].movementType = ((sHillData->tag.floors[floorId].direction >> bits) & 0xF) + MOVEMENT_TYPE_FACE_UP; + eventTemplates[i].trainerRange_berryTreeId = (sHillData->tag.floors[floorId].range >> bits) & 0xF; + eventTemplates[i].script = EventScript_2C83F0; + gSaveBlock2Ptr->frontier.field_CB4[i] = i + 1; + } + + FreeDataStruct(); +} + +bool32 sub_81D5F48(void) +{ + SetUpDataStruct(); + FreeDataStruct(); + return TRUE; +} + +// Functionally equivalent. +#ifdef NONMATCHING +static u32 sub_81D5F58(u8 floorId, u32 bit, u32 arg2, u32 arg3) +{ + u32 var0, var1, var2, var3; + + var0 = (sHillData->tag.floors[floorId].unk3A0[arg2] >> (15 - bit)) & 1; + var1 = sHillData->tag.floors[floorId].data[arg2 * arg3 + bit]; + var3 = 0x200; + var2 = 0x3000; + + return ((var0 << 10) | var2) | (var1 | var3); +} +#else +NAKED +static u32 sub_81D5F58(u8 floorId, u32 bit, u32 arg2, u32 arg3) +{ + asm_unified("\n\ + push {r4,r5,lr}\n\ + lsls r0, 24\n\ + lsrs r0, 24\n\ + ldr r4, =sHillData\n\ + ldr r4, [r4]\n\ + mov r12, r4\n\ + lsls r4, r2, 1\n\ + lsls r5, r0, 4\n\ + subs r5, r0\n\ + lsls r5, 3\n\ + subs r5, r0\n\ + lsls r5, 3\n\ + adds r4, r5\n\ + movs r0, 0xE8\n\ + lsls r0, 2\n\ + add r0, r12\n\ + adds r0, r4\n\ + ldrh r0, [r0]\n\ + movs r4, 0xF\n\ + subs r4, r1\n\ + asrs r0, r4\n\ + movs r4, 0x1\n\ + ands r0, r4\n\ + muls r2, r3\n\ + adds r2, r1\n\ + adds r2, r5\n\ + movs r1, 0xA8\n\ + lsls r1, 2\n\ + add r1, r12\n\ + adds r1, r2\n\ + ldrb r1, [r1]\n\ + movs r2, 0x80\n\ + lsls r2, 2\n\ + adds r3, r2, 0\n\ + movs r2, 0xC0\n\ + lsls r2, 6\n\ + lsls r0, 10\n\ + orrs r0, r2\n\ + orrs r1, r3\n\ + orrs r0, r1\n\ + pop {r4,r5}\n\ + pop {r1}\n\ + bx r1\n\ + .pool"); +} +#endif // NONMATCHING + +void sub_81D5FB4(u16 *mapArg) +{ + s32 i, j; + u16 *src, *dst; + u8 mapId = GetCurrentTrainerHillMapId(); + + if (mapId == 6) + { + InitMapFromSavedGame(); + return; + } + + SetUpDataStruct(); + if (mapId == 5) + { + InitMapFromSavedGame(); + FreeDataStruct(); + return; + } + + mapId = GetFloorId(); + src = gMapHeader.mapLayout->map; + gBackupMapLayout.map = mapArg; + gBackupMapLayout.width = 31; + gBackupMapLayout.height = 35; + dst = mapArg + 224; + for (i = 0; i < 5; i++) + { + for (j = 0; j < 16; j++) + dst[j] = src[j]; + dst += 31; + src += 16; + } + + for (i = 0; i < 16; i++) + { + for (j = 0; j < 16; j++) + dst[j] = sub_81D5F58(mapId, j, i, 0x10); + dst += 31; + } + + mapheader_run_script_with_tag_x1(); + FreeDataStruct(); +} + +bool32 InTrainerHill(void) +{ + bool32 ret; + + if (gMapHeader.mapLayoutId == 0x19F + || gMapHeader.mapLayoutId == 0x1A0 + || gMapHeader.mapLayoutId == 0x1A1 + || gMapHeader.mapLayoutId == 0x1A2) + ret = TRUE; + else + ret = FALSE; + + return ret; +} + +u8 GetCurrentTrainerHillMapId(void) +{ + u8 ret; + + if (gMapHeader.mapLayoutId == 0x19F) + ret = 1; + else if (gMapHeader.mapLayoutId == 0x1A0) + ret = 2; + else if (gMapHeader.mapLayoutId == 0x1A1) + ret = 3; + else if (gMapHeader.mapLayoutId == 0x1A2) + ret = 4; + else if (gMapHeader.mapLayoutId == 0x1A3) + ret = 5; + else if (gMapHeader.mapLayoutId == 0x19E) + ret = 6; + else + ret = 0; + + return ret; +} + +static bool32 sub_81D6100(void) +{ + bool32 ret; + + if (gMapHeader.mapLayoutId == 0x1A3) + ret = TRUE; + else + ret = FALSE; + + return ret; +} + +const struct WarpEvent* sub_81D6120(void) +{ + const struct MapHeader *header = Overworld_GetMapHeaderByGroupAndId(MAP_GROUP(TRAINER_HILL_4F), MAP_NUM(TRAINER_HILL_4F)); + + return &header->events->warps[1]; +} + +const struct WarpEvent* sub_81D6134(u8 warpEventId) +{ + u8 id; + const struct MapHeader *header; + + if (warpEventId == 1) + return &gMapHeader.events->warps[1]; + + id = sub_81D6490(); + if (id == 0 || id >= 5) + id = 4; + + header = Overworld_GetMapHeaderByGroupAndId(MAP_GROUP(TRAINER_HILL_4F), gUnknown_0862A688[id - 1]); + return &header->events->warps[0]; +} + +u16 LocalIdToHillTrainerId(u8 localId) +{ + return gSaveBlock2Ptr->frontier.field_CB4[localId - 1]; +} + +bool8 GetHillTrainerFlag(u8 eventObjectId) +{ + u32 floorId = GetFloorId() * 2; + u8 bitId = gEventObjects[eventObjectId].localId - 1 + floorId; + + return gSaveBlock2Ptr->frontier.field_EE0 & gBitTable[bitId]; +} + +void SetHillTrainerFlag(void) +{ + u8 i; + u8 floorId = GetFloorId() * 2; + + for (i = 0; i < 2; i++) + { + if (gSaveBlock2Ptr->frontier.field_CB4[i] == gTrainerBattleOpponent_A) + { + gSaveBlock2Ptr->frontier.field_EE0 |= gBitTable[floorId + i]; + break; + } + } + + if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) + { + for (i = 0; i < 2; i++) + { + if (gSaveBlock2Ptr->frontier.field_CB4[i] == gTrainerBattleOpponent_B) + { + gSaveBlock2Ptr->frontier.field_EE0 |= gBitTable[floorId + i]; + break; + } + } + } +} + +const u8 *sub_81D62AC(void) +{ + return EventScript_2C83F0; +} + +static void sub_81D62B4(void) +{ + CopyTrainerHillTrainerText(5, gSpecialVar_LastTalked); + sub_80982B8(); +} + +static void sub_81D62CC(u16 trainerId, u8 firstMonId) +{ + u8 trId, level; + s32 i, floorId, arrId; + + if (trainerId == 0 || trainerId > 2) + return; + + trId = trainerId - 1; + SetUpDataStruct(); + level = GetHighestLevelInPlayerParty(); + floorId = GetFloorId(); + for (i = firstMonId, arrId = 0; i < firstMonId + 3; i++, arrId++) + { + u8 id = gUnknown_0862A698[trId][arrId]; + struct Pokemon *mon = &gEnemyParty[i]; + + CreateBattleTowerMon(mon, &sHillData->tag.floors[floorId].trainers[trId].mons[id]); + sub_81D642C(mon, level); + } + + FreeDataStruct(); +} + +void FillHillTrainerParty(void) +{ + ZeroEnemyPartyMons(); + sub_81D62CC(gTrainerBattleOpponent_A, 0); +} + +void FillHillTrainersParties(void) +{ + ZeroEnemyPartyMons(); + sub_81D62CC(gTrainerBattleOpponent_A, 0); + sub_81D62CC(gTrainerBattleOpponent_B, 3); +} + +// This function is unused, but my best guess is +// it was supposed to return AI scripts for trainer +// hill trainers. +u32 sub_81D63C4(void) +{ + return 7; +} + +u8 GetTrainerEncounterMusicIdInTrainerHill(u16 trainerId) +{ + s32 i; + u8 trId, facilityClass; + + SetUpDataStruct(); + trId = trainerId - 1; + facilityClass = sHillData->tag.floors[sHillData->floorId].trainers[trId].facilityClass; + FreeDataStruct(); + + for (i = 0; i < ARRAY_COUNT(gUnknown_0862A3B4); i++) + { + if (gUnknown_0862A3B4[i].trainerClass == gFacilityClassToTrainerClass[facilityClass]) + return gUnknown_0862A3B4[i].musicId; + } + + return 0; +} + +static void sub_81D642C(struct Pokemon *mon, u8 level) +{ + u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); + u32 exp = gExperienceTables[gBaseStats[species].growthRate][level]; + + SetMonData(mon, MON_DATA_EXP, &exp); + SetMonData(mon, MON_DATA_LEVEL, &level); + CalculateMonStats(mon); +} + +u8 sub_81D6490(void) +{ + u8 ret; + + SetUpDataStruct(); + ret = sHillData->tag.unkField_2; + FreeDataStruct(); + + return ret; +} + +static void sub_81D64AC(void) +{ + gSaveBlock2Ptr->frontier.field_EE0 = 0xFF; +} + +void sub_81D64C0(void) +{ + if (sub_81D6534() == TRUE) + LoadPalette(gUnknown_0862A5D4, 0x70, 0x20); +} + +static void sub_81D64DC(void) +{ + gSpecialVar_Result = gSaveBlock2Ptr->frontier.field_EF9_1; +} + +static void sub_81D64FC(void) +{ + gSaveBlock2Ptr->frontier.field_EF9_1 = 1; +} + +static void sub_81D6518(void) +{ + gSaveBlock2Ptr->frontier.field_EF9_1 = 0; +} + +bool32 sub_81D6534(void) +{ + if (!sub_81D5C18() || GetCurrentTrainerHillMapId() == 6) + return FALSE; + + sub_81D5C00(); + if (gSpecialVar_Result == 0) + return FALSE; + else + return TRUE; +} + +static void sub_81D6568(void) +{ + if (gSaveBlock1Ptr->trainerHill.field_3D6E_0d) + gSpecialVar_Result = 0; + else + gSpecialVar_Result = 1; +} + +static void sub_81D65A0(void) +{ + gSaveBlock1Ptr->trainerHill.tag = gSpecialVar_0x8005; + gSaveBlock1Ptr->trainerHill.field_3D68 = gSaveBlock1Ptr->trainerHillTimes[gSpecialVar_0x8005]; +} + +static u8 sub_81D65E8(u8 arg0) +{ + u8 var, i, modBy; + + var = 0; + for (i = 0; i < 4; i++) + { + var ^= sHillData->tag.floors[i].unk0 & 0x1F; + var ^= sHillData->tag.floors[i].unk1 & 0x1F; + } + + if (arg0) + modBy = 10; + else + modBy = 5; + + var %= modBy; + return var; +} + +static u16 sub_81D6640(void) +{ + u8 i; + const u16 *ptr; + s32 var = 0, var2, minutes, id; + + for (i = 0; i < 4; i++) + { + var += sHillData->tag.floors[i].unk0; + var += sHillData->tag.floors[i].unk1; + } + + var2 = var / 256; + var2 %= 2; + if (FlagGet(FLAG_SYS_GAME_CLEAR) && sHillData->tag.unkField_0 == 8) + i = sub_81D65E8(1); + else + i = sub_81D65E8(0); + + if (gSaveBlock1Ptr->trainerHill.tag == HILL_TAG_EXPERT) + i = (i + 1) % 10; + + ptr = gUnknown_0862A5CC[var2][i]; + minutes = (signed)(gSaveBlock1Ptr->trainerHill.field_3D64) / (60 * 60); + if (minutes < 12) + id = 0; + else if (minutes < 13) + id = 1; + else if (minutes < 14) + id = 2; + else if (minutes < 16) + id = 3; + else if (minutes < 18) + id = 4; + else + id = 5; + + return ptr[id]; +} diff --git a/src/trainer_pokemon_sprites.c b/src/trainer_pokemon_sprites.c index 5ddae218b..d57685423 100644 --- a/src/trainer_pokemon_sprites.c +++ b/src/trainer_pokemon_sprites.c @@ -109,7 +109,7 @@ static void LoadPicPaletteByTagOrSlot(u16 species, u32 otId, u32 personality, u8 { if (paletteTag == 0xFFFF) { - sCreatingSpriteTemplate.paletteTag |= 0xFFFF; + sCreatingSpriteTemplate.paletteTag = 0xFFFF; LoadCompressedPalette(GetFrontSpritePalFromSpeciesAndPersonality(species, otId, personality), 0x100 + paletteSlot * 0x10, 0x20); } else @@ -122,7 +122,7 @@ static void LoadPicPaletteByTagOrSlot(u16 species, u32 otId, u32 personality, u8 { if (paletteTag == 0xFFFF) { - sCreatingSpriteTemplate.paletteTag |= 0xFFFF; + sCreatingSpriteTemplate.paletteTag = 0xFFFF; LoadCompressedPalette(gTrainerFrontPicPaletteTable[species].data, 0x100 + paletteSlot * 0x10, 0x20); } else diff --git a/src/trainer_see.c b/src/trainer_see.c index eeebcb575..3846eca46 100644 --- a/src/trainer_see.c +++ b/src/trainer_see.c @@ -6,18 +6,16 @@ #include "field_effect.h" #include "field_player_avatar.h" #include "pokemon.h" -#include "pokenav.h" #include "script.h" #include "script_movement.h" #include "sprite.h" #include "task.h" #include "trainer_see.h" +#include "trainer_hill.h" #include "util.h" #include "battle_pyramid.h" #include "constants/field_effects.h" -extern bool32 InTrainerHill(void); -extern bool8 GetTrainerHillTrainerFlag(u8 eventObjectId); extern void sub_809BE48(u16 npcId); // this file's functions @@ -240,7 +238,7 @@ static u8 CheckTrainer(u8 eventObjectId) } else if (InTrainerHill() == TRUE) { - if (GetTrainerHillTrainerFlag(eventObjectId)) + if (GetHillTrainerFlag(eventObjectId)) return 0; } else |