2019-04-14 17:13:51 +02:00
|
|
|
#include "global.h"
|
2019-04-14 20:21:06 +02:00
|
|
|
#include "battle_setup.h"
|
|
|
|
#include "data.h"
|
|
|
|
#include "event_data.h"
|
|
|
|
#include "gym_leader_rematch.h"
|
|
|
|
#include "international_string_util.h"
|
|
|
|
#include "main.h"
|
|
|
|
#include "match_call.h"
|
|
|
|
#include "overworld.h"
|
|
|
|
#include "pokemon.h"
|
2019-04-14 17:13:51 +02:00
|
|
|
#include "pokenav.h"
|
2019-04-14 20:21:06 +02:00
|
|
|
#include "sound.h"
|
|
|
|
#include "string_util.h"
|
|
|
|
#include "strings.h"
|
|
|
|
#include "constants/flags.h"
|
|
|
|
#include "constants/songs.h"
|
2019-04-14 17:13:51 +02:00
|
|
|
|
|
|
|
struct Pokenav3Struct
|
|
|
|
{
|
2019-04-14 20:21:06 +02:00
|
|
|
u16 unk0;
|
|
|
|
u16 unk2;
|
|
|
|
const u8 *unk4;
|
2019-04-14 17:13:51 +02:00
|
|
|
u16 unk8;
|
2019-04-14 20:21:06 +02:00
|
|
|
u16 unkA;
|
|
|
|
u16 unkC;
|
2019-04-14 17:13:51 +02:00
|
|
|
u32 unk10;
|
|
|
|
u32 unk14;
|
2019-04-14 20:21:06 +02:00
|
|
|
u32 (*callback)(struct Pokenav3Struct*);
|
|
|
|
struct Pokenav3Struct_Unk1C unk1C[99];
|
2019-04-14 17:13:51 +02:00
|
|
|
};
|
|
|
|
|
2019-04-14 20:21:06 +02:00
|
|
|
static u32 sub_81CAB44(struct Pokenav3Struct *);
|
|
|
|
static u32 sub_81CABFC(struct Pokenav3Struct *);
|
|
|
|
static u32 sub_81CAC04(struct Pokenav3Struct *);
|
|
|
|
static u32 sub_81CACB8(struct Pokenav3Struct *);
|
|
|
|
static u32 sub_81CACF8(struct Pokenav3Struct *);
|
|
|
|
static u32 sub_81CAD20(int);
|
|
|
|
static bool32 sub_81CB1D0(void);
|
|
|
|
|
|
|
|
extern const u8 gUnknown_08622508[];
|
|
|
|
extern const u8 gUnknown_0862250A[];
|
|
|
|
extern const u8 *const gUnknown_08622028[][4];
|
2019-04-14 17:13:51 +02:00
|
|
|
|
|
|
|
bool32 sub_81CAAE8(void)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = AllocSubstruct(5, sizeof(struct Pokenav3Struct));
|
|
|
|
if (!state)
|
|
|
|
return FALSE;
|
|
|
|
|
2019-04-14 20:21:06 +02:00
|
|
|
state->callback = sub_81CAB44;
|
2019-04-14 17:13:51 +02:00
|
|
|
state->unk8 = 0;
|
|
|
|
state->unk10 = 0;
|
|
|
|
state->unk14 = CreateLoopedTask(sub_81CAD20, 1);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 sub_81CAB24(void)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
2019-04-14 20:21:06 +02:00
|
|
|
return state->callback(state);
|
2019-04-14 17:13:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void sub_81CAB38(void)
|
|
|
|
{
|
|
|
|
FreePokenavSubstruct(5);
|
|
|
|
}
|
2019-04-14 20:21:06 +02:00
|
|
|
|
|
|
|
static u32 sub_81CAB44(struct Pokenav3Struct *state)
|
|
|
|
{
|
|
|
|
int selectedMatchCall;
|
|
|
|
|
|
|
|
if (gMain.newAndRepeatedKeys & DPAD_UP)
|
|
|
|
return 2;
|
|
|
|
if (gMain.newAndRepeatedKeys & DPAD_DOWN)
|
|
|
|
return 1;
|
|
|
|
if (gMain.newAndRepeatedKeys & DPAD_LEFT)
|
|
|
|
return 4;
|
|
|
|
if (gMain.newAndRepeatedKeys & DPAD_RIGHT)
|
|
|
|
return 3;
|
|
|
|
|
|
|
|
if (gMain.newKeys & A_BUTTON)
|
|
|
|
{
|
|
|
|
state->callback = sub_81CAC04;
|
|
|
|
state->unk0 = 0;
|
|
|
|
selectedMatchCall = GetSelectedMatchCall();
|
|
|
|
if (!state->unk1C[selectedMatchCall].unk0 || sub_81D17E8(state->unk1C[selectedMatchCall].unk2))
|
|
|
|
{
|
|
|
|
state->unk4 = gUnknown_0862250A;
|
|
|
|
state->unk2 = 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
state->unk4 = gUnknown_08622508;
|
|
|
|
state->unk2 = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gMain.newKeys & B_BUTTON)
|
|
|
|
{
|
|
|
|
if (GetPokenavMode() != POKENAV_MODE_FORCE_CALL_1)
|
|
|
|
{
|
|
|
|
state->callback = sub_81CABFC;
|
|
|
|
return 15;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PlaySE(SE_HAZURE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u32 sub_81CABFC(struct Pokenav3Struct *state)
|
|
|
|
{
|
|
|
|
return POKENAV_MENU_4;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u32 sub_81CAC04(struct Pokenav3Struct *state)
|
|
|
|
{
|
|
|
|
if ((gMain.newKeys & DPAD_UP) && state->unk0)
|
|
|
|
{
|
|
|
|
state->unk0--;
|
|
|
|
return 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((gMain.newKeys & DPAD_DOWN) && state->unk0 < state->unk2)
|
|
|
|
{
|
|
|
|
state->unk0++;
|
|
|
|
return 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gMain.newKeys & A_BUTTON)
|
|
|
|
{
|
|
|
|
switch (state->unk4[state->unk0])
|
|
|
|
{
|
|
|
|
case 2:
|
|
|
|
state->callback = sub_81CAB44;
|
|
|
|
return 7;
|
|
|
|
case 0:
|
|
|
|
if (GetPokenavMode() == POKENAV_MODE_FORCE_CALL_1)
|
|
|
|
SetPokenavMode(POKENAV_MODE_FORCE_CALL_2);
|
|
|
|
|
|
|
|
state->callback = sub_81CACF8;
|
|
|
|
if (sub_81CB1D0())
|
|
|
|
return 9;
|
|
|
|
|
|
|
|
return 8;
|
|
|
|
case 1:
|
|
|
|
state->callback = sub_81CACB8;
|
|
|
|
return 11;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gMain.newKeys & B_BUTTON)
|
|
|
|
{
|
|
|
|
state->callback = sub_81CAB44;
|
|
|
|
return 7;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u32 sub_81CACB8(struct Pokenav3Struct *state)
|
|
|
|
{
|
|
|
|
if (gMain.newAndRepeatedKeys & DPAD_UP)
|
|
|
|
return 12;
|
|
|
|
if (gMain.newAndRepeatedKeys & DPAD_DOWN)
|
|
|
|
return 13;
|
|
|
|
|
|
|
|
if (gMain.newKeys & B_BUTTON)
|
|
|
|
{
|
|
|
|
state->callback = sub_81CAB44;
|
|
|
|
return 14;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u32 sub_81CACF8(struct Pokenav3Struct *state)
|
|
|
|
{
|
|
|
|
if (gMain.newKeys & (A_BUTTON | B_BUTTON))
|
|
|
|
{
|
|
|
|
state->callback = sub_81CAB44;
|
|
|
|
return 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static u32 sub_81CAD20(int taskState)
|
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
switch (taskState)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
state->unk8 = 0;
|
|
|
|
state->unkA = 0;
|
|
|
|
return LT_INC_AND_CONTINUE;
|
|
|
|
case 1:
|
|
|
|
for (i = 0, j = state->unk8; i < 30; i++, j++)
|
|
|
|
{
|
|
|
|
if (MatchCallFlagGetByIndex(j))
|
|
|
|
{
|
|
|
|
state->unk1C[state->unkA].unk2 = j;
|
|
|
|
state->unk1C[state->unkA].unk0 = 1;
|
|
|
|
state->unk1C[state->unkA].unk1 = sub_81D16DC(j);
|
|
|
|
state->unkA++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (++state->unk8 >= 21) // TODO: This is the size of sMatchCallHeaders
|
|
|
|
{
|
|
|
|
state->unkC = state->unk8;
|
|
|
|
state->unk8 = 0;
|
|
|
|
return LT_INC_AND_CONTINUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return LT_CONTINUE;
|
|
|
|
case 2:
|
|
|
|
for (i = 0, j = state->unk8; i < 30; i++, j++)
|
|
|
|
{
|
|
|
|
if (!sub_81D1BF8(state->unk8) && sub_81CAE08(state->unk8))
|
|
|
|
{
|
|
|
|
state->unk1C[state->unkA].unk2 = state->unk8;
|
|
|
|
state->unk1C[state->unkA].unk0 = 0;
|
|
|
|
state->unk1C[state->unkA].unk1 = sub_81CB0C8(j);
|
|
|
|
state->unkA++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (++state->unk8 > REMATCH_TABLE_ENTRIES - 1)
|
|
|
|
return LT_INC_AND_CONTINUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LT_CONTINUE;
|
|
|
|
case 3:
|
|
|
|
state->unk10 = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LT_FINISH;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool32 sub_81CAE08(int rematchIndex)
|
|
|
|
{
|
|
|
|
if (rematchIndex < REMATCH_TABLE_ENTRIES)
|
|
|
|
return FlagGet(FLAG_MATCH_CALL_REGISTERED + rematchIndex);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sub_81CAE28(void)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
return state->unk10;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sub_81CAE38(void)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
return state->unkA;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sub_81CAE48(void)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
return state->unkC;
|
|
|
|
}
|
|
|
|
|
|
|
|
int unref_sub_81CAE58(void)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
return state->unkA - state->unkC;
|
|
|
|
}
|
|
|
|
|
|
|
|
int unref_sub_81CAE6C(int arg0)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
arg0 += state->unkC;
|
|
|
|
if (arg0 >= state->unkA)
|
|
|
|
return REMATCH_TABLE_ENTRIES;
|
2019-05-26 12:42:01 +02:00
|
|
|
|
2019-04-14 20:21:06 +02:00
|
|
|
return state->unk1C[arg0].unk2;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Pokenav3Struct_Unk1C *sub_81CAE94(void)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
return state->unk1C;
|
|
|
|
}
|
|
|
|
|
|
|
|
u16 sub_81CAEA4(int index)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
return state->unk1C[index].unk1;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool32 sub_81CAEBC(int index)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
if (!state->unk1C[index].unk0)
|
|
|
|
index = state->unk1C[index].unk2;
|
|
|
|
else
|
|
|
|
index = MatchCall_GetRematchTableIdx(state->unk1C[index].unk2);
|
|
|
|
|
|
|
|
if (index == REMATCH_TABLE_ENTRIES)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return gSaveBlock1Ptr->trainerRematches[index] != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sub_81CAF04(int index)
|
|
|
|
{
|
|
|
|
int var0;
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
if (!state->unk1C[index].unk0)
|
|
|
|
{
|
|
|
|
index = GetTrainerIdxByRematchIdx(state->unk1C[index].unk2);
|
|
|
|
return gTrainers[index].trainerPic;
|
|
|
|
}
|
2019-05-26 12:42:01 +02:00
|
|
|
|
2019-04-14 20:21:06 +02:00
|
|
|
var0 = state->unk1C[index].unk2;
|
|
|
|
index = MatchCall_GetRematchTableIdx(var0);
|
|
|
|
if (index != REMATCH_TABLE_ENTRIES)
|
|
|
|
{
|
|
|
|
index = GetTrainerIdxByRematchIdx(index);
|
|
|
|
return gTrainers[index].trainerPic;
|
|
|
|
}
|
|
|
|
|
|
|
|
index = sub_81D1BD0(var0);
|
|
|
|
return gFacilityClassToPicIndex[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
const u8 *sub_81CAF78(int index, u8 *arg1)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
*arg1 = 0;
|
|
|
|
if (!Overworld_MapTypeAllowsTeleportAndFly(gMapHeader.mapType))
|
|
|
|
return gText_CallCantBeMadeHere;
|
|
|
|
|
|
|
|
if (!state->unk1C[index].unk0)
|
|
|
|
*arg1 = SelectMatchCallMessage(GetTrainerIdxByRematchIdx(state->unk1C[index].unk2), gStringVar4);
|
|
|
|
else
|
|
|
|
MatchCall_GetMessage(state->unk1C[index].unk2, gStringVar4);
|
|
|
|
|
|
|
|
return gStringVar4;
|
|
|
|
}
|
|
|
|
|
|
|
|
const u8 *sub_81CAFD8(int index, int textType)
|
|
|
|
{
|
|
|
|
int var0;
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
if (state->unk1C[index].unk0)
|
|
|
|
{
|
|
|
|
var0 = MatchCall_GetRematchTableIdx(state->unk1C[index].unk2);
|
|
|
|
if (var0 == REMATCH_TABLE_ENTRIES)
|
|
|
|
return sub_81D1B40(state->unk1C[index].unk2, textType);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
var0 = state->unk1C[index].unk2;
|
|
|
|
}
|
|
|
|
|
|
|
|
return gUnknown_08622028[var0][textType];
|
|
|
|
}
|
|
|
|
|
|
|
|
u16 sub_81CB01C(void)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
return state->unk0;
|
|
|
|
}
|
|
|
|
|
|
|
|
u16 sub_81CB02C(int arg0)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
if (state->unk2 < arg0)
|
|
|
|
return 3;
|
|
|
|
|
|
|
|
return state->unk4[arg0];
|
|
|
|
}
|
|
|
|
|
2019-04-16 18:00:13 +02:00
|
|
|
void sub_81CB050(u32 arg0, u8 *str)
|
2019-04-14 20:21:06 +02:00
|
|
|
{
|
2019-04-16 18:00:13 +02:00
|
|
|
struct Pokenav3Struct_Unk1C *var0 = (struct Pokenav3Struct_Unk1C *)arg0;
|
2019-04-14 20:21:06 +02:00
|
|
|
const u8 *trainerName;
|
|
|
|
const u8 *className;
|
2019-04-16 18:00:13 +02:00
|
|
|
if (!var0->unk0)
|
2019-04-14 20:21:06 +02:00
|
|
|
{
|
2019-04-16 18:00:13 +02:00
|
|
|
int index = GetTrainerIdxByRematchIdx(var0->unk2);
|
2019-04-14 20:21:06 +02:00
|
|
|
const struct Trainer *trainer = &gTrainers[index];
|
|
|
|
int class = trainer->trainerClass;
|
|
|
|
className = gTrainerClassNames[class];
|
|
|
|
trainerName = trainer->trainerName;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-04-16 18:00:13 +02:00
|
|
|
sub_81D1A78(var0->unk2, &className, &trainerName);
|
2019-04-14 20:21:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (className && trainerName)
|
|
|
|
{
|
|
|
|
u8 *str2 = sub_81DB494(str, 7, className, 69);
|
|
|
|
sub_81DB494(str2, 7, trainerName, 51);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sub_81DB494(str, 7, NULL, 120);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-26 12:42:01 +02:00
|
|
|
u8 sub_81CB0C8(int rematchIndex)
|
2019-04-14 20:21:06 +02:00
|
|
|
{
|
|
|
|
int mapGroup = gRematchTable[rematchIndex].mapGroup;
|
|
|
|
int mapNum = gRematchTable[rematchIndex].mapNum;
|
|
|
|
return Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum)->regionMapSectionId;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sub_81CB0E4(int index)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
int count = 1;
|
|
|
|
while (++index < state->unkA)
|
|
|
|
{
|
|
|
|
if (!state->unk1C[index].unk0)
|
|
|
|
return count;
|
|
|
|
if (sub_81D17E8(state->unk1C[index].unk2))
|
|
|
|
return count;
|
|
|
|
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sub_81CB128(int index)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
int count = -1;
|
|
|
|
while (--index >= 0)
|
|
|
|
{
|
|
|
|
if (!state->unk1C[index].unk0)
|
|
|
|
return count;
|
|
|
|
if (sub_81D17E8(state->unk1C[index].unk2))
|
|
|
|
return count;
|
|
|
|
|
|
|
|
count--;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool32 unref_sub_81CB16C(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < REMATCH_TABLE_ENTRIES; i++)
|
|
|
|
{
|
|
|
|
if (sub_81CAE08(i) && gSaveBlock1Ptr->trainerRematches[i])
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < 21; i++) // TODO: This is the size of sMatchCallHeaders
|
|
|
|
{
|
|
|
|
if (MatchCallFlagGetByIndex(i))
|
|
|
|
{
|
|
|
|
int index = MatchCall_GetRematchTableIdx(i);
|
|
|
|
if (gSaveBlock1Ptr->trainerRematches[index])
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool32 sub_81CB1D0(void)
|
|
|
|
{
|
|
|
|
struct Pokenav3Struct *state = GetSubstructPtr(5);
|
|
|
|
int index = GetSelectedMatchCall();
|
|
|
|
if (!state->unk1C[index].unk0)
|
|
|
|
{
|
|
|
|
if (sub_81CAEA4(index) == gMapHeader.regionMapSectionId)
|
|
|
|
{
|
|
|
|
if (!gSaveBlock1Ptr->trainerRematches[state->unk1C[index].unk2])
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (state->unk1C[index].unk2 == 11)
|
|
|
|
{
|
|
|
|
if (sub_81CAEA4(index) == gMapHeader.regionMapSectionId
|
|
|
|
&& FlagGet(FLAG_BADGE05_GET) == TRUE)
|
|
|
|
{
|
|
|
|
if (!FlagGet(FLAG_WATTSON_REMATCH_AVAILABLE))
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|