2018-08-26 17:54:58 +02:00
# include "global.h"
2018-10-21 00:06:42 +02:00
# include "battle_tower.h"
# include "apprentice.h"
2018-08-26 17:54:58 +02:00
# include "event_data.h"
# include "battle_setup.h"
# include "overworld.h"
# include "random.h"
2018-10-21 00:06:42 +02:00
# include "text.h"
2018-10-21 20:13:12 +02:00
# include "main.h"
2018-10-21 00:06:42 +02:00
# include "international_string_util.h"
# include "battle.h"
2018-10-30 21:45:26 +01:00
# include "frontier_util.h"
2018-12-05 22:21:26 +01:00
# include "strings.h"
2018-10-21 00:06:42 +02:00
# include "recorded_battle.h"
# include "easy_chat.h"
2018-10-21 20:13:12 +02:00
# include "gym_leader_rematch.h"
# include "battle_transition.h"
# include "trainer_see.h"
# include "new_game.h"
# include "string_util.h"
2019-04-04 23:53:06 +02:00
# include "data.h"
2018-10-22 19:22:57 +02:00
# include "link.h"
# include "field_message_box.h"
# include "tv.h"
2018-11-11 16:44:27 +01:00
# include "battle_factory.h"
2020-01-08 05:43:06 -05:00
# include "constants/apprentice.h"
2020-04-09 15:18:53 -04:00
# include "constants/battle_dome.h"
2018-10-20 00:33:51 +02:00
# include "constants/battle_frontier.h"
2019-12-27 02:26:27 -08:00
# include "constants/battle_frontier_mons.h"
2020-01-08 01:07:53 -05:00
# include "constants/battle_tent_mons.h"
# include "constants/battle_tent_trainers.h"
2019-11-16 18:11:27 -05:00
# include "constants/battle_tower.h"
2019-11-24 16:58:40 -05:00
# include "constants/frontier_util.h"
2018-12-05 22:21:26 +01:00
# include "constants/items.h"
2018-10-21 00:06:42 +02:00
# include "constants/trainers.h"
# include "constants/event_objects.h"
# include "constants/moves.h"
2018-12-02 23:22:42 -05:00
# include "constants/easy_chat.h"
2019-11-10 21:54:00 -05:00
# include "constants/tv.h"
2018-08-26 17:54:58 +02:00
2019-11-01 17:50:54 -04:00
extern const u8 MossdeepCity_SpaceCenter_2F_EventScript_MaxieTrainer [ ] ;
extern const u8 MossdeepCity_SpaceCenter_2F_EventScript_TabithaTrainer [ ] ;
2018-08-26 17:54:58 +02:00
2018-10-26 23:54:41 +02:00
// EWRAM vars.
EWRAM_DATA const struct BattleFrontierTrainer * gFacilityTrainers = NULL ;
EWRAM_DATA const struct FacilityMon * gFacilityTrainerMons = NULL ;
2018-11-19 01:03:14 +01:00
// IWRAM common
2019-12-02 08:44:34 -05:00
u16 gUnknown_03006298 [ MAX_FRONTIER_PARTY_SIZE ] ;
2018-11-19 01:03:14 +01:00
2018-08-26 17:54:58 +02:00
// This file's functions.
2019-11-28 21:09:35 -05:00
static void InitTowerChallenge ( void ) ;
static void GetTowerData ( void ) ;
static void SetTowerData ( void ) ;
2019-11-28 22:46:39 -05:00
static void SetNextFacilityOpponent ( void ) ;
static void SetTowerBattleWon ( void ) ;
2018-10-25 21:27:10 +02:00
static void AwardBattleTowerRibbons ( void ) ;
2019-11-28 21:09:35 -05:00
static void SaveTowerChallenge ( void ) ;
2019-11-28 22:46:39 -05:00
static void GetOpponentIntroSpeech ( void ) ;
2018-10-25 21:27:10 +02:00
static void nullsub_61 ( void ) ;
2019-11-16 20:50:52 -05:00
static void nullsub_116 ( void ) ;
2020-01-08 05:43:06 -05:00
static void LoadMultiPartnerCandidatesData ( void ) ;
static void ShowPartnerCandidateMessage ( void ) ;
static void LoadLinkMultiOpponentsData ( void ) ;
2018-10-25 21:27:10 +02:00
static void sub_8164DCC ( void ) ;
2020-01-08 05:43:06 -05:00
static void SetMultiPartnerGfx ( void ) ;
2019-11-28 22:46:39 -05:00
static void SetTowerInterviewData ( void ) ;
2018-10-25 21:27:10 +02:00
static void ValidateBattleTowerRecordChecksums ( void ) ;
static void SaveCurrentWinStreak ( void ) ;
static void ValidateApprenticesChecksums ( void ) ;
2019-11-28 22:46:39 -05:00
static void SetNextBattleTentOpponent ( void ) ;
2018-10-25 21:27:10 +02:00
static void CopyEReaderTrainerFarewellMessage ( void ) ;
static void ClearBattleTowerRecord ( struct EmeraldBattleTowerRecord * record ) ;
2018-10-22 19:22:57 +02:00
static void FillTrainerParty ( u16 trainerId , u8 firstMonId , u8 monCount ) ;
2018-10-25 21:27:10 +02:00
static void FillTentTrainerParty_ ( u16 trainerId , u8 firstMonId , u8 monCount ) ;
2018-10-26 23:54:41 +02:00
static void FillFactoryFrontierTrainerParty ( u16 trainerId , u8 firstMonId ) ;
static void FillFactoryTentTrainerParty ( u16 trainerId , u8 firstMonId ) ;
2018-10-25 21:27:10 +02:00
static u8 GetFrontierTrainerFixedIvs ( u16 trainerId ) ;
static void FillPartnerParty ( u16 trainerId ) ;
static void SetEReaderTrainerChecksum ( struct BattleTowerEReaderTrainer * ereaderTrainer ) ;
static u8 SetTentPtrsGetLevel ( void ) ;
// Const rom data.
2018-12-05 22:21:26 +01:00
const u16 gBattleFrontierHeldItems [ ] =
2018-12-04 12:09:35 -05:00
{
ITEM_NONE ,
ITEM_KINGS_ROCK ,
ITEM_SITRUS_BERRY ,
ITEM_ORAN_BERRY ,
ITEM_CHESTO_BERRY ,
ITEM_HARD_STONE ,
ITEM_FOCUS_BAND ,
ITEM_PERSIM_BERRY ,
ITEM_MIRACLE_SEED ,
ITEM_BERRY_JUICE ,
ITEM_MACHO_BRACE ,
ITEM_SILVER_POWDER ,
ITEM_CHERI_BERRY ,
ITEM_BLACK_GLASSES ,
ITEM_BLACK_BELT ,
ITEM_SOUL_DEW ,
ITEM_CHOICE_BAND ,
ITEM_MAGNET ,
ITEM_SILK_SCARF ,
ITEM_WHITE_HERB ,
ITEM_DEEP_SEA_SCALE ,
ITEM_DEEP_SEA_TOOTH ,
ITEM_MYSTIC_WATER ,
ITEM_SHARP_BEAK ,
ITEM_QUICK_CLAW ,
ITEM_LEFTOVERS ,
ITEM_RAWST_BERRY ,
ITEM_LIGHT_BALL ,
ITEM_POISON_BARB ,
ITEM_NEVER_MELT_ICE ,
ITEM_ASPEAR_BERRY ,
ITEM_SPELL_TAG ,
ITEM_BRIGHT_POWDER ,
ITEM_LEPPA_BERRY ,
ITEM_SCOPE_LENS ,
ITEM_TWISTED_SPOON ,
ITEM_METAL_COAT ,
ITEM_MENTAL_HERB ,
ITEM_CHARCOAL ,
ITEM_PECHA_BERRY ,
ITEM_SOFT_SAND ,
ITEM_LUM_BERRY ,
ITEM_DRAGON_SCALE ,
ITEM_DRAGON_FANG ,
ITEM_IAPAPA_BERRY ,
ITEM_WIKI_BERRY ,
ITEM_SEA_INCENSE ,
ITEM_SHELL_BELL ,
ITEM_SALAC_BERRY ,
ITEM_LANSAT_BERRY ,
ITEM_APICOT_BERRY ,
ITEM_STARF_BERRY ,
ITEM_LIECHI_BERRY ,
ITEM_STICK ,
ITEM_LAX_INCENSE ,
ITEM_AGUAV_BERRY ,
ITEM_FIGY_BERRY ,
ITEM_THICK_CLUB ,
ITEM_MAGO_BERRY ,
ITEM_METAL_POWDER ,
ITEM_PETAYA_BERRY ,
ITEM_LUCKY_PUNCH ,
ITEM_GANLON_BERRY
} ;
2018-12-02 23:22:42 -05:00
2018-12-04 12:09:35 -05:00
# include "data/battle_frontier/battle_frontier_trainer_mons.h"
# include "data/battle_frontier/battle_frontier_trainers.h"
# include "data/battle_frontier/battle_frontier_mons.h"
2018-12-02 23:22:42 -05:00
2018-12-10 10:33:51 -05:00
const u8 gTowerMaleFacilityClasses [ 30 ] =
2018-12-04 12:09:35 -05:00
{
FACILITY_CLASS_RUIN_MANIAC ,
FACILITY_CLASS_TUBER_M ,
FACILITY_CLASS_COOLTRAINER_M ,
FACILITY_CLASS_RICH_BOY ,
FACILITY_CLASS_POKEMANIAC ,
FACILITY_CLASS_SWIMMER_M ,
FACILITY_CLASS_BLACK_BELT ,
FACILITY_CLASS_GUITARIST ,
FACILITY_CLASS_KINDLER ,
FACILITY_CLASS_CAMPER ,
FACILITY_CLASS_BUG_MANIAC ,
FACILITY_CLASS_PSYCHIC_M ,
FACILITY_CLASS_GENTLEMAN ,
FACILITY_CLASS_SCHOOL_KID_M ,
FACILITY_CLASS_POKEFAN_M ,
FACILITY_CLASS_EXPERT_M ,
FACILITY_CLASS_YOUNGSTER ,
FACILITY_CLASS_FISHERMAN ,
FACILITY_CLASS_CYCLING_TRIATHLETE_M ,
FACILITY_CLASS_RUNNING_TRIATHLETE_M ,
FACILITY_CLASS_SWIMMING_TRIATHLETE_M ,
FACILITY_CLASS_DRAGON_TAMER ,
FACILITY_CLASS_BIRD_KEEPER ,
FACILITY_CLASS_NINJA_BOY ,
FACILITY_CLASS_SAILOR ,
FACILITY_CLASS_COLLECTOR ,
FACILITY_CLASS_PKMN_BREEDER_M ,
FACILITY_CLASS_PKMN_RANGER_M ,
FACILITY_CLASS_BUG_CATCHER ,
FACILITY_CLASS_HIKER
} ;
2018-12-02 23:22:42 -05:00
2018-12-10 10:33:51 -05:00
const u8 gTowerFemaleFacilityClasses [ 20 ] =
2018-12-04 12:09:35 -05:00
{
FACILITY_CLASS_AROMA_LADY ,
FACILITY_CLASS_TUBER_F ,
FACILITY_CLASS_COOLTRAINER_F ,
FACILITY_CLASS_HEX_MANIAC ,
FACILITY_CLASS_LADY ,
FACILITY_CLASS_BEAUTY ,
FACILITY_CLASS_PSYCHIC_F ,
FACILITY_CLASS_SCHOOL_KID_F ,
FACILITY_CLASS_POKEFAN_F ,
FACILITY_CLASS_EXPERT_F ,
FACILITY_CLASS_CYCLING_TRIATHLETE_F ,
FACILITY_CLASS_RUNNING_TRIATHLETE_F ,
FACILITY_CLASS_SWIMMING_TRIATHLETE_F ,
FACILITY_CLASS_BATTLE_GIRL ,
FACILITY_CLASS_PARASOL_LADY ,
FACILITY_CLASS_SWIMMER_F ,
FACILITY_CLASS_PICNICKER ,
2019-11-24 16:58:40 -05:00
FACILITY_CLASS_PKMN_BREEDER_F ,
2018-12-04 12:09:35 -05:00
FACILITY_CLASS_PKMN_RANGER_F ,
FACILITY_CLASS_LASS
} ;
2018-12-02 23:22:42 -05:00
2018-12-10 10:33:51 -05:00
const u8 gTowerMaleTrainerGfxIds [ 30 ] =
2018-12-04 12:09:35 -05:00
{
2019-11-20 23:12:51 -05:00
OBJ_EVENT_GFX_HIKER ,
OBJ_EVENT_GFX_TUBER_M ,
OBJ_EVENT_GFX_MAN_3 ,
OBJ_EVENT_GFX_RICH_BOY ,
OBJ_EVENT_GFX_MANIAC ,
OBJ_EVENT_GFX_RUNNING_TRIATHLETE_M ,
OBJ_EVENT_GFX_BLACK_BELT ,
OBJ_EVENT_GFX_MAN_5 ,
OBJ_EVENT_GFX_MAN_5 ,
OBJ_EVENT_GFX_CAMPER ,
OBJ_EVENT_GFX_MANIAC ,
OBJ_EVENT_GFX_PSYCHIC_M ,
OBJ_EVENT_GFX_GENTLEMAN ,
OBJ_EVENT_GFX_SCHOOL_KID_M ,
OBJ_EVENT_GFX_POKEFAN_M ,
OBJ_EVENT_GFX_EXPERT_M ,
OBJ_EVENT_GFX_YOUNGSTER ,
OBJ_EVENT_GFX_FISHERMAN ,
OBJ_EVENT_GFX_CYCLING_TRIATHLETE_M ,
OBJ_EVENT_GFX_RUNNING_TRIATHLETE_M ,
OBJ_EVENT_GFX_RUNNING_TRIATHLETE_M ,
OBJ_EVENT_GFX_MAN_3 ,
OBJ_EVENT_GFX_MAN_5 ,
OBJ_EVENT_GFX_NINJA_BOY ,
OBJ_EVENT_GFX_SAILOR ,
OBJ_EVENT_GFX_MANIAC ,
OBJ_EVENT_GFX_MAN_4 ,
OBJ_EVENT_GFX_CAMPER ,
OBJ_EVENT_GFX_BUG_CATCHER ,
OBJ_EVENT_GFX_HIKER
2018-12-04 12:09:35 -05:00
} ;
2018-12-02 23:22:42 -05:00
2018-12-10 10:33:51 -05:00
const u8 gTowerFemaleTrainerGfxIds [ 20 ] =
2018-12-04 12:09:35 -05:00
{
2019-11-20 23:12:51 -05:00
OBJ_EVENT_GFX_WOMAN_2 ,
OBJ_EVENT_GFX_TUBER_F ,
OBJ_EVENT_GFX_WOMAN_5 ,
OBJ_EVENT_GFX_HEX_MANIAC ,
OBJ_EVENT_GFX_WOMAN_2 ,
OBJ_EVENT_GFX_BEAUTY ,
OBJ_EVENT_GFX_LASS ,
OBJ_EVENT_GFX_GIRL_3 ,
OBJ_EVENT_GFX_POKEFAN_F ,
OBJ_EVENT_GFX_EXPERT_F ,
OBJ_EVENT_GFX_CYCLING_TRIATHLETE_F ,
OBJ_EVENT_GFX_RUNNING_TRIATHLETE_F ,
OBJ_EVENT_GFX_RUNNING_TRIATHLETE_F ,
OBJ_EVENT_GFX_GIRL_3 ,
OBJ_EVENT_GFX_WOMAN_5 ,
OBJ_EVENT_GFX_RUNNING_TRIATHLETE_F ,
OBJ_EVENT_GFX_PICNICKER ,
OBJ_EVENT_GFX_WOMAN_2 ,
OBJ_EVENT_GFX_PICNICKER ,
OBJ_EVENT_GFX_LASS
2018-12-04 12:09:35 -05:00
} ;
2018-12-02 23:22:42 -05:00
2019-11-24 16:58:40 -05:00
// Excludes the unused RS_FACILITY_CLASS_BOARDER_1 and _2
static const u8 sRubyFacilityClassToEmerald [ RS_FACILITY_CLASSES_COUNT - 2 ] [ 2 ] =
{
{ RS_FACILITY_CLASS_AQUA_LEADER_ARCHIE , FACILITY_CLASS_AQUA_LEADER_ARCHIE } ,
{ RS_FACILITY_CLASS_AQUA_GRUNT_M , FACILITY_CLASS_AQUA_GRUNT_M } ,
{ RS_FACILITY_CLASS_AQUA_GRUNT_F , FACILITY_CLASS_AQUA_GRUNT_F } ,
{ RS_FACILITY_CLASS_AROMA_LADY , FACILITY_CLASS_AROMA_LADY } ,
{ RS_FACILITY_CLASS_RUIN_MANIAC , FACILITY_CLASS_RUIN_MANIAC } ,
{ RS_FACILITY_CLASS_INTERVIEWER , FACILITY_CLASS_INTERVIEWER } ,
{ RS_FACILITY_CLASS_TUBER_F , FACILITY_CLASS_TUBER_F } ,
{ RS_FACILITY_CLASS_TUBER_M , FACILITY_CLASS_TUBER_M } ,
{ RS_FACILITY_CLASS_COOLTRAINER_M , FACILITY_CLASS_COOLTRAINER_M } ,
{ RS_FACILITY_CLASS_COOLTRAINER_F , FACILITY_CLASS_COOLTRAINER_F } ,
{ RS_FACILITY_CLASS_HEX_MANIAC , FACILITY_CLASS_HEX_MANIAC } ,
{ RS_FACILITY_CLASS_LADY , FACILITY_CLASS_LADY } ,
{ RS_FACILITY_CLASS_BEAUTY , FACILITY_CLASS_BEAUTY } ,
{ RS_FACILITY_CLASS_RICH_BOY , FACILITY_CLASS_RICH_BOY } ,
{ RS_FACILITY_CLASS_POKEMANIAC , FACILITY_CLASS_POKEMANIAC } ,
{ RS_FACILITY_CLASS_SWIMMER_M , FACILITY_CLASS_SWIMMER_M } ,
{ RS_FACILITY_CLASS_BLACK_BELT , FACILITY_CLASS_BLACK_BELT } ,
{ RS_FACILITY_CLASS_GUITARIST , FACILITY_CLASS_GUITARIST } ,
{ RS_FACILITY_CLASS_KINDLER , FACILITY_CLASS_KINDLER } ,
{ RS_FACILITY_CLASS_CAMPER , FACILITY_CLASS_CAMPER } ,
{ RS_FACILITY_CLASS_BUG_MANIAC , FACILITY_CLASS_BUG_MANIAC } ,
{ RS_FACILITY_CLASS_PSYCHIC_M , FACILITY_CLASS_PSYCHIC_M } ,
{ RS_FACILITY_CLASS_PSYCHIC_F , FACILITY_CLASS_PSYCHIC_F } ,
{ RS_FACILITY_CLASS_GENTLEMAN , FACILITY_CLASS_GENTLEMAN } ,
{ RS_FACILITY_CLASS_ELITE_FOUR_M , FACILITY_CLASS_ELITE_FOUR_SIDNEY } ,
{ RS_FACILITY_CLASS_ELITE_FOUR_F , FACILITY_CLASS_ELITE_FOUR_PHOEBE } ,
{ RS_FACILITY_CLASS_LEADER_F , FACILITY_CLASS_LEADER_ROXANNE } ,
{ RS_FACILITY_CLASS_LEADER_M , FACILITY_CLASS_LEADER_BRAWLY } ,
{ RS_FACILITY_CLASS_LEADER_MF , FACILITY_CLASS_LEADER_TATE_AND_LIZA } ,
{ RS_FACILITY_CLASS_SCHOOL_KID_M , FACILITY_CLASS_SCHOOL_KID_M } ,
{ RS_FACILITY_CLASS_SCHOOL_KID_F , FACILITY_CLASS_SCHOOL_KID_F } ,
{ RS_FACILITY_CLASS_SR_AND_JR , FACILITY_CLASS_SR_AND_JR } ,
{ RS_FACILITY_CLASS_POKEFAN_M , FACILITY_CLASS_POKEFAN_M } ,
{ RS_FACILITY_CLASS_POKEFAN_F , FACILITY_CLASS_POKEFAN_F } ,
{ RS_FACILITY_CLASS_EXPERT_M , FACILITY_CLASS_EXPERT_M } ,
{ RS_FACILITY_CLASS_EXPERT_F , FACILITY_CLASS_EXPERT_F } ,
{ RS_FACILITY_CLASS_YOUNGSTER , FACILITY_CLASS_YOUNGSTER } ,
{ RS_FACILITY_CLASS_CHAMPION , FACILITY_CLASS_CHAMPION_WALLACE } ,
{ RS_FACILITY_CLASS_FISHERMAN , FACILITY_CLASS_FISHERMAN } ,
{ RS_FACILITY_CLASS_CYCLING_TRIATHLETE_M , FACILITY_CLASS_CYCLING_TRIATHLETE_M } ,
{ RS_FACILITY_CLASS_CYCLING_TRIATHLETE_F , FACILITY_CLASS_CYCLING_TRIATHLETE_F } ,
{ RS_FACILITY_CLASS_RUNNING_TRIATHLETE_M , FACILITY_CLASS_RUNNING_TRIATHLETE_M } ,
{ RS_FACILITY_CLASS_RUNNING_TRIATHLETE_F , FACILITY_CLASS_RUNNING_TRIATHLETE_F } ,
{ RS_FACILITY_CLASS_SWIMMING_TRIATHLETE_M , FACILITY_CLASS_SWIMMING_TRIATHLETE_M } ,
{ RS_FACILITY_CLASS_SWIMMING_TRIATHLETE_F , FACILITY_CLASS_SWIMMING_TRIATHLETE_F } ,
{ RS_FACILITY_CLASS_DRAGON_TAMER , FACILITY_CLASS_DRAGON_TAMER } ,
{ RS_FACILITY_CLASS_BIRD_KEEPER , FACILITY_CLASS_BIRD_KEEPER } ,
{ RS_FACILITY_CLASS_NINJA_BOY , FACILITY_CLASS_NINJA_BOY } ,
{ RS_FACILITY_CLASS_BATTLE_GIRL , FACILITY_CLASS_BATTLE_GIRL } ,
{ RS_FACILITY_CLASS_PARASOL_LADY , FACILITY_CLASS_PARASOL_LADY } ,
{ RS_FACILITY_CLASS_SWIMMER_F , FACILITY_CLASS_SWIMMER_F } ,
{ RS_FACILITY_CLASS_PICNICKER , FACILITY_CLASS_PICNICKER } ,
{ RS_FACILITY_CLASS_TWINS , FACILITY_CLASS_TWINS } ,
{ RS_FACILITY_CLASS_SAILOR , FACILITY_CLASS_SAILOR } ,
{ RS_FACILITY_CLASS_COLLECTOR , FACILITY_CLASS_COLLECTOR } ,
{ RS_FACILITY_CLASS_WALLY , FACILITY_CLASS_WALLY } ,
{ RS_FACILITY_CLASS_BRENDAN_1 , FACILITY_CLASS_BRENDAN } ,
{ RS_FACILITY_CLASS_BRENDAN_2 , FACILITY_CLASS_BRENDAN_2 } ,
{ RS_FACILITY_CLASS_BRENDAN_3 , FACILITY_CLASS_BRENDAN_3 } ,
{ RS_FACILITY_CLASS_MAY_1 , FACILITY_CLASS_MAY } ,
{ RS_FACILITY_CLASS_MAY_2 , FACILITY_CLASS_MAY_2 } ,
{ RS_FACILITY_CLASS_MAY_3 , FACILITY_CLASS_MAY_3 } ,
{ RS_FACILITY_CLASS_PKMN_BREEDER_M , FACILITY_CLASS_PKMN_BREEDER_M } ,
{ RS_FACILITY_CLASS_PKMN_BREEDER_F , FACILITY_CLASS_PKMN_BREEDER_F } ,
{ RS_FACILITY_CLASS_PKMN_RANGER_M , FACILITY_CLASS_PKMN_RANGER_M } ,
{ RS_FACILITY_CLASS_PKMN_RANGER_F , FACILITY_CLASS_PKMN_RANGER_F } ,
{ RS_FACILITY_CLASS_MAGMA_LEADER , FACILITY_CLASS_MAGMA_LEADER_MAXIE } ,
{ RS_FACILITY_CLASS_MAGMA_GRUNT_M , FACILITY_CLASS_MAGMA_GRUNT_M } ,
{ RS_FACILITY_CLASS_MAGMA_GRUNT_F , FACILITY_CLASS_MAGMA_GRUNT_F } ,
{ RS_FACILITY_CLASS_LASS , FACILITY_CLASS_LASS } ,
{ RS_FACILITY_CLASS_BUG_CATCHER , FACILITY_CLASS_BUG_CATCHER } ,
{ RS_FACILITY_CLASS_HIKER , FACILITY_CLASS_HIKER } ,
{ RS_FACILITY_CLASS_YOUNG_COUPLE , FACILITY_CLASS_YOUNG_COUPLE } ,
{ RS_FACILITY_CLASS_OLD_COUPLE , FACILITY_CLASS_OLD_COUPLE } ,
{ RS_FACILITY_CLASS_SIS_AND_BRO , FACILITY_CLASS_SIS_AND_BRO } ,
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
# define PARTNER_TEXTS(name) \
BattleFrontier_BattleTowerMultiPartnerRoom_Text_ # # name # # Intro , \
BattleFrontier_BattleTowerMultiPartnerRoom_Text_ # # name # # Mon1 , \
BattleFrontier_BattleTowerMultiPartnerRoom_Text_ # # name # # Mon2Ask , \
BattleFrontier_BattleTowerMultiPartnerRoom_Text_ # # name # # Accept , \
BattleFrontier_BattleTowerMultiPartnerRoom_Text_ # # name # # Reject
static const u8 * const sPartnerApprenticeTexts1 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice1 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts2 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice2 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts3 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice3 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts4 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice4 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts5 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice5 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts6 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice6 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts7 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice7 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts8 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice8 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts9 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice9 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts10 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice10 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts11 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice11 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts12 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice12 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts13 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice13 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts14 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice14 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts15 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice15 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerApprenticeTexts16 [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Apprentice16 )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsLass [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Lass )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsYoungster [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Youngster )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsHiker [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Hiker )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsBeauty [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Beauty )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsFisherman [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Fisherman )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsLady [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Lady )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsCyclingTriathleteF [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( CyclingTriathleteF )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsBugCatcher [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( BugCatcher )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsSchoolKidM [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( SchoolKidM )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsRichBoy [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( RichBoy )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsBlackBelt [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( BlackBelt )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsTuberF [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( TuberF )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsHexManiac [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( HexManiac )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsPkmnBreederM [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( PkmnBreederM )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsRunningTriathleteF [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( RunningTriathleteF )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsRunningTriathleteM [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( RunningTriathleteM )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsBattleGirl [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( BattleGirl )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsCyclingTriathleteM [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( CyclingTriathleteM )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsTuberM [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( TuberM )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsGuitarist [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Guitarist )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsGentleman [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Gentleman )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsPokefanM [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( PokefanM )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsExpertM [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( ExpertM )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsExpertF [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( ExpertF )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsDragonTamer [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( DragonTamer )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsBirdKeeper [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( BirdKeeper )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsNinjaBoy [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( NinjaBoy )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsParasolLady [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( ParasolLady )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsBugManiac [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( BugManiac )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsSailor [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Sailor )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsCollector [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Collector )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsPkmnRangerM [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( PkmnRangerM )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsPkmnRangerF [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( PkmnRangerF )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsAromaLady [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( AromaLady )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsRuinManiac [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( RuinManiac )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsCoolTrainerM [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( CoolTrainerM )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsCoolTrainerF [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( CoolTrainerF )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsPokemaniac [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Pokemaniac )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsKindler [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Kindler )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsCamper [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Camper )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsPicnicker [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( Picnicker )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsPsychicM [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( PsychicM )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsPsychicF [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( PsychicF )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsSchoolKidF [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( SchoolKidF )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsPkmnBreederF [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( PkmnBreederF )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsPokefanF [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( PokefanF )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsSwimmerF [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( SwimmerF )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsSwimmingTriathleteM [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( SwimmingTriathleteM )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsSwimmingTriathleteF [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( SwimmingTriathleteF )
2018-12-02 23:22:42 -05:00
} ;
2020-01-08 05:43:06 -05:00
static const u8 * const sPartnerTextsSwimmerM [ ] =
2018-12-02 23:22:42 -05:00
{
2020-01-08 05:43:06 -05:00
PARTNER_TEXTS ( SwimmerM )
2018-12-02 23:22:42 -05:00
} ;
struct
{
u32 facilityClass ;
const u8 * const * strings ;
2020-01-08 05:43:06 -05:00
} const sPartnerTrainerTextTables [ ] =
{
{ FACILITY_CLASS_LASS , sPartnerTextsLass } ,
{ FACILITY_CLASS_YOUNGSTER , sPartnerTextsYoungster } ,
{ FACILITY_CLASS_HIKER , sPartnerTextsHiker } ,
{ FACILITY_CLASS_BEAUTY , sPartnerTextsBeauty } ,
{ FACILITY_CLASS_FISHERMAN , sPartnerTextsFisherman } ,
{ FACILITY_CLASS_LADY , sPartnerTextsLady } ,
{ FACILITY_CLASS_CYCLING_TRIATHLETE_F , sPartnerTextsCyclingTriathleteF } ,
{ FACILITY_CLASS_BUG_CATCHER , sPartnerTextsBugCatcher } ,
{ FACILITY_CLASS_SCHOOL_KID_M , sPartnerTextsSchoolKidM } ,
{ FACILITY_CLASS_RICH_BOY , sPartnerTextsRichBoy } ,
{ FACILITY_CLASS_BLACK_BELT , sPartnerTextsBlackBelt } ,
{ FACILITY_CLASS_TUBER_F , sPartnerTextsTuberF } ,
{ FACILITY_CLASS_HEX_MANIAC , sPartnerTextsHexManiac } ,
{ FACILITY_CLASS_PKMN_BREEDER_M , sPartnerTextsPkmnBreederM } ,
{ FACILITY_CLASS_RUNNING_TRIATHLETE_F , sPartnerTextsRunningTriathleteF } ,
{ FACILITY_CLASS_RUNNING_TRIATHLETE_M , sPartnerTextsRunningTriathleteM } ,
{ FACILITY_CLASS_BATTLE_GIRL , sPartnerTextsBattleGirl } ,
{ FACILITY_CLASS_CYCLING_TRIATHLETE_M , sPartnerTextsCyclingTriathleteM } ,
{ FACILITY_CLASS_TUBER_M , sPartnerTextsTuberM } ,
{ FACILITY_CLASS_GUITARIST , sPartnerTextsGuitarist } ,
{ FACILITY_CLASS_GENTLEMAN , sPartnerTextsGentleman } ,
{ FACILITY_CLASS_POKEFAN_M , sPartnerTextsPokefanM } ,
{ FACILITY_CLASS_EXPERT_M , sPartnerTextsExpertM } ,
{ FACILITY_CLASS_EXPERT_F , sPartnerTextsExpertF } ,
{ FACILITY_CLASS_DRAGON_TAMER , sPartnerTextsDragonTamer } ,
{ FACILITY_CLASS_BIRD_KEEPER , sPartnerTextsBirdKeeper } ,
{ FACILITY_CLASS_NINJA_BOY , sPartnerTextsNinjaBoy } ,
{ FACILITY_CLASS_PARASOL_LADY , sPartnerTextsParasolLady } ,
{ FACILITY_CLASS_BUG_MANIAC , sPartnerTextsBugManiac } ,
{ FACILITY_CLASS_SAILOR , sPartnerTextsSailor } ,
{ FACILITY_CLASS_COLLECTOR , sPartnerTextsCollector } ,
{ FACILITY_CLASS_PKMN_RANGER_M , sPartnerTextsPkmnRangerM } ,
{ FACILITY_CLASS_PKMN_RANGER_F , sPartnerTextsPkmnRangerF } ,
{ FACILITY_CLASS_AROMA_LADY , sPartnerTextsAromaLady } ,
{ FACILITY_CLASS_RUIN_MANIAC , sPartnerTextsRuinManiac } ,
{ FACILITY_CLASS_COOLTRAINER_M , sPartnerTextsCoolTrainerM } ,
{ FACILITY_CLASS_COOLTRAINER_F , sPartnerTextsCoolTrainerF } ,
{ FACILITY_CLASS_POKEMANIAC , sPartnerTextsPokemaniac } ,
{ FACILITY_CLASS_KINDLER , sPartnerTextsKindler } ,
{ FACILITY_CLASS_CAMPER , sPartnerTextsCamper } ,
{ FACILITY_CLASS_PICNICKER , sPartnerTextsPicnicker } ,
{ FACILITY_CLASS_PSYCHIC_M , sPartnerTextsPsychicM } ,
{ FACILITY_CLASS_PSYCHIC_F , sPartnerTextsPsychicF } ,
{ FACILITY_CLASS_SCHOOL_KID_F , sPartnerTextsSchoolKidF } ,
{ FACILITY_CLASS_PKMN_BREEDER_F , sPartnerTextsPkmnBreederF } ,
{ FACILITY_CLASS_POKEFAN_F , sPartnerTextsPokefanF } ,
{ FACILITY_CLASS_SWIMMER_F , sPartnerTextsSwimmerF } ,
{ FACILITY_CLASS_SWIMMING_TRIATHLETE_M , sPartnerTextsSwimmingTriathleteM } ,
{ FACILITY_CLASS_SWIMMING_TRIATHLETE_F , sPartnerTextsSwimmingTriathleteF } ,
{ FACILITY_CLASS_SWIMMER_M , sPartnerTextsSwimmerM }
} ;
static const u8 * const * const sPartnerApprenticeTextTables [ NUM_APPRENTICES ] =
{
sPartnerApprenticeTexts1 ,
sPartnerApprenticeTexts2 ,
sPartnerApprenticeTexts3 ,
sPartnerApprenticeTexts4 ,
sPartnerApprenticeTexts5 ,
sPartnerApprenticeTexts6 ,
sPartnerApprenticeTexts7 ,
sPartnerApprenticeTexts8 ,
sPartnerApprenticeTexts9 ,
sPartnerApprenticeTexts10 ,
sPartnerApprenticeTexts11 ,
sPartnerApprenticeTexts12 ,
sPartnerApprenticeTexts13 ,
sPartnerApprenticeTexts14 ,
sPartnerApprenticeTexts15 ,
sPartnerApprenticeTexts16
2018-12-02 23:22:42 -05:00
} ;
struct
{
u16 species ;
u8 fixedIV ;
u8 level ;
u8 nature ;
2020-01-08 05:43:06 -05:00
u8 evs [ NUM_STATS ] ;
2019-09-08 11:53:48 -04:00
u16 moves [ MAX_MON_MOVES ] ;
2020-01-08 05:43:06 -05:00
} const sStevenMons [ MULTI_PARTY_SIZE ] =
2018-12-02 23:22:42 -05:00
{
{
. species = SPECIES_METANG ,
. fixedIV = 31 ,
. level = 42 ,
. nature = NATURE_BRAVE ,
. evs = { 0 , 252 , 252 , 0 , 6 , 0 } ,
. moves = { MOVE_LIGHT_SCREEN , MOVE_PSYCHIC , MOVE_REFLECT , MOVE_METAL_CLAW }
} ,
{
. species = SPECIES_SKARMORY ,
. fixedIV = 31 ,
. level = 43 ,
. nature = NATURE_IMPISH ,
. evs = { 252 , 0 , 0 , 0 , 6 , 252 } ,
. moves = { MOVE_TOXIC , MOVE_AERIAL_ACE , MOVE_PROTECT , MOVE_STEEL_WING }
} ,
{
. species = SPECIES_AGGRON ,
. fixedIV = 31 ,
. level = 44 ,
. nature = NATURE_ADAMANT ,
. evs = { 0 , 252 , 0 , 0 , 252 , 6 } ,
. moves = { MOVE_THUNDER , MOVE_PROTECT , MOVE_SOLAR_BEAM , MOVE_DRAGON_CLAW }
}
} ;
# include "data/battle_frontier/battle_tent.h"
2019-11-16 18:11:27 -05:00
static void ( * const sBattleTowerFuncs [ ] ) ( void ) =
{
2020-01-08 05:43:06 -05:00
[ BATTLE_TOWER_FUNC_INIT ] = InitTowerChallenge ,
[ BATTLE_TOWER_FUNC_GET_DATA ] = GetTowerData ,
[ BATTLE_TOWER_FUNC_SET_DATA ] = SetTowerData ,
[ BATTLE_TOWER_FUNC_SET_OPPONENT ] = SetNextFacilityOpponent ,
[ BATTLE_TOWER_FUNC_SET_BATTLE_WON ] = SetTowerBattleWon ,
[ BATTLE_TOWER_FUNC_GIVE_RIBBONS ] = AwardBattleTowerRibbons ,
[ BATTLE_TOWER_FUNC_SAVE ] = SaveTowerChallenge ,
[ BATTLE_TOWER_FUNC_GET_OPPONENT_INTRO ] = GetOpponentIntroSpeech ,
[ BATTLE_TOWER_FUNC_NOP ] = nullsub_61 ,
[ BATTLE_TOWER_FUNC_NOP2 ] = nullsub_116 ,
[ BATTLE_TOWER_FUNC_LOAD_PARTNERS ] = LoadMultiPartnerCandidatesData ,
[ BATTLE_TOWER_FUNC_PARTNER_MSG ] = ShowPartnerCandidateMessage ,
[ BATTLE_TOWER_FUNC_LOAD_LINK_OPPONENTS ] = LoadLinkMultiOpponentsData ,
[ BATTLE_TOWER_FUNC_13 ] = sub_8164DCC ,
[ BATTLE_TOWER_FUNC_SET_PARTNER_GFX ] = SetMultiPartnerGfx ,
[ BATTLE_TOWER_FUNC_SET_INTERVIEW_DATA ] = SetTowerInterviewData ,
2018-10-25 21:27:10 +02:00
} ;
2019-11-24 16:58:40 -05:00
static const u32 sWinStreakFlags [ ] [ 2 ] =
2018-10-25 21:27:10 +02:00
{
2019-11-24 16:58:40 -05:00
{ STREAK_TOWER_SINGLES_50 , STREAK_TOWER_SINGLES_OPEN } ,
{ STREAK_TOWER_DOUBLES_50 , STREAK_TOWER_DOUBLES_OPEN } ,
{ STREAK_TOWER_MULTIS_50 , STREAK_TOWER_MULTIS_OPEN } ,
{ STREAK_TOWER_LINK_MULTIS_50 , STREAK_TOWER_LINK_MULTIS_OPEN } ,
2018-10-25 21:27:10 +02:00
} ;
2019-11-24 16:58:40 -05:00
static const u32 sWinStreakMasks [ ] [ 2 ] =
2018-10-25 21:27:10 +02:00
{
2019-11-24 16:58:40 -05:00
{ ~ ( STREAK_TOWER_SINGLES_50 ) , ~ ( STREAK_TOWER_SINGLES_OPEN ) } ,
{ ~ ( STREAK_TOWER_DOUBLES_50 ) , ~ ( STREAK_TOWER_DOUBLES_OPEN ) } ,
{ ~ ( STREAK_TOWER_MULTIS_50 ) , ~ ( STREAK_TOWER_MULTIS_OPEN ) } ,
{ ~ ( STREAK_TOWER_LINK_MULTIS_50 ) , ~ ( STREAK_TOWER_LINK_MULTIS_OPEN ) } ,
2018-10-25 21:27:10 +02:00
} ;
2020-01-08 05:43:06 -05:00
// The challenge number at which an Apprentice can appear, depending on how many of their questions were answered
static const u8 sApprenticeChallengeThreshold [ MAX_APPRENTICE_QUESTIONS ] =
2018-10-25 21:27:10 +02:00
{
2020-01-08 05:43:06 -05:00
1 , 2 , 3 , 4 , 5 , 8 , 9 , 10 , 11 , 12
2018-10-25 21:27:10 +02:00
} ;
2019-11-24 16:58:40 -05:00
// Unclear why this was duplicated
static const u8 sBattleTowerPartySizes2 [ ] =
2018-10-25 21:27:10 +02:00
{
2019-11-24 16:58:40 -05:00
[ FRONTIER_MODE_SINGLES ] = FRONTIER_PARTY_SIZE ,
[ FRONTIER_MODE_DOUBLES ] = FRONTIER_DOUBLES_PARTY_SIZE ,
[ FRONTIER_MODE_MULTIS ] = FRONTIER_MULTI_PARTY_SIZE ,
[ FRONTIER_MODE_LINK_MULTIS ] = FRONTIER_MULTI_PARTY_SIZE ,
2018-10-25 21:27:10 +02:00
} ;
2019-12-20 18:52:29 -05:00
// Trainer ID ranges for possible frontier trainers to encounter on particular challenges
// Trainers are scaled by difficulty, so higher trainer IDs have better teams
static const u16 sFrontierTrainerIdRanges [ ] [ 2 ] =
2018-10-25 21:27:10 +02:00
{
2019-12-20 18:52:29 -05:00
{ FRONTIER_TRAINER_BRADY , FRONTIER_TRAINER_JILL } , // 0 - 99
{ FRONTIER_TRAINER_TREVIN , FRONTIER_TRAINER_CHLOE } , // 80 - 119
{ FRONTIER_TRAINER_ERIK , FRONTIER_TRAINER_SOFIA } , // 100 - 139
{ FRONTIER_TRAINER_NORTON , FRONTIER_TRAINER_JAZLYN } , // 120 - 159
{ FRONTIER_TRAINER_BRADEN , FRONTIER_TRAINER_ALISON } , // 140 - 179
{ FRONTIER_TRAINER_ZACHERY , FRONTIER_TRAINER_LAMAR } , // 160 - 199
{ FRONTIER_TRAINER_HANK , FRONTIER_TRAINER_TESS } , // 180 - 219
{ FRONTIER_TRAINER_JAXON , FRONTIER_TRAINER_GRETEL } , // 200 - 299
2018-10-25 21:27:10 +02:00
} ;
2019-12-20 18:52:29 -05:00
static const u16 sFrontierTrainerIdRangesHard [ ] [ 2 ] =
2018-10-25 21:27:10 +02:00
{
2019-12-20 18:52:29 -05:00
{ FRONTIER_TRAINER_ERIK , FRONTIER_TRAINER_CHLOE } , // 100 - 119
{ FRONTIER_TRAINER_NORTON , FRONTIER_TRAINER_SOFIA } , // 120 - 139
{ FRONTIER_TRAINER_BRADEN , FRONTIER_TRAINER_JAZLYN } , // 140 - 159
{ FRONTIER_TRAINER_ZACHERY , FRONTIER_TRAINER_ALISON } , // 160 - 179
{ FRONTIER_TRAINER_HANK , FRONTIER_TRAINER_LAMAR } , // 180 - 199
{ FRONTIER_TRAINER_JAXON , FRONTIER_TRAINER_TESS } , // 200 - 219
{ FRONTIER_TRAINER_LEON , FRONTIER_TRAINER_RAUL } , // 220 - 239
{ FRONTIER_TRAINER_JAXON , FRONTIER_TRAINER_GRETEL } , // 200 - 299
} ;
// Trainer IDs? Don't make sense as part of previous array, min/max relationship reversed and never accessed
static const u16 sUnused_085DFA1A [ ] [ 2 ] =
{
{ 179 , 141 } , // FRONTIER_TRAINER_ALISON - FRONTIER_TRAINER_KAYDEN
{ 200 , 183 } , // FRONTIER_TRAINER_JAXON - FRONTIER_TRAINER_HUNTER
2018-10-25 21:27:10 +02:00
} ;
2019-11-24 16:58:40 -05:00
static const u8 sBattleTowerPartySizes [ FRONTIER_MODE_COUNT ] =
2018-10-25 21:27:10 +02:00
{
2019-11-24 16:58:40 -05:00
[ FRONTIER_MODE_SINGLES ] = FRONTIER_PARTY_SIZE ,
[ FRONTIER_MODE_DOUBLES ] = FRONTIER_DOUBLES_PARTY_SIZE ,
[ FRONTIER_MODE_MULTIS ] = FRONTIER_MULTI_PARTY_SIZE ,
[ FRONTIER_MODE_LINK_MULTIS ] = FRONTIER_MULTI_PARTY_SIZE ,
2018-10-25 21:27:10 +02:00
} ;
2019-11-24 16:58:40 -05:00
static const u16 sRecordTrainerSpeechWon [ ] =
2018-10-25 21:27:10 +02:00
{
2019-11-24 16:58:40 -05:00
EC_WORD_YAY , EC_WORD_YAY , EC_WORD_EXCL_EXCL , EC_WORD_I_VE , EC_WORD_WON , EC_WORD_EXCL_EXCL
2018-10-25 21:27:10 +02:00
} ;
2019-11-24 16:58:40 -05:00
static const u16 sRecordTrainerSpeechLost [ ] =
2018-10-25 21:27:10 +02:00
{
2019-11-24 16:58:40 -05:00
EC_WORD_TOO , EC_WORD_BAD , EC_WORD_ELLIPSIS , EC_WORD_WE , EC_WORD_LOST , EC_WORD_ELLIPSIS
2018-10-25 21:27:10 +02:00
} ;
2018-08-26 17:54:58 +02:00
// code
2019-11-16 18:11:27 -05:00
void CallBattleTowerFunc ( void )
2018-08-26 17:54:58 +02:00
{
2019-11-16 18:11:27 -05:00
sBattleTowerFuncs [ gSpecialVar_0x8004 ] ( ) ;
2018-08-26 17:54:58 +02:00
}
2019-11-28 21:09:35 -05:00
static void InitTowerChallenge ( void )
2018-08-26 17:54:58 +02:00
{
u32 lvlMode = gSaveBlock2Ptr - > frontier . lvlMode ;
u32 battleMode = VarGet ( VAR_FRONTIER_BATTLE_MODE ) ;
2019-11-24 16:58:40 -05:00
gSaveBlock2Ptr - > frontier . challengeStatus = CHALLENGE_STATUS_SAVING ;
2018-10-21 00:06:42 +02:00
gSaveBlock2Ptr - > frontier . curChallengeBattleNum = 0 ;
2019-11-24 16:58:40 -05:00
gSaveBlock2Ptr - > frontier . challengePaused = FALSE ;
2020-01-08 05:43:06 -05:00
gSaveBlock2Ptr - > frontier . disableRecordBattle = FALSE ;
2019-11-24 16:58:40 -05:00
ResetFrontierTrainerIds ( ) ;
if ( ! ( gSaveBlock2Ptr - > frontier . winStreakActiveFlags & sWinStreakFlags [ battleMode ] [ lvlMode ] ) )
2018-10-27 17:39:05 +02:00
gSaveBlock2Ptr - > frontier . towerWinStreaks [ battleMode ] [ lvlMode ] = 0 ;
2018-08-26 17:54:58 +02:00
2018-10-22 19:22:57 +02:00
ValidateBattleTowerRecordChecksums ( ) ;
2018-12-27 16:30:47 -06:00
SetDynamicWarp ( 0 , gSaveBlock1Ptr - > location . mapGroup , gSaveBlock1Ptr - > location . mapNum , - 1 ) ;
2018-08-26 17:54:58 +02:00
gTrainerBattleOpponent_A = 0 ;
}
2019-11-28 21:09:35 -05:00
static void GetTowerData ( void )
2018-08-26 17:54:58 +02:00
{
u32 lvlMode = gSaveBlock2Ptr - > frontier . lvlMode ;
u32 battleMode = VarGet ( VAR_FRONTIER_BATTLE_MODE ) ;
switch ( gSpecialVar_0x8005 )
{
case 0 :
break ;
2019-11-28 22:46:39 -05:00
case TOWER_DATA_WIN_STREAK :
2018-10-20 00:33:51 +02:00
gSpecialVar_Result = GetCurrentBattleTowerWinStreak ( lvlMode , battleMode ) ;
2018-08-26 17:54:58 +02:00
break ;
2019-11-28 22:46:39 -05:00
case TOWER_DATA_WIN_STREAK_ACTIVE :
2019-11-24 16:58:40 -05:00
gSpecialVar_Result = ( ( gSaveBlock2Ptr - > frontier . winStreakActiveFlags & sWinStreakFlags [ battleMode ] [ lvlMode ] ) ! = 0 ) ;
2018-08-26 17:54:58 +02:00
break ;
2019-11-28 22:46:39 -05:00
case TOWER_DATA_LVL_MODE :
2019-11-24 16:58:40 -05:00
gSaveBlock2Ptr - > frontier . towerLvlMode = gSaveBlock2Ptr - > frontier . lvlMode ;
2018-08-26 17:54:58 +02:00
break ;
}
}
2019-11-28 21:09:35 -05:00
static void SetTowerData ( void )
2018-08-26 17:54:58 +02:00
{
u32 lvlMode = gSaveBlock2Ptr - > frontier . lvlMode ;
u32 battleMode = VarGet ( VAR_FRONTIER_BATTLE_MODE ) ;
switch ( gSpecialVar_0x8005 )
{
case 0 :
break ;
2019-11-28 22:46:39 -05:00
case TOWER_DATA_WIN_STREAK :
2018-10-27 17:39:05 +02:00
gSaveBlock2Ptr - > frontier . towerWinStreaks [ battleMode ] [ lvlMode ] = gSpecialVar_0x8006 ;
2018-08-26 17:54:58 +02:00
break ;
2019-11-28 22:46:39 -05:00
case TOWER_DATA_WIN_STREAK_ACTIVE :
2018-08-26 17:54:58 +02:00
if ( gSpecialVar_0x8006 )
2019-11-24 16:58:40 -05:00
gSaveBlock2Ptr - > frontier . winStreakActiveFlags | = sWinStreakFlags [ battleMode ] [ lvlMode ] ;
2018-08-26 17:54:58 +02:00
else
2019-11-24 16:58:40 -05:00
gSaveBlock2Ptr - > frontier . winStreakActiveFlags & = sWinStreakMasks [ battleMode ] [ lvlMode ] ;
2018-08-26 17:54:58 +02:00
break ;
2019-11-28 22:46:39 -05:00
case TOWER_DATA_LVL_MODE :
2019-11-24 16:58:40 -05:00
gSaveBlock2Ptr - > frontier . towerLvlMode = gSaveBlock2Ptr - > frontier . lvlMode ;
2018-08-26 17:54:58 +02:00
break ;
}
}
2018-10-20 00:33:51 +02:00
2019-11-28 22:46:39 -05:00
static void SetTowerBattleWon ( void )
2018-10-20 00:33:51 +02:00
{
2018-10-26 23:54:41 +02:00
if ( gTrainerBattleOpponent_A = = TRAINER_EREADER )
2018-10-22 19:22:57 +02:00
ClearEReaderTrainer ( & gSaveBlock2Ptr - > frontier . ereaderTrainer ) ;
2018-10-20 00:33:51 +02:00
2019-11-28 22:46:39 -05:00
// towerNumWins is never read outside this conditional
2019-11-24 16:58:40 -05:00
if ( gSaveBlock2Ptr - > frontier . towerNumWins < MAX_STREAK )
gSaveBlock2Ptr - > frontier . towerNumWins + + ;
2018-10-20 00:33:51 +02:00
2018-10-21 00:06:42 +02:00
gSaveBlock2Ptr - > frontier . curChallengeBattleNum + + ;
2018-10-21 20:13:12 +02:00
SaveCurrentWinStreak ( ) ;
2018-10-21 00:06:42 +02:00
gSpecialVar_Result = gSaveBlock2Ptr - > frontier . curChallengeBattleNum ;
2018-10-20 00:33:51 +02:00
}
2018-10-25 21:27:10 +02:00
static bool8 ChooseSpecialBattleTowerTrainer ( void )
2018-10-20 00:33:51 +02:00
{
s32 i , j , validMons ;
s32 trainerIds [ 9 ] ;
s32 idsCount = 0 ;
s32 winStreak = 0 ;
u8 lvlMode = gSaveBlock2Ptr - > frontier . lvlMode ;
u8 battleMode = VarGet ( VAR_FRONTIER_BATTLE_MODE ) ;
if ( VarGet ( VAR_FRONTIER_FACILITY ) ! = FRONTIER_FACILITY_TOWER )
return FALSE ;
winStreak = GetCurrentBattleTowerWinStreak ( lvlMode , battleMode ) ;
for ( i = 0 ; i < 5 ; i + + )
{
2018-10-21 20:13:12 +02:00
u32 * record = ( u32 * ) ( & gSaveBlock2Ptr - > frontier . towerRecords [ i ] ) ;
2018-10-20 00:33:51 +02:00
u32 recordHasData = 0 ;
u32 checksum = 0 ;
for ( j = 0 ; j < ( sizeof ( struct EmeraldBattleTowerRecord ) - 4 ) / 4 ; j + + ) // - 4, because of the last field being the checksum itself.
{
recordHasData | = record [ j ] ;
checksum + = record [ j ] ;
}
validMons = 0 ;
for ( j = 0 ; j < 4 ; j + + )
{
2018-10-21 20:13:12 +02:00
if ( gSaveBlock2Ptr - > frontier . towerRecords [ i ] . party [ j ] . species ! = 0
& & gSaveBlock2Ptr - > frontier . towerRecords [ i ] . party [ j ] . level < = GetFrontierEnemyMonLevel ( lvlMode ) )
2018-10-20 00:33:51 +02:00
validMons + + ;
}
2019-11-24 16:58:40 -05:00
if ( validMons > = sBattleTowerPartySizes2 [ battleMode ]
2018-10-21 20:13:12 +02:00
& & gSaveBlock2Ptr - > frontier . towerRecords [ i ] . winStreak = = winStreak
& & gSaveBlock2Ptr - > frontier . towerRecords [ i ] . lvlMode = = lvlMode
2018-10-20 00:33:51 +02:00
& & recordHasData
2018-10-21 20:13:12 +02:00
& & gSaveBlock2Ptr - > frontier . towerRecords [ i ] . checksum = = checksum )
2018-10-20 00:33:51 +02:00
{
2018-10-26 23:54:41 +02:00
trainerIds [ idsCount ] = i + TRAINER_RECORD_MIXING_FRIEND ;
2018-10-20 00:33:51 +02:00
idsCount + + ;
}
}
if ( battleMode = = FRONTIER_MODE_SINGLES )
{
2018-10-24 23:14:45 +02:00
ValidateApprenticesChecksums ( ) ;
2019-11-20 17:36:52 -05:00
for ( i = 0 ; i < APPRENTICE_COUNT ; i + + )
2018-10-20 00:33:51 +02:00
{
if ( gSaveBlock2Ptr - > apprentices [ i ] . lvlMode ! = 0
2020-01-08 05:43:06 -05:00
& & sApprenticeChallengeThreshold [ gSaveBlock2Ptr - > apprentices [ i ] . numQuestions ] = = winStreak
2018-10-20 00:33:51 +02:00
& & gSaveBlock2Ptr - > apprentices [ i ] . lvlMode - 1 = = lvlMode )
{
2018-10-26 23:54:41 +02:00
trainerIds [ idsCount ] = i + TRAINER_RECORD_MIXING_APPRENTICE ;
2018-10-20 00:33:51 +02:00
idsCount + + ;
}
}
}
if ( idsCount ! = 0 )
{
gTrainerBattleOpponent_A = trainerIds [ Random ( ) % idsCount ] ;
return TRUE ;
}
else
{
return FALSE ;
}
}
2018-10-21 00:06:42 +02:00
2019-11-28 22:46:39 -05:00
static void SetNextFacilityOpponent ( void )
2018-10-21 00:06:42 +02:00
{
u32 lvlMode = gSaveBlock2Ptr - > frontier . lvlMode ;
if ( lvlMode = = FRONTIER_LVL_TENT )
{
2019-11-28 22:46:39 -05:00
SetNextBattleTentOpponent ( ) ;
2018-10-21 00:06:42 +02:00
}
else
{
u16 id ;
u32 battleMode = VarGet ( VAR_FRONTIER_BATTLE_MODE ) ;
2018-10-27 21:01:35 +02:00
u16 winStreak = GetCurrentFacilityWinStreak ( ) ;
u32 challengeNum = winStreak / 7 ;
2018-10-24 23:14:45 +02:00
SetFacilityPtrsGetLevel ( ) ;
2018-10-21 00:06:42 +02:00
if ( battleMode = = FRONTIER_MODE_MULTIS | | battleMode = = FRONTIER_MODE_LINK_MULTIS )
{
id = gSaveBlock2Ptr - > frontier . curChallengeBattleNum ;
2019-02-07 11:37:28 -06:00
gTrainerBattleOpponent_A = gSaveBlock2Ptr - > frontier . trainerIds [ id * 2 ] ;
gTrainerBattleOpponent_B = gSaveBlock2Ptr - > frontier . trainerIds [ id * 2 + 1 ] ;
2018-10-21 00:06:42 +02:00
SetBattleFacilityTrainerGfxId ( gTrainerBattleOpponent_A , 0 ) ;
SetBattleFacilityTrainerGfxId ( gTrainerBattleOpponent_B , 1 ) ;
}
else if ( ChooseSpecialBattleTowerTrainer ( ) )
{
SetBattleFacilityTrainerGfxId ( gTrainerBattleOpponent_A , 0 ) ;
2019-02-07 11:37:28 -06:00
gSaveBlock2Ptr - > frontier . trainerIds [ gSaveBlock2Ptr - > frontier . curChallengeBattleNum ] = gTrainerBattleOpponent_A ;
2018-10-21 00:06:42 +02:00
}
else
{
s32 i ;
while ( 1 )
{
2019-12-20 18:52:29 -05:00
id = GetRandomScaledFrontierTrainerId ( challengeNum , gSaveBlock2Ptr - > frontier . curChallengeBattleNum ) ;
2018-10-21 00:06:42 +02:00
// Ensure trainer wasn't previously fought in this challenge.
for ( i = 0 ; i < gSaveBlock2Ptr - > frontier . curChallengeBattleNum ; i + + )
{
2019-02-07 11:37:28 -06:00
if ( gSaveBlock2Ptr - > frontier . trainerIds [ i ] = = id )
2018-10-21 00:06:42 +02:00
break ;
}
if ( i = = gSaveBlock2Ptr - > frontier . curChallengeBattleNum )
break ;
}
gTrainerBattleOpponent_A = id ;
SetBattleFacilityTrainerGfxId ( gTrainerBattleOpponent_A , 0 ) ;
if ( gSaveBlock2Ptr - > frontier . curChallengeBattleNum + 1 < 7 )
2019-02-07 11:37:28 -06:00
gSaveBlock2Ptr - > frontier . trainerIds [ gSaveBlock2Ptr - > frontier . curChallengeBattleNum ] = gTrainerBattleOpponent_A ;
2018-10-21 00:06:42 +02:00
}
}
}
2019-12-20 18:52:29 -05:00
u16 GetRandomScaledFrontierTrainerId ( u8 challengeNum , u8 battleNum )
2018-10-21 00:06:42 +02:00
{
u16 trainerId ;
if ( challengeNum < = 7 )
{
if ( battleNum = = 6 )
{
2019-12-20 18:52:29 -05:00
// The last battle in each challenge has a jump in difficulty, pulls from a table with higher ranges
trainerId = ( sFrontierTrainerIdRangesHard [ challengeNum ] [ 1 ] - sFrontierTrainerIdRangesHard [ challengeNum ] [ 0 ] ) + 1 ;
trainerId = sFrontierTrainerIdRangesHard [ challengeNum ] [ 0 ] + ( Random ( ) % trainerId ) ;
2018-10-21 00:06:42 +02:00
}
else
{
2019-12-20 18:52:29 -05:00
trainerId = ( sFrontierTrainerIdRanges [ challengeNum ] [ 1 ] - sFrontierTrainerIdRanges [ challengeNum ] [ 0 ] ) + 1 ;
trainerId = sFrontierTrainerIdRanges [ challengeNum ] [ 0 ] + ( Random ( ) % trainerId ) ;
2018-10-21 00:06:42 +02:00
}
}
else
{
2019-12-20 18:52:29 -05:00
// After challenge 7, trainer IDs always come from the last, hardest range, which is the same for both trainer ID tables
trainerId = ( sFrontierTrainerIdRanges [ 7 ] [ 1 ] - sFrontierTrainerIdRanges [ 7 ] [ 0 ] ) + 1 ;
trainerId = sFrontierTrainerIdRanges [ 7 ] [ 0 ] + ( Random ( ) % trainerId ) ;
2018-10-21 00:06:42 +02:00
}
return trainerId ;
}
2019-12-20 18:52:29 -05:00
// Unused
static void GetRandomScaledFrontierTrainerIdRange ( u8 challengeNum , u8 battleNum , u16 * trainerIdPtr , u8 * rangePtr )
2018-10-21 00:06:42 +02:00
{
2019-12-20 18:52:29 -05:00
u16 trainerId , range ;
2018-10-21 00:06:42 +02:00
if ( challengeNum < = 7 )
{
if ( battleNum = = 6 )
{
2019-12-20 18:52:29 -05:00
// The last battle in each challenge has a jump in difficulty, pulls from a table with higher ranges
range = ( sFrontierTrainerIdRangesHard [ challengeNum ] [ 1 ] - sFrontierTrainerIdRangesHard [ challengeNum ] [ 0 ] ) + 1 ;
trainerId = sFrontierTrainerIdRangesHard [ challengeNum ] [ 0 ] ;
2018-10-21 00:06:42 +02:00
}
else
{
2019-12-20 18:52:29 -05:00
range = ( sFrontierTrainerIdRanges [ challengeNum ] [ 1 ] - sFrontierTrainerIdRanges [ challengeNum ] [ 0 ] ) + 1 ;
trainerId = sFrontierTrainerIdRanges [ challengeNum ] [ 0 ] ;
2018-10-21 00:06:42 +02:00
}
}
else
{
2019-12-20 18:52:29 -05:00
// After challenge 7, trainer IDs always come from the last, hardest range, which is the same for both trainer ID tables
range = ( sFrontierTrainerIdRanges [ 7 ] [ 1 ] - sFrontierTrainerIdRanges [ 7 ] [ 0 ] ) + 1 ;
trainerId = sFrontierTrainerIdRanges [ 7 ] [ 0 ] ;
2018-10-21 00:06:42 +02:00
}
* trainerIdPtr = trainerId ;
2019-12-20 18:52:29 -05:00
* rangePtr = range ;
2018-10-21 00:06:42 +02:00
}
void SetBattleFacilityTrainerGfxId ( u16 trainerId , u8 tempVarId )
{
u32 i ;
u8 facilityClass ;
u8 trainerObjectGfxId ;
2018-10-24 23:14:45 +02:00
SetFacilityPtrsGetLevel ( ) ;
2018-10-26 23:54:41 +02:00
if ( trainerId = = TRAINER_EREADER )
2018-10-21 00:06:42 +02:00
{
facilityClass = gSaveBlock2Ptr - > frontier . ereaderTrainer . facilityClass ;
}
else if ( trainerId = = TRAINER_FRONTIER_BRAIN )
{
2019-11-21 00:14:40 -05:00
SetFrontierBrainObjEventGfx_2 ( ) ;
2018-10-21 00:06:42 +02:00
return ;
}
2019-12-20 18:52:29 -05:00
else if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-21 00:06:42 +02:00
{
facilityClass = gFacilityTrainers [ trainerId ] . facilityClass ;
}
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
2018-10-21 00:06:42 +02:00
{
2018-10-26 23:54:41 +02:00
facilityClass = gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . facilityClass ;
2018-10-21 00:06:42 +02:00
}
else
{
2018-10-26 23:54:41 +02:00
facilityClass = gApprentices [ gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . id ] . facilityClass ;
2018-10-21 00:06:42 +02:00
}
// Search male classes.
for ( i = 0 ; i < ARRAY_COUNT ( gTowerMaleFacilityClasses ) ; i + + )
{
if ( gTowerMaleFacilityClasses [ i ] = = facilityClass )
break ;
}
if ( i ! = ARRAY_COUNT ( gTowerMaleFacilityClasses ) )
{
trainerObjectGfxId = gTowerMaleTrainerGfxIds [ i ] ;
switch ( tempVarId )
{
case 0 :
default :
VarSet ( VAR_OBJ_GFX_ID_0 , trainerObjectGfxId ) ;
return ;
case 1 :
VarSet ( VAR_OBJ_GFX_ID_1 , trainerObjectGfxId ) ;
return ;
case 15 :
VarSet ( VAR_OBJ_GFX_ID_E , trainerObjectGfxId ) ;
return ;
}
}
// Search female classes.
for ( i = 0 ; i < ARRAY_COUNT ( gTowerFemaleFacilityClasses ) ; i + + )
{
if ( gTowerFemaleFacilityClasses [ i ] = = facilityClass )
break ;
}
if ( i ! = ARRAY_COUNT ( gTowerFemaleFacilityClasses ) )
{
trainerObjectGfxId = gTowerFemaleTrainerGfxIds [ i ] ;
switch ( tempVarId )
{
case 0 :
default :
VarSet ( VAR_OBJ_GFX_ID_0 , trainerObjectGfxId ) ;
return ;
case 1 :
VarSet ( VAR_OBJ_GFX_ID_1 , trainerObjectGfxId ) ;
return ;
case 15 :
VarSet ( VAR_OBJ_GFX_ID_E , trainerObjectGfxId ) ;
return ;
}
}
switch ( tempVarId )
{
case 0 :
default :
2019-11-20 23:12:51 -05:00
VarSet ( VAR_OBJ_GFX_ID_0 , OBJ_EVENT_GFX_BOY_1 ) ;
2018-10-21 00:06:42 +02:00
return ;
case 1 :
2019-11-20 23:12:51 -05:00
VarSet ( VAR_OBJ_GFX_ID_1 , OBJ_EVENT_GFX_BOY_1 ) ;
2018-10-21 00:06:42 +02:00
return ;
case 15 :
2019-11-20 23:12:51 -05:00
VarSet ( VAR_OBJ_GFX_ID_E , OBJ_EVENT_GFX_BOY_1 ) ;
2018-10-21 00:06:42 +02:00
return ;
}
}
void SetEReaderTrainerGfxId ( void )
{
2018-10-26 23:54:41 +02:00
SetBattleFacilityTrainerGfxId ( TRAINER_EREADER , 0 ) ;
2018-10-21 00:06:42 +02:00
}
u8 GetBattleFacilityTrainerGfxId ( u16 trainerId )
{
u32 i ;
u8 facilityClass ;
u8 trainerObjectGfxId ;
2018-10-24 23:14:45 +02:00
SetFacilityPtrsGetLevel ( ) ;
2018-10-26 23:54:41 +02:00
if ( trainerId = = TRAINER_EREADER )
2018-10-21 00:06:42 +02:00
{
facilityClass = gSaveBlock2Ptr - > frontier . ereaderTrainer . facilityClass ;
}
2019-12-20 18:52:29 -05:00
else if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-21 00:06:42 +02:00
{
facilityClass = gFacilityTrainers [ trainerId ] . facilityClass ;
}
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
2018-10-21 00:06:42 +02:00
{
2018-10-26 23:54:41 +02:00
facilityClass = gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . facilityClass ;
2018-10-21 00:06:42 +02:00
}
else
{
2018-10-26 23:54:41 +02:00
facilityClass = gApprentices [ gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . id ] . facilityClass ;
2018-10-21 00:06:42 +02:00
}
// Search male classes.
for ( i = 0 ; i < ARRAY_COUNT ( gTowerMaleFacilityClasses ) ; i + + )
{
if ( gTowerMaleFacilityClasses [ i ] = = facilityClass )
break ;
}
if ( i ! = ARRAY_COUNT ( gTowerMaleFacilityClasses ) )
{
trainerObjectGfxId = gTowerMaleTrainerGfxIds [ i ] ;
return trainerObjectGfxId ;
}
// Search female classes.
for ( i = 0 ; i < ARRAY_COUNT ( gTowerFemaleFacilityClasses ) ; i + + )
{
if ( gTowerFemaleFacilityClasses [ i ] = = facilityClass )
break ;
}
if ( i ! = ARRAY_COUNT ( gTowerFemaleFacilityClasses ) )
{
trainerObjectGfxId = gTowerFemaleTrainerGfxIds [ i ] ;
return trainerObjectGfxId ;
}
else
{
2019-11-20 23:12:51 -05:00
return OBJ_EVENT_GFX_BOY_1 ;
2018-10-21 00:06:42 +02:00
}
}
2018-10-22 19:22:57 +02:00
void PutNewBattleTowerRecord ( struct EmeraldBattleTowerRecord * newRecordEm )
2018-10-21 00:06:42 +02:00
{
u16 slotValues [ 6 ] ;
u16 slotIds [ 6 ] ;
s32 i , j , k ;
s32 slotsCount = 0 ;
2018-10-22 19:22:57 +02:00
struct EmeraldBattleTowerRecord * newRecord = newRecordEm ; // Needed to match.
2018-10-21 00:06:42 +02:00
// Find a record slot of the same player and replace it.
for ( i = 0 ; i < 5 ; i + + )
{
k = 0 ;
2019-09-08 11:53:48 -04:00
for ( j = 0 ; j < TRAINER_ID_LENGTH ; j + + )
2018-10-21 00:06:42 +02:00
{
2018-10-22 19:22:57 +02:00
if ( gSaveBlock2Ptr - > frontier . towerRecords [ i ] . trainerId [ j ] ! = newRecord - > trainerId [ j ] )
2018-10-21 00:06:42 +02:00
break ;
}
if ( j = = 4 )
{
for ( k = 0 ; k < PLAYER_NAME_LENGTH ; k + + )
{
// BUG: Wrong variable used, 'j' instead of 'k'.
2018-10-22 19:22:57 +02:00
if ( gSaveBlock2Ptr - > frontier . towerRecords [ i ] . name [ j ] ! = newRecord - > name [ j ] )
2018-10-21 00:06:42 +02:00
break ;
2018-10-22 19:22:57 +02:00
if ( newRecord - > name [ j ] = = EOS )
2018-10-21 00:06:42 +02:00
{
k = PLAYER_NAME_LENGTH ;
break ;
}
}
}
if ( k = = PLAYER_NAME_LENGTH )
break ;
}
if ( i < 5 )
{
2018-10-22 19:22:57 +02:00
gSaveBlock2Ptr - > frontier . towerRecords [ i ] = * newRecord ;
2018-10-21 00:06:42 +02:00
return ;
}
// Find an empty record slot.
for ( i = 0 ; i < 5 ; i + + )
{
2018-10-21 20:13:12 +02:00
if ( gSaveBlock2Ptr - > frontier . towerRecords [ i ] . winStreak = = 0 )
2018-10-21 00:06:42 +02:00
break ;
}
if ( i < 5 )
{
2018-10-22 19:22:57 +02:00
gSaveBlock2Ptr - > frontier . towerRecords [ i ] = * newRecord ;
2018-10-21 00:06:42 +02:00
return ;
}
// Find possible slots to replace the record.
2018-10-21 20:13:12 +02:00
slotValues [ 0 ] = gSaveBlock2Ptr - > frontier . towerRecords [ 0 ] . winStreak ;
2018-10-21 00:06:42 +02:00
slotIds [ 0 ] = 0 ;
slotsCount + + ;
for ( i = 1 ; i < 5 ; i + + )
{
for ( j = 0 ; j < slotsCount ; j + + )
{
2018-10-21 20:13:12 +02:00
if ( gSaveBlock2Ptr - > frontier . towerRecords [ i ] . winStreak < slotValues [ j ] )
2018-10-21 00:06:42 +02:00
{
j = 0 ;
slotsCount = 1 ;
2018-10-21 20:13:12 +02:00
slotValues [ 0 ] = gSaveBlock2Ptr - > frontier . towerRecords [ i ] . winStreak ;
2018-10-21 00:06:42 +02:00
slotIds [ 0 ] = i ;
break ;
}
2018-10-21 20:13:12 +02:00
else if ( gSaveBlock2Ptr - > frontier . towerRecords [ i ] . winStreak > slotValues [ j ] )
2018-10-21 00:06:42 +02:00
{
break ;
}
}
if ( j = = slotsCount )
{
2018-10-21 20:13:12 +02:00
slotValues [ slotsCount ] = gSaveBlock2Ptr - > frontier . towerRecords [ i ] . winStreak ;
2018-10-21 00:06:42 +02:00
slotIds [ slotsCount ] = i ;
slotsCount + + ;
}
}
i = Random ( ) % slotsCount ;
2018-10-22 19:22:57 +02:00
gSaveBlock2Ptr - > frontier . towerRecords [ slotIds [ i ] ] = * newRecord ;
2018-10-21 00:06:42 +02:00
}
u8 GetFrontierTrainerFrontSpriteId ( u16 trainerId )
{
2018-10-25 21:27:10 +02:00
SetFacilityPtrsGetLevel ( ) ;
2018-10-21 00:06:42 +02:00
2018-10-26 23:54:41 +02:00
if ( trainerId = = TRAINER_EREADER )
2018-10-21 00:06:42 +02:00
{
return gFacilityClassToPicIndex [ gSaveBlock2Ptr - > frontier . ereaderTrainer . facilityClass ] ;
}
else if ( trainerId = = TRAINER_FRONTIER_BRAIN )
{
return GetFrontierBrainTrainerPicIndex ( ) ;
}
2019-12-20 18:52:29 -05:00
else if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-21 00:06:42 +02:00
{
return gFacilityClassToPicIndex [ gFacilityTrainers [ trainerId ] . facilityClass ] ;
}
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
2018-10-21 00:06:42 +02:00
{
if ( gBattleTypeFlags & BATTLE_TYPE_RECORDED )
2018-11-01 15:06:50 +01:00
return gFacilityClassToPicIndex [ GetRecordedBattleRecordMixFriendClass ( ) ] ;
2018-10-21 00:06:42 +02:00
else
2018-10-26 23:54:41 +02:00
return gFacilityClassToPicIndex [ gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . facilityClass ] ;
2018-10-21 00:06:42 +02:00
}
else
{
if ( gBattleTypeFlags & BATTLE_TYPE_RECORDED )
2018-11-01 15:06:50 +01:00
return gFacilityClassToPicIndex [ gApprentices [ GetRecordedBattleApprenticeId ( ) ] . facilityClass ] ;
2018-10-21 00:06:42 +02:00
else
2018-10-26 23:54:41 +02:00
return gFacilityClassToPicIndex [ gApprentices [ gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . id ] . facilityClass ] ;
2018-10-21 00:06:42 +02:00
}
}
u8 GetFrontierOpponentClass ( u16 trainerId )
{
u8 trainerClass = 0 ;
2018-10-24 23:14:45 +02:00
SetFacilityPtrsGetLevel ( ) ;
2018-10-21 00:06:42 +02:00
2018-10-26 23:54:41 +02:00
if ( trainerId = = TRAINER_EREADER )
2018-10-21 00:06:42 +02:00
{
trainerClass = gFacilityClassToTrainerClass [ gSaveBlock2Ptr - > frontier . ereaderTrainer . facilityClass ] ;
}
else if ( trainerId = = TRAINER_FRONTIER_BRAIN )
{
2020-09-09 11:21:16 -04:00
return GetFrontierBrainTrainerClass ( ) ; // This sticks out like a sore thumb, but this is the only other way that matches. Maybe it SHOULD be assigned to ret, or all early returns. I don't know.
2018-10-21 00:06:42 +02:00
}
else if ( trainerId = = TRAINER_STEVEN_PARTNER )
{
trainerClass = gTrainers [ TRAINER_STEVEN ] . trainerClass ;
}
2019-12-20 18:52:29 -05:00
else if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-21 00:06:42 +02:00
{
trainerClass = gFacilityClassToTrainerClass [ gFacilityTrainers [ trainerId ] . facilityClass ] ;
}
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
2018-10-21 00:06:42 +02:00
{
if ( gBattleTypeFlags & BATTLE_TYPE_RECORDED )
{
2018-11-01 15:06:50 +01:00
trainerClass = gFacilityClassToTrainerClass [ GetRecordedBattleRecordMixFriendClass ( ) ] ;
2018-10-21 00:06:42 +02:00
}
else
{
2018-10-26 23:54:41 +02:00
trainerClass = gFacilityClassToTrainerClass [ gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . facilityClass ] ;
2018-10-21 00:06:42 +02:00
}
}
else
{
if ( gBattleTypeFlags & BATTLE_TYPE_RECORDED )
{
2018-11-01 15:06:50 +01:00
trainerClass = gFacilityClassToTrainerClass [ gApprentices [ GetRecordedBattleApprenticeId ( ) ] . facilityClass ] ;
2018-10-21 00:06:42 +02:00
}
else
{
2018-10-26 23:54:41 +02:00
trainerClass = gFacilityClassToTrainerClass [ gApprentices [ gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . id ] . facilityClass ] ;
2018-10-21 00:06:42 +02:00
}
}
return trainerClass ;
}
2018-10-25 21:27:10 +02:00
static u8 GetFrontierTrainerFacilityClass ( u16 trainerId )
2018-10-21 00:06:42 +02:00
{
u8 facilityClass ;
2018-10-24 23:14:45 +02:00
SetFacilityPtrsGetLevel ( ) ;
2018-10-21 00:06:42 +02:00
2018-10-26 23:54:41 +02:00
if ( trainerId = = TRAINER_EREADER )
2018-10-21 00:06:42 +02:00
{
facilityClass = gSaveBlock2Ptr - > frontier . ereaderTrainer . facilityClass ;
}
2019-12-20 18:52:29 -05:00
else if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-21 00:06:42 +02:00
{
facilityClass = gFacilityTrainers [ trainerId ] . facilityClass ;
}
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
2018-10-21 00:06:42 +02:00
{
if ( gBattleTypeFlags & BATTLE_TYPE_RECORDED )
2018-11-01 15:06:50 +01:00
facilityClass = GetRecordedBattleRecordMixFriendClass ( ) ;
2018-10-21 00:06:42 +02:00
else
2018-10-26 23:54:41 +02:00
facilityClass = gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . facilityClass ;
2018-10-21 00:06:42 +02:00
}
else
{
if ( gBattleTypeFlags & BATTLE_TYPE_RECORDED )
2018-11-01 15:06:50 +01:00
facilityClass = gApprentices [ GetRecordedBattleApprenticeId ( ) ] . facilityClass ;
2018-10-21 00:06:42 +02:00
else
2018-10-26 23:54:41 +02:00
facilityClass = gApprentices [ gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . id ] . facilityClass ;
2018-10-21 00:06:42 +02:00
}
return facilityClass ;
}
void GetFrontierTrainerName ( u8 * dst , u16 trainerId )
{
s32 i = 0 ;
2018-10-24 23:14:45 +02:00
SetFacilityPtrsGetLevel ( ) ;
2018-10-21 00:06:42 +02:00
2018-10-26 23:54:41 +02:00
if ( trainerId = = TRAINER_EREADER )
2018-10-21 00:06:42 +02:00
{
for ( i = 0 ; i < PLAYER_NAME_LENGTH ; i + + )
dst [ i ] = gSaveBlock2Ptr - > frontier . ereaderTrainer . name [ i ] ;
}
else if ( trainerId = = TRAINER_FRONTIER_BRAIN )
{
CopyFrontierBrainTrainerName ( dst ) ;
return ;
}
else if ( trainerId = = TRAINER_STEVEN_PARTNER )
{
for ( i = 0 ; i < PLAYER_NAME_LENGTH ; i + + )
dst [ i ] = gTrainers [ TRAINER_STEVEN ] . trainerName [ i ] ;
}
2019-12-20 18:52:29 -05:00
else if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-21 00:06:42 +02:00
{
for ( i = 0 ; i < PLAYER_NAME_LENGTH ; i + + )
dst [ i ] = gFacilityTrainers [ trainerId ] . trainerName [ i ] ;
}
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
2018-10-21 00:06:42 +02:00
{
if ( gBattleTypeFlags & BATTLE_TYPE_RECORDED )
{
sub_8186468 ( dst ) ;
return ;
}
else
{
2018-10-26 23:54:41 +02:00
struct EmeraldBattleTowerRecord * record = & gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] ;
2018-10-21 00:06:42 +02:00
TVShowConvertInternationalString ( dst , record - > name , record - > language ) ;
return ;
}
}
else
{
u8 id , language ;
if ( gBattleTypeFlags & BATTLE_TYPE_RECORDED )
{
2018-11-01 15:06:50 +01:00
id = GetRecordedBattleApprenticeId ( ) ;
language = GetRecordedBattleApprenticeLanguage ( ) ;
2018-10-21 00:06:42 +02:00
}
else
{
2018-10-26 23:54:41 +02:00
struct Apprentice * apprentice = & gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] ;
2018-10-21 00:06:42 +02:00
id = apprentice - > id ;
language = apprentice - > language ;
}
TVShowConvertInternationalString ( dst , GetApprenticeNameInLanguage ( id , language ) , language ) ;
return ;
}
dst [ i ] = EOS ;
}
2018-10-25 21:27:10 +02:00
static bool8 IsFrontierTrainerFemale ( u16 trainerId )
2018-10-21 00:06:42 +02:00
{
u32 i ;
u8 facilityClass ;
2018-10-24 23:14:45 +02:00
SetFacilityPtrsGetLevel ( ) ;
2018-10-26 23:54:41 +02:00
if ( trainerId = = TRAINER_EREADER )
2018-10-21 00:06:42 +02:00
{
facilityClass = gSaveBlock2Ptr - > frontier . ereaderTrainer . facilityClass ;
}
else if ( trainerId = = TRAINER_FRONTIER_BRAIN )
{
return IsFrontierBrainFemale ( ) ;
}
2019-12-20 18:52:29 -05:00
else if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-21 00:06:42 +02:00
{
facilityClass = gFacilityTrainers [ trainerId ] . facilityClass ;
}
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
2018-10-21 00:06:42 +02:00
{
2018-10-26 23:54:41 +02:00
facilityClass = gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . facilityClass ;
2018-10-21 00:06:42 +02:00
}
else
{
2018-10-26 23:54:41 +02:00
facilityClass = gApprentices [ gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . id ] . facilityClass ;
2018-10-21 00:06:42 +02:00
}
// Search female classes.
for ( i = 0 ; i < ARRAY_COUNT ( gTowerFemaleFacilityClasses ) ; i + + )
{
if ( gTowerFemaleFacilityClasses [ i ] = = facilityClass )
break ;
}
if ( i ! = ARRAY_COUNT ( gTowerFemaleFacilityClasses ) )
return TRUE ;
else
return FALSE ;
}
2018-10-22 19:22:57 +02:00
void FillFrontierTrainerParty ( u8 monsCount )
2018-10-21 00:06:42 +02:00
{
ZeroEnemyPartyMons ( ) ;
2018-10-22 19:22:57 +02:00
FillTrainerParty ( gTrainerBattleOpponent_A , 0 , monsCount ) ;
2018-10-21 00:06:42 +02:00
}
2018-10-22 19:22:57 +02:00
void FillFrontierTrainersParties ( u8 monsCount )
2018-10-21 00:06:42 +02:00
{
ZeroEnemyPartyMons ( ) ;
2018-10-22 19:22:57 +02:00
FillTrainerParty ( gTrainerBattleOpponent_A , 0 , monsCount ) ;
FillTrainerParty ( gTrainerBattleOpponent_B , 3 , monsCount ) ;
2018-10-21 00:06:42 +02:00
}
2018-10-25 21:27:10 +02:00
static void FillTentTrainerParty ( u8 monsCount )
2018-10-21 00:06:42 +02:00
{
ZeroEnemyPartyMons ( ) ;
2018-10-24 23:14:45 +02:00
FillTentTrainerParty_ ( gTrainerBattleOpponent_A , 0 , monsCount ) ;
2018-10-21 00:06:42 +02:00
}
2018-10-22 19:22:57 +02:00
static void FillTrainerParty ( u16 trainerId , u8 firstMonId , u8 monCount )
2018-10-21 00:06:42 +02:00
{
s32 i , j ;
u16 chosenMonIndices [ 4 ] ;
2019-12-18 02:32:52 -05:00
u8 friendship = MAX_FRIENDSHIP ;
2018-10-24 23:14:45 +02:00
u8 level = SetFacilityPtrsGetLevel ( ) ;
2018-10-21 00:06:42 +02:00
u8 fixedIV = 0 ;
u8 bfMonCount ;
2020-01-05 10:50:32 -05:00
const u16 * monSet = NULL ;
2018-10-21 00:06:42 +02:00
u32 otID = 0 ;
2019-12-20 18:52:29 -05:00
if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-21 00:06:42 +02:00
{
// Normal battle frontier trainer.
fixedIV = GetFrontierTrainerFixedIvs ( trainerId ) ;
2020-01-05 10:50:32 -05:00
monSet = gFacilityTrainers [ gTrainerBattleOpponent_A ] . monSet ;
2018-10-21 00:06:42 +02:00
}
2018-10-26 23:54:41 +02:00
else if ( trainerId = = TRAINER_EREADER )
2018-10-21 00:06:42 +02:00
{
for ( i = firstMonId ; i < firstMonId + 3 ; i + + )
2019-01-13 12:12:27 +01:00
CreateBattleTowerMon ( & gEnemyParty [ i ] , & gSaveBlock2Ptr - > frontier . ereaderTrainer . party [ i - firstMonId ] ) ;
2018-10-21 00:06:42 +02:00
return ;
}
else if ( trainerId = = TRAINER_FRONTIER_BRAIN )
{
CreateFrontierBrainPokemon ( ) ;
return ;
}
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
2018-10-21 00:06:42 +02:00
{
// Record mixed player.
for ( j = 0 , i = firstMonId ; i < firstMonId + monCount ; j + + , i + + )
{
2018-10-26 23:54:41 +02:00
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 )
2018-10-21 00:06:42 +02:00
{
2019-01-13 12:12:27 +01:00
CreateBattleTowerMon2 ( & gEnemyParty [ i ] , & gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . party [ j ] , FALSE ) ;
2018-10-21 00:06:42 +02:00
}
}
return ;
}
else
{
// Apprentice.
for ( i = firstMonId ; i < firstMonId + 3 ; i + + )
2018-10-26 23:54:41 +02:00
CreateApprenticeMon ( & gEnemyParty [ i ] , & gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] , i - firstMonId ) ;
2018-10-21 00:06:42 +02:00
return ;
}
// Regular battle frontier trainer.
// Attempt to fill the trainer's party with random Pokemon until 3 have been
// successfully chosen. The trainer's party may not have duplicate pokemon species
// or duplicate held items.
2020-01-05 10:50:32 -05:00
for ( bfMonCount = 0 ; monSet [ bfMonCount ] ! = 0xFFFF ; bfMonCount + + )
2018-10-21 00:06:42 +02:00
;
i = 0 ;
otID = Random32 ( ) ;
while ( i ! = monCount )
{
2020-01-05 10:50:32 -05:00
u16 monId = monSet [ Random ( ) % bfMonCount ] ;
if ( ( level = = 50 | | level = = 20 ) & & monId > FRONTIER_MONS_HIGH_TIER )
2018-10-21 00:06:42 +02:00
continue ;
// Ensure this pokemon species isn't a duplicate.
for ( j = 0 ; j < i + firstMonId ; j + + )
{
2020-01-05 10:50:32 -05:00
if ( GetMonData ( & gEnemyParty [ j ] , MON_DATA_SPECIES , NULL ) = = gFacilityTrainerMons [ monId ] . species )
2018-10-21 00:06:42 +02:00
break ;
}
if ( j ! = i + firstMonId )
continue ;
// Ensure this Pokemon's held item isn't a duplicate.
for ( j = 0 ; j < i + firstMonId ; j + + )
{
if ( GetMonData ( & gEnemyParty [ j ] , MON_DATA_HELD_ITEM , NULL ) ! = 0
2020-01-05 10:50:32 -05:00
& & GetMonData ( & gEnemyParty [ j ] , MON_DATA_HELD_ITEM , NULL ) = = gBattleFrontierHeldItems [ gFacilityTrainerMons [ monId ] . itemTableId ] )
2018-10-21 00:06:42 +02:00
break ;
}
if ( j ! = i + firstMonId )
continue ;
// Ensure this exact pokemon index isn't a duplicate. This check doesn't seem necessary
// because the species and held items were already checked directly above.
for ( j = 0 ; j < i ; j + + )
{
2020-01-05 10:50:32 -05:00
if ( chosenMonIndices [ j ] = = monId )
2018-10-21 00:06:42 +02:00
break ;
}
if ( j ! = i )
continue ;
2020-01-05 10:50:32 -05:00
chosenMonIndices [ i ] = monId ;
2018-10-21 00:06:42 +02:00
// Place the chosen pokemon into the trainer's party.
2018-11-11 16:44:27 +01:00
CreateMonWithEVSpreadNatureOTID ( & gEnemyParty [ i + firstMonId ] ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . species ,
2018-10-21 00:06:42 +02:00
level ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . nature ,
2018-10-21 00:06:42 +02:00
fixedIV ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . evSpread ,
2018-10-21 00:06:42 +02:00
otID ) ;
2019-12-18 02:32:52 -05:00
friendship = MAX_FRIENDSHIP ;
2018-10-21 00:06:42 +02:00
// Give the chosen pokemon its specified moves.
2018-12-25 12:50:15 -05:00
for ( j = 0 ; j < MAX_MON_MOVES ; j + + )
2018-10-21 00:06:42 +02:00
{
2020-01-05 10:50:32 -05:00
SetMonMoveSlot ( & gEnemyParty [ i + firstMonId ] , gFacilityTrainerMons [ monId ] . moves [ j ] , j ) ;
if ( gFacilityTrainerMons [ monId ] . moves [ j ] = = MOVE_FRUSTRATION )
2018-10-21 00:06:42 +02:00
friendship = 0 ; // Frustration is more powerful the lower the pokemon's friendship is.
}
SetMonData ( & gEnemyParty [ i + firstMonId ] , MON_DATA_FRIENDSHIP , & friendship ) ;
2020-01-05 10:50:32 -05:00
SetMonData ( & gEnemyParty [ i + firstMonId ] , MON_DATA_HELD_ITEM , & gBattleFrontierHeldItems [ gFacilityTrainerMons [ monId ] . itemTableId ] ) ;
2018-10-21 00:06:42 +02:00
// The pokemon was successfully added to the trainer's party, so it's safe to move on to
// the next party slot.
i + + ;
}
}
// Probably an early draft before the 'CreateApprenticeMon' was written.
2018-10-25 21:27:10 +02:00
static void Unused_CreateApprenticeMons ( u16 trainerId , u8 firstMonId )
2018-10-21 00:06:42 +02:00
{
s32 i , j ;
2019-12-18 02:32:52 -05:00
u8 friendship = MAX_FRIENDSHIP ;
2018-10-21 00:06:42 +02:00
u8 level = 0 ;
u8 fixedIV = 0 ;
struct Apprentice * apprentice = & gSaveBlock2Ptr - > apprentices [ 0 ] ;
2019-11-20 17:36:52 -05:00
if ( apprentice - > numQuestions < 5 )
2018-10-21 00:06:42 +02:00
fixedIV = 6 ;
else
fixedIV = 9 ;
if ( gSaveBlock2Ptr - > frontier . lvlMode ! = FRONTIER_LVL_50 )
level = 100 ;
else
level = 50 ;
for ( i = 0 ; i ! = 3 ; i + + )
{
2018-10-22 19:22:57 +02:00
CreateMonWithEVSpread ( & gEnemyParty [ firstMonId + i ] , apprentice - > party [ i ] . species , level , fixedIV , 8 ) ;
2019-12-18 02:32:52 -05:00
friendship = MAX_FRIENDSHIP ;
2018-12-25 12:50:15 -05:00
for ( j = 0 ; j < MAX_MON_MOVES ; j + + )
2018-10-21 00:06:42 +02:00
{
2018-10-22 19:22:57 +02:00
if ( apprentice - > party [ i ] . moves [ j ] = = MOVE_FRUSTRATION )
2018-10-21 00:06:42 +02:00
friendship = 0 ;
}
SetMonData ( & gEnemyParty [ firstMonId + i ] , MON_DATA_FRIENDSHIP , & friendship ) ;
2018-10-22 19:22:57 +02:00
SetMonData ( & gEnemyParty [ firstMonId + i ] , MON_DATA_HELD_ITEM , & apprentice - > party [ i ] . item ) ;
2018-10-21 00:06:42 +02:00
}
}
2020-01-05 10:50:32 -05:00
u16 GetRandomFrontierMonFromSet ( u16 trainerId )
2018-10-21 00:06:42 +02:00
{
2018-10-24 23:14:45 +02:00
u8 level = SetFacilityPtrsGetLevel ( ) ;
2020-01-05 10:50:32 -05:00
const u16 * monSet = gFacilityTrainers [ trainerId ] . monSet ;
u8 numMons = 0 ;
u32 monId = monSet [ numMons ] ;
2018-10-21 00:06:42 +02:00
2020-01-05 10:50:32 -05:00
while ( monId ! = 0xFFFF )
2018-10-21 00:06:42 +02:00
{
2020-01-05 10:50:32 -05:00
numMons + + ;
monId = monSet [ numMons ] ;
if ( monId = = 0xFFFF )
2018-10-21 00:06:42 +02:00
break ;
}
do
{
2020-01-05 10:50:32 -05:00
monId = monSet [ Random ( ) % numMons ] ;
} while ( ( level = = 50 | | level = = 20 ) & & monId > FRONTIER_MONS_HIGH_TIER ) ;
2018-10-21 00:06:42 +02:00
2020-01-05 10:50:32 -05:00
return monId ;
2018-10-21 00:06:42 +02:00
}
2018-10-26 23:54:41 +02:00
static void FillFactoryTrainerParty ( void )
2018-10-21 00:06:42 +02:00
{
ZeroEnemyPartyMons ( ) ;
if ( gSaveBlock2Ptr - > frontier . lvlMode ! = FRONTIER_LVL_TENT )
2018-10-26 23:54:41 +02:00
FillFactoryFrontierTrainerParty ( gTrainerBattleOpponent_A , 0 ) ;
2018-10-21 00:06:42 +02:00
else
2018-10-26 23:54:41 +02:00
FillFactoryTentTrainerParty ( gTrainerBattleOpponent_A , 0 ) ;
2018-10-21 00:06:42 +02:00
}
2018-10-26 23:54:41 +02:00
static void FillFactoryFrontierTrainerParty ( u16 trainerId , u8 firstMonId )
2018-10-21 00:06:42 +02:00
{
u8 i , j ;
u8 friendship ;
u8 level ;
u8 fixedIV ;
u32 otID ;
2019-12-20 18:52:29 -05:00
if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-21 00:06:42 +02:00
{
u8 lvlMode = gSaveBlock2Ptr - > frontier . lvlMode ; // Unused variable.
u8 battleMode = VarGet ( VAR_FRONTIER_BATTLE_MODE ) ;
2018-10-27 17:39:05 +02:00
u8 challengeNum = gSaveBlock2Ptr - > frontier . towerWinStreaks [ battleMode ] [ 0 ] / 7 ;
2018-10-21 00:06:42 +02:00
if ( gSaveBlock2Ptr - > frontier . curChallengeBattleNum < 6 )
2018-11-11 16:44:27 +01:00
fixedIV = GetFactoryMonFixedIV ( challengeNum , 0 ) ;
2018-10-21 00:06:42 +02:00
else
2018-11-11 16:44:27 +01:00
fixedIV = GetFactoryMonFixedIV ( challengeNum , 1 ) ;
2018-10-21 00:06:42 +02:00
}
2018-10-26 23:54:41 +02:00
else if ( trainerId = = TRAINER_EREADER )
2018-10-21 00:06:42 +02:00
{
for ( i = firstMonId ; i < firstMonId + 3 ; i + + )
2019-01-13 12:12:27 +01:00
CreateBattleTowerMon ( & gEnemyParty [ i ] , & gSaveBlock2Ptr - > frontier . ereaderTrainer . party [ i - firstMonId ] ) ;
2018-10-21 00:06:42 +02:00
return ;
}
else if ( trainerId = = TRAINER_FRONTIER_BRAIN )
{
2018-11-11 16:44:27 +01:00
FillFactoryBrainParty ( ) ;
2018-10-21 00:06:42 +02:00
return ;
}
else
{
fixedIV = 31 ;
}
2018-10-24 23:14:45 +02:00
level = SetFacilityPtrsGetLevel ( ) ;
2018-10-21 00:06:42 +02:00
otID = T1_READ_32 ( gSaveBlock2Ptr - > playerTrainerId ) ;
2019-12-02 08:44:34 -05:00
for ( i = 0 ; i < FRONTIER_PARTY_SIZE ; i + + )
2018-10-21 00:06:42 +02:00
{
2020-01-05 10:50:32 -05:00
u16 monId = gUnknown_03006298 [ i ] ;
2018-11-11 16:44:27 +01:00
CreateMonWithEVSpreadNatureOTID ( & gEnemyParty [ firstMonId + i ] ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . species ,
2018-10-21 00:06:42 +02:00
level ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . nature ,
2018-10-21 00:06:42 +02:00
fixedIV ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . evSpread ,
2018-10-21 00:06:42 +02:00
otID ) ;
friendship = 0 ;
2018-12-25 12:50:15 -05:00
for ( j = 0 ; j < MAX_MON_MOVES ; j + + )
2020-01-05 10:50:32 -05:00
SetMonMoveAvoidReturn ( & gEnemyParty [ firstMonId + i ] , gFacilityTrainerMons [ monId ] . moves [ j ] , j ) ;
2018-10-21 00:06:42 +02:00
SetMonData ( & gEnemyParty [ firstMonId + i ] , MON_DATA_FRIENDSHIP , & friendship ) ;
2020-01-05 10:50:32 -05:00
SetMonData ( & gEnemyParty [ firstMonId + i ] , MON_DATA_HELD_ITEM , & gBattleFrontierHeldItems [ gFacilityTrainerMons [ monId ] . itemTableId ] ) ;
2018-10-21 00:06:42 +02:00
}
}
2018-10-26 23:54:41 +02:00
static void FillFactoryTentTrainerParty ( u16 trainerId , u8 firstMonId )
2018-10-21 00:06:42 +02:00
{
u8 i , j ;
u8 friendship ;
u8 level = 30 ;
u8 fixedIV = 0 ;
u32 otID = T1_READ_32 ( gSaveBlock2Ptr - > playerTrainerId ) ;
2019-12-02 08:44:34 -05:00
for ( i = 0 ; i < FRONTIER_PARTY_SIZE ; i + + )
2018-10-21 00:06:42 +02:00
{
2020-01-05 10:50:32 -05:00
u16 monId = gUnknown_03006298 [ i ] ;
2018-11-11 16:44:27 +01:00
CreateMonWithEVSpreadNatureOTID ( & gEnemyParty [ firstMonId + i ] ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . species ,
2018-10-21 00:06:42 +02:00
level ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . nature ,
2018-10-21 00:06:42 +02:00
fixedIV ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . evSpread ,
2018-10-21 00:06:42 +02:00
otID ) ;
friendship = 0 ;
2018-12-25 12:50:15 -05:00
for ( j = 0 ; j < MAX_MON_MOVES ; j + + )
2018-10-21 00:06:42 +02:00
{
2020-01-05 10:50:32 -05:00
SetMonMoveAvoidReturn ( & gEnemyParty [ firstMonId + i ] , gFacilityTrainerMons [ monId ] . moves [ j ] , j ) ;
if ( gFacilityTrainerMons [ monId ] . moves [ j ] = = MOVE_FRUSTRATION )
2018-10-21 00:06:42 +02:00
friendship = 0 ;
}
SetMonData ( & gEnemyParty [ firstMonId + i ] , MON_DATA_FRIENDSHIP , & friendship ) ;
2020-01-05 10:50:32 -05:00
SetMonData ( & gEnemyParty [ firstMonId + i ] , MON_DATA_HELD_ITEM , & gBattleFrontierHeldItems [ gFacilityTrainerMons [ monId ] . itemTableId ] ) ;
2018-10-21 00:06:42 +02:00
}
}
2018-10-21 20:13:12 +02:00
void FrontierSpeechToString ( const u16 * words )
2018-10-21 00:06:42 +02:00
{
ConvertEasyChatWordsToString ( gStringVar4 , words , 3 , 2 ) ;
2018-12-20 22:53:08 +01:00
if ( GetStringWidth ( 1 , gStringVar4 , - 1 ) > 204u )
2018-10-21 00:06:42 +02:00
{
s32 i = 0 ;
ConvertEasyChatWordsToString ( gStringVar4 , words , 2 , 3 ) ;
while ( gStringVar4 [ i + + ] ! = CHAR_NEWLINE )
;
while ( gStringVar4 [ i ] ! = CHAR_NEWLINE )
i + + ;
gStringVar4 [ i ] = CHAR_PROMPT_SCROLL ;
}
}
2018-10-21 20:13:12 +02:00
2019-11-28 22:46:39 -05:00
static void GetOpponentIntroSpeech ( void )
2018-10-21 20:13:12 +02:00
{
u16 trainerId ;
2018-10-24 23:14:45 +02:00
SetFacilityPtrsGetLevel ( ) ;
2018-10-21 20:13:12 +02:00
if ( gSpecialVar_0x8005 )
trainerId = gTrainerBattleOpponent_B ;
else
trainerId = gTrainerBattleOpponent_A ;
2018-10-26 23:54:41 +02:00
if ( trainerId = = TRAINER_EREADER )
2018-10-21 20:13:12 +02:00
FrontierSpeechToString ( gSaveBlock2Ptr - > frontier . ereaderTrainer . greeting ) ;
2019-12-20 18:52:29 -05:00
else if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-21 20:13:12 +02:00
FrontierSpeechToString ( gFacilityTrainers [ trainerId ] . speechBefore ) ;
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
FrontierSpeechToString ( gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . greeting ) ;
2018-10-21 20:13:12 +02:00
else
2019-11-20 17:36:52 -05:00
BufferApprenticeChallengeText ( trainerId - TRAINER_RECORD_MIXING_APPRENTICE ) ;
2018-10-21 20:13:12 +02:00
}
static void HandleSpecialTrainerBattleEnd ( void )
{
s32 i ;
2018-11-01 15:06:50 +01:00
RecordedBattle_SaveBattleOutcome ( ) ;
2018-10-21 20:13:12 +02:00
switch ( gBattleScripting . specialTrainerBattleType )
{
case SPECIAL_BATTLE_TOWER :
case SPECIAL_BATTLE_DOME :
case SPECIAL_BATTLE_PALACE :
case SPECIAL_BATTLE_ARENA :
case SPECIAL_BATTLE_FACTORY :
case SPECIAL_BATTLE_PIKE_SINGLE :
case SPECIAL_BATTLE_PIKE_DOUBLE :
case SPECIAL_BATTLE_PYRAMID :
if ( gSaveBlock2Ptr - > frontier . battlesCount < 0xFFFFFF )
{
gSaveBlock2Ptr - > frontier . battlesCount + + ;
if ( gSaveBlock2Ptr - > frontier . battlesCount % 20 = = 0 )
UpdateGymLeaderRematch ( ) ;
}
else
{
gSaveBlock2Ptr - > frontier . battlesCount = 0xFFFFFF ;
}
break ;
case SPECIAL_BATTLE_SECRET_BASE :
for ( i = 0 ; i < PARTY_SIZE ; i + + )
{
u16 itemBefore = GetMonData ( & gSaveBlock1Ptr - > playerParty [ i ] , MON_DATA_HELD_ITEM ) ;
SetMonData ( & gPlayerParty [ i ] , MON_DATA_HELD_ITEM , & itemBefore ) ;
}
break ;
case SPECIAL_BATTLE_EREADER :
2018-10-22 19:22:57 +02:00
CopyEReaderTrainerFarewellMessage ( ) ;
2018-10-21 20:13:12 +02:00
break ;
}
SetMainCallback2 ( CB2_ReturnToFieldContinueScriptPlayMapMusic ) ;
}
static void Task_StartBattleAfterTransition ( u8 taskId )
{
if ( IsBattleTransitionDone ( ) = = TRUE )
{
gMain . savedCallback = HandleSpecialTrainerBattleEnd ;
SetMainCallback2 ( CB2_InitBattle ) ;
DestroyTask ( taskId ) ;
}
}
void DoSpecialTrainerBattle ( void )
{
s32 i ;
gBattleScripting . specialTrainerBattleType = gSpecialVar_0x8004 ;
switch ( gSpecialVar_0x8004 )
{
case SPECIAL_BATTLE_TOWER :
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_BATTLE_TOWER ;
switch ( VarGet ( VAR_FRONTIER_BATTLE_MODE ) )
{
case FRONTIER_MODE_SINGLES :
2019-11-24 16:58:40 -05:00
FillFrontierTrainerParty ( FRONTIER_PARTY_SIZE ) ;
2018-10-21 20:13:12 +02:00
break ;
case FRONTIER_MODE_DOUBLES :
2019-11-24 16:58:40 -05:00
FillFrontierTrainerParty ( FRONTIER_DOUBLES_PARTY_SIZE ) ;
2018-10-21 20:13:12 +02:00
gBattleTypeFlags | = BATTLE_TYPE_DOUBLE ;
break ;
case FRONTIER_MODE_MULTIS :
2019-11-24 16:58:40 -05:00
FillFrontierTrainersParties ( FRONTIER_MULTI_PARTY_SIZE ) ;
2019-02-07 11:37:28 -06:00
gPartnerTrainerId = gSaveBlock2Ptr - > frontier . trainerIds [ 17 ] ;
2018-10-24 23:14:45 +02:00
FillPartnerParty ( gPartnerTrainerId ) ;
2018-10-21 20:13:12 +02:00
gBattleTypeFlags | = BATTLE_TYPE_DOUBLE | BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS ;
break ;
case FRONTIER_MODE_LINK_MULTIS :
gBattleTypeFlags | = BATTLE_TYPE_DOUBLE | BATTLE_TYPE_LINK | BATTLE_TYPE_MULTI | BATTLE_TYPE_x800000 ;
2019-11-24 16:58:40 -05:00
FillFrontierTrainersParties ( FRONTIER_MULTI_PARTY_SIZE ) ;
2018-10-21 20:13:12 +02:00
break ;
}
CreateTask ( Task_StartBattleAfterTransition , 1 ) ;
PlayMapChosenOrBattleBGM ( 0 ) ;
2020-07-02 15:45:37 -04:00
BattleTransition_StartOnField ( GetSpecialBattleTransition ( 0 ) ) ;
2018-10-21 20:13:12 +02:00
break ;
case SPECIAL_BATTLE_SECRET_BASE :
for ( i = 0 ; i < PARTY_SIZE ; i + + )
{
u16 itemBefore = GetMonData ( & gPlayerParty [ i ] , MON_DATA_HELD_ITEM ) ;
SetMonData ( & gSaveBlock1Ptr - > playerParty [ i ] , MON_DATA_HELD_ITEM , & itemBefore ) ;
}
CreateTask ( Task_StartBattleAfterTransition , 1 ) ;
PlayMapChosenOrBattleBGM ( 0 ) ;
2020-07-02 15:45:37 -04:00
BattleTransition_StartOnField ( GetSpecialBattleTransition ( 12 ) ) ;
2018-10-21 20:13:12 +02:00
break ;
case SPECIAL_BATTLE_EREADER :
ZeroEnemyPartyMons ( ) ;
for ( i = 0 ; i < 3 ; i + + )
2019-01-13 12:12:27 +01:00
CreateBattleTowerMon ( & gEnemyParty [ i ] , & gSaveBlock2Ptr - > frontier . ereaderTrainer . party [ i ] ) ;
2018-10-21 20:13:12 +02:00
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_EREADER_TRAINER ;
gTrainerBattleOpponent_A = 0 ;
CreateTask ( Task_StartBattleAfterTransition , 1 ) ;
PlayMapChosenOrBattleBGM ( 0 ) ;
2020-07-02 15:45:37 -04:00
BattleTransition_StartOnField ( GetSpecialBattleTransition ( 13 ) ) ;
2018-10-21 20:13:12 +02:00
break ;
case SPECIAL_BATTLE_DOME :
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOME ;
if ( VarGet ( VAR_FRONTIER_BATTLE_MODE ) = = FRONTIER_MODE_DOUBLES )
gBattleTypeFlags | = BATTLE_TYPE_DOUBLE ;
if ( gTrainerBattleOpponent_A = = TRAINER_FRONTIER_BRAIN )
2020-04-09 15:18:53 -04:00
FillFrontierTrainerParty ( DOME_BATTLE_PARTY_SIZE ) ;
2018-10-21 20:13:12 +02:00
CreateTask ( Task_StartBattleAfterTransition , 1 ) ;
sub_806E694 ( 0 ) ;
2020-07-02 15:45:37 -04:00
BattleTransition_StartOnField ( GetSpecialBattleTransition ( 3 ) ) ;
2018-10-21 20:13:12 +02:00
break ;
case SPECIAL_BATTLE_PALACE :
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_PALACE ;
if ( VarGet ( VAR_FRONTIER_BATTLE_MODE ) = = FRONTIER_MODE_DOUBLES )
gBattleTypeFlags | = BATTLE_TYPE_DOUBLE ;
if ( gSaveBlock2Ptr - > frontier . lvlMode ! = FRONTIER_LVL_TENT )
2019-11-24 16:58:40 -05:00
FillFrontierTrainerParty ( FRONTIER_PARTY_SIZE ) ;
2018-10-21 20:13:12 +02:00
else
2019-11-24 16:58:40 -05:00
FillTentTrainerParty ( FRONTIER_PARTY_SIZE ) ;
2018-10-21 20:13:12 +02:00
CreateTask ( Task_StartBattleAfterTransition , 1 ) ;
PlayMapChosenOrBattleBGM ( 0 ) ;
2020-07-02 15:45:37 -04:00
BattleTransition_StartOnField ( GetSpecialBattleTransition ( 4 ) ) ;
2018-10-21 20:13:12 +02:00
break ;
case SPECIAL_BATTLE_ARENA :
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_ARENA ;
if ( gSaveBlock2Ptr - > frontier . lvlMode ! = FRONTIER_LVL_TENT )
2019-11-24 16:58:40 -05:00
FillFrontierTrainerParty ( FRONTIER_PARTY_SIZE ) ;
2018-10-21 20:13:12 +02:00
else
2019-11-24 16:58:40 -05:00
FillTentTrainerParty ( FRONTIER_PARTY_SIZE ) ;
2018-10-21 20:13:12 +02:00
CreateTask ( Task_StartBattleAfterTransition , 1 ) ;
PlayMapChosenOrBattleBGM ( 0 ) ;
2020-07-02 15:45:37 -04:00
BattleTransition_StartOnField ( GetSpecialBattleTransition ( 5 ) ) ;
2018-10-21 20:13:12 +02:00
break ;
case SPECIAL_BATTLE_FACTORY :
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_FACTORY ;
if ( VarGet ( VAR_FRONTIER_BATTLE_MODE ) = = FRONTIER_MODE_DOUBLES )
gBattleTypeFlags | = BATTLE_TYPE_DOUBLE ;
2018-10-26 23:54:41 +02:00
FillFactoryTrainerParty ( ) ;
2018-10-21 20:13:12 +02:00
CreateTask ( Task_StartBattleAfterTransition , 1 ) ;
PlayMapChosenOrBattleBGM ( 0 ) ;
2020-07-02 15:45:37 -04:00
BattleTransition_StartOnField ( GetSpecialBattleTransition ( 6 ) ) ;
2018-10-21 20:13:12 +02:00
break ;
case SPECIAL_BATTLE_PIKE_SINGLE :
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_BATTLE_TOWER ;
2019-11-24 16:58:40 -05:00
FillFrontierTrainerParty ( FRONTIER_PARTY_SIZE ) ;
2018-10-21 20:13:12 +02:00
CreateTask ( Task_StartBattleAfterTransition , 1 ) ;
PlayMapChosenOrBattleBGM ( 0 ) ;
2020-07-02 15:45:37 -04:00
BattleTransition_StartOnField ( GetSpecialBattleTransition ( 7 ) ) ;
2018-10-21 20:13:12 +02:00
break ;
case SPECIAL_BATTLE_PYRAMID :
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_PYRAMID ;
2019-11-24 16:58:40 -05:00
FillFrontierTrainerParty ( FRONTIER_PARTY_SIZE ) ;
2018-10-21 20:13:12 +02:00
CreateTask ( Task_StartBattleAfterTransition , 1 ) ;
PlayMapChosenOrBattleBGM ( 0 ) ;
2020-07-02 15:45:37 -04:00
BattleTransition_StartOnField ( GetSpecialBattleTransition ( 10 ) ) ;
2018-10-21 20:13:12 +02:00
break ;
case SPECIAL_BATTLE_PIKE_DOUBLE :
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_BATTLE_TOWER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS ;
2018-10-22 19:22:57 +02:00
FillFrontierTrainersParties ( 1 ) ;
2018-10-21 20:13:12 +02:00
CreateTask ( Task_StartBattleAfterTransition , 1 ) ;
PlayMapChosenOrBattleBGM ( 0 ) ;
2020-07-02 15:45:37 -04:00
BattleTransition_StartOnField ( GetSpecialBattleTransition ( 7 ) ) ;
2018-10-21 20:13:12 +02:00
break ;
case SPECIAL_BATTLE_STEVEN :
gBattleTypeFlags = BATTLE_TYPE_TRAINER | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER ;
2018-10-24 23:14:45 +02:00
FillPartnerParty ( TRAINER_STEVEN_PARTNER ) ;
2018-10-21 20:13:12 +02:00
gApproachingTrainerId = 0 ;
2019-11-01 17:50:54 -04:00
BattleSetup_ConfigureTrainerBattle ( MossdeepCity_SpaceCenter_2F_EventScript_MaxieTrainer + 1 ) ;
2018-10-21 20:13:12 +02:00
gApproachingTrainerId = 1 ;
2019-11-01 17:50:54 -04:00
BattleSetup_ConfigureTrainerBattle ( MossdeepCity_SpaceCenter_2F_EventScript_TabithaTrainer + 1 ) ;
2018-10-21 20:13:12 +02:00
gPartnerTrainerId = TRAINER_STEVEN_PARTNER ;
CreateTask ( Task_StartBattleAfterTransition , 1 ) ;
PlayMapChosenOrBattleBGM ( 0 ) ;
BattleTransition_StartOnField ( B_TRANSITION_MAGMA ) ;
break ;
}
}
2018-10-25 21:27:10 +02:00
static void SaveCurrentWinStreak ( void )
2018-10-21 20:13:12 +02:00
{
u8 lvlMode = gSaveBlock2Ptr - > frontier . lvlMode ;
u8 battleMode = VarGet ( VAR_FRONTIER_BATTLE_MODE ) ;
u16 winStreak = GetCurrentBattleTowerWinStreak ( lvlMode , battleMode ) ;
2018-10-27 17:39:05 +02:00
if ( gSaveBlock2Ptr - > frontier . towerWinStreaks [ battleMode ] [ lvlMode ] < winStreak )
gSaveBlock2Ptr - > frontier . towerWinStreaks [ battleMode ] [ lvlMode ] = winStreak ;
2018-10-21 20:13:12 +02:00
}
2018-10-25 21:27:10 +02:00
static void sub_8163EE4 ( void )
2018-10-21 20:13:12 +02:00
{
s32 i ;
u8 lvlMode , battleMode , class ;
struct EmeraldBattleTowerRecord * playerRecord = & gSaveBlock2Ptr - > frontier . towerPlayer ;
2018-10-22 19:22:57 +02:00
ClearBattleTowerRecord ( playerRecord ) ;
2018-10-21 20:13:12 +02:00
lvlMode = gSaveBlock2Ptr - > frontier . lvlMode ;
battleMode = VarGet ( VAR_FRONTIER_BATTLE_MODE ) ;
if ( gSaveBlock2Ptr - > playerGender ! = MALE )
{
class = gTowerFemaleFacilityClasses [ ( gSaveBlock2Ptr - > playerTrainerId [ 0 ] +
gSaveBlock2Ptr - > playerTrainerId [ 1 ] +
gSaveBlock2Ptr - > playerTrainerId [ 2 ] +
gSaveBlock2Ptr - > playerTrainerId [ 3 ] ) % ARRAY_COUNT ( gTowerFemaleFacilityClasses ) ] ;
}
else
{
class = gTowerMaleFacilityClasses [ ( gSaveBlock2Ptr - > playerTrainerId [ 0 ] +
gSaveBlock2Ptr - > playerTrainerId [ 1 ] +
gSaveBlock2Ptr - > playerTrainerId [ 2 ] +
gSaveBlock2Ptr - > playerTrainerId [ 3 ] ) % ARRAY_COUNT ( gTowerMaleFacilityClasses ) ] ;
}
playerRecord - > lvlMode = lvlMode ;
playerRecord - > facilityClass = class ;
2018-11-01 21:31:10 +01:00
CopyTrainerId ( playerRecord - > trainerId , gSaveBlock2Ptr - > playerTrainerId ) ;
2018-10-21 20:13:12 +02:00
StringCopy7 ( playerRecord - > name , gSaveBlock2Ptr - > playerName ) ;
playerRecord - > winStreak = GetCurrentBattleTowerWinStreak ( lvlMode , battleMode ) ;
2019-12-20 18:52:29 -05:00
for ( i = 0 ; i < EASY_CHAT_BATTLE_WORDS_COUNT ; i + + )
2018-10-21 20:13:12 +02:00
{
2019-02-27 12:45:31 -06:00
playerRecord - > greeting [ i ] = gSaveBlock1Ptr - > easyChatBattleStart [ i ] ;
playerRecord - > speechWon [ i ] = gSaveBlock1Ptr - > easyChatBattleWon [ i ] ;
playerRecord - > speechLost [ i ] = gSaveBlock1Ptr - > easyChatBattleLost [ i ] ;
2018-10-21 20:13:12 +02:00
}
2019-11-24 16:58:40 -05:00
for ( i = 0 ; i < MAX_FRONTIER_PARTY_SIZE ; i + + )
2018-10-21 20:13:12 +02:00
{
2018-10-22 19:22:57 +02:00
if ( gSaveBlock2Ptr - > frontier . selectedPartyMons [ i ] ! = 0 )
sub_80686FC ( & gPlayerParty [ gSaveBlock2Ptr - > frontier . selectedPartyMons [ i ] - 1 ] , & playerRecord - > party [ i ] ) ;
2018-10-21 20:13:12 +02:00
}
playerRecord - > language = gGameLanguage ;
CalcEmeraldBattleTowerChecksum ( & gSaveBlock2Ptr - > frontier . towerPlayer ) ;
SaveCurrentWinStreak ( ) ;
}
2019-11-28 21:09:35 -05:00
static void SaveTowerChallenge ( void )
2018-10-21 20:13:12 +02:00
{
u16 lvlMode = gSaveBlock2Ptr - > frontier . lvlMode ;
u16 battleMode = VarGet ( VAR_FRONTIER_BATTLE_MODE ) ;
2018-10-27 17:39:05 +02:00
s32 challengeNum = ( signed ) ( gSaveBlock2Ptr - > frontier . towerWinStreaks [ battleMode ] [ lvlMode ] / 7 ) ;
2018-10-21 20:13:12 +02:00
if ( gSpecialVar_0x8005 = = 0 & & ( challengeNum > 1 | | gSaveBlock2Ptr - > frontier . curChallengeBattleNum ! = 0 ) )
sub_8163EE4 ( ) ;
2019-11-24 16:58:40 -05:00
gSaveBlock2Ptr - > frontier . challengeStatus = gSpecialVar_0x8005 ;
2018-10-21 20:13:12 +02:00
VarSet ( VAR_TEMP_0 , 0 ) ;
2019-11-24 16:58:40 -05:00
gSaveBlock2Ptr - > frontier . challengePaused = TRUE ;
SaveGameFrontier ( ) ;
2018-10-21 20:13:12 +02:00
}
2018-10-25 21:27:10 +02:00
static void nullsub_61 ( void )
2018-10-21 20:13:12 +02:00
{
}
2019-11-16 20:50:52 -05:00
static void nullsub_116 ( void )
2018-10-21 20:13:12 +02:00
{
}
2020-01-08 05:43:06 -05:00
static void GetApprenticeMultiPartnerParty ( u16 trainerId )
2018-10-21 20:13:12 +02:00
{
s32 i , count ;
2020-04-09 15:18:53 -04:00
u32 validSpecies [ MULTI_PARTY_SIZE ] ;
2018-10-21 20:13:12 +02:00
u16 species1 = GetMonData ( & gPlayerParty [ 0 ] , MON_DATA_SPECIES , NULL ) ;
u16 species2 = GetMonData ( & gPlayerParty [ 1 ] , MON_DATA_SPECIES , NULL ) ;
count = 0 ;
2020-04-09 15:18:53 -04:00
for ( i = 0 ; i < MULTI_PARTY_SIZE ; i + + )
2018-10-21 20:13:12 +02:00
{
2018-10-26 23:54:41 +02:00
u16 apprenticeSpecies = gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . party [ i ] . species ;
2018-10-21 20:13:12 +02:00
if ( apprenticeSpecies ! = species1 & & apprenticeSpecies ! = species2 )
{
validSpecies [ count ] = i ;
count + + ;
}
}
gUnknown_03006298 [ 0 ] = validSpecies [ Random ( ) % count ] ;
do
{
gUnknown_03006298 [ 1 ] = validSpecies [ Random ( ) % count ] ;
} while ( gUnknown_03006298 [ 0 ] = = gUnknown_03006298 [ 1 ] ) ;
}
2020-01-08 05:43:06 -05:00
static void GetRecordMixFriendMultiPartnerParty ( u16 trainerId )
2018-10-21 20:13:12 +02:00
{
s32 i , count ;
u32 validSpecies [ 3 ] ;
u32 lvlMode = gSaveBlock2Ptr - > frontier . lvlMode ;
u16 species1 = GetMonData ( & gPlayerParty [ 0 ] , MON_DATA_SPECIES , NULL ) ;
u16 species2 = GetMonData ( & gPlayerParty [ 1 ] , MON_DATA_SPECIES , NULL ) ;
count = 0 ;
for ( i = 0 ; i < 4 ; i + + )
{
2018-10-26 23:54:41 +02:00
if ( gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . party [ i ] . species ! = species1
& & gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . party [ i ] . species ! = species2
& & gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . party [ i ] . level < = GetFrontierEnemyMonLevel ( lvlMode )
& & gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . party [ i ] . species ! = 0 )
2018-10-21 20:13:12 +02:00
{
validSpecies [ count ] = i ;
count + + ;
}
}
gUnknown_03006298 [ 2 ] = validSpecies [ Random ( ) % count ] ;
do
{
gUnknown_03006298 [ 3 ] = validSpecies [ Random ( ) % count ] ;
} while ( gUnknown_03006298 [ 2 ] = = gUnknown_03006298 [ 3 ] ) ;
}
2020-01-08 05:43:06 -05:00
static void LoadMultiPartnerCandidatesData ( void )
2018-10-21 20:13:12 +02:00
{
s32 i , j , k ;
u32 spArray [ 5 ] ;
s32 r10 ;
u16 trainerId ;
2020-01-05 10:50:32 -05:00
u16 monId ;
2018-10-21 20:13:12 +02:00
u32 lvlMode , battleMode ;
s32 challengeNum ;
u32 species1 , species2 ;
u32 level ;
2019-11-20 22:55:44 -05:00
struct ObjectEventTemplate * objEventTemplates ;
2018-10-21 20:13:12 +02:00
2019-11-20 22:55:44 -05:00
objEventTemplates = gSaveBlock1Ptr - > objectEventTemplates ;
2018-10-21 20:13:12 +02:00
lvlMode = gSaveBlock2Ptr - > frontier . lvlMode ;
battleMode = VarGet ( VAR_FRONTIER_BATTLE_MODE ) ;
2018-10-27 17:39:05 +02:00
challengeNum = gSaveBlock2Ptr - > frontier . towerWinStreaks [ battleMode ] [ lvlMode ] / 7 ;
2018-10-21 20:13:12 +02:00
species1 = GetMonData ( & gPlayerParty [ 0 ] , MON_DATA_SPECIES , NULL ) ;
species2 = GetMonData ( & gPlayerParty [ 1 ] , MON_DATA_SPECIES , NULL ) ;
2018-10-24 23:14:45 +02:00
level = SetFacilityPtrsGetLevel ( ) ;
2018-10-21 20:13:12 +02:00
2018-10-22 19:22:57 +02:00
j = 0 ;
do
2018-10-21 20:13:12 +02:00
{
do
{
2019-12-20 18:52:29 -05:00
trainerId = GetRandomScaledFrontierTrainerId ( challengeNum , 0 ) ;
2018-10-21 20:13:12 +02:00
for ( i = 0 ; i < j ; i + + )
{
2019-02-07 11:37:28 -06:00
if ( gSaveBlock2Ptr - > frontier . trainerIds [ i ] = = trainerId )
2018-10-21 20:13:12 +02:00
break ;
2019-02-07 11:37:28 -06:00
if ( gFacilityTrainers [ gSaveBlock2Ptr - > frontier . trainerIds [ i ] ] . facilityClass = = gFacilityTrainers [ trainerId ] . facilityClass )
2018-10-21 20:13:12 +02:00
break ;
}
} while ( i ! = j ) ;
2019-02-07 11:37:28 -06:00
gSaveBlock2Ptr - > frontier . trainerIds [ j ] = trainerId ;
2018-10-22 19:22:57 +02:00
j + + ;
} while ( j < 6 ) ;
2018-10-21 20:13:12 +02:00
r10 = 8 ;
for ( i = 0 ; i < 6 ; i + + )
{
2019-02-07 11:37:28 -06:00
trainerId = gSaveBlock2Ptr - > frontier . trainerIds [ i ] ;
2019-11-20 22:55:44 -05:00
objEventTemplates [ i + 1 ] . graphicsId = GetBattleFacilityTrainerGfxId ( trainerId ) ;
2018-10-21 20:13:12 +02:00
for ( j = 0 ; j < 2 ; j + + )
{
while ( 1 )
{
2020-01-05 10:50:32 -05:00
monId = GetRandomFrontierMonFromSet ( trainerId ) ;
if ( j % 2 ! = 0 & & gFacilityTrainerMons [ gSaveBlock2Ptr - > frontier . trainerIds [ r10 - 1 ] ] . itemTableId = = gFacilityTrainerMons [ monId ] . itemTableId )
2018-10-21 20:13:12 +02:00
continue ;
for ( k = 8 ; k < r10 ; k + + )
{
2020-01-05 10:50:32 -05:00
if ( gFacilityTrainerMons [ gSaveBlock2Ptr - > frontier . trainerIds [ k ] ] . species = = gFacilityTrainerMons [ monId ] . species )
2018-10-21 20:13:12 +02:00
break ;
2020-01-05 10:50:32 -05:00
if ( species1 = = gFacilityTrainerMons [ monId ] . species )
2018-10-21 20:13:12 +02:00
break ;
2020-01-05 10:50:32 -05:00
if ( species2 = = gFacilityTrainerMons [ monId ] . species )
2018-10-21 20:13:12 +02:00
break ;
}
if ( k = = r10 )
break ;
}
2020-01-05 10:50:32 -05:00
gSaveBlock2Ptr - > frontier . trainerIds [ r10 ] = monId ;
2018-10-21 20:13:12 +02:00
r10 + + ;
}
}
r10 = 0 ;
2018-10-24 23:14:45 +02:00
ValidateApprenticesChecksums ( ) ;
2019-11-20 17:36:52 -05:00
for ( i = 0 ; i < APPRENTICE_COUNT ; i + + )
2018-10-21 20:13:12 +02:00
{
if ( gSaveBlock2Ptr - > apprentices [ i ] . lvlMode ! = 0
2020-01-08 05:43:06 -05:00
& & sApprenticeChallengeThreshold [ gSaveBlock2Ptr - > apprentices [ i ] . numQuestions ] / 7 < = challengeNum
2018-10-21 20:13:12 +02:00
& & gSaveBlock2Ptr - > apprentices [ i ] . lvlMode - 1 = = lvlMode )
{
k = 0 ;
2020-04-09 15:18:53 -04:00
for ( j = 0 ; j < MULTI_PARTY_SIZE ; j + + )
2018-10-21 20:13:12 +02:00
{
2018-10-22 19:22:57 +02:00
if ( species1 ! = gSaveBlock2Ptr - > apprentices [ i ] . party [ j ] . species
& & species2 ! = gSaveBlock2Ptr - > apprentices [ i ] . party [ j ] . species )
2018-10-21 20:13:12 +02:00
{
k + + ;
}
}
if ( k > 2 )
{
2018-10-26 23:54:41 +02:00
spArray [ r10 ] = i + TRAINER_RECORD_MIXING_APPRENTICE ;
2018-10-21 20:13:12 +02:00
r10 + + ;
}
}
}
if ( r10 ! = 0 )
{
2019-02-07 11:37:28 -06:00
gSaveBlock2Ptr - > frontier . trainerIds [ 6 ] = spArray [ Random ( ) % r10 ] ;
2019-11-20 22:55:44 -05:00
objEventTemplates [ 7 ] . graphicsId = GetBattleFacilityTrainerGfxId ( gSaveBlock2Ptr - > frontier . trainerIds [ 6 ] ) ;
2018-10-21 20:13:12 +02:00
FlagClear ( FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_1 ) ;
2020-01-08 05:43:06 -05:00
GetApprenticeMultiPartnerParty ( gSaveBlock2Ptr - > frontier . trainerIds [ 6 ] ) ;
2018-10-21 20:13:12 +02:00
}
r10 = 0 ;
for ( i = 0 ; i < 5 ; i + + )
{
u32 * record = ( u32 * ) ( & gSaveBlock2Ptr - > frontier . towerRecords [ i ] ) ;
u32 recordHasData = 0 ;
u32 checksum = 0 ;
for ( j = 0 ; j < ( sizeof ( struct EmeraldBattleTowerRecord ) - 4 ) / 4 ; j + + ) // - 4, because of the last field being the checksum itself.
{
recordHasData | = record [ j ] ;
checksum + = record [ j ] ;
}
if ( gSaveBlock2Ptr - > frontier . towerRecords [ i ] . winStreak / 7 < = challengeNum
& & gSaveBlock2Ptr - > frontier . towerRecords [ i ] . lvlMode = = lvlMode
& & recordHasData
& & gSaveBlock2Ptr - > frontier . towerRecords [ i ] . checksum = = checksum )
{
k = 0 ;
for ( j = 0 ; j < 4 ; j + + )
{
if ( species1 ! = gSaveBlock2Ptr - > frontier . towerRecords [ i ] . party [ j ] . species
& & species2 ! = gSaveBlock2Ptr - > frontier . towerRecords [ i ] . party [ j ] . species
& & gSaveBlock2Ptr - > frontier . towerRecords [ i ] . party [ j ] . level < = GetFrontierEnemyMonLevel ( lvlMode )
& & gSaveBlock2Ptr - > frontier . towerRecords [ i ] . party [ j ] . species ! = 0 )
{
k + + ;
}
}
if ( k > 1 )
{
2018-10-26 23:54:41 +02:00
spArray [ r10 ] = i + TRAINER_RECORD_MIXING_FRIEND ;
2018-10-21 20:13:12 +02:00
r10 + + ;
}
}
}
if ( r10 ! = 0 )
{
2019-02-07 11:37:28 -06:00
gSaveBlock2Ptr - > frontier . trainerIds [ 7 ] = spArray [ Random ( ) % r10 ] ;
2019-11-20 22:55:44 -05:00
objEventTemplates [ 8 ] . graphicsId = GetBattleFacilityTrainerGfxId ( gSaveBlock2Ptr - > frontier . trainerIds [ 7 ] ) ;
2018-10-21 20:13:12 +02:00
FlagClear ( FLAG_HIDE_BATTLE_TOWER_MULTI_BATTLE_PARTNER_ALT_2 ) ;
2020-01-08 05:43:06 -05:00
GetRecordMixFriendMultiPartnerParty ( gSaveBlock2Ptr - > frontier . trainerIds [ 7 ] ) ;
2018-10-22 19:22:57 +02:00
}
}
2020-01-05 10:50:32 -05:00
static void sub_81646BC ( u16 trainerId , u16 monId )
2018-10-22 19:22:57 +02:00
{
u16 move = 0 ;
u16 species = 0 ;
2018-10-24 23:14:45 +02:00
SetFacilityPtrsGetLevel ( ) ;
2018-10-22 19:22:57 +02:00
2018-10-26 23:54:41 +02:00
if ( trainerId ! = TRAINER_EREADER )
2018-10-22 19:22:57 +02:00
{
2019-12-20 18:52:29 -05:00
if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-22 19:22:57 +02:00
{
2020-01-05 10:50:32 -05:00
move = gFacilityTrainerMons [ monId ] . moves [ 0 ] ;
species = gFacilityTrainerMons [ monId ] . species ;
2018-10-22 19:22:57 +02:00
}
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
2018-10-22 19:22:57 +02:00
{
2018-10-26 23:54:41 +02:00
move = gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . party [ gUnknown_03006298 [ gSpecialVar_0x8005 + 1 ] ] . moves [ 0 ] ;
species = gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . party [ gUnknown_03006298 [ gSpecialVar_0x8005 + 1 ] ] . species ;
2018-10-22 19:22:57 +02:00
}
else
{
s32 i ;
2018-10-26 23:54:41 +02:00
move = gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . party [ gUnknown_03006298 [ gSpecialVar_0x8005 - 1 ] ] . moves [ 0 ] ;
species = gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . party [ gUnknown_03006298 [ gSpecialVar_0x8005 - 1 ] ] . species ;
2018-10-22 19:22:57 +02:00
for ( i = 0 ; i < PLAYER_NAME_LENGTH ; i + + )
2018-10-26 23:54:41 +02:00
gStringVar3 [ i ] = gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . playerName [ i ] ;
2018-10-22 19:22:57 +02:00
gStringVar3 [ i ] = EOS ;
2018-10-26 23:54:41 +02:00
ConvertInternationalString ( gStringVar3 , gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . language ) ;
2018-10-22 19:22:57 +02:00
}
}
StringCopy ( gStringVar1 , gMoveNames [ move ] ) ;
StringCopy ( gStringVar2 , gSpeciesNames [ species ] ) ;
}
2020-01-08 05:43:06 -05:00
static void ShowPartnerCandidateMessage ( void )
2018-10-22 19:22:57 +02:00
{
2020-01-08 05:43:06 -05:00
s32 i , j , partnerId ;
2020-01-05 10:50:32 -05:00
s32 monId ;
2018-10-24 23:14:45 +02:00
s32 level = SetFacilityPtrsGetLevel ( ) ;
2018-10-27 21:01:35 +02:00
u16 winStreak = GetCurrentFacilityWinStreak ( ) ;
s32 challengeNum = winStreak / 7 ;
2018-10-22 19:22:57 +02:00
s32 k = gSpecialVar_LastTalked - 2 ;
2019-02-07 11:37:28 -06:00
s32 trainerId = gSaveBlock2Ptr - > frontier . trainerIds [ k ] ;
2018-10-22 19:22:57 +02:00
2020-01-08 05:43:06 -05:00
for ( partnerId = 0 ; partnerId < ARRAY_COUNT ( sPartnerTrainerTextTables ) ; partnerId + + )
2018-10-22 19:22:57 +02:00
{
2020-01-08 05:43:06 -05:00
if ( sPartnerTrainerTextTables [ partnerId ] . facilityClass = = GetFrontierTrainerFacilityClass ( trainerId ) )
2018-10-22 19:22:57 +02:00
break ;
}
switch ( gSpecialVar_0x8005 )
{
2020-01-08 05:43:06 -05:00
case PARTNER_MSGID_INTRO :
2018-10-26 23:54:41 +02:00
if ( trainerId = = TRAINER_EREADER )
2018-10-22 19:22:57 +02:00
return ;
2019-12-20 18:52:29 -05:00
if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-22 19:22:57 +02:00
{
GetFrontierTrainerName ( gStringVar1 , trainerId ) ;
}
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
2018-10-22 19:22:57 +02:00
{
GetFrontierTrainerName ( gStringVar1 , trainerId ) ;
}
else
{
s32 i ;
for ( i = 0 ; i < PLAYER_NAME_LENGTH ; i + + )
2018-10-26 23:54:41 +02:00
gStringVar1 [ i ] = gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . playerName [ i ] ;
2018-10-22 19:22:57 +02:00
gStringVar1 [ i ] = EOS ;
2018-10-26 23:54:41 +02:00
ConvertInternationalString ( gStringVar1 , gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . language ) ;
ConvertIntToDecimalStringN ( gStringVar2 , gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . number , STR_CONV_MODE_LEFT_ALIGN , 3 ) ;
2018-10-22 19:22:57 +02:00
GetFrontierTrainerName ( gStringVar3 , trainerId ) ;
}
break ;
2020-01-08 05:43:06 -05:00
case PARTNER_MSGID_MON1 :
2020-01-05 10:50:32 -05:00
monId = gSaveBlock2Ptr - > frontier . trainerIds [ 8 + k * 2 ] ;
sub_81646BC ( trainerId , monId ) ;
2018-10-22 19:22:57 +02:00
break ;
2020-01-08 05:43:06 -05:00
case PARTNER_MSGID_MON2_ASK :
2020-01-05 10:50:32 -05:00
monId = gSaveBlock2Ptr - > frontier . trainerIds [ 9 + k * 2 ] ;
sub_81646BC ( trainerId , monId ) ;
2018-10-22 19:22:57 +02:00
break ;
2020-01-08 05:43:06 -05:00
case PARTNER_MSGID_ACCEPT :
2018-10-22 19:22:57 +02:00
gPartnerTrainerId = trainerId ;
2019-12-20 18:52:29 -05:00
if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-22 19:22:57 +02:00
{
2019-02-07 11:37:28 -06:00
gSaveBlock2Ptr - > frontier . trainerIds [ 18 ] = gSaveBlock2Ptr - > frontier . trainerIds [ 8 + k * 2 ] ;
gSaveBlock2Ptr - > frontier . trainerIds [ 19 ] = gSaveBlock2Ptr - > frontier . trainerIds [ 9 + k * 2 ] ;
2018-10-22 19:22:57 +02:00
}
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
2018-10-22 19:22:57 +02:00
{
2019-02-07 11:37:28 -06:00
gSaveBlock2Ptr - > frontier . trainerIds [ 18 ] = gUnknown_03006298 [ 2 ] ;
gSaveBlock2Ptr - > frontier . trainerIds [ 19 ] = gUnknown_03006298 [ 3 ] ;
2018-10-22 19:22:57 +02:00
}
else
{
2019-02-07 11:37:28 -06:00
gSaveBlock2Ptr - > frontier . trainerIds [ 18 ] = gUnknown_03006298 [ 0 ] ;
gSaveBlock2Ptr - > frontier . trainerIds [ 19 ] = gUnknown_03006298 [ 1 ] ;
2018-10-22 19:22:57 +02:00
}
for ( k = 0 ; k < 14 ; k + + )
{
while ( 1 )
{
2019-12-20 18:52:29 -05:00
i = GetRandomScaledFrontierTrainerId ( challengeNum , k / 2 ) ;
2018-10-22 19:22:57 +02:00
if ( gPartnerTrainerId = = i )
continue ;
for ( j = 0 ; j < k ; j + + )
{
2019-02-07 11:37:28 -06:00
if ( gSaveBlock2Ptr - > frontier . trainerIds [ j ] = = i )
2018-10-22 19:22:57 +02:00
break ;
}
if ( j = = k )
break ;
}
2019-02-07 11:37:28 -06:00
gSaveBlock2Ptr - > frontier . trainerIds [ k ] = i ;
2018-10-22 19:22:57 +02:00
}
2019-02-07 11:37:28 -06:00
gSaveBlock2Ptr - > frontier . trainerIds [ 17 ] = trainerId ;
2018-10-22 19:22:57 +02:00
break ;
2020-01-08 05:43:06 -05:00
case PARTNER_MSGID_REJECT :
2018-10-22 19:22:57 +02:00
break ;
}
2018-10-26 23:54:41 +02:00
if ( trainerId = = TRAINER_EREADER )
2018-10-22 19:22:57 +02:00
return ;
2020-01-08 05:43:06 -05:00
// First check is redundant, only needs to make sure it's not an Apprentice
2019-12-20 18:52:29 -05:00
if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-22 19:22:57 +02:00
{
2020-01-08 05:43:06 -05:00
ShowFieldMessage ( sPartnerTrainerTextTables [ partnerId ] . strings [ gSpecialVar_0x8005 ] ) ;
2018-10-22 19:22:57 +02:00
}
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
2018-10-22 19:22:57 +02:00
{
2020-01-08 05:43:06 -05:00
ShowFieldMessage ( sPartnerTrainerTextTables [ partnerId ] . strings [ gSpecialVar_0x8005 ] ) ;
2018-10-22 19:22:57 +02:00
}
2020-01-08 05:43:06 -05:00
// Trainer is a former/record-mixed Apprentice, do Apprentice message
2018-10-22 19:22:57 +02:00
else
{
2020-01-08 05:43:06 -05:00
u8 apprenticeId = gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . id ;
ShowFieldMessage ( sPartnerApprenticeTextTables [ apprenticeId ] [ gSpecialVar_0x8005 ] ) ;
2018-10-22 19:22:57 +02:00
}
}
2020-01-08 05:43:06 -05:00
static void LoadLinkMultiOpponentsData ( void )
2018-10-22 19:22:57 +02:00
{
s32 challengeNum ;
s32 i , j ;
s32 trainerId = 0 ;
u32 lvlMode = gSaveBlock2Ptr - > frontier . lvlMode ;
u32 battleMode = VarGet ( VAR_FRONTIER_BATTLE_MODE ) ;
u32 battleNum = gSaveBlock2Ptr - > frontier . curChallengeBattleNum ;
GetMultiplayerId ( ) ; // Yet another pointless function call.
switch ( gSpecialVar_Result )
{
case 0 :
if ( battleMode = = FRONTIER_MODE_LINK_MULTIS )
{
2018-10-27 17:39:05 +02:00
challengeNum = gSaveBlock2Ptr - > frontier . towerWinStreaks [ battleMode ] [ lvlMode ] / 7 ;
2018-12-31 02:22:21 -06:00
if ( IsLinkTaskFinished ( ) )
2018-10-22 19:22:57 +02:00
{
SendBlock ( bitmask_all_link_players_but_self ( ) , & challengeNum , sizeof ( challengeNum ) ) ;
gSpecialVar_Result = 1 ;
}
}
else
{
gSpecialVar_Result = 6 ;
}
break ;
case 1 :
if ( ( GetBlockReceivedStatus ( ) & 3 ) = = 3 )
{
ResetBlockReceivedFlags ( ) ;
if ( gBlockRecvBuffer [ 0 ] [ 0 ] > gBlockRecvBuffer [ 1 ] [ 0 ] )
challengeNum = gBlockRecvBuffer [ 0 ] [ 0 ] ;
else
challengeNum = gBlockRecvBuffer [ 1 ] [ 0 ] ;
for ( i = 0 ; i < 14 ; i + + )
{
do
{
2019-12-20 18:52:29 -05:00
trainerId = GetRandomScaledFrontierTrainerId ( challengeNum , i / 2 ) ;
2018-10-22 19:22:57 +02:00
for ( j = 0 ; j < i ; j + + )
{
2019-02-07 11:37:28 -06:00
if ( gSaveBlock2Ptr - > frontier . trainerIds [ j ] = = trainerId )
2018-10-22 19:22:57 +02:00
break ;
}
} while ( i ! = j ) ;
if ( i = = j ) // This condition is always true, because of the loop above.
2019-02-07 11:37:28 -06:00
gSaveBlock2Ptr - > frontier . trainerIds [ i ] = trainerId ;
2018-10-22 19:22:57 +02:00
}
gSpecialVar_Result = 2 ;
}
break ;
case 2 :
2018-12-31 02:22:21 -06:00
if ( IsLinkTaskFinished ( ) )
2018-10-22 19:22:57 +02:00
{
2019-02-07 11:37:28 -06:00
SendBlock ( bitmask_all_link_players_but_self ( ) , & gSaveBlock2Ptr - > frontier . trainerIds , sizeof ( gSaveBlock2Ptr - > frontier . trainerIds ) ) ;
2018-10-22 19:22:57 +02:00
gSpecialVar_Result = 3 ;
}
break ;
case 3 :
if ( ( GetBlockReceivedStatus ( ) & 3 ) = = 3 )
{
ResetBlockReceivedFlags ( ) ;
2019-02-07 11:37:28 -06:00
memcpy ( & gSaveBlock2Ptr - > frontier . trainerIds , gBlockRecvBuffer , sizeof ( gSaveBlock2Ptr - > frontier . trainerIds ) ) ;
gTrainerBattleOpponent_A = gSaveBlock2Ptr - > frontier . trainerIds [ battleNum * 2 ] ;
gTrainerBattleOpponent_B = gSaveBlock2Ptr - > frontier . trainerIds [ battleNum * 2 + 1 ] ;
2018-10-22 19:22:57 +02:00
SetBattleFacilityTrainerGfxId ( gTrainerBattleOpponent_A , 0 ) ;
SetBattleFacilityTrainerGfxId ( gTrainerBattleOpponent_B , 1 ) ;
if ( gReceivedRemoteLinkPlayers ! = 0 & & gWirelessCommType = = 0 )
gSpecialVar_Result = 4 ;
else
gSpecialVar_Result = 6 ;
}
break ;
case 4 :
2020-08-13 03:09:47 -04:00
SetCloseLinkCallback ( ) ;
2018-10-22 19:22:57 +02:00
gSpecialVar_Result = 5 ;
break ;
case 5 :
if ( gReceivedRemoteLinkPlayers = = 0 )
{
gSpecialVar_Result = 6 ;
}
break ;
case 6 :
return ;
}
}
2018-10-25 21:27:10 +02:00
static void sub_8164DCC ( void )
2018-10-22 19:22:57 +02:00
{
if ( gWirelessCommType ! = 0 )
2020-08-13 03:09:47 -04:00
SetCloseLinkCallback ( ) ;
2018-10-22 19:22:57 +02:00
}
2020-01-08 05:43:06 -05:00
static void SetMultiPartnerGfx ( void )
2018-10-22 19:22:57 +02:00
{
2020-01-08 05:43:06 -05:00
// 0xF below means use VAR_OBJ_GFX_ID_E
SetBattleFacilityTrainerGfxId ( gSaveBlock2Ptr - > frontier . trainerIds [ 17 ] , 0xF ) ;
2018-10-22 19:22:57 +02:00
}
2019-11-28 22:46:39 -05:00
static void SetTowerInterviewData ( void )
2018-10-22 19:22:57 +02:00
{
s32 i ;
u8 text [ 32 ] ;
if ( VarGet ( VAR_FRONTIER_BATTLE_MODE ) ! = FRONTIER_MODE_SINGLES )
return ;
GetFrontierTrainerName ( text , gTrainerBattleOpponent_A ) ;
StripExtCtrlCodes ( text ) ;
2019-11-24 16:58:40 -05:00
StringCopy ( gSaveBlock2Ptr - > frontier . towerInterview . opponentName , text ) ;
GetBattleTowerTrainerLanguage ( & gSaveBlock2Ptr - > frontier . towerInterview . opponentLanguage , gTrainerBattleOpponent_A ) ;
gSaveBlock2Ptr - > frontier . towerInterview . opponentSpecies = GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ 1 ] ] , MON_DATA_SPECIES , NULL ) ;
gSaveBlock2Ptr - > frontier . towerInterview . playerSpecies = GetMonData ( & gPlayerParty [ gBattlerPartyIndexes [ 0 ] ] , MON_DATA_SPECIES , NULL ) ;
2018-10-22 19:22:57 +02:00
for ( i = 0 ; i < POKEMON_NAME_LENGTH + 1 ; i + + )
2019-11-24 16:58:40 -05:00
gSaveBlock2Ptr - > frontier . towerInterview . opponentMonNickname [ i ] = gBattleMons [ 0 ] . nickname [ i ] ;
gSaveBlock2Ptr - > frontier . towerBattleOutcome = gBattleOutcome ;
2018-10-22 19:22:57 +02:00
}
2018-10-25 21:27:10 +02:00
static void ValidateBattleTowerRecordChecksums ( void )
2018-10-22 19:22:57 +02:00
{
s32 i , j ;
u32 * record = ( u32 * ) ( & gSaveBlock2Ptr - > frontier . towerPlayer ) ;
u32 checksum = 0 ;
for ( j = 0 ; j < ( sizeof ( struct EmeraldBattleTowerRecord ) - 4 ) / 4 ; j + + ) // - 4, because of the last field being the checksum itself.
{
checksum + = record [ j ] ;
}
if ( gSaveBlock2Ptr - > frontier . towerPlayer . checksum ! = checksum )
ClearBattleTowerRecord ( & gSaveBlock2Ptr - > frontier . towerPlayer ) ;
for ( i = 0 ; i < 5 ; i + + )
{
record = ( u32 * ) ( & gSaveBlock2Ptr - > frontier . towerRecords [ i ] ) ;
checksum = 0 ;
for ( j = 0 ; j < ( sizeof ( struct EmeraldBattleTowerRecord ) - 4 ) / 4 ; j + + ) // - 4, because of the last field being the checksum itself.
{
checksum + = record [ j ] ;
}
if ( gSaveBlock2Ptr - > frontier . towerRecords [ i ] . checksum ! = checksum )
ClearBattleTowerRecord ( & gSaveBlock2Ptr - > frontier . towerRecords [ i ] ) ;
}
}
void CalcEmeraldBattleTowerChecksum ( struct EmeraldBattleTowerRecord * record )
{
u32 i ;
record - > checksum = 0 ;
for ( i = 0 ; i < ( sizeof ( struct EmeraldBattleTowerRecord ) - 4 ) / 4 ; i + + ) // - 4, because of the last field being the checksum itself.
record - > checksum + = ( ( u32 * ) record ) [ i ] ;
}
void CalcRubyBattleTowerChecksum ( struct RSBattleTowerRecord * record )
{
u32 i ;
record - > checksum = 0 ;
for ( i = 0 ; i < ( sizeof ( struct RSBattleTowerRecord ) - 4 ) / 4 ; i + + ) // - 4, because of the last field being the checksum itself.
record - > checksum + = ( ( u32 * ) record ) [ i ] ;
}
2018-10-25 21:27:10 +02:00
static void ClearBattleTowerRecord ( struct EmeraldBattleTowerRecord * record )
2018-10-22 19:22:57 +02:00
{
u32 i ;
for ( i = 0 ; i < sizeof ( struct EmeraldBattleTowerRecord ) / 4 ; i + + )
( ( u32 * ) record ) [ i ] = 0 ;
}
u16 GetCurrentBattleTowerWinStreak ( u8 lvlMode , u8 battleMode )
{
2018-10-27 17:39:05 +02:00
u16 winStreak = gSaveBlock2Ptr - > frontier . towerWinStreaks [ battleMode ] [ lvlMode ] ;
2018-10-22 19:22:57 +02:00
if ( winStreak > 9999 )
return 9999 ;
else
return winStreak ;
}
2018-10-25 21:27:10 +02:00
static u8 GetMonCountForBattleMode ( u8 battleMode )
2018-10-22 19:22:57 +02:00
{
2019-11-24 16:58:40 -05:00
u8 partySizes [ ARRAY_COUNT ( sBattleTowerPartySizes ) ] ;
memcpy ( partySizes , sBattleTowerPartySizes , sizeof ( sBattleTowerPartySizes ) ) ;
2018-10-22 19:22:57 +02:00
2019-11-24 16:58:40 -05:00
if ( battleMode < ARRAY_COUNT ( sBattleTowerPartySizes ) )
return partySizes [ battleMode ] ;
2018-10-22 19:22:57 +02:00
else
2019-11-24 16:58:40 -05:00
return FRONTIER_PARTY_SIZE ;
2018-10-22 19:22:57 +02:00
}
struct RibbonCounter
{
u8 partyIndex ;
u8 count ;
} ;
2018-10-25 21:27:10 +02:00
static void AwardBattleTowerRibbons ( void )
2018-10-22 19:22:57 +02:00
{
s32 i ;
u32 partyIndex ;
struct RibbonCounter ribbons [ 3 ] ; // BUG: 4 Pokemon can receive ribbons in a double battle mode.
u8 ribbonType = 0 ;
u8 lvlMode = gSaveBlock2Ptr - > frontier . lvlMode ;
u8 battleMode = VarGet ( VAR_FRONTIER_BATTLE_MODE ) ;
u8 monCount = GetMonCountForBattleMode ( battleMode ) ;
if ( lvlMode ! = FRONTIER_LVL_50 )
ribbonType = MON_DATA_VICTORY_RIBBON ;
else
ribbonType = MON_DATA_WINNING_RIBBON ;
gSpecialVar_Result = FALSE ;
if ( GetCurrentBattleTowerWinStreak ( lvlMode , battleMode ) > 55 )
{
for ( i = 0 ; i < monCount ; i + + )
{
partyIndex = gSaveBlock2Ptr - > frontier . selectedPartyMons [ i ] - 1 ;
ribbons [ i ] . partyIndex = partyIndex ;
ribbons [ i ] . count = 0 ;
if ( ! GetMonData ( & gSaveBlock1Ptr - > playerParty [ partyIndex ] , ribbonType ) )
{
gSpecialVar_Result = TRUE ;
SetMonData ( & gSaveBlock1Ptr - > playerParty [ partyIndex ] , ribbonType , & gSpecialVar_Result ) ;
ribbons [ i ] . count = GetRibbonCount ( & gSaveBlock1Ptr - > playerParty [ partyIndex ] ) ;
}
}
}
if ( gSpecialVar_Result )
{
IncrementGameStat ( GAME_STAT_RECEIVED_RIBBONS ) ;
for ( i = 1 ; i < monCount ; i + + )
{
if ( ribbons [ i ] . count > ribbons [ 0 ] . count )
{
struct RibbonCounter prevBest = ribbons [ 0 ] ;
ribbons [ 0 ] = ribbons [ i ] ;
ribbons [ i ] = prevBest ;
}
}
2019-11-10 21:54:00 -05:00
if ( ribbons [ 0 ] . count > NUM_CUTIES_RIBBONS )
2018-10-22 19:22:57 +02:00
{
2019-11-10 21:54:00 -05:00
TryPutSpotTheCutiesOnAir ( & gSaveBlock1Ptr - > playerParty [ ribbons [ 0 ] . partyIndex ] , ribbonType ) ;
2018-10-22 19:22:57 +02:00
}
}
}
// This is a leftover debugging function that is used to populate the E-Reader
// trainer with the player's current data.
2018-10-25 21:27:10 +02:00
static void FillEReaderTrainerWithPlayerData ( void )
2018-10-22 19:22:57 +02:00
{
struct BattleTowerEReaderTrainer * ereaderTrainer = & gSaveBlock2Ptr - > frontier . ereaderTrainer ;
s32 i , j ;
if ( gSaveBlock2Ptr - > playerGender ! = MALE )
{
ereaderTrainer - > facilityClass = gTowerFemaleFacilityClasses [ ( gSaveBlock2Ptr - > playerTrainerId [ 0 ] + gSaveBlock2Ptr - > playerTrainerId [ 1 ]
+ gSaveBlock2Ptr - > playerTrainerId [ 2 ] + gSaveBlock2Ptr - > playerTrainerId [ 3 ] ) % ARRAY_COUNT ( gTowerFemaleFacilityClasses ) ] ;
}
else
{
ereaderTrainer - > facilityClass = gTowerMaleFacilityClasses [ ( gSaveBlock2Ptr - > playerTrainerId [ 0 ] + gSaveBlock2Ptr - > playerTrainerId [ 1 ]
+ gSaveBlock2Ptr - > playerTrainerId [ 2 ] + gSaveBlock2Ptr - > playerTrainerId [ 3 ] ) % ARRAY_COUNT ( gTowerMaleFacilityClasses ) ] ;
}
2018-11-01 21:31:10 +01:00
CopyTrainerId ( ereaderTrainer - > trainerId , gSaveBlock2Ptr - > playerTrainerId ) ;
2018-10-22 19:22:57 +02:00
StringCopy7 ( ereaderTrainer - > name , gSaveBlock2Ptr - > playerName ) ;
ereaderTrainer - > winStreak = 1 ;
j = 7 ;
for ( i = 0 ; i < 6 ; i + + )
{
2019-02-27 12:45:31 -06:00
ereaderTrainer - > greeting [ i ] = gSaveBlock1Ptr - > easyChatBattleStart [ i ] ;
2018-10-22 19:22:57 +02:00
ereaderTrainer - > farewellPlayerLost [ i ] = j ;
ereaderTrainer - > farewellPlayerWon [ i ] = j + 6 ;
j + + ;
}
for ( i = 0 ; i < 3 ; i + + )
sub_80686FC ( & gPlayerParty [ i ] , & ereaderTrainer - > party [ i ] ) ;
SetEReaderTrainerChecksum ( ereaderTrainer ) ;
}
u8 GetEreaderTrainerFrontSpriteId ( void )
{
return gFacilityClassToPicIndex [ gSaveBlock2Ptr - > frontier . ereaderTrainer . facilityClass ] ;
}
u8 GetEreaderTrainerClassId ( void )
{
return gFacilityClassToTrainerClass [ gSaveBlock2Ptr - > frontier . ereaderTrainer . facilityClass ] ;
}
2018-10-25 21:27:10 +02:00
void GetEreaderTrainerName ( u8 * dst )
2018-10-22 19:22:57 +02:00
{
s32 i ;
for ( i = 0 ; i < 5 ; i + + )
2018-10-25 21:27:10 +02:00
dst [ i ] = gSaveBlock2Ptr - > frontier . ereaderTrainer . name [ i ] ;
2018-10-22 19:22:57 +02:00
2018-10-25 21:27:10 +02:00
dst [ i ] = EOS ;
2018-10-22 19:22:57 +02:00
}
// Checks if the saved E-Reader trainer is valid.
void ValidateEReaderTrainer ( void )
{
u32 i ;
u32 checksum ;
struct BattleTowerEReaderTrainer * ereaderTrainer ;
gSpecialVar_Result = FALSE ;
ereaderTrainer = & gSaveBlock2Ptr - > frontier . ereaderTrainer ;
checksum = 0 ;
for ( i = 0 ; i < ( sizeof ( struct BattleTowerEReaderTrainer ) - 4 ) / 4 ; i + + ) // - 4, because of the last field being the checksum itself.
checksum | = ( ( u32 * ) ereaderTrainer ) [ i ] ;
if ( checksum = = 0 )
{
gSpecialVar_Result = TRUE ;
return ;
}
checksum = 0 ;
for ( i = 0 ; i < ( sizeof ( struct BattleTowerEReaderTrainer ) - 4 ) / 4 ; i + + ) // - 4, because of the last field being the checksum itself.
checksum + = ( ( u32 * ) ereaderTrainer ) [ i ] ;
if ( gSaveBlock2Ptr - > frontier . ereaderTrainer . checksum ! = checksum )
{
ClearEReaderTrainer ( & gSaveBlock2Ptr - > frontier . ereaderTrainer ) ;
gSpecialVar_Result = TRUE ;
}
}
2018-10-25 21:27:10 +02:00
static void SetEReaderTrainerChecksum ( struct BattleTowerEReaderTrainer * ereaderTrainer )
2018-10-22 19:22:57 +02:00
{
s32 i ;
ereaderTrainer - > checksum = 0 ;
for ( i = 0 ; i < ( sizeof ( struct BattleTowerEReaderTrainer ) - 4 ) / 4 ; i + + ) // - 4, because of the last field being the checksum itself.
ereaderTrainer - > checksum + = ( ( u32 * ) ereaderTrainer ) [ i ] ;
}
void ClearEReaderTrainer ( struct BattleTowerEReaderTrainer * ereaderTrainer )
{
u32 i ;
for ( i = 0 ; i < ( sizeof ( struct BattleTowerEReaderTrainer ) ) / 4 ; i + + )
( ( u32 * ) ereaderTrainer ) [ i ] = 0 ;
}
void CopyEReaderTrainerGreeting ( void )
{
FrontierSpeechToString ( gSaveBlock2Ptr - > frontier . ereaderTrainer . greeting ) ;
}
2018-10-25 21:27:10 +02:00
static void CopyEReaderTrainerFarewellMessage ( void )
2018-10-22 19:22:57 +02:00
{
if ( gBattleOutcome = = B_OUTCOME_DREW )
gStringVar4 [ 0 ] = EOS ;
else if ( gBattleOutcome = = B_OUTCOME_WON )
FrontierSpeechToString ( gSaveBlock2Ptr - > frontier . ereaderTrainer . farewellPlayerWon ) ;
else
FrontierSpeechToString ( gSaveBlock2Ptr - > frontier . ereaderTrainer . farewellPlayerLost ) ;
}
2020-01-08 04:26:26 -05:00
void TryHideBattleTowerReporter ( void )
2018-10-22 19:22:57 +02:00
{
2019-11-24 16:58:40 -05:00
if ( gSaveBlock2Ptr - > frontier . challengeStatus = = CHALLENGE_STATUS_SAVING )
2020-01-08 04:26:26 -05:00
HideBattleTowerReporter ( ) ;
2019-01-02 21:12:43 +00:00
if ( FlagGet ( FLAG_CANCEL_BATTLE_ROOM_CHALLENGE ) = = TRUE )
2018-10-22 19:22:57 +02:00
{
2020-01-08 04:26:26 -05:00
HideBattleTowerReporter ( ) ;
2019-01-02 21:12:43 +00:00
FlagClear ( FLAG_CANCEL_BATTLE_ROOM_CHALLENGE ) ;
2018-10-22 19:22:57 +02:00
}
}
# define STEVEN_OTID 61226
2018-10-25 21:27:10 +02:00
static void FillPartnerParty ( u16 trainerId )
2018-10-22 19:22:57 +02:00
{
s32 i , j ;
u32 ivs , level ;
u32 friendship ;
2020-01-05 10:50:32 -05:00
u16 monId ;
2018-10-22 19:22:57 +02:00
u32 otID ;
u8 trainerName [ PLAYER_NAME_LENGTH + 1 ] ;
2018-10-24 23:14:45 +02:00
SetFacilityPtrsGetLevel ( ) ;
2018-10-22 19:22:57 +02:00
if ( trainerId = = TRAINER_STEVEN_PARTNER )
{
2020-04-09 15:18:53 -04:00
for ( i = 0 ; i < MULTI_PARTY_SIZE ; i + + )
2018-10-22 19:22:57 +02:00
{
do
{
j = Random32 ( ) ;
} while ( IsShinyOtIdPersonality ( STEVEN_OTID , j ) | | sStevenMons [ i ] . nature ! = GetNatureFromPersonality ( j ) ) ;
2020-04-09 15:18:53 -04:00
CreateMon ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] ,
2018-10-22 19:22:57 +02:00
sStevenMons [ i ] . species ,
sStevenMons [ i ] . level ,
sStevenMons [ i ] . fixedIV ,
TRUE , i , // BUG: personality was stored in the 'j' variable. As a result, Steven's pokemon do not have the intended natures.
2019-08-30 23:06:43 -04:00
OT_ID_PRESET , STEVEN_OTID ) ;
2019-10-17 19:22:03 -04:00
for ( j = 0 ; j < PARTY_SIZE ; j + + )
2020-04-09 15:18:53 -04:00
SetMonData ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] , MON_DATA_HP_EV + j , & sStevenMons [ i ] . evs [ j ] ) ;
2018-12-25 12:50:15 -05:00
for ( j = 0 ; j < MAX_MON_MOVES ; j + + )
2020-04-09 15:18:53 -04:00
SetMonMoveSlot ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] , sStevenMons [ i ] . moves [ j ] , j ) ;
SetMonData ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] , MON_DATA_OT_NAME , gTrainers [ TRAINER_STEVEN ] . trainerName ) ;
2018-10-22 19:22:57 +02:00
j = MALE ;
2020-04-09 15:18:53 -04:00
SetMonData ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] , MON_DATA_OT_GENDER , & j ) ;
CalculateMonStats ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] ) ;
2018-10-22 19:22:57 +02:00
}
}
2018-10-26 23:54:41 +02:00
else if ( trainerId = = TRAINER_EREADER )
2018-10-22 19:22:57 +02:00
{
// Scrapped, lol.
trainerName [ 0 ] = gGameLanguage ;
}
2019-12-20 18:52:29 -05:00
else if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-22 19:22:57 +02:00
{
2018-10-24 23:14:45 +02:00
level = SetFacilityPtrsGetLevel ( ) ;
2018-10-22 19:22:57 +02:00
ivs = GetFrontierTrainerFixedIvs ( trainerId ) ;
otID = Random32 ( ) ;
2020-04-09 15:18:53 -04:00
for ( i = 0 ; i < FRONTIER_MULTI_PARTY_SIZE ; i + + )
2018-10-22 19:22:57 +02:00
{
2020-01-05 10:50:32 -05:00
monId = gSaveBlock2Ptr - > frontier . trainerIds [ i + 18 ] ;
2020-04-09 15:18:53 -04:00
CreateMonWithEVSpreadNatureOTID ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . species ,
2018-10-22 19:22:57 +02:00
level ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . nature ,
2018-10-22 19:22:57 +02:00
ivs ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . evSpread ,
2018-10-22 19:22:57 +02:00
otID ) ;
2019-12-18 02:32:52 -05:00
friendship = MAX_FRIENDSHIP ;
2018-12-25 12:50:15 -05:00
for ( j = 0 ; j < MAX_MON_MOVES ; j + + )
2018-10-22 19:22:57 +02:00
{
2020-04-09 15:18:53 -04:00
SetMonMoveSlot ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] , gFacilityTrainerMons [ monId ] . moves [ j ] , j ) ;
2020-01-05 10:50:32 -05:00
if ( gFacilityTrainerMons [ monId ] . moves [ j ] = = MOVE_FRUSTRATION )
2018-10-22 19:22:57 +02:00
friendship = 0 ;
}
2020-04-09 15:18:53 -04:00
SetMonData ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] , MON_DATA_FRIENDSHIP , & friendship ) ;
SetMonData ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] , MON_DATA_HELD_ITEM , & gBattleFrontierHeldItems [ gFacilityTrainerMons [ monId ] . itemTableId ] ) ;
2018-10-22 19:22:57 +02:00
for ( j = 0 ; j < PLAYER_NAME_LENGTH + 1 ; j + + )
trainerName [ j ] = gFacilityTrainers [ trainerId ] . trainerName [ j ] ;
2020-04-09 15:18:53 -04:00
SetMonData ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] , MON_DATA_OT_NAME , & trainerName ) ;
2018-10-22 19:22:57 +02:00
j = IsFrontierTrainerFemale ( trainerId ) ;
2020-04-09 15:18:53 -04:00
SetMonData ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] , MON_DATA_OT_GENDER , & j ) ;
2018-10-22 19:22:57 +02:00
}
}
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
2018-10-22 19:22:57 +02:00
{
2018-10-26 23:54:41 +02:00
trainerId - = TRAINER_RECORD_MIXING_FRIEND ;
2020-04-09 15:18:53 -04:00
for ( i = 0 ; i < FRONTIER_MULTI_PARTY_SIZE ; i + + )
2018-10-22 19:22:57 +02:00
{
struct EmeraldBattleTowerRecord * record = & gSaveBlock2Ptr - > frontier . towerRecords [ trainerId ] ;
2019-02-07 11:37:28 -06:00
struct BattleTowerPokemon monData = record - > party [ gSaveBlock2Ptr - > frontier . trainerIds [ 18 + i ] ] ;
2018-10-22 19:22:57 +02:00
StringCopy ( trainerName , record - > name ) ;
if ( record - > language = = LANGUAGE_JAPANESE )
{
if ( monData . nickname [ 0 ] ! = EXT_CTRL_CODE_BEGIN | | monData . nickname [ 1 ] ! = EXT_CTRL_CODE_JPN )
{
monData . nickname [ 5 ] = EOS ;
ConvertInternationalString ( monData . nickname , LANGUAGE_JAPANESE ) ;
}
}
else
{
if ( monData . nickname [ 0 ] = = EXT_CTRL_CODE_BEGIN & & monData . nickname [ 1 ] = = EXT_CTRL_CODE_JPN )
trainerName [ 5 ] = EOS ;
}
2020-04-09 15:18:53 -04:00
CreateBattleTowerMon2 ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] , & monData , TRUE ) ;
SetMonData ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] , MON_DATA_OT_NAME , trainerName ) ;
2018-10-26 23:54:41 +02:00
j = IsFrontierTrainerFemale ( trainerId + TRAINER_RECORD_MIXING_FRIEND ) ;
2020-04-09 15:18:53 -04:00
SetMonData ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] , MON_DATA_OT_GENDER , & j ) ;
2018-10-22 19:22:57 +02:00
}
}
else
{
2018-10-26 23:54:41 +02:00
trainerId - = TRAINER_RECORD_MIXING_APPRENTICE ;
2020-04-09 15:18:53 -04:00
for ( i = 0 ; i < FRONTIER_MULTI_PARTY_SIZE ; i + + )
2018-10-22 19:22:57 +02:00
{
2020-04-09 15:18:53 -04:00
CreateApprenticeMon ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] , & gSaveBlock2Ptr - > apprentices [ trainerId ] , gSaveBlock2Ptr - > frontier . trainerIds [ 18 + i ] ) ;
2018-10-26 23:54:41 +02:00
j = IsFrontierTrainerFemale ( trainerId + TRAINER_RECORD_MIXING_APPRENTICE ) ;
2020-04-09 15:18:53 -04:00
SetMonData ( & gPlayerParty [ MULTI_PARTY_SIZE + i ] , MON_DATA_OT_GENDER , & j ) ;
2018-10-22 19:22:57 +02:00
}
}
}
bool32 RubyBattleTowerRecordToEmerald ( struct RSBattleTowerRecord * src , struct EmeraldBattleTowerRecord * dst )
{
s32 i , validMons = 0 ;
2019-11-24 16:58:40 -05:00
for ( i = 0 ; i < FRONTIER_PARTY_SIZE ; i + + )
2018-10-22 19:22:57 +02:00
{
if ( src - > party [ i ] . species )
validMons + + ;
}
2019-11-24 16:58:40 -05:00
if ( validMons ! = FRONTIER_PARTY_SIZE )
2018-10-22 19:22:57 +02:00
{
memset ( dst , 0 , sizeof ( * dst ) ) ;
return FALSE ;
}
else
{
dst - > lvlMode = src - > lvlMode ;
dst - > winStreak = src - > winStreak ;
2018-12-05 22:21:26 +01:00
// BUG: Reading outside the array. sRubyFacilityClassToEmerald has less than FACILITY_CLASSES_COUNT entries.
2019-11-24 16:58:40 -05:00
// Fix by using ARRAY_COUNT(sRubyFacilityClassToEmerald)
2018-12-05 22:21:26 +01:00
for ( i = 0 ; i < FACILITY_CLASSES_COUNT ; i + + )
2018-10-22 19:22:57 +02:00
{
if ( sRubyFacilityClassToEmerald [ i ] [ 0 ] = = src - > facilityClass )
break ;
}
2018-12-05 22:21:26 +01:00
if ( i ! = FACILITY_CLASSES_COUNT )
2018-10-22 19:22:57 +02:00
dst - > facilityClass = sRubyFacilityClassToEmerald [ i ] [ 1 ] ;
else
dst - > facilityClass = FACILITY_CLASS_YOUNGSTER ;
for ( i = 0 ; i < PLAYER_NAME_LENGTH + 1 ; i + + )
dst - > name [ i ] = src - > name [ i ] ;
2019-09-08 11:53:48 -04:00
for ( i = 0 ; i < TRAINER_ID_LENGTH ; i + + )
2018-10-22 19:22:57 +02:00
dst - > trainerId [ i ] = src - > trainerId [ i ] ;
2019-11-24 16:58:40 -05:00
for ( i = 0 ; i < EASY_CHAT_BATTLE_WORDS_COUNT ; i + + )
2018-10-22 19:22:57 +02:00
dst - > greeting [ i ] = src - > greeting [ i ] ;
2019-11-24 16:58:40 -05:00
for ( i = 0 ; i < EASY_CHAT_BATTLE_WORDS_COUNT ; i + + )
dst - > speechWon [ i ] = sRecordTrainerSpeechWon [ i ] ;
for ( i = 0 ; i < EASY_CHAT_BATTLE_WORDS_COUNT ; i + + )
dst - > speechLost [ i ] = sRecordTrainerSpeechLost [ i ] ;
for ( i = 0 ; i < FRONTIER_PARTY_SIZE ; i + + )
2018-10-22 19:22:57 +02:00
dst - > party [ i ] = src - > party [ i ] ;
2019-11-24 16:58:40 -05:00
CpuFill32 ( 0 , & dst - > party [ FRONTIER_PARTY_SIZE ] , sizeof ( dst - > party [ FRONTIER_PARTY_SIZE ] ) ) ;
2018-10-22 19:22:57 +02:00
CalcEmeraldBattleTowerChecksum ( dst ) ;
return TRUE ;
2018-10-21 20:13:12 +02:00
}
}
2018-10-24 23:14:45 +02:00
bool32 EmeraldBattleTowerRecordToRuby ( struct EmeraldBattleTowerRecord * src , struct RSBattleTowerRecord * dst )
{
s32 i , validMons = 0 ;
2019-11-24 16:58:40 -05:00
for ( i = 0 ; i < FRONTIER_PARTY_SIZE ; i + + )
2018-10-24 23:14:45 +02:00
{
if ( src - > party [ i ] . species )
validMons + + ;
}
2019-11-24 16:58:40 -05:00
if ( validMons ! = FRONTIER_PARTY_SIZE )
2018-10-24 23:14:45 +02:00
{
memset ( dst , 0 , sizeof ( * dst ) ) ;
return FALSE ;
}
else
{
dst - > lvlMode = src - > lvlMode ;
dst - > winStreak = src - > winStreak ;
2018-12-05 22:21:26 +01:00
// BUG: Reading outside the array. sRubyFacilityClassToEmerald has less than FACILITY_CLASSES_COUNT entries.
2019-11-24 16:58:40 -05:00
// Fix by using ARRAY_COUNT(sRubyFacilityClassToEmerald) instead
2018-12-05 22:21:26 +01:00
for ( i = 0 ; i < FACILITY_CLASSES_COUNT ; i + + )
2018-10-24 23:14:45 +02:00
{
if ( sRubyFacilityClassToEmerald [ i ] [ 1 ] = = src - > facilityClass )
break ;
}
2018-12-05 22:21:26 +01:00
if ( i ! = FACILITY_CLASSES_COUNT )
2018-10-24 23:14:45 +02:00
dst - > facilityClass = sRubyFacilityClassToEmerald [ i ] [ 0 ] ;
else
2019-11-24 16:58:40 -05:00
dst - > facilityClass = RS_FACILITY_CLASS_YOUNGSTER ;
2018-10-24 23:14:45 +02:00
for ( i = 0 ; i < PLAYER_NAME_LENGTH + 1 ; i + + )
dst - > name [ i ] = src - > name [ i ] ;
2019-09-08 11:53:48 -04:00
for ( i = 0 ; i < TRAINER_ID_LENGTH ; i + + )
2018-10-24 23:14:45 +02:00
dst - > trainerId [ i ] = src - > trainerId [ i ] ;
2019-11-24 16:58:40 -05:00
for ( i = 0 ; i < EASY_CHAT_BATTLE_WORDS_COUNT ; i + + )
2018-10-24 23:14:45 +02:00
dst - > greeting [ i ] = src - > greeting [ i ] ;
2019-11-24 16:58:40 -05:00
for ( i = 0 ; i < FRONTIER_PARTY_SIZE ; i + + )
2018-10-24 23:14:45 +02:00
dst - > party [ i ] = src - > party [ i ] ;
CalcRubyBattleTowerChecksum ( dst ) ;
return TRUE ;
}
}
void CalcApprenticeChecksum ( struct Apprentice * apprentice )
{
s32 i ;
apprentice - > checksum = 0 ;
for ( i = 0 ; i < ( sizeof ( struct Apprentice ) - 4 ) / 4 ; i + + )
apprentice - > checksum + = ( ( u32 * ) apprentice ) [ i ] ;
}
2018-10-25 21:27:10 +02:00
static void ClearApprentice ( struct Apprentice * apprentice )
2018-10-24 23:14:45 +02:00
{
s32 i ;
for ( i = 0 ; i < ( sizeof ( struct Apprentice ) ) / 4 ; i + + )
( ( u32 * ) apprentice ) [ i ] = 0 ;
ResetApprenticeStruct ( apprentice ) ;
}
2018-10-25 21:27:10 +02:00
static void ValidateApprenticesChecksums ( void )
2018-10-24 23:14:45 +02:00
{
s32 i , j ;
2019-11-20 17:36:52 -05:00
for ( i = 0 ; i < APPRENTICE_COUNT ; i + + )
2018-10-24 23:14:45 +02:00
{
u32 * data = ( u32 * ) & gSaveBlock2Ptr - > apprentices [ i ] ;
u32 checksum = 0 ;
for ( j = 0 ; j < ( sizeof ( struct Apprentice ) - 4 ) / 4 ; j + + )
checksum + = data [ j ] ;
if ( gSaveBlock2Ptr - > apprentices [ i ] . checksum ! = checksum )
ClearApprentice ( & gSaveBlock2Ptr - > apprentices [ i ] ) ;
}
}
void GetBattleTowerTrainerLanguage ( u8 * dst , u16 trainerId )
{
2018-10-26 23:54:41 +02:00
if ( trainerId = = TRAINER_EREADER )
2018-10-24 23:14:45 +02:00
{
* dst = gGameLanguage ;
}
2019-12-20 18:52:29 -05:00
else if ( trainerId < FRONTIER_TRAINERS_COUNT )
2018-10-24 23:14:45 +02:00
{
* dst = gGameLanguage ;
}
2018-10-26 23:54:41 +02:00
else if ( trainerId < TRAINER_RECORD_MIXING_APPRENTICE )
2018-10-24 23:14:45 +02:00
{
if ( gBattleTypeFlags & BATTLE_TYPE_RECORDED )
2018-11-01 15:06:50 +01:00
* dst = GetRecordedBattleRecordMixFriendLanguage ( ) ;
2018-10-24 23:14:45 +02:00
else
2018-10-26 23:54:41 +02:00
* dst = gSaveBlock2Ptr - > frontier . towerRecords [ trainerId - TRAINER_RECORD_MIXING_FRIEND ] . language ;
2018-10-24 23:14:45 +02:00
}
else
{
if ( gBattleTypeFlags & BATTLE_TYPE_RECORDED )
2018-11-01 15:06:50 +01:00
* dst = GetRecordedBattleApprenticeLanguage ( ) ;
2018-10-24 23:14:45 +02:00
else
2018-10-26 23:54:41 +02:00
* dst = gSaveBlock2Ptr - > apprentices [ trainerId - TRAINER_RECORD_MIXING_APPRENTICE ] . language ;
2018-10-24 23:14:45 +02:00
}
}
u8 SetFacilityPtrsGetLevel ( void )
{
if ( gSaveBlock2Ptr - > frontier . lvlMode = = FRONTIER_LVL_TENT )
{
return SetTentPtrsGetLevel ( ) ;
}
else
{
gFacilityTrainers = gBattleFrontierTrainers ;
gFacilityTrainerMons = gBattleFrontierMons ;
return GetFrontierEnemyMonLevel ( gSaveBlock2Ptr - > frontier . lvlMode ) ;
}
}
u8 GetFrontierEnemyMonLevel ( u8 lvlMode )
{
u8 level ;
switch ( lvlMode )
{
default :
case FRONTIER_LVL_50 :
level = 50 ;
break ;
case FRONTIER_LVL_OPEN :
level = GetHighestLevelInPlayerParty ( ) ;
if ( level < 60 )
level = 60 ;
break ;
}
return level ;
}
s32 GetHighestLevelInPlayerParty ( void )
{
s32 highestLevel = 0 ;
s32 i ;
for ( i = 0 ; i < PARTY_SIZE ; i + + )
{
if ( GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES , NULL )
& & GetMonData ( & gPlayerParty [ i ] , MON_DATA_SPECIES2 , NULL ) ! = SPECIES_EGG )
{
s32 level = GetMonData ( & gPlayerParty [ i ] , MON_DATA_LEVEL , NULL ) ;
if ( level > highestLevel )
highestLevel = level ;
}
}
return highestLevel ;
}
2019-12-20 18:52:29 -05:00
// Frontier Trainer parties are roughly scaled in difficulty with higher trainer IDs, so scale IVs as well
// Duplicated in Battle Dome as GetDomeTrainerMonIvs
2018-10-25 21:27:10 +02:00
static u8 GetFrontierTrainerFixedIvs ( u16 trainerId )
2018-10-24 23:14:45 +02:00
{
2019-12-20 18:52:29 -05:00
u8 fixedIv ;
2018-10-24 23:14:45 +02:00
2019-12-20 18:52:29 -05:00
if ( trainerId < = FRONTIER_TRAINER_JILL ) // 0 - 99
fixedIv = 3 ;
else if ( trainerId < = FRONTIER_TRAINER_CHLOE ) // 100 - 119
fixedIv = 6 ;
else if ( trainerId < = FRONTIER_TRAINER_SOFIA ) // 120 - 139
fixedIv = 9 ;
else if ( trainerId < = FRONTIER_TRAINER_JAZLYN ) // 140 - 159
fixedIv = 12 ;
else if ( trainerId < = FRONTIER_TRAINER_ALISON ) // 160 - 179
fixedIv = 15 ;
else if ( trainerId < = FRONTIER_TRAINER_LAMAR ) // 180 - 199
fixedIv = 18 ;
else if ( trainerId < = FRONTIER_TRAINER_TESS ) // 200 - 219
fixedIv = 21 ;
else // 220+ (- 299)
fixedIv = 31 ;
2018-10-24 23:14:45 +02:00
2019-12-20 18:52:29 -05:00
return fixedIv ;
2018-10-24 23:14:45 +02:00
}
2018-10-25 21:27:10 +02:00
static u16 sub_8165D40 ( void )
2018-10-24 23:14:45 +02:00
{
u32 facility = VarGet ( VAR_FRONTIER_FACILITY ) ;
if ( facility = = FRONTIER_FACILITY_PALACE )
return Random ( ) % 30 ;
else if ( facility = = FRONTIER_FACILITY_ARENA )
return Random ( ) % 30 ;
else if ( facility = = FRONTIER_FACILITY_FACTORY )
return Random ( ) % 30 ;
else if ( facility = = FRONTIER_FACILITY_TOWER )
return 0 ;
else
return 0 ;
}
2018-10-25 21:27:10 +02:00
static u8 SetTentPtrsGetLevel ( void )
2018-10-24 23:14:45 +02:00
{
u8 level = 30 ;
2019-12-18 02:32:52 -05:00
u32 facility = VarGet ( VAR_FRONTIER_FACILITY ) ;
2018-10-24 23:14:45 +02:00
2019-12-18 02:32:52 -05:00
if ( facility = = FRONTIER_FACILITY_FACTORY )
2018-10-24 23:14:45 +02:00
{
gFacilityTrainers = gSlateportBattleTentTrainers ;
gFacilityTrainerMons = gSlateportBattleTentMons ;
}
2019-12-18 02:32:52 -05:00
else if ( facility = = FRONTIER_FACILITY_PALACE )
2018-10-24 23:14:45 +02:00
{
gFacilityTrainers = gVerdanturfBattleTentTrainers ;
gFacilityTrainerMons = gVerdanturfBattleTentMons ;
}
2019-12-18 02:32:52 -05:00
else if ( facility = = FRONTIER_FACILITY_ARENA )
2018-10-24 23:14:45 +02:00
{
gFacilityTrainers = gFallarborBattleTentTrainers ;
gFacilityTrainerMons = gFallarborBattleTentMons ;
}
else
{
gFacilityTrainers = gBattleFrontierTrainers ;
gFacilityTrainerMons = gBattleFrontierMons ;
}
level = GetHighestLevelInPlayerParty ( ) ;
if ( level < 30 )
level = 30 ;
return level ;
}
2019-11-28 22:46:39 -05:00
static void SetNextBattleTentOpponent ( void )
2018-10-24 23:14:45 +02:00
{
s32 i ;
u16 trainerId ;
do
{
trainerId = sub_8165D40 ( ) ;
for ( i = 0 ; i < gSaveBlock2Ptr - > frontier . curChallengeBattleNum ; i + + )
{
2019-02-07 11:37:28 -06:00
if ( gSaveBlock2Ptr - > frontier . trainerIds [ i ] = = trainerId )
2018-10-24 23:14:45 +02:00
break ;
}
} while ( i ! = gSaveBlock2Ptr - > frontier . curChallengeBattleNum ) ;
gTrainerBattleOpponent_A = trainerId ;
SetBattleFacilityTrainerGfxId ( gTrainerBattleOpponent_A , 0 ) ;
if ( gSaveBlock2Ptr - > frontier . curChallengeBattleNum + 1 < 3 )
2019-02-07 11:37:28 -06:00
gSaveBlock2Ptr - > frontier . trainerIds [ gSaveBlock2Ptr - > frontier . curChallengeBattleNum ] = gTrainerBattleOpponent_A ;
2018-10-24 23:14:45 +02:00
}
2018-10-25 21:27:10 +02:00
static void FillTentTrainerParty_ ( u16 trainerId , u8 firstMonId , u8 monCount )
2018-10-24 23:14:45 +02:00
{
s32 i , j ;
2020-04-09 15:18:53 -04:00
u16 chosenMonIndices [ MAX_FRONTIER_PARTY_SIZE ] ;
2018-10-24 23:14:45 +02:00
u8 friendship ;
u8 level = SetTentPtrsGetLevel ( ) ;
u8 fixedIV = 0 ;
u8 bfMonCount ;
2020-01-05 10:50:32 -05:00
const u16 * monSet = NULL ;
2018-10-24 23:14:45 +02:00
u32 otID = 0 ;
2020-01-05 10:50:32 -05:00
u16 monId ;
2018-10-24 23:14:45 +02:00
2020-01-05 10:50:32 -05:00
monSet = gFacilityTrainers [ gTrainerBattleOpponent_A ] . monSet ;
2018-10-24 23:14:45 +02:00
bfMonCount = 0 ;
2020-01-05 10:50:32 -05:00
monId = monSet [ bfMonCount ] ;
while ( monId ! = 0xFFFF )
2018-10-24 23:14:45 +02:00
{
bfMonCount + + ;
2020-01-05 10:50:32 -05:00
monId = monSet [ bfMonCount ] ;
if ( monId = = 0xFFFF )
2018-10-24 23:14:45 +02:00
break ;
}
i = 0 ;
otID = Random32 ( ) ;
while ( i ! = monCount )
{
2020-01-05 10:50:32 -05:00
u16 monId = monSet [ Random ( ) % bfMonCount ] ;
2018-10-24 23:14:45 +02:00
// Ensure this pokemon species isn't a duplicate.
for ( j = 0 ; j < i + firstMonId ; j + + )
{
2020-01-05 10:50:32 -05:00
if ( GetMonData ( & gEnemyParty [ j ] , MON_DATA_SPECIES , NULL ) = = gFacilityTrainerMons [ monId ] . species )
2018-10-24 23:14:45 +02:00
break ;
}
if ( j ! = i + firstMonId )
continue ;
// Ensure this Pokemon's held item isn't a duplicate.
for ( j = 0 ; j < i + firstMonId ; j + + )
{
if ( GetMonData ( & gEnemyParty [ j ] , MON_DATA_HELD_ITEM , NULL ) ! = 0
2020-01-05 10:50:32 -05:00
& & GetMonData ( & gEnemyParty [ j ] , MON_DATA_HELD_ITEM , NULL ) = = gBattleFrontierHeldItems [ gFacilityTrainerMons [ monId ] . itemTableId ] )
2018-10-24 23:14:45 +02:00
break ;
}
if ( j ! = i + firstMonId )
continue ;
// Ensure this exact pokemon index isn't a duplicate. This check doesn't seem necessary
// because the species and held items were already checked directly above.
for ( j = 0 ; j < i ; j + + )
{
2020-01-05 10:50:32 -05:00
if ( chosenMonIndices [ j ] = = monId )
2018-10-24 23:14:45 +02:00
break ;
}
if ( j ! = i )
continue ;
2020-01-05 10:50:32 -05:00
chosenMonIndices [ i ] = monId ;
2018-10-24 23:14:45 +02:00
// Place the chosen pokemon into the trainer's party.
2018-11-11 16:44:27 +01:00
CreateMonWithEVSpreadNatureOTID ( & gEnemyParty [ i + firstMonId ] ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . species ,
2018-10-24 23:14:45 +02:00
level ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . nature ,
2018-10-24 23:14:45 +02:00
fixedIV ,
2020-01-05 10:50:32 -05:00
gFacilityTrainerMons [ monId ] . evSpread ,
2018-10-24 23:14:45 +02:00
otID ) ;
2019-12-18 02:32:52 -05:00
friendship = MAX_FRIENDSHIP ;
2018-10-24 23:14:45 +02:00
// Give the chosen pokemon its specified moves.
2018-12-25 12:50:15 -05:00
for ( j = 0 ; j < MAX_MON_MOVES ; j + + )
2018-10-24 23:14:45 +02:00
{
2020-01-05 10:50:32 -05:00
SetMonMoveSlot ( & gEnemyParty [ i + firstMonId ] , gFacilityTrainerMons [ monId ] . moves [ j ] , j ) ;
if ( gFacilityTrainerMons [ monId ] . moves [ j ] = = MOVE_FRUSTRATION )
2018-10-24 23:14:45 +02:00
friendship = 0 ; // Frustration is more powerful the lower the pokemon's friendship is.
}
SetMonData ( & gEnemyParty [ i + firstMonId ] , MON_DATA_FRIENDSHIP , & friendship ) ;
2020-01-05 10:50:32 -05:00
SetMonData ( & gEnemyParty [ i + firstMonId ] , MON_DATA_HELD_ITEM , & gBattleFrontierHeldItems [ gFacilityTrainerMons [ monId ] . itemTableId ] ) ;
2018-10-24 23:14:45 +02:00
// The pokemon was successfully added to the trainer's party, so it's safe to move on to
// the next party slot.
i + + ;
}
}
2018-10-25 21:27:10 +02:00
2019-01-13 12:12:27 +01:00
u8 FacilityClassToGraphicsId ( u8 facilityClass )
2018-10-25 21:27:10 +02:00
{
u8 trainerObjectGfxId ;
u8 i ;
// Search male classes.
for ( i = 0 ; i < ARRAY_COUNT ( gTowerMaleFacilityClasses ) ; i + + )
{
if ( gTowerMaleFacilityClasses [ i ] = = facilityClass )
break ;
}
if ( i ! = ARRAY_COUNT ( gTowerMaleFacilityClasses ) )
{
trainerObjectGfxId = gTowerMaleTrainerGfxIds [ i ] ;
return trainerObjectGfxId ;
}
// Search female classes.
for ( i = 0 ; i < ARRAY_COUNT ( gTowerFemaleFacilityClasses ) ; i + + )
{
if ( gTowerFemaleFacilityClasses [ i ] = = facilityClass )
break ;
}
if ( i ! = ARRAY_COUNT ( gTowerFemaleFacilityClasses ) )
{
trainerObjectGfxId = gTowerFemaleTrainerGfxIds [ i ] ;
return trainerObjectGfxId ;
}
else
{
2019-11-20 23:12:51 -05:00
return OBJ_EVENT_GFX_BOY_1 ;
2018-10-25 21:27:10 +02:00
}
}
bool32 ValidateBattleTowerRecord ( u8 recordId ) // unused
{
s32 i ;
u32 * record = ( u32 * ) ( & gSaveBlock2Ptr - > frontier . towerRecords [ recordId ] ) ;
u32 checksum = 0 ;
u32 hasData = 0 ;
for ( i = 0 ; i < ( sizeof ( struct EmeraldBattleTowerRecord ) - 4 ) / 4 ; i + + ) // - 4, because of the last fjeld bejng the checksum jtself.
{
checksum + = record [ i ] ;
hasData | = record [ i ] ;
}
if ( checksum = = 0 & & hasData = = 0 )
{
return FALSE ;
}
else if ( gSaveBlock2Ptr - > frontier . towerRecords [ recordId ] . checksum ! = checksum )
{
ClearBattleTowerRecord ( & gSaveBlock2Ptr - > frontier . towerRecords [ recordId ] ) ;
return FALSE ;
}
else
{
return TRUE ;
}
}
void sub_8166188 ( void )
{
if ( gBattleTypeFlags & ( BATTLE_TYPE_LINK | BATTLE_TYPE_x2000000 ) )
{
s32 i ;
u8 enemyLevel = SetFacilityPtrsGetLevel ( ) ;
for ( i = 0 ; i < PARTY_SIZE ; i + + )
{
u32 species = GetMonData ( & gEnemyParty [ i ] , MON_DATA_SPECIES , NULL ) ;
if ( species )
{
SetMonData ( & gEnemyParty [ i ] , MON_DATA_EXP , & gExperienceTables [ gBaseStats [ species ] . growthRate ] [ enemyLevel ] ) ;
CalculateMonStats ( & gEnemyParty [ i ] ) ;
}
}
}
}