Files
Pokemon-Firered/src/vs_seeker.c
T
2019-10-21 13:15:45 -04:00

1609 lines
63 KiB
C

#include "global.h"
#include "constants/songs.h"
#include "sound.h"
#include "task.h"
#include "malloc.h"
#include "field_map_obj.h"
#include "new_menu_helpers.h"
#include "item_use.h"
#include "event_scripts.h"
#include "event_data.h"
#include "script.h"
#include "map_obj_lock.h"
#include "field_specials.h"
#include "item_menu.h"
#include "field_effect.h"
#include "script_movement.h"
#include "battle.h"
#include "battle_setup.h"
#include "random.h"
#include "field_map_obj.h"
#include "field_player_avatar.h"
#include "map_obj_80688E4.h"
#include "map_obj_8097404.h"
#include "unk_810c3a4.h"
#include "vs_seeker.h"
#include "constants/movement_commands.h"
#include "constants/map_objects.h"
#include "constants/trainers.h"
#include "constants/maps.h"
typedef enum
{
VSSEEKER_RESPONSE_NO_RESPONSE,
VSSEEKER_RESPONSE_UNFOUGHT_TRAINERS,
VSSEEKER_RESPONSE_FOUND_REMATCHES
} VsSeekerResponseCode;
// static types
typedef struct VsSeekerData
{
u16 trainerIdxs[6];
u16 unk_c; // unused
u16 unk_e; // unused
} VsSeekerData;
struct VsSeekerTrainerInfo
{
const u8 *script;
u16 trainerIdx;
u8 localId;
u8 fieldObjectId;
s16 xCoord;
s16 yCoord;
u8 graphicsId;
};
struct VsSeekerStruct
{
/*0x000*/ struct VsSeekerTrainerInfo trainerInfo[MAP_OBJECTS_COUNT];
/*0x100*/ u8 filler_100[0x300];
/*0x400*/ u16 trainerIdxArray[MAP_OBJECTS_COUNT];
/*0x420*/ u8 runningBehaviourEtcArray[MAP_OBJECTS_COUNT];
/*0x430*/ u8 numRematchableTrainers;
/*0x431*/ u8 trainerHasNotYetBeenFought:1;
/*0x431*/ u8 trainerDoesNotWantRematch:1;
/*0x431*/ u8 trainerWantsRematch:1;
u8 responseCode:5;
};
extern u16 gSpecialVar_LastTalked;
extern struct MapObject gMapObjects[MAP_OBJECTS_COUNT];
extern u8 gSelectedEventObject;
// static declarations
static EWRAM_DATA struct VsSeekerStruct *sVsSeeker = NULL;
static void sub_810C3B8(u8 taskId);
static void sub_810C594(void);
static void Task_VsSeeker_1(u8 taskId);
static void Task_VsSeeker_2(u8 taskId);
static void GatherNearbyTrainerInfo(void);
static void Task_VsSeeker_3(u8 taskId);
static bool8 CanUseVsSeeker(void);
static u8 GetVsSeekerResponseInArea(const VsSeekerData *);
static u8 GetRematchTrainerIdGivenGameState(const u16 *, u8);
static u8 sub_810CD80(const VsSeekerData *, u16);
static u8 HasRematchTrainerAlreadyBeenFought(const VsSeekerData *, u16);
static s32 sub_810CE10(const VsSeekerData * a0, u16 a1);
static bool8 sub_810CED0(const VsSeekerData *, u16);
static u8 GetRunningBehaviorFromGraphicsId(u8);
static u16 GetTrainerFlagFromScript(const u8 *);
static s32 GetRematchIdx(const VsSeekerData *, u16);
static bool32 IsThisTrainerRematchable(u32);
static bool8 IsTrainerVisibleOnScreen(struct VsSeekerTrainerInfo *);
static u8 GetNextAvailableRematchTrainer(const VsSeekerData *, u16, u8 *);
static u8 GetRematchableTrainerLocalId(void);
static void StartTrainerObjectMovementScript(struct VsSeekerTrainerInfo *, const u8 *);
static u8 GetCurVsSeekerResponse(s32, u16);
static void StartAllRespondantIdleMovements(void);
// rodata
static const VsSeekerData sVsSeekerData[] = {
{ {TRAINER_YOUNGSTER_BEN, TRAINER_YOUNGSTER_BEN_2, 0xFFFF, TRAINER_YOUNGSTER_BEN_3, TRAINER_YOUNGSTER_BEN_4},
MAP_GROUP(ROUTE3), MAP_NUM(ROUTE3) },
{ {TRAINER_YOUNGSTER_CALVIN, TRAINER_YOUNGSTER_CALVIN},
MAP_GROUP(ROUTE3), MAP_NUM(ROUTE3) },
{ {TRAINER_BUG_CATCHER_COLTON, TRAINER_BUG_CATCHER_COLTON_2, 0xFFFF, TRAINER_BUG_CATCHER_COLTON_3, 0xFFFF, TRAINER_BUG_CATCHER_COLTON_4},
MAP_GROUP(ROUTE3), MAP_NUM(ROUTE3) },
{ {TRAINER_BUG_CATCHER_GREG, TRAINER_BUG_CATCHER_GREG},
MAP_GROUP(ROUTE3), MAP_NUM(ROUTE3) },
{ {TRAINER_BUG_CATCHER_JAMES, TRAINER_BUG_CATCHER_JAMES},
MAP_GROUP(ROUTE3), MAP_NUM(ROUTE3) },
{ {TRAINER_LASS_JANICE, TRAINER_LASS_JANICE_2, 0xFFFF, TRAINER_LASS_JANICE_3},
MAP_GROUP(ROUTE3), MAP_NUM(ROUTE3) },
{ {TRAINER_LASS_SALLY, TRAINER_LASS_SALLY},
MAP_GROUP(ROUTE3), MAP_NUM(ROUTE3) },
{ {TRAINER_LASS_ROBIN, TRAINER_LASS_ROBIN},
MAP_GROUP(ROUTE3), MAP_NUM(ROUTE3) },
{ {TRAINER_LASS_CRISSY, TRAINER_LASS_CRISSY},
MAP_GROUP(ROUTE4), MAP_NUM(ROUTE4) },
{ {TRAINER_YOUNGSTER_TIMMY, TRAINER_YOUNGSTER_TIMMY_2, 0xFFFF, TRAINER_YOUNGSTER_TIMMY_3, 0xFFFF, TRAINER_YOUNGSTER_TIMMY_4},
MAP_GROUP(ROUTE24), MAP_NUM(ROUTE24) },
{ {TRAINER_BUG_CATCHER_CALE, TRAINER_BUG_CATCHER_CALE},
MAP_GROUP(ROUTE24), MAP_NUM(ROUTE24) },
{ {TRAINER_LASS_RELI, TRAINER_LASS_RELI_2, 0xFFFF, TRAINER_LASS_RELI_3},
MAP_GROUP(ROUTE24), MAP_NUM(ROUTE24) },
{ {TRAINER_LASS_ALI, TRAINER_LASS_ALI},
MAP_GROUP(ROUTE24), MAP_NUM(ROUTE24) },
{ {TRAINER_CAMPER_SHANE, TRAINER_CAMPER_SHANE},
MAP_GROUP(ROUTE24), MAP_NUM(ROUTE24) },
{ {TRAINER_CAMPER_ETHAN, TRAINER_CAMPER_ETHAN},
MAP_GROUP(ROUTE24), MAP_NUM(ROUTE24) },
{ {TRAINER_YOUNGSTER_JOEY, TRAINER_YOUNGSTER_JOEY},
MAP_GROUP(ROUTE25), MAP_NUM(ROUTE25) },
{ {TRAINER_YOUNGSTER_DAN, TRAINER_YOUNGSTER_DAN},
MAP_GROUP(ROUTE25), MAP_NUM(ROUTE25) },
{ {TRAINER_YOUNGSTER_CHAD, TRAINER_YOUNGSTER_CHAD_2, 0xFFFF, TRAINER_YOUNGSTER_CHAD_3, TRAINER_YOUNGSTER_CHAD_4},
MAP_GROUP(ROUTE25), MAP_NUM(ROUTE25) },
{ {TRAINER_PICNICKER_KELSEY, TRAINER_PICNICKER_KELSEY_2, 0xFFFF, TRAINER_PICNICKER_KELSEY_3, TRAINER_PICNICKER_KELSEY_4},
MAP_GROUP(ROUTE25), MAP_NUM(ROUTE25) },
{ {TRAINER_LASS_HALEY, TRAINER_LASS_HALEY},
MAP_GROUP(ROUTE25), MAP_NUM(ROUTE25) },
{ {TRAINER_HIKER_FRANKLIN, 0xFFFF, TRAINER_HIKER_FRANKLIN_2},
MAP_GROUP(ROUTE25), MAP_NUM(ROUTE25) },
{ {TRAINER_HIKER_NOB, TRAINER_HIKER_NOB},
MAP_GROUP(ROUTE25), MAP_NUM(ROUTE25) },
{ {TRAINER_HIKER_WAYNE, TRAINER_HIKER_WAYNE},
MAP_GROUP(ROUTE25), MAP_NUM(ROUTE25) },
{ {TRAINER_CAMPER_FLINT, TRAINER_CAMPER_FLINT},
MAP_GROUP(ROUTE25), MAP_NUM(ROUTE25) },
{ {TRAINER_BUG_CATCHER_KEIGO, TRAINER_BUG_CATCHER_KEIGO},
MAP_GROUP(ROUTE6), MAP_NUM(ROUTE6) },
{ {TRAINER_BUG_CATCHER_ELIJAH, TRAINER_BUG_CATCHER_ELIJAH},
MAP_GROUP(ROUTE6), MAP_NUM(ROUTE6) },
{ {TRAINER_CAMPER_RICKY, TRAINER_CAMPER_RICKY_2, 0xFFFF, TRAINER_CAMPER_RICKY_3, 0xFFFF, TRAINER_CAMPER_RICKY_4},
MAP_GROUP(ROUTE6), MAP_NUM(ROUTE6) },
{ {TRAINER_CAMPER_JEFF, TRAINER_CAMPER_JEFF_2, 0xFFFF, TRAINER_CAMPER_JEFF_3, 0xFFFF, TRAINER_CAMPER_JEFF_4},
MAP_GROUP(ROUTE6), MAP_NUM(ROUTE6) },
{ {TRAINER_PICNICKER_NANCY, TRAINER_PICNICKER_NANCY},
MAP_GROUP(ROUTE6), MAP_NUM(ROUTE6) },
{ {TRAINER_PICNICKER_ISABELLE, TRAINER_PICNICKER_ISABELLE_2, 0xFFFF, TRAINER_PICNICKER_ISABELLE_3, TRAINER_PICNICKER_ISABELLE_4},
MAP_GROUP(ROUTE6), MAP_NUM(ROUTE6) },
{ {TRAINER_YOUNGSTER_EDDIE, TRAINER_YOUNGSTER_EDDIE},
MAP_GROUP(ROUTE11), MAP_NUM(ROUTE11) },
{ {TRAINER_YOUNGSTER_DILLON, TRAINER_YOUNGSTER_DILLON},
MAP_GROUP(ROUTE11), MAP_NUM(ROUTE11) },
{ {TRAINER_YOUNGSTER_YASU, 0xFFFF, TRAINER_YOUNGSTER_YASU_2, 0xFFFF, TRAINER_YOUNGSTER_YASU_3},
MAP_GROUP(ROUTE11), MAP_NUM(ROUTE11) },
{ {TRAINER_YOUNGSTER_DAVE, TRAINER_YOUNGSTER_DAVE},
MAP_GROUP(ROUTE11), MAP_NUM(ROUTE11) },
{ {TRAINER_ENGINEER_BRAXTON, TRAINER_ENGINEER_BRAXTON},
MAP_GROUP(ROUTE11), MAP_NUM(ROUTE11) },
{ {TRAINER_ENGINEER_BERNIE, 0xFFFF, 0xFFFF, TRAINER_ENGINEER_BERNIE_2},
MAP_GROUP(ROUTE11), MAP_NUM(ROUTE11) },
{ {TRAINER_GAMER_HUGO, TRAINER_GAMER_HUGO},
MAP_GROUP(ROUTE11), MAP_NUM(ROUTE11) },
{ {TRAINER_GAMER_JASPER, TRAINER_GAMER_JASPER},
MAP_GROUP(ROUTE11), MAP_NUM(ROUTE11) },
{ {TRAINER_GAMER_DIRK, TRAINER_GAMER_DIRK},
MAP_GROUP(ROUTE11), MAP_NUM(ROUTE11) },
{ {TRAINER_GAMER_DARIAN, 0xFFFF, 0xFFFF, TRAINER_GAMER_DARIAN_2},
MAP_GROUP(ROUTE11), MAP_NUM(ROUTE11) },
{ {TRAINER_BUG_CATCHER_BRENT, TRAINER_BUG_CATCHER_BRENT},
MAP_GROUP(ROUTE9), MAP_NUM(ROUTE9) },
{ {TRAINER_BUG_CATCHER_CONNER, TRAINER_BUG_CATCHER_CONNER},
MAP_GROUP(ROUTE9), MAP_NUM(ROUTE9) },
{ {TRAINER_CAMPER_CHRIS, 0xFFFF, TRAINER_CAMPER_CHRIS_2, TRAINER_CAMPER_CHRIS_3, 0xFFFF, TRAINER_CAMPER_CHRIS_4},
MAP_GROUP(ROUTE9), MAP_NUM(ROUTE9) },
{ {TRAINER_CAMPER_DREW, TRAINER_CAMPER_DREW},
MAP_GROUP(ROUTE9), MAP_NUM(ROUTE9) },
{ {TRAINER_PICNICKER_ALICIA, 0xFFFF, TRAINER_PICNICKER_ALICIA_2, TRAINER_PICNICKER_ALICIA_3, 0xFFFF, TRAINER_PICNICKER_ALICIA_4},
MAP_GROUP(ROUTE9), MAP_NUM(ROUTE9) },
{ {TRAINER_PICNICKER_CAITLIN, TRAINER_PICNICKER_CAITLIN},
MAP_GROUP(ROUTE9), MAP_NUM(ROUTE9) },
{ {TRAINER_HIKER_ALAN, TRAINER_HIKER_ALAN},
MAP_GROUP(ROUTE9), MAP_NUM(ROUTE9) },
{ {TRAINER_HIKER_BRICE, TRAINER_HIKER_BRICE},
MAP_GROUP(ROUTE9), MAP_NUM(ROUTE9) },
{ {TRAINER_HIKER_JEREMY, 0xFFFF, 0xFFFF, TRAINER_HIKER_JEREMY_2},
MAP_GROUP(ROUTE9), MAP_NUM(ROUTE9) },
{ {TRAINER_PICNICKER_HEIDI, TRAINER_PICNICKER_HEIDI},
MAP_GROUP(ROUTE10), MAP_NUM(ROUTE10) },
{ {TRAINER_PICNICKER_CAROL, TRAINER_PICNICKER_CAROL},
MAP_GROUP(ROUTE10), MAP_NUM(ROUTE10) },
{ {TRAINER_POKEMANIAC_MARK, 0xFFFF, 0xFFFF, TRAINER_POKEMANIAC_MARK_2, 0xFFFF, TRAINER_POKEMANIAC_MARK_3},
MAP_GROUP(ROUTE10), MAP_NUM(ROUTE10) },
{ {TRAINER_POKEMANIAC_HERMAN, 0xFFFF, 0xFFFF, TRAINER_POKEMANIAC_HERMAN_2, 0xFFFF, TRAINER_POKEMANIAC_HERMAN_3},
MAP_GROUP(ROUTE10), MAP_NUM(ROUTE10) },
{ {TRAINER_HIKER_CLARK, TRAINER_HIKER_CLARK},
MAP_GROUP(ROUTE10), MAP_NUM(ROUTE10) },
{ {TRAINER_HIKER_TRENT, 0xFFFF, 0xFFFF, TRAINER_HIKER_TRENT_2},
MAP_GROUP(ROUTE10), MAP_NUM(ROUTE10) },
{ {TRAINER_LASS_PAIGE, TRAINER_LASS_PAIGE},
MAP_GROUP(ROUTE8), MAP_NUM(ROUTE8) },
{ {TRAINER_LASS_ANDREA, TRAINER_LASS_ANDREA},
MAP_GROUP(ROUTE8), MAP_NUM(ROUTE8) },
{ {TRAINER_LASS_MEGAN, 0xFFFF, TRAINER_LASS_MEGAN_2, 0xFFFF, TRAINER_LASS_MEGAN_3},
MAP_GROUP(ROUTE8), MAP_NUM(ROUTE8) },
{ {TRAINER_LASS_JULIA, TRAINER_LASS_JULIA},
MAP_GROUP(ROUTE8), MAP_NUM(ROUTE8) },
{ {TRAINER_SUPER_NERD_AIDAN, TRAINER_SUPER_NERD_AIDAN},
MAP_GROUP(ROUTE8), MAP_NUM(ROUTE8) },
{ {TRAINER_SUPER_NERD_GLENN, 0xFFFF, 0xFFFF, TRAINER_SUPER_NERD_GLENN_2},
MAP_GROUP(ROUTE8), MAP_NUM(ROUTE8) },
{ {TRAINER_SUPER_NERD_LESLIE, TRAINER_SUPER_NERD_LESLIE},
MAP_GROUP(ROUTE8), MAP_NUM(ROUTE8) },
{ {TRAINER_GAMER_STAN, TRAINER_GAMER_STAN},
MAP_GROUP(ROUTE8), MAP_NUM(ROUTE8) },
{ {TRAINER_GAMER_RICH, 0xFFFF, 0xFFFF, TRAINER_GAMER_RICH_2},
MAP_GROUP(ROUTE8), MAP_NUM(ROUTE8) },
{ {TRAINER_TWINS_ELI_ANNE, 0xFFFF, 0xFFFF, TRAINER_TWINS_ELI_ANNE_2},
MAP_GROUP(ROUTE8), MAP_NUM(ROUTE8) },
{ {TRAINER_BIKER_RICARDO, TRAINER_BIKER_RICARDO},
MAP_GROUP(ROUTE8), MAP_NUM(ROUTE8) },
{ {TRAINER_BIKER_JAREN, 0xFFFF, 0xFFFF, TRAINER_BIKER_JAREN_2},
MAP_GROUP(ROUTE8), MAP_NUM(ROUTE8) },
{ {TRAINER_FISHERMAN_NED, TRAINER_FISHERMAN_NED},
MAP_GROUP(ROUTE12), MAP_NUM(ROUTE12) },
{ {TRAINER_FISHERMAN_CHIP, TRAINER_FISHERMAN_CHIP},
MAP_GROUP(ROUTE12), MAP_NUM(ROUTE12) },
{ {TRAINER_FISHERMAN_HANK, TRAINER_FISHERMAN_HANK},
MAP_GROUP(ROUTE12), MAP_NUM(ROUTE12) },
{ {TRAINER_FISHERMAN_ELLIOT, 0xFFFF, 0xFFFF, TRAINER_FISHERMAN_ELLIOT_2},
MAP_GROUP(ROUTE12), MAP_NUM(ROUTE12) },
{ {TRAINER_FISHERMAN_ANDREW, TRAINER_FISHERMAN_ANDREW},
MAP_GROUP(ROUTE12), MAP_NUM(ROUTE12) },
{ {TRAINER_ROCKER_LUCA, 0xFFFF, 0xFFFF, TRAINER_ROCKER_LUCA_2},
MAP_GROUP(ROUTE12), MAP_NUM(ROUTE12) },
{ {TRAINER_CAMPER_JUSTIN, TRAINER_CAMPER_JUSTIN},
MAP_GROUP(ROUTE12), MAP_NUM(ROUTE12) },
{ {TRAINER_YOUNG_COUPLE_GIA_JES, 0xFFFF, 0xFFFF, TRAINER_YOUNG_COUPLE_GIA_JES_2, 0xFFFF, TRAINER_YOUNG_COUPLE_GIA_JES_3},
MAP_GROUP(ROUTE12), MAP_NUM(ROUTE12) },
{ {TRAINER_BIKER_JARED, TRAINER_BIKER_JARED},
MAP_GROUP(ROUTE13), MAP_NUM(ROUTE13) },
{ {TRAINER_BEAUTY_LOLA, TRAINER_BEAUTY_LOLA},
MAP_GROUP(ROUTE13), MAP_NUM(ROUTE13) },
{ {TRAINER_BEAUTY_SHEILA, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_BEAUTY_SHEILA_2},
MAP_GROUP(ROUTE13), MAP_NUM(ROUTE13) },
{ {TRAINER_BIRD_KEEPER_SEBASTIAN, TRAINER_BIRD_KEEPER_SEBASTIAN},
MAP_GROUP(ROUTE13), MAP_NUM(ROUTE13) },
{ {TRAINER_BIRD_KEEPER_PERRY, TRAINER_BIRD_KEEPER_PERRY},
MAP_GROUP(ROUTE13), MAP_NUM(ROUTE13) },
{ {TRAINER_BIRD_KEEPER_ROBERT, 0xFFFF, 0xFFFF, TRAINER_BIRD_KEEPER_ROBERT_2, TRAINER_BIRD_KEEPER_ROBERT_3},
MAP_GROUP(ROUTE13), MAP_NUM(ROUTE13) },
{ {TRAINER_PICNICKER_ALMA, TRAINER_PICNICKER_ALMA},
MAP_GROUP(ROUTE13), MAP_NUM(ROUTE13) },
{ {TRAINER_PICNICKER_SUSIE, 0xFFFF, 0xFFFF, TRAINER_PICNICKER_SUSIE_2, TRAINER_PICNICKER_SUSIE_3, TRAINER_PICNICKER_SUSIE_4},
MAP_GROUP(ROUTE13), MAP_NUM(ROUTE13) },
{ {TRAINER_PICNICKER_VALERIE, TRAINER_PICNICKER_VALERIE},
MAP_GROUP(ROUTE13), MAP_NUM(ROUTE13) },
{ {TRAINER_PICNICKER_GWEN, TRAINER_PICNICKER_GWEN},
MAP_GROUP(ROUTE13), MAP_NUM(ROUTE13) },
{ {TRAINER_BIKER_MALIK, TRAINER_BIKER_MALIK},
MAP_GROUP(ROUTE14), MAP_NUM(ROUTE14) },
{ {TRAINER_BIKER_LUKAS, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_BIKER_LUKAS_2},
MAP_GROUP(ROUTE14), MAP_NUM(ROUTE14) },
{ {TRAINER_BIKER_ISAAC, TRAINER_BIKER_ISAAC},
MAP_GROUP(ROUTE14), MAP_NUM(ROUTE14) },
{ {TRAINER_BIKER_GERALD, TRAINER_BIKER_GERALD},
MAP_GROUP(ROUTE14), MAP_NUM(ROUTE14) },
{ {TRAINER_BIRD_KEEPER_DONALD, TRAINER_BIRD_KEEPER_DONALD},
MAP_GROUP(ROUTE14), MAP_NUM(ROUTE14) },
{ {TRAINER_BIRD_KEEPER_BENNY, 0xFFFF, 0xFFFF, TRAINER_BIRD_KEEPER_BENNY_2, TRAINER_BIRD_KEEPER_BENNY_3},
MAP_GROUP(ROUTE14), MAP_NUM(ROUTE14) },
{ {TRAINER_BIRD_KEEPER_CARTER, TRAINER_BIRD_KEEPER_CARTER},
MAP_GROUP(ROUTE14), MAP_NUM(ROUTE14) },
{ {TRAINER_BIRD_KEEPER_MITCH, TRAINER_BIRD_KEEPER_MITCH},
MAP_GROUP(ROUTE14), MAP_NUM(ROUTE14) },
{ {TRAINER_BIRD_KEEPER_BECK, TRAINER_BIRD_KEEPER_BECK},
MAP_GROUP(ROUTE14), MAP_NUM(ROUTE14) },
{ {TRAINER_BIRD_KEEPER_MARLON, 0xFFFF, 0xFFFF, TRAINER_BIRD_KEEPER_MARLON_2, TRAINER_BIRD_KEEPER_MARLON_3},
MAP_GROUP(ROUTE14), MAP_NUM(ROUTE14) },
{ {TRAINER_TWINS_KIRI_JAN, TRAINER_TWINS_KIRI_JAN},
MAP_GROUP(ROUTE14), MAP_NUM(ROUTE14) },
{ {TRAINER_BIKER_ERNEST, TRAINER_BIKER_ERNEST},
MAP_GROUP(ROUTE15), MAP_NUM(ROUTE15) },
{ {TRAINER_BIKER_ALEX, TRAINER_BIKER_ALEX},
MAP_GROUP(ROUTE15), MAP_NUM(ROUTE15) },
{ {TRAINER_BEAUTY_GRACE, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_BEAUTY_GRACE_2},
MAP_GROUP(ROUTE15), MAP_NUM(ROUTE15) },
{ {TRAINER_BEAUTY_OLIVIA, TRAINER_BEAUTY_OLIVIA},
MAP_GROUP(ROUTE15), MAP_NUM(ROUTE15) },
{ {TRAINER_BIRD_KEEPER_EDWIN, TRAINER_BIRD_KEEPER_EDWIN},
MAP_GROUP(ROUTE15), MAP_NUM(ROUTE15) },
{ {TRAINER_BIRD_KEEPER_CHESTER, 0xFFFF, 0xFFFF, TRAINER_BIRD_KEEPER_CHESTER_2, TRAINER_BIRD_KEEPER_CHESTER_3},
MAP_GROUP(ROUTE15), MAP_NUM(ROUTE15) },
{ {TRAINER_PICNICKER_YAZMIN, TRAINER_PICNICKER_YAZMIN},
MAP_GROUP(ROUTE15), MAP_NUM(ROUTE15) },
{ {TRAINER_PICNICKER_KINDRA, TRAINER_PICNICKER_KINDRA},
MAP_GROUP(ROUTE15), MAP_NUM(ROUTE15) },
{ {TRAINER_PICNICKER_BECKY, 0xFFFF, 0xFFFF, TRAINER_PICNICKER_BECKY_2, TRAINER_PICNICKER_BECKY_3, TRAINER_PICNICKER_BECKY_4},
MAP_GROUP(ROUTE15), MAP_NUM(ROUTE15) },
{ {TRAINER_PICNICKER_CELIA, TRAINER_PICNICKER_CELIA},
MAP_GROUP(ROUTE15), MAP_NUM(ROUTE15) },
{ {TRAINER_CRUSH_KIN_RON_MYA, 0xFFFF, 0xFFFF, TRAINER_CRUSH_KIN_RON_MYA_2, TRAINER_CRUSH_KIN_RON_MYA_3, TRAINER_CRUSH_KIN_RON_MYA_4},
MAP_GROUP(ROUTE15), MAP_NUM(ROUTE15) },
{ {TRAINER_BIKER_LAO, TRAINER_BIKER_LAO},
MAP_GROUP(ROUTE16), MAP_NUM(ROUTE16) },
{ {TRAINER_BIKER_HIDEO, TRAINER_BIKER_HIDEO},
MAP_GROUP(ROUTE16), MAP_NUM(ROUTE16) },
{ {TRAINER_BIKER_RUBEN, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_BIKER_RUBEN_2},
MAP_GROUP(ROUTE16), MAP_NUM(ROUTE16) },
{ {TRAINER_CUE_BALL_KOJI, TRAINER_CUE_BALL_KOJI},
MAP_GROUP(ROUTE16), MAP_NUM(ROUTE16) },
{ {TRAINER_CUE_BALL_LUKE, TRAINER_CUE_BALL_LUKE},
MAP_GROUP(ROUTE16), MAP_NUM(ROUTE16) },
{ {TRAINER_CUE_BALL_CAMRON, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_CUE_BALL_CAMRON_2},
MAP_GROUP(ROUTE16), MAP_NUM(ROUTE16) },
{ {TRAINER_YOUNG_COUPLE_LEA_JED, TRAINER_YOUNG_COUPLE_LEA_JED},
MAP_GROUP(ROUTE16), MAP_NUM(ROUTE16) },
{ {TRAINER_BIKER_BILLY, TRAINER_BIKER_BILLY},
MAP_GROUP(ROUTE17), MAP_NUM(ROUTE17) },
{ {TRAINER_BIKER_NIKOLAS, TRAINER_BIKER_NIKOLAS},
MAP_GROUP(ROUTE17), MAP_NUM(ROUTE17) },
{ {TRAINER_BIKER_JAXON, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_BIKER_JAXON_2},
MAP_GROUP(ROUTE17), MAP_NUM(ROUTE17) },
{ {TRAINER_BIKER_WILLIAM, TRAINER_BIKER_WILLIAM},
MAP_GROUP(ROUTE17), MAP_NUM(ROUTE17) },
{ {TRAINER_CUE_BALL_RAUL, TRAINER_CUE_BALL_RAUL},
MAP_GROUP(ROUTE17), MAP_NUM(ROUTE17) },
{ {TRAINER_CUE_BALL_ISAIAH, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_CUE_BALL_ISAIAH_2},
MAP_GROUP(ROUTE17), MAP_NUM(ROUTE17) },
{ {TRAINER_CUE_BALL_ZEEK, TRAINER_CUE_BALL_ZEEK},
MAP_GROUP(ROUTE17), MAP_NUM(ROUTE17) },
{ {TRAINER_CUE_BALL_JAMAL, TRAINER_CUE_BALL_JAMAL},
MAP_GROUP(ROUTE17), MAP_NUM(ROUTE17) },
{ {TRAINER_CUE_BALL_COREY, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_CUE_BALL_COREY_2},
MAP_GROUP(ROUTE17), MAP_NUM(ROUTE17) },
{ {TRAINER_BIKER_VIRGIL, TRAINER_BIKER_VIRGIL},
MAP_GROUP(ROUTE17), MAP_NUM(ROUTE17) },
{ {TRAINER_BIRD_KEEPER_WILTON, TRAINER_BIRD_KEEPER_WILTON},
MAP_GROUP(ROUTE18), MAP_NUM(ROUTE18) },
{ {TRAINER_BIRD_KEEPER_RAMIRO, TRAINER_BIRD_KEEPER_RAMIRO},
MAP_GROUP(ROUTE18), MAP_NUM(ROUTE18) },
{ {TRAINER_BIRD_KEEPER_JACOB, 0xFFFF, 0xFFFF, TRAINER_BIRD_KEEPER_JACOB_2, TRAINER_BIRD_KEEPER_JACOB_3},
MAP_GROUP(ROUTE18), MAP_NUM(ROUTE18) },
{ {TRAINER_SWIMMER_MALE_RICHARD, TRAINER_SWIMMER_MALE_RICHARD},
MAP_GROUP(ROUTE19), MAP_NUM(ROUTE19) },
{ {TRAINER_SWIMMER_MALE_REECE, TRAINER_SWIMMER_MALE_REECE},
MAP_GROUP(ROUTE19), MAP_NUM(ROUTE19) },
{ {TRAINER_SWIMMER_MALE_MATTHEW, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_SWIMMER_MALE_MATTHEW_2},
MAP_GROUP(ROUTE19), MAP_NUM(ROUTE19) },
{ {TRAINER_SWIMMER_MALE_DOUGLAS, TRAINER_SWIMMER_MALE_DOUGLAS},
MAP_GROUP(ROUTE19), MAP_NUM(ROUTE19) },
{ {TRAINER_SWIMMER_MALE_DAVID, TRAINER_SWIMMER_MALE_DAVID},
MAP_GROUP(ROUTE19), MAP_NUM(ROUTE19) },
{ {TRAINER_SWIMMER_MALE_TONY, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_SWIMMER_MALE_TONY_2},
MAP_GROUP(ROUTE19), MAP_NUM(ROUTE19) },
{ {TRAINER_SWIMMER_MALE_AXLE, TRAINER_SWIMMER_MALE_AXLE},
MAP_GROUP(ROUTE19), MAP_NUM(ROUTE19) },
{ {TRAINER_SWIMMER_FEMALE_ANYA, TRAINER_SWIMMER_FEMALE_ANYA},
MAP_GROUP(ROUTE19), MAP_NUM(ROUTE19) },
{ {TRAINER_SWIMMER_FEMALE_ALICE, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_SWIMMER_FEMALE_ALICE_2},
MAP_GROUP(ROUTE19), MAP_NUM(ROUTE19) },
{ {TRAINER_SWIMMER_FEMALE_CONNIE, TRAINER_SWIMMER_FEMALE_CONNIE},
MAP_GROUP(ROUTE19), MAP_NUM(ROUTE19) },
{ {TRAINER_SIS_AND_BRO_LIA_LUC, TRAINER_SIS_AND_BRO_LIA_LUC},
MAP_GROUP(ROUTE19), MAP_NUM(ROUTE19) },
{ {TRAINER_SWIMMER_MALE_BARRY, TRAINER_SWIMMER_MALE_BARRY},
MAP_GROUP(ROUTE20), MAP_NUM(ROUTE20) },
{ {TRAINER_SWIMMER_MALE_DEAN, TRAINER_SWIMMER_MALE_DEAN},
MAP_GROUP(ROUTE20), MAP_NUM(ROUTE20) },
{ {TRAINER_SWIMMER_MALE_DARRIN, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_SWIMMER_MALE_DARRIN_2},
MAP_GROUP(ROUTE20), MAP_NUM(ROUTE20) },
{ {TRAINER_SWIMMER_FEMALE_TIFFANY, TRAINER_SWIMMER_FEMALE_TIFFANY},
MAP_GROUP(ROUTE20), MAP_NUM(ROUTE20) },
{ {TRAINER_SWIMMER_FEMALE_NORA, TRAINER_SWIMMER_FEMALE_NORA},
MAP_GROUP(ROUTE20), MAP_NUM(ROUTE20) },
{ {TRAINER_SWIMMER_FEMALE_MELISSA, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_SWIMMER_FEMALE_MELISSA_2},
MAP_GROUP(ROUTE20), MAP_NUM(ROUTE20) },
{ {TRAINER_SWIMMER_FEMALE_SHIRLEY, TRAINER_SWIMMER_FEMALE_SHIRLEY},
MAP_GROUP(ROUTE20), MAP_NUM(ROUTE20) },
{ {TRAINER_BIRD_KEEPER_ROGER, TRAINER_BIRD_KEEPER_ROGER},
MAP_GROUP(ROUTE20), MAP_NUM(ROUTE20) },
{ {TRAINER_PICNICKER_MISSY, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_PICNICKER_MISSY_2, TRAINER_PICNICKER_MISSY_3},
MAP_GROUP(ROUTE20), MAP_NUM(ROUTE20) },
{ {TRAINER_PICNICKER_IRENE, TRAINER_PICNICKER_IRENE},
MAP_GROUP(ROUTE20), MAP_NUM(ROUTE20) },
{ {TRAINER_FISHERMAN_RONALD, TRAINER_FISHERMAN_RONALD},
MAP_GROUP(ROUTE21_NORTH), MAP_NUM(ROUTE21_NORTH) },
{ {TRAINER_FISHERMAN_CLAUDE, TRAINER_FISHERMAN_CLAUDE},
MAP_GROUP(ROUTE21_NORTH), MAP_NUM(ROUTE21_NORTH) },
{ {TRAINER_FISHERMAN_WADE, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_FISHERMAN_WADE_2},
MAP_GROUP(ROUTE21_NORTH), MAP_NUM(ROUTE21_NORTH) },
{ {TRAINER_FISHERMAN_NOLAN, TRAINER_FISHERMAN_NOLAN},
MAP_GROUP(ROUTE21_NORTH), MAP_NUM(ROUTE21_NORTH) },
{ {TRAINER_SWIMMER_MALE_SPENCER, TRAINER_SWIMMER_MALE_SPENCER},
MAP_GROUP(ROUTE21_NORTH), MAP_NUM(ROUTE21_NORTH) },
{ {TRAINER_SWIMMER_MALE_JACK, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_SWIMMER_MALE_JACK_2},
MAP_GROUP(ROUTE21_NORTH), MAP_NUM(ROUTE21_NORTH) },
{ {TRAINER_SWIMMER_MALE_JEROME, TRAINER_SWIMMER_MALE_JEROME},
MAP_GROUP(ROUTE21_NORTH), MAP_NUM(ROUTE21_NORTH) },
{ {TRAINER_SWIMMER_MALE_ROLAND, TRAINER_SWIMMER_MALE_ROLAND},
MAP_GROUP(ROUTE21_NORTH), MAP_NUM(ROUTE21_NORTH) },
{ {TRAINER_SIS_AND_BRO_LIL_IAN, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_SIS_AND_BRO_LIL_IAN_2, TRAINER_SIS_AND_BRO_LIL_IAN_3},
MAP_GROUP(ROUTE21_NORTH), MAP_NUM(ROUTE21_NORTH) },
{ {TRAINER_SWIMMER_FEMALE_MARIA, TRAINER_SWIMMER_FEMALE_MARIA},
MAP_GROUP(ONE_ISLAND_KINDLE_ROAD), MAP_NUM(ONE_ISLAND_KINDLE_ROAD) },
{ {TRAINER_SWIMMER_FEMALE_ABIGAIL, TRAINER_SWIMMER_FEMALE_ABIGAIL},
MAP_GROUP(ONE_ISLAND_KINDLE_ROAD), MAP_NUM(ONE_ISLAND_KINDLE_ROAD) },
{ {TRAINER_SWIMMER_MALE_FINN, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_SWIMMER_MALE_FINN_2},
MAP_GROUP(ONE_ISLAND_KINDLE_ROAD), MAP_NUM(ONE_ISLAND_KINDLE_ROAD) },
{ {TRAINER_SWIMMER_MALE_GARRETT, TRAINER_SWIMMER_MALE_GARRETT},
MAP_GROUP(ONE_ISLAND_KINDLE_ROAD), MAP_NUM(ONE_ISLAND_KINDLE_ROAD) },
{ {TRAINER_FISHERMAN_TOMMY, TRAINER_FISHERMAN_TOMMY},
MAP_GROUP(ONE_ISLAND_KINDLE_ROAD), MAP_NUM(ONE_ISLAND_KINDLE_ROAD) },
{ {TRAINER_CRUSH_GIRL_SHARON, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_CRUSH_GIRL_SHARON_2, TRAINER_CRUSH_GIRL_SHARON_3},
MAP_GROUP(ONE_ISLAND_KINDLE_ROAD), MAP_NUM(ONE_ISLAND_KINDLE_ROAD) },
{ {TRAINER_CRUSH_GIRL_TANYA, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_CRUSH_GIRL_TANYA_2, TRAINER_CRUSH_GIRL_TANYA_3},
MAP_GROUP(ONE_ISLAND_KINDLE_ROAD), MAP_NUM(ONE_ISLAND_KINDLE_ROAD) },
{ {TRAINER_BLACK_BELT_SHEA, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_BLACK_BELT_SHEA_2, TRAINER_BLACK_BELT_SHEA_3},
MAP_GROUP(ONE_ISLAND_KINDLE_ROAD), MAP_NUM(ONE_ISLAND_KINDLE_ROAD) },
{ {TRAINER_BLACK_BELT_HUGH, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_BLACK_BELT_HUGH_2, TRAINER_BLACK_BELT_HUGH_3},
MAP_GROUP(ONE_ISLAND_KINDLE_ROAD), MAP_NUM(ONE_ISLAND_KINDLE_ROAD) },
{ {TRAINER_CAMPER_BRYCE, TRAINER_CAMPER_BRYCE},
MAP_GROUP(ONE_ISLAND_KINDLE_ROAD), MAP_NUM(ONE_ISLAND_KINDLE_ROAD) },
{ {TRAINER_PICNICKER_CLAIRE, TRAINER_PICNICKER_CLAIRE},
MAP_GROUP(ONE_ISLAND_KINDLE_ROAD), MAP_NUM(ONE_ISLAND_KINDLE_ROAD) },
{ {TRAINER_CRUSH_KIN_MIK_KIA, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_CRUSH_KIN_MIK_KIA_2, TRAINER_CRUSH_KIN_MIK_KIA_3},
MAP_GROUP(ONE_ISLAND_KINDLE_ROAD), MAP_NUM(ONE_ISLAND_KINDLE_ROAD) },
{ {TRAINER_SWIMMER_FEMALE_AMARA, TRAINER_SWIMMER_FEMALE_AMARA},
MAP_GROUP(ONE_ISLAND_TREASURE_BEACH), MAP_NUM(ONE_ISLAND_TREASURE_BEACH) },
{ {TRAINER_AROMA_LADY_NIKKI, TRAINER_AROMA_LADY_NIKKI},
MAP_GROUP(THREE_ISLAND_BOND_BRIDGE), MAP_NUM(THREE_ISLAND_BOND_BRIDGE) },
{ {TRAINER_AROMA_LADY_VIOLET, TRAINER_AROMA_LADY_VIOLET},
MAP_GROUP(THREE_ISLAND_BOND_BRIDGE), MAP_NUM(THREE_ISLAND_BOND_BRIDGE) },
{ {TRAINER_TUBER_AMIRA, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_TUBER_AMIRA_2},
MAP_GROUP(THREE_ISLAND_BOND_BRIDGE), MAP_NUM(THREE_ISLAND_BOND_BRIDGE) },
{ {TRAINER_TUBER_ALEXIS, TRAINER_TUBER_ALEXIS},
MAP_GROUP(THREE_ISLAND_BOND_BRIDGE), MAP_NUM(THREE_ISLAND_BOND_BRIDGE) },
{ {TRAINER_SWIMMER_FEMALE_TISHA, TRAINER_SWIMMER_FEMALE_TISHA},
MAP_GROUP(THREE_ISLAND_BOND_BRIDGE), MAP_NUM(THREE_ISLAND_BOND_BRIDGE) },
{ {TRAINER_TWINS_JOY_MEG, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_TWINS_JOY_MEG_2},
MAP_GROUP(THREE_ISLAND_BOND_BRIDGE), MAP_NUM(THREE_ISLAND_BOND_BRIDGE) },
{ {TRAINER_PAINTER_DAISY, TRAINER_PAINTER_DAISY},
MAP_GROUP(FIVE_ISLAND_RESORT_GORGEOUS), MAP_NUM(FIVE_ISLAND_RESORT_GORGEOUS) },
{ {TRAINER_PAINTER_CELINA, TRAINER_PAINTER_CELINA},
MAP_GROUP(FIVE_ISLAND_RESORT_GORGEOUS), MAP_NUM(FIVE_ISLAND_RESORT_GORGEOUS) },
{ {TRAINER_PAINTER_RAYNA, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_PAINTER_RAYNA_2},
MAP_GROUP(FIVE_ISLAND_RESORT_GORGEOUS), MAP_NUM(FIVE_ISLAND_RESORT_GORGEOUS) },
{ {TRAINER_LADY_JACKI, TRAINER_LADY_JACKI},
MAP_GROUP(FIVE_ISLAND_RESORT_GORGEOUS), MAP_NUM(FIVE_ISLAND_RESORT_GORGEOUS) },
{ {TRAINER_LADY_GILLIAN, TRAINER_LADY_GILLIAN},
MAP_GROUP(FIVE_ISLAND_RESORT_GORGEOUS), MAP_NUM(FIVE_ISLAND_RESORT_GORGEOUS) },
{ {TRAINER_YOUNGSTER_DESTIN, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_YOUNGSTER_DESTIN_2},
MAP_GROUP(FIVE_ISLAND_RESORT_GORGEOUS), MAP_NUM(FIVE_ISLAND_RESORT_GORGEOUS) },
{ {TRAINER_SWIMMER_MALE_TOBY, TRAINER_SWIMMER_MALE_TOBY},
MAP_GROUP(FIVE_ISLAND_RESORT_GORGEOUS), MAP_NUM(FIVE_ISLAND_RESORT_GORGEOUS) },
{ {TRAINER_PKMN_BREEDER_ALIZE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_PKMN_BREEDER_ALIZE_2},
MAP_GROUP(FIVE_ISLAND_WATER_LABYRINTH), MAP_NUM(FIVE_ISLAND_WATER_LABYRINTH) },
{ {TRAINER_BIRD_KEEPER_MILO, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_BIRD_KEEPER_MILO_2},
MAP_GROUP(FIVE_ISLAND_MEMORIAL_PILLAR), MAP_NUM(FIVE_ISLAND_MEMORIAL_PILLAR) },
{ {TRAINER_BIRD_KEEPER_CHAZ, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_BIRD_KEEPER_CHAZ_2},
MAP_GROUP(FIVE_ISLAND_MEMORIAL_PILLAR), MAP_NUM(FIVE_ISLAND_MEMORIAL_PILLAR) },
{ {TRAINER_BIRD_KEEPER_HAROLD, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_BIRD_KEEPER_HAROLD_2},
MAP_GROUP(FIVE_ISLAND_MEMORIAL_PILLAR), MAP_NUM(FIVE_ISLAND_MEMORIAL_PILLAR) },
{ {TRAINER_FISHERMAN_TYLOR, TRAINER_FISHERMAN_TYLOR},
MAP_GROUP(SIX_ISLAND_OUTCAST_ISLAND), MAP_NUM(SIX_ISLAND_OUTCAST_ISLAND) },
{ {TRAINER_SWIMMER_MALE_MYMO, TRAINER_SWIMMER_MALE_MYMO},
MAP_GROUP(SIX_ISLAND_OUTCAST_ISLAND), MAP_NUM(SIX_ISLAND_OUTCAST_ISLAND) },
{ {TRAINER_SWIMMER_FEMALE_NICOLE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_SWIMMER_FEMALE_NICOLE_2},
MAP_GROUP(SIX_ISLAND_OUTCAST_ISLAND), MAP_NUM(SIX_ISLAND_OUTCAST_ISLAND) },
{ {TRAINER_SIS_AND_BRO_AVA_GEB, TRAINER_SIS_AND_BRO_AVA_GEB},
MAP_GROUP(SIX_ISLAND_OUTCAST_ISLAND), MAP_NUM(SIX_ISLAND_OUTCAST_ISLAND) },
{ {TRAINER_PSYCHIC_JACLYN, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_PSYCHIC_JACLYN_2},
MAP_GROUP(SIX_ISLAND_GREEN_PATH), MAP_NUM(SIX_ISLAND_GREEN_PATH) },
{ {TRAINER_AROMA_LADY_ROSE, TRAINER_AROMA_LADY_ROSE},
MAP_GROUP(SIX_ISLAND_WATER_PATH), MAP_NUM(SIX_ISLAND_WATER_PATH) },
{ {TRAINER_JUGGLER_EDWARD, TRAINER_JUGGLER_EDWARD},
MAP_GROUP(SIX_ISLAND_WATER_PATH), MAP_NUM(SIX_ISLAND_WATER_PATH) },
{ {TRAINER_SWIMMER_MALE_SAMIR, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_SWIMMER_MALE_SAMIR_2},
MAP_GROUP(SIX_ISLAND_WATER_PATH), MAP_NUM(SIX_ISLAND_WATER_PATH) },
{ {TRAINER_SWIMMER_FEMALE_DENISE, TRAINER_SWIMMER_FEMALE_DENISE},
MAP_GROUP(SIX_ISLAND_WATER_PATH), MAP_NUM(SIX_ISLAND_WATER_PATH) },
{ {TRAINER_TWINS_MIU_MIA, TRAINER_TWINS_MIU_MIA},
MAP_GROUP(SIX_ISLAND_WATER_PATH), MAP_NUM(SIX_ISLAND_WATER_PATH) },
{ {TRAINER_HIKER_EARL, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_HIKER_EARL_2},
MAP_GROUP(SIX_ISLAND_WATER_PATH), MAP_NUM(SIX_ISLAND_WATER_PATH) },
{ {TRAINER_RUIN_MANIAC_STANLY, TRAINER_RUIN_MANIAC_STANLY},
MAP_GROUP(SIX_ISLAND_RUIN_VALLEY), MAP_NUM(SIX_ISLAND_RUIN_VALLEY) },
{ {TRAINER_RUIN_MANIAC_FOSTER, TRAINER_RUIN_MANIAC_FOSTER},
MAP_GROUP(SIX_ISLAND_RUIN_VALLEY), MAP_NUM(SIX_ISLAND_RUIN_VALLEY) },
{ {TRAINER_RUIN_MANIAC_LARRY, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_RUIN_MANIAC_LARRY_2},
MAP_GROUP(SIX_ISLAND_RUIN_VALLEY), MAP_NUM(SIX_ISLAND_RUIN_VALLEY) },
{ {TRAINER_HIKER_DARYL, TRAINER_HIKER_DARYL},
MAP_GROUP(SIX_ISLAND_RUIN_VALLEY), MAP_NUM(SIX_ISLAND_RUIN_VALLEY) },
{ {TRAINER_POKEMANIAC_HECTOR, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_POKEMANIAC_HECTOR_2},
MAP_GROUP(SIX_ISLAND_RUIN_VALLEY), MAP_NUM(SIX_ISLAND_RUIN_VALLEY) },
{ {TRAINER_PSYCHIC_DARIO, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_PSYCHIC_DARIO_2},
MAP_GROUP(SEVEN_ISLAND_TRAINER_TOWER), MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER) },
{ {TRAINER_PSYCHIC_RODETTE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_PSYCHIC_RODETTE_2},
MAP_GROUP(SEVEN_ISLAND_TRAINER_TOWER), MAP_NUM(SEVEN_ISLAND_TRAINER_TOWER) },
{ {TRAINER_AROMA_LADY_MIAH, TRAINER_AROMA_LADY_MIAH},
MAP_GROUP(SEVEN_ISLAND_SEVAULT_CANYON_ENTRANCE), MAP_NUM(SEVEN_ISLAND_SEVAULT_CANYON_ENTRANCE) },
{ {TRAINER_YOUNG_COUPLE_EVE_JON, TRAINER_YOUNG_COUPLE_EVE_JON},
MAP_GROUP(SEVEN_ISLAND_SEVAULT_CANYON_ENTRANCE), MAP_NUM(SEVEN_ISLAND_SEVAULT_CANYON_ENTRANCE) },
{ {TRAINER_JUGGLER_MASON, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_JUGGLER_MASON_2},
MAP_GROUP(SEVEN_ISLAND_SEVAULT_CANYON_ENTRANCE), MAP_NUM(SEVEN_ISLAND_SEVAULT_CANYON_ENTRANCE) },
{ {TRAINER_PKMN_RANGER_NICOLAS, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_PKMN_RANGER_NICOLAS_2},
MAP_GROUP(SEVEN_ISLAND_SEVAULT_CANYON_ENTRANCE), MAP_NUM(SEVEN_ISLAND_SEVAULT_CANYON_ENTRANCE) },
{ {TRAINER_PKMN_RANGER_MADELINE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_PKMN_RANGER_MADELINE_2},
MAP_GROUP(SEVEN_ISLAND_SEVAULT_CANYON_ENTRANCE), MAP_NUM(SEVEN_ISLAND_SEVAULT_CANYON_ENTRANCE) },
{ {TRAINER_CRUSH_GIRL_CYNDY, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_CRUSH_GIRL_CYNDY_2},
MAP_GROUP(SEVEN_ISLAND_SEVAULT_CANYON), MAP_NUM(SEVEN_ISLAND_SEVAULT_CANYON) },
{ {TRAINER_TAMER_EVAN, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_TAMER_EVAN_2},
MAP_GROUP(SEVEN_ISLAND_SEVAULT_CANYON), MAP_NUM(SEVEN_ISLAND_SEVAULT_CANYON) },
{ {TRAINER_PKMN_RANGER_JACKSON, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_PKMN_RANGER_JACKSON_2},
MAP_GROUP(SEVEN_ISLAND_SEVAULT_CANYON), MAP_NUM(SEVEN_ISLAND_SEVAULT_CANYON) },
{ {TRAINER_PKMN_RANGER_KATELYN, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_PKMN_RANGER_KATELYN_2},
MAP_GROUP(SEVEN_ISLAND_SEVAULT_CANYON), MAP_NUM(SEVEN_ISLAND_SEVAULT_CANYON) },
{ {TRAINER_COOLTRAINER_LEROY, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_COOLTRAINER_LEROY_2},
MAP_GROUP(SEVEN_ISLAND_SEVAULT_CANYON), MAP_NUM(SEVEN_ISLAND_SEVAULT_CANYON) },
{ {TRAINER_COOLTRAINER_MICHELLE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_COOLTRAINER_MICHELLE_2},
MAP_GROUP(SEVEN_ISLAND_SEVAULT_CANYON), MAP_NUM(SEVEN_ISLAND_SEVAULT_CANYON) },
{ {TRAINER_COOL_COUPLE_LEX_NYA, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, TRAINER_COOL_COUPLE_LEX_NYA_2},
MAP_GROUP(SEVEN_ISLAND_SEVAULT_CANYON), MAP_NUM(SEVEN_ISLAND_SEVAULT_CANYON) },
{ {TRAINER_RUIN_MANIAC_BRANDON, TRAINER_RUIN_MANIAC_BRANDON},
MAP_GROUP(SEVEN_ISLAND_TANOBY_RUINS), MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS) },
{ {TRAINER_RUIN_MANIAC_BENJAMIN, TRAINER_RUIN_MANIAC_BENJAMIN},
MAP_GROUP(SEVEN_ISLAND_TANOBY_RUINS), MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS) },
{ {TRAINER_PAINTER_EDNA, TRAINER_PAINTER_EDNA},
MAP_GROUP(SEVEN_ISLAND_TANOBY_RUINS), MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS) },
{ {TRAINER_GENTLEMAN_CLIFFORD, TRAINER_GENTLEMAN_CLIFFORD},
MAP_GROUP(SEVEN_ISLAND_TANOBY_RUINS), MAP_NUM(SEVEN_ISLAND_TANOBY_RUINS) },
};
static const u8 gUnknown_8453F5C[] = {
step_1c,
step_1c,
step_1c,
step_end
};
static const u8 gUnknown_8453F60[] = {
step_62,
step_end
};
static const u8 sMovementScript_TrainerNoRematch[] = {
step_64,
step_end
};
static const u8 gUnknown_8453F64[] = {
step_2d,
step_65,
step_end
};
static const u8 gUnknown_8453F67[] = { 0x08, 0x08, 0x07, 0x09, 0x0a };
// text
void sub_810C3A4(void)
{
CreateTask(sub_810C3B8, 80);
}
static void sub_810C3B8(u8 taskId)
{
struct Task * task = &gTasks[taskId];
u8 i;
if (task->data[0] == 0 && walkrun_is_standing_still() == TRUE)
{
sub_805C270();
task->data[0] = 1;
}
if (task->data[1] == 0)
{
for (i = 0; i < MAP_OBJECTS_COUNT; i++)
{
if (sub_810CF04(i) == TRUE)
{
if (gMapObjects[i].mapobj_bit_1)
return;
FreezeMapObject(&gMapObjects[i]);
}
}
}
task->data[1] = 1;
if (task->data[0] != 0)
{
DestroyTask(taskId);
sub_805C780();
EnableBothScriptContexts();
}
}
void sub_810C444(void)
{
struct MapObjectTemplate * templates = gSaveBlock1Ptr->mapObjectTemplates;
u8 i;
u8 r6;
u8 sp0;
struct MapObject * mapObject;
for (i = 0; i < gMapHeader.events->mapObjectCount; i++)
{
if ((templates[i].unkC == 1 || templates[i].unkC == 3) && (templates[i].movementType == 0x4D || templates[i].movementType == 0x4E || templates[i].movementType == 0x4F))
{
r6 = sub_810CF54();
TryGetFieldObjectIdByLocalIdAndMap(templates[i].localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &sp0);
mapObject = &gMapObjects[sp0];
if (sub_810CF04(sp0) == TRUE)
{
npc_set_running_behaviour_etc(mapObject, r6);
}
templates[i].movementType = r6;
}
}
}
#ifdef NONMATCHING
bool8 sub_810C4EC(void)
{
if (CheckBagHasItem(ITEM_VS_SEEKER, 1) == TRUE)
{
if ((gSaveBlock1Ptr->trainerRematchStepCounter & 0xFF) < 100)
gSaveBlock1Ptr->trainerRematchStepCounter++;
}
if (FlagGet(FLAG_SYS_VS_SEEKER_CHARGING) == TRUE)
{
u16 x;
do {
x = (gSaveBlock1Ptr->trainerRematchStepCounter >> 8) & 0xFF;
} while (0);
if (x < 100)
{
x++;
gSaveBlock1Ptr->trainerRematchStepCounter = ((u16)(x << 8)) | (gSaveBlock1Ptr->trainerRematchStepCounter & 0xFF);
}
do {
x = (gSaveBlock1Ptr->trainerRematchStepCounter >> 8) & 0xFF;
} while (0);
if (x == 100)
{
FlagClear(FLAG_SYS_VS_SEEKER_CHARGING);
sub_810C640();
sub_810D0D0();
return TRUE;
}
}
return FALSE;
}
#else
NAKED
bool8 sub_810C4EC(void)
{
asm_unified("\tpush {r4-r7,lr}\n"
"\tmovs r0, 0xB5\n"
"\tlsls r0, 1\n"
"\tmovs r1, 0x1\n"
"\tbl CheckBagHasItem\n"
"\tlsls r0, 24\n"
"\tlsrs r0, 24\n"
"\tcmp r0, 0x1\n"
"\tbne _0810C516\n"
"\tldr r0, _0810C568 @ =gSaveBlock1Ptr\n"
"\tldr r0, [r0]\n"
"\tmovs r2, 0xC7\n"
"\tlsls r2, 3\n"
"\tadds r1, r0, r2\n"
"\tldrh r2, [r1]\n"
"\tldrb r0, [r1]\n"
"\tcmp r0, 0x63\n"
"\tbhi _0810C516\n"
"\tadds r0, r2, 0x1\n"
"\tstrh r0, [r1]\n"
"_0810C516:\n"
"\tldr r7, _0810C56C @ =0x00000801\n"
"\tadds r0, r7, 0\n"
"\tbl FlagGet\n"
"\tlsls r0, 24\n"
"\tlsrs r0, 24\n"
"\tcmp r0, 0x1\n"
"\tbne _0810C570\n"
"\tldr r6, _0810C568 @ =gSaveBlock1Ptr\n"
"\tldr r0, [r6]\n"
"\tmovs r5, 0xC7\n"
"\tlsls r5, 3\n"
"\tadds r3, r0, r5\n"
"\tldrh r2, [r3]\n"
"\tlsrs r1, r2, 8\n"
"\tmovs r4, 0xFF\n"
"\tcmp r1, 0x63\n"
"\tbhi _0810C548\n"
"\tadds r1, 0x1\n"
"\tlsls r1, 24\n"
"\tmovs r0, 0xFF\n"
"\tands r0, r2\n"
"\tlsrs r1, 16\n"
"\torrs r0, r1\n"
"\tstrh r0, [r3]\n"
"_0810C548:\n"
"\tldr r0, [r6]\n"
"\tadds r0, r5\n"
"\tldrh r0, [r0]\n"
"\tlsrs r0, 8\n"
"\tands r0, r4\n"
"\tcmp r0, 0x64\n"
"\tbne _0810C570\n"
"\tadds r0, r7, 0\n"
"\tbl FlagClear\n"
"\tbl sub_810C640\n"
"\tbl sub_810D0D0\n"
"\tmovs r0, 0x1\n"
"\tb _0810C572\n"
"\t.align 2, 0\n"
"_0810C568: .4byte gSaveBlock1Ptr\n"
"_0810C56C: .4byte 0x00000801\n"
"_0810C570:\n"
"\tmovs r0, 0\n"
"_0810C572:\n"
"\tpop {r4-r7}\n"
"\tpop {r1}\n"
"\tbx r1");
}
#endif
void sub_810C578(void)
{
FlagClear(FLAG_SYS_VS_SEEKER_CHARGING);
sub_810C640();
sub_810D0D0();
sub_810C594();
}
static void sub_810C594(void)
{
u8 i;
for (i = 0; i < MAP_OBJECTS_COUNT; i++)
{
struct MapObject * mapObject = &gMapObjects[i];
if (mapObject->animPattern == 0x4D || mapObject->animPattern == 0x4E || mapObject->animPattern == 0x4F)
{
u8 r3 = sub_810CF54();
if (mapObject->active && gSprites[mapObject->spriteId].data[0] == i)
{
gSprites[mapObject->spriteId].pos2.x = 0;
gSprites[mapObject->spriteId].pos2.y = 0;
npc_set_running_behaviour_etc(mapObject, r3);
}
}
}
}
void sub_810C604(void)
{
gSaveBlock1Ptr->trainerRematchStepCounter &= 0xFF00;
}
void sub_810C620(void)
{
gSaveBlock1Ptr->trainerRematchStepCounter &= 0xFF00;
gSaveBlock1Ptr->trainerRematchStepCounter |= 100;
}
void sub_810C640(void)
{
gSaveBlock1Ptr->trainerRematchStepCounter &= 0x00FF;
}
void sub_810C654(void)
{
gSaveBlock1Ptr->trainerRematchStepCounter &= 0x00FF;
gSaveBlock1Ptr->trainerRematchStepCounter |= (100 << 8);
}
void Task_VsSeeker_0(u8 taskId)
{
u8 i;
u8 respval;
for (i = 0; i < 16; i++)
gTasks[taskId].data[i] = 0;
sVsSeeker = AllocZeroed(sizeof(struct VsSeekerStruct));
GatherNearbyTrainerInfo();
respval = CanUseVsSeeker();
if (respval == 0)
{
Free(sVsSeeker);
DisplayItemMessageOnField(taskId, 2, gUnknown_81C137C, sub_80A1E0C);
}
else if (respval == 1)
{
Free(sVsSeeker);
DisplayItemMessageOnField(taskId, 2, gUnknown_81C13D6, sub_80A1E0C);
}
else if (respval == 2)
{
ItemUse_SetQuestLogEvent(4, 0, gSpecialVar_ItemId, 0xffff);
FieldEffectStart(FLDEFF_UNK_41); // TODO: name this enum
gTasks[taskId].func = Task_VsSeeker_1;
gTasks[taskId].data[0] = 15;
}
}
static void Task_VsSeeker_1(u8 taskId)
{
if (--gTasks[taskId].data[0] == 0)
{
gTasks[taskId].func = Task_VsSeeker_2;
gTasks[taskId].data[1] = 16;
}
}
static void Task_VsSeeker_2(u8 taskId)
{
s16 * data = gTasks[taskId].data;
if (data[2] != 2 && --data[1] == 0)
{
PlaySE(SE_C_PIKON);
data[1] = 11;
data[2]++;
}
if (!FieldEffectActiveListContains(FLDEFF_UNK_41))
{
data[1] = 0;
data[2] = 0;
sub_810C604();
sVsSeeker->responseCode = GetVsSeekerResponseInArea(sVsSeekerData);
ScriptMovement_StartObjectMovementScript(0xFF, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, gUnknown_8453F5C);
gTasks[taskId].func = Task_VsSeeker_3;
}
}
static void GatherNearbyTrainerInfo(void)
{
struct MapObjectTemplate *templates = gSaveBlock1Ptr->mapObjectTemplates;
u8 fieldObjectId = 0;
u8 vsSeekerObjectIdx = 0;
s32 mapObjectIdx;
for (mapObjectIdx = 0; mapObjectIdx < gMapHeader.events->mapObjectCount; mapObjectIdx++)
{
if (templates[mapObjectIdx].unkC == 1 || templates[mapObjectIdx].unkC == 3)
{
sVsSeeker->trainerInfo[vsSeekerObjectIdx].script = templates[mapObjectIdx].script;
sVsSeeker->trainerInfo[vsSeekerObjectIdx].trainerIdx = GetTrainerFlagFromScript(templates[mapObjectIdx].script);
sVsSeeker->trainerInfo[vsSeekerObjectIdx].localId = templates[mapObjectIdx].localId;
TryGetFieldObjectIdByLocalIdAndMap(templates[mapObjectIdx].localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &fieldObjectId);
sVsSeeker->trainerInfo[vsSeekerObjectIdx].fieldObjectId = fieldObjectId;
sVsSeeker->trainerInfo[vsSeekerObjectIdx].xCoord = gMapObjects[fieldObjectId].coords2.x - 7;
sVsSeeker->trainerInfo[vsSeekerObjectIdx].yCoord = gMapObjects[fieldObjectId].coords2.y - 7;
sVsSeeker->trainerInfo[vsSeekerObjectIdx].graphicsId = templates[mapObjectIdx].graphicsId;
vsSeekerObjectIdx++;
}
}
sVsSeeker->trainerInfo[vsSeekerObjectIdx].localId = 0xFF;
}
static void Task_VsSeeker_3(u8 taskId)
{
if (ScriptMovement_IsObjectMovementFinished(0xFF, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup))
{
if (sVsSeeker->responseCode == 0)
{
DisplayItemMessageOnField(taskId, 2, gUnknown_81C1429, sub_80A1E0C);
}
else
{
if (sVsSeeker->responseCode == 2)
StartAllRespondantIdleMovements();
ClearDialogWindowAndFrame(0, 1);
sub_80696C0();
ScriptContext2_Disable();
DestroyTask(taskId);
}
Free(sVsSeeker);
}
}
u8 CanUseVsSeeker(void)
{
u8 vsSeekerChargeSteps = gSaveBlock1Ptr->trainerRematchStepCounter;
if (vsSeekerChargeSteps == 100)
{
if (GetRematchableTrainerLocalId() == 0xFF)
return 1;
else
return 2;
}
else
{
TV_PrintIntToStringVar(0, 100 - vsSeekerChargeSteps);
return 0;
}
}
// Nonmatching due to register roulette
#ifdef NONMATCHING
static u8 GetVsSeekerResponseInArea(const VsSeekerData * a0)
{
u16 r8 = 0;
u8 sp0 = 0;
s32 vsSeekerIdx;
for (vsSeekerIdx = 0; sVsSeeker->trainerInfo[vsSeekerIdx].localId != 0xFF; vsSeekerIdx++)
{
if (IsTrainerVisibleOnScreen(&sVsSeeker->trainerInfo[vsSeekerIdx]) == 1)
{
r8 = sVsSeeker->trainerInfo[vsSeekerIdx].trainerIdx;
if (!HasTrainerAlreadyBeenFought(r8))
{
StartTrainerObjectMovementScript(&sVsSeeker->trainerInfo[vsSeekerIdx], gUnknown_8453F60);
sVsSeeker->trainerHasNotYetBeenFought = 1;
}
else
{
u8 r7 = GetNextAvailableRematchTrainer(a0, r8, &sp0);
if (r7 == 0)
{
StartTrainerObjectMovementScript(&sVsSeeker->trainerInfo[vsSeekerIdx], sMovementScript_TrainerNoRematch);
sVsSeeker->trainerDoesNotWantRematch = 1;
}
else
{
u16 rval = Random() % 100;
u8 r0 = GetCurVsSeekerResponse(vsSeekerIdx, r8);
if (r0 == 2)
rval = 100;
else if (r0 == 1)
rval = 0;
if (rval < 30)
{
StartTrainerObjectMovementScript(&sVsSeeker->trainerInfo[vsSeekerIdx], sMovementScript_TrainerNoRematch);
sVsSeeker->trainerDoesNotWantRematch = 1;
}
else
{
gSaveBlock1Ptr->trainerRematches[sVsSeeker->trainerInfo[vsSeekerIdx].localId] = r7;
npc_coords_shift_still(&gMapObjects[sVsSeeker->trainerInfo[vsSeekerIdx].fieldObjectId]);
StartTrainerObjectMovementScript(&sVsSeeker->trainerInfo[vsSeekerIdx], gUnknown_8453F64);
sVsSeeker->trainerIdxArray[sVsSeeker->numRematchableTrainers] = r8;
sVsSeeker->runningBehaviourEtcArray[sVsSeeker->numRematchableTrainers] = GetRunningBehaviorFromGraphicsId(sVsSeeker->trainerInfo[vsSeekerIdx].graphicsId);
sVsSeeker->numRematchableTrainers++;
sVsSeeker->trainerWantsRematch = 1;
}
}
}
}
}
if (sVsSeeker->trainerWantsRematch)
{
PlaySE(SE_PIN);
FlagSet(FLAG_SYS_VS_SEEKER_CHARGING);
sub_810C640();
return 2;
}
if (sVsSeeker->trainerHasNotYetBeenFought)
return 1;
return 0;
}
#else
NAKED
static u8 GetVsSeekerResponseInArea(const VsSeekerData * a0)
{
asm_unified("\tpush {r4-r7,lr}\n"
"\tmov r7, r10\n"
"\tmov r6, r9\n"
"\tmov r5, r8\n"
"\tpush {r5-r7}\n"
"\tsub sp, 0x8\n"
"\tstr r0, [sp, 0x4]\n"
"\tmovs r0, 0\n"
"\tmov r8, r0\n"
"\tmov r0, sp\n"
"\tmov r1, r8\n"
"\tstrb r1, [r0]\n"
"\tmovs r2, 0\n"
"\tmov r9, r2\n"
"\tldr r4, _0810CA14 @ =sVsSeeker\n"
"\tldr r0, [r4]\n"
"\tldrb r0, [r0, 0x6]\n"
"\tcmp r0, 0xFF\n"
"\tbne _0810C9D0\n"
"\tb _0810CB2C\n"
"_0810C9D0:\n"
"\tadds r6, r4, 0\n"
"\tmovs r3, 0x86\n"
"\tlsls r3, 3\n"
"\tmov r10, r3\n"
"\tmovs r5, 0\n"
"_0810C9DA:\n"
"\tldr r0, [r6]\n"
"\tadds r0, r5\n"
"\tbl IsTrainerVisibleOnScreen\n"
"\tlsls r0, 24\n"
"\tlsrs r0, 24\n"
"\tcmp r0, 0x1\n"
"\tbeq _0810C9EC\n"
"\tb _0810CB18\n"
"_0810C9EC:\n"
"\tldr r0, [r4]\n"
"\tadds r0, r5\n"
"\tldrh r0, [r0, 0x4]\n"
"\tmov r8, r0\n"
"\tbl HasTrainerAlreadyBeenFought\n"
"\tlsls r0, 24\n"
"\tcmp r0, 0\n"
"\tbne _0810CA20\n"
"\tldr r0, [r6]\n"
"\tadds r0, r5\n"
"\tldr r1, _0810CA18 @ =gUnknown_8453F60\n"
"\tbl StartTrainerObjectMovementScript\n"
"\tldr r2, [r6]\n"
"\tldr r0, _0810CA1C @ =0x00000431\n"
"\tadds r2, r0\n"
"\tldrb r0, [r2]\n"
"\tmovs r1, 0x1\n"
"\tb _0810CB14\n"
"\t.align 2, 0\n"
"_0810CA14: .4byte sVsSeeker\n"
"_0810CA18: .4byte gUnknown_8453F60\n"
"_0810CA1C: .4byte 0x00000431\n"
"_0810CA20:\n"
"\tldr r0, [sp, 0x4]\n"
"\tmov r1, r8\n"
"\tmov r2, sp\n"
"\tbl GetNextAvailableRematchTrainer\n"
"\tlsls r0, 24\n"
"\tlsrs r7, r0, 24\n"
"\tcmp r7, 0\n"
"\tbne _0810CA50\n"
"\tldr r0, [r6]\n"
"\tadds r0, r5\n"
"\tldr r1, _0810CA48 @ =sMovementScript_TrainerNoRematch\n"
"\tbl StartTrainerObjectMovementScript\n"
"\tldr r2, [r6]\n"
"\tldr r3, _0810CA4C @ =0x00000431\n"
"\tadds r2, r3\n"
"\tldrb r0, [r2]\n"
"\tmovs r1, 0x2\n"
"\tb _0810CB14\n"
"\t.align 2, 0\n"
"_0810CA48: .4byte sMovementScript_TrainerNoRematch\n"
"_0810CA4C: .4byte 0x00000431\n"
"_0810CA50:\n"
"\tbl Random\n"
"\tlsls r0, 16\n"
"\tlsrs r0, 16\n"
"\tmovs r1, 0x64\n"
"\tbl __umodsi3\n"
"\tlsls r0, 16\n"
"\tlsrs r4, r0, 16\n"
"\tmov r0, r9\n"
"\tmov r1, r8\n"
"\tbl GetCurVsSeekerResponse\n"
"\tlsls r0, 24\n"
"\tlsrs r0, 24\n"
"\tcmp r0, 0x2\n"
"\tbne _0810CA76\n"
"\tmovs r4, 0x64\n"
"\tb _0810CA7C\n"
"_0810CA76:\n"
"\tcmp r0, 0x1\n"
"\tbne _0810CA7C\n"
"\tmovs r4, 0\n"
"_0810CA7C:\n"
"\tcmp r4, 0x1D\n"
"\tbhi _0810CAA0\n"
"\tldr r0, [r6]\n"
"\tadds r0, r5\n"
"\tldr r1, _0810CA98 @ =sMovementScript_TrainerNoRematch\n"
"\tbl StartTrainerObjectMovementScript\n"
"\tldr r2, [r6]\n"
"\tldr r0, _0810CA9C @ =0x00000431\n"
"\tadds r2, r0\n"
"\tldrb r0, [r2]\n"
"\tmovs r1, 0x2\n"
"\tb _0810CB14\n"
"\t.align 2, 0\n"
"_0810CA98: .4byte sMovementScript_TrainerNoRematch\n"
"_0810CA9C: .4byte 0x00000431\n"
"_0810CAA0:\n"
"\tldr r0, _0810CB54 @ =gSaveBlock1Ptr\n"
"\tldr r1, [r0]\n"
"\tldr r0, [r6]\n"
"\tadds r0, r5\n"
"\tldr r2, _0810CB58 @ =0x0000063a\n"
"\tadds r1, r2\n"
"\tldrb r0, [r0, 0x6]\n"
"\tadds r1, r0\n"
"\tstrb r7, [r1]\n"
"\tldr r0, [r6]\n"
"\tadds r0, r5\n"
"\tldrb r1, [r0, 0x7]\n"
"\tlsls r0, r1, 3\n"
"\tadds r0, r1\n"
"\tlsls r0, 2\n"
"\tldr r1, _0810CB5C @ =gMapObjects\n"
"\tadds r0, r1\n"
"\tbl npc_coords_shift_still\n"
"\tldr r0, [r6]\n"
"\tadds r0, r5\n"
"\tldr r1, _0810CB60 @ =gUnknown_8453F64\n"
"\tbl StartTrainerObjectMovementScript\n"
"\tldr r2, [r6]\n"
"\tmov r3, r10\n"
"\tadds r0, r2, r3\n"
"\tldrb r1, [r0]\n"
"\tlsls r1, 1\n"
"\tmovs r3, 0x80\n"
"\tlsls r3, 3\n"
"\tadds r0, r2, r3\n"
"\tadds r0, r1\n"
"\tmov r1, r8\n"
"\tstrh r1, [r0]\n"
"\tadds r2, r5\n"
"\tldrb r0, [r2, 0xC]\n"
"\tbl GetRunningBehaviorFromGraphicsId\n"
"\tldr r1, [r6]\n"
"\tmov r3, r10\n"
"\tadds r2, r1, r3\n"
"\tmovs r3, 0x84\n"
"\tlsls r3, 3\n"
"\tadds r1, r3\n"
"\tldrb r2, [r2]\n"
"\tadds r1, r2\n"
"\tstrb r0, [r1]\n"
"\tldr r1, [r6]\n"
"\tadd r1, r10\n"
"\tldrb r0, [r1]\n"
"\tadds r0, 0x1\n"
"\tstrb r0, [r1]\n"
"\tldr r2, [r6]\n"
"\tldr r0, _0810CB64 @ =0x00000431\n"
"\tadds r2, r0\n"
"\tldrb r0, [r2]\n"
"\tmovs r1, 0x4\n"
"_0810CB14:\n"
"\torrs r0, r1\n"
"\tstrb r0, [r2]\n"
"_0810CB18:\n"
"\tadds r5, 0x10\n"
"\tmovs r1, 0x1\n"
"\tadd r9, r1\n"
"\tldr r4, _0810CB68 @ =sVsSeeker\n"
"\tldr r0, [r4]\n"
"\tadds r0, r5\n"
"\tldrb r0, [r0, 0x6]\n"
"\tcmp r0, 0xFF\n"
"\tbeq _0810CB2C\n"
"\tb _0810C9DA\n"
"_0810CB2C:\n"
"\tldr r2, _0810CB68 @ =sVsSeeker\n"
"\tldr r0, [r2]\n"
"\tldr r3, _0810CB64 @ =0x00000431\n"
"\tadds r0, r3\n"
"\tldrb r1, [r0]\n"
"\tmovs r0, 0x4\n"
"\tands r0, r1\n"
"\tcmp r0, 0\n"
"\tbeq _0810CB70\n"
"\tmovs r0, 0x15\n"
"\tbl PlaySE\n"
"\tldr r0, _0810CB6C @ =0x00000801\n"
"\tbl FlagSet\n"
"\tbl sub_810C640\n"
"\tmovs r0, 0x2\n"
"\tb _0810CB7E\n"
"\t.align 2, 0\n"
"_0810CB54: .4byte gSaveBlock1Ptr\n"
"_0810CB58: .4byte 0x0000063a\n"
"_0810CB5C: .4byte gMapObjects\n"
"_0810CB60: .4byte gUnknown_8453F64\n"
"_0810CB64: .4byte 0x00000431\n"
"_0810CB68: .4byte sVsSeeker\n"
"_0810CB6C: .4byte 0x00000801\n"
"_0810CB70:\n"
"\tmovs r0, 0x1\n"
"\tands r0, r1\n"
"\tcmp r0, 0\n"
"\tbne _0810CB7C\n"
"\tmovs r0, 0\n"
"\tb _0810CB7E\n"
"_0810CB7C:\n"
"\tmovs r0, 0x1\n"
"_0810CB7E:\n"
"\tadd sp, 0x8\n"
"\tpop {r3-r5}\n"
"\tmov r8, r3\n"
"\tmov r9, r4\n"
"\tmov r10, r5\n"
"\tpop {r4-r7}\n"
"\tpop {r1}\n"
"\tbx r1");
}
#endif
void sub_810CB90(void)
{
u8 sp0 = 0;
struct MapObjectTemplate *r4 = gSaveBlock1Ptr->mapObjectTemplates;
s32 r9 = sub_810CE10(sVsSeekerData, gTrainerBattleOpponent_A);
if (r9 != -1)
{
s32 r8;
for (r8 = 0; r8 < gMapHeader.events->mapObjectCount; r8++)
{
if ((r4[r8].unkC == 1 || r4[r8].unkC == 3) && r9 == sub_810CE10(sVsSeekerData, GetTrainerFlagFromScript(r4[r8].script)))
{
struct MapObject *r4_2;
TryGetFieldObjectIdByLocalIdAndMap(r4[r8].localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &sp0);
r4_2 = &gMapObjects[sp0];
sub_810CF54(&r4[r8]); // You are using this function incorrectly. Please consult the manual.
sub_805FE7C(r4_2, gUnknown_8453F67[r4_2->mapobj_unk_18]);
gSaveBlock1Ptr->trainerRematches[r4[r8].localId] = 0;
if (gSelectedEventObject == sp0)
r4_2->animPattern = gUnknown_8453F67[r4_2->mapobj_unk_18];
else
r4_2->animPattern = 0x08;
}
}
}
}
static void TryGetRematchTrainerIdGivenGameState(const u16 * a0, u8 * a1)
{
switch (*a1)
{
case 0:
break;
case 1:
if (!FlagGet(FLAG_GOT_VS_SEEKER))
*a1 = GetRematchTrainerIdGivenGameState(a0, *a1);
break;
case 2:
if (!FlagGet(FLAG_WORLD_MAP_CELADON_CITY))
*a1 = GetRematchTrainerIdGivenGameState(a0, *a1);
break;
case 3:
if (!FlagGet(FLAG_WORLD_MAP_FUCHSIA_CITY))
*a1 = GetRematchTrainerIdGivenGameState(a0, *a1);
break;
case 4:
if (!FlagGet(FLAG_SYS_GAME_CLEAR))
*a1 = GetRematchTrainerIdGivenGameState(a0, *a1);
break;
case 5:
if (!FlagGet(FLAG_SYS_CAN_LINK_WITH_RS))
*a1 = GetRematchTrainerIdGivenGameState(a0, *a1);
break;
}
}
static u8 GetRematchTrainerIdGivenGameState(const u16 * a0, u8 a1)
{
while (--a1 != 0)
{
const u16 *r0 = a0 + a1;
if (*r0 != 0xFFFF)
return a1;
}
return 0;
}
u8 sub_810CD4C(void)
{
if (sub_810CD80(sVsSeekerData, gTrainerBattleOpponent_A))
{
return 1;
}
return HasRematchTrainerAlreadyBeenFought(sVsSeekerData, gTrainerBattleOpponent_A);
}
static bool8 sub_810CD80(const VsSeekerData *vsSeekerData, u16 trainerBattleOpponent)
{
s32 rematchIdx = GetRematchIdx(vsSeekerData, trainerBattleOpponent);
if (rematchIdx == -1)
return FALSE;
if (rematchIdx >= 0 && rematchIdx < NELEMS(sVsSeekerData))
{
if (IsThisTrainerRematchable(gSpecialVar_LastTalked))
return TRUE;
}
return FALSE;
}
static bool8 HasRematchTrainerAlreadyBeenFought(const VsSeekerData *vsSeekerData, u16 trainerBattleOpponent)
{
s32 rematchIdx = GetRematchIdx(vsSeekerData, trainerBattleOpponent);
if (rematchIdx == -1)
return FALSE;
if (!HasTrainerAlreadyBeenFought(vsSeekerData[rematchIdx].trainerIdxs[0]))
return FALSE;
return TRUE;
}
void sub_810CDE8(void)
{
gSaveBlock1Ptr->trainerRematches[gSpecialVar_LastTalked] = 0;
sub_80803FC();
}
static s32 sub_810CE10(const VsSeekerData * a0, u16 a1)
{
u32 r1;
s32 r3;
for (r1 = 0; r1 < NELEMS(sVsSeekerData); r1++)
{
for (r3 = 0; r3 < 6; r3++)
{
u16 r0;
if (a0[r1].trainerIdxs[r3] == 0)
break;
r0 = a0[r1].trainerIdxs[r3];
if (r0 == 0xFFFF)
continue;
if (r0 == a1)
return r1;
}
}
return -1;
}
s32 sub_810CE64(u16 a0)
{
u8 i;
u8 j;
j = GetNextAvailableRematchTrainer(sVsSeekerData, a0, &i);
if (!j)
return 0;
TryGetRematchTrainerIdGivenGameState(sVsSeekerData[i].trainerIdxs, &j);
return sVsSeekerData[i].trainerIdxs[j];
}
u8 sub_810CEB4(void) // unreferenced, or reference not disassembled
{
return sub_810CED0(sVsSeekerData, gTrainerBattleOpponent_A);
}
static bool8 sub_810CED0(const VsSeekerData * a0, u16 a1)
{
s32 r1 = sub_810CE10(a0, a1);
if (r1 == -1)
return FALSE;
if ((u32)r1 >= NELEMS(sVsSeekerData))
return FALSE;
if (!IsThisTrainerRematchable(gSpecialVar_LastTalked))
return FALSE;
return TRUE;
}
bool8 sub_810CF04(u8 a0)
{
struct MapObject *r1 = &gMapObjects[a0];
if (r1->active && gMapHeader.events->mapObjectCount >= r1->localId && gSprites[r1->spriteId].data[0] == a0)
return TRUE;
return FALSE;
}
u8 sub_810CF54()
{
u16 r1 = Random() % 4;
switch (r1)
{
case 0:
return 7;
case 1:
return 8;
case 2:
return 9;
case 3:
return 10;
default:
return 8;
}
}
static u8 GetRunningBehaviorFromGraphicsId(u8 graphicsId)
{
switch (graphicsId)
{
case MAP_OBJ_GFX_LITTLE_GIRL:
case MAP_OBJ_GFX_YOUNGSTER:
case MAP_OBJ_GFX_BOY:
case MAP_OBJ_GFX_BUG_CATCHER:
case MAP_OBJ_GFX_LASS:
case MAP_OBJ_GFX_WOMAN_1:
case MAP_OBJ_GFX_BATTLE_GIRL:
case MAP_OBJ_GFX_MAN:
case MAP_OBJ_GFX_ROCKER:
case MAP_OBJ_GFX_WOMAN_2:
case MAP_OBJ_GFX_BEAUTY:
case MAP_OBJ_GFX_BALDING_MAN:
case MAP_OBJ_GFX_TUBER_F:
case MAP_OBJ_GFX_CAMPER:
case MAP_OBJ_GFX_PICNICKER:
case MAP_OBJ_GFX_COOLTRAINER_M:
case MAP_OBJ_GFX_COOLTRAINER_F:
case MAP_OBJ_GFX_SWIMMER_M_LAND:
case MAP_OBJ_GFX_SWIMMER_F_LAND:
case MAP_OBJ_GFX_BLACKBELT:
case MAP_OBJ_GFX_HIKER:
case MAP_OBJ_GFX_SAILOR:
return 0x4e;
case MAP_OBJ_GFX_TUBER_M_1:
case MAP_OBJ_GFX_SWIMMER_M_WATER:
case MAP_OBJ_GFX_SWIMMER_F_WATER:
return 0x4f;
default:
return 0x4d;
}
}
static u16 GetTrainerFlagFromScript(const u8 *script)
/*
* The trainer flag is a little-endian short located +2 from
* the script pointer, assuming the trainerbattle command is
* first in the script. Because scripts are unaligned, and
* because the ARM processor requires shorts to be 16-bit
* aligned, this function needs to perform explicit bitwise
* operations to get the correct flag.
*
* 5c XX YY ZZ ...
* -- --
*/
{
u16 trainerFlag;
script += 2;
trainerFlag = script[0];
trainerFlag |= script[1] << 8;
return trainerFlag;
}
static s32 GetRematchIdx(const VsSeekerData * vsSeekerData, u16 trainerFlagIdx)
{
u32 i;
for (i = 0; i < NELEMS(sVsSeekerData); i++)
{
if (vsSeekerData[i].trainerIdxs[0] == trainerFlagIdx)
return i;
}
return -1;
}
static bool32 IsThisTrainerRematchable(u32 a0)
{
if (!gSaveBlock1Ptr->trainerRematches[a0])
return FALSE;
return TRUE;
}
void sub_810D0D0(void)
{
u8 i;
for (i = 0; i < NELEMS(gSaveBlock1Ptr->trainerRematches); i++)
gSaveBlock1Ptr->trainerRematches[i] = 0;
}
static bool8 IsTrainerVisibleOnScreen(struct VsSeekerTrainerInfo * trainerInfo)
{
s16 x;
s16 y;
PlayerGetDestCoords(&x, &y);
x -= 7;
y -= 7;
if ( x - 7 <= trainerInfo->xCoord
&& x + 7 >= trainerInfo->xCoord
&& y - 5 <= trainerInfo->yCoord
&& y + 5 >= trainerInfo->yCoord
&& sub_810CF04(trainerInfo->fieldObjectId) == 1)
return TRUE;
return FALSE;
}
static u8 GetNextAvailableRematchTrainer(const VsSeekerData * vsSeekerData, u16 trainerFlagNo, u8 * idxPtr)
{
u32 i;
s32 j;
for (i = 0; i < NELEMS(sVsSeekerData); i++)
{
if (vsSeekerData[i].trainerIdxs[0] == trainerFlagNo)
{
*idxPtr = i;
for (j = 1; j < 6; j++)
{
if (vsSeekerData[i].trainerIdxs[j] == 0)
return j - 1;
if (vsSeekerData[i].trainerIdxs[j] == 0xffff)
continue;
if (HasTrainerAlreadyBeenFought(vsSeekerData[i].trainerIdxs[j]))
continue;
return j;
}
return j - 1;
}
}
*idxPtr = 0;
return 0;
}
static u8 GetRematchableTrainerLocalId(void)
{
u8 idx;
u8 i;
for (i = 0; sVsSeeker->trainerInfo[i].localId != 0xFF; i++)
{
if (IsTrainerVisibleOnScreen(&sVsSeeker->trainerInfo[i]) == 1)
{
if (HasTrainerAlreadyBeenFought(sVsSeeker->trainerInfo[i].trainerIdx) != 1 || GetNextAvailableRematchTrainer(sVsSeekerData, sVsSeeker->trainerInfo[i].trainerIdx, &idx))
return sVsSeeker->trainerInfo[i].localId;
}
}
return 0xFF;
}
static void StartTrainerObjectMovementScript(struct VsSeekerTrainerInfo * trainerInfo, const u8 * script)
{
npc_sync_anim_pause_bits(&gMapObjects[trainerInfo->fieldObjectId]);
ScriptMovement_StartObjectMovementScript(trainerInfo->localId, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, script);
}
static u8 GetCurVsSeekerResponse(s32 a0, u16 a1)
{
s32 i;
s32 j;
for (i = 0; i < a0; i++)
{
if (IsTrainerVisibleOnScreen(&sVsSeeker->trainerInfo[i]) == 1 && sVsSeeker->trainerInfo[i].trainerIdx == a1)
{
for (j = 0; j < sVsSeeker->numRematchableTrainers; j++)
{
if (sVsSeeker->trainerIdxArray[j] == sVsSeeker->trainerInfo[i].trainerIdx)
return 2;
}
return 1;
}
}
return 0;
}
static void StartAllRespondantIdleMovements(void)
{
u8 dummy = 0;
s32 i;
s32 j;
for (i = 0; i < sVsSeeker->numRematchableTrainers; i++)
{
for (j = 0; sVsSeeker->trainerInfo[j].localId != 0xFF; j++)
{
if (sVsSeeker->trainerInfo[j].trainerIdx == sVsSeeker->trainerIdxArray[i])
{
struct MapObject *r4 = &gMapObjects[sVsSeeker->trainerInfo[j].fieldObjectId];
if (sub_810CF04(sVsSeeker->trainerInfo[j].fieldObjectId) == 1)
npc_set_running_behaviour_etc(r4, sVsSeeker->runningBehaviourEtcArray[i]);
sub_805FE7C(r4, sVsSeeker->runningBehaviourEtcArray[i]);
gSaveBlock1Ptr->trainerRematches[sVsSeeker->trainerInfo[j].localId] = GetNextAvailableRematchTrainer(sVsSeekerData, sVsSeeker->trainerInfo[j].trainerIdx, &dummy);
}
}
}
}