From 8a793e73a515e9c66aa98ef6c14e923b18dd4ce3 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Fri, 19 Aug 2022 15:22:32 -0400 Subject: [PATCH 01/12] Sync link_rfu_2 --- common_syms/link_rfu_2.txt | 4 +- include/link_rfu.h | 28 +++++----- include/trade.h | 4 +- include/union_room.h | 4 +- src/link_rfu_2.c | 102 ++++++++++++++++++------------------- src/link_rfu_3.c | 12 ++--- src/party_menu.c | 4 +- src/rfu_union_tool.c | 10 ++-- src/trade.c | 4 +- src/union_room.c | 10 ++-- 10 files changed, 91 insertions(+), 91 deletions(-) diff --git a/common_syms/link_rfu_2.txt b/common_syms/link_rfu_2.txt index 5e6f69ff6..abd9a5f93 100644 --- a/common_syms/link_rfu_2.txt +++ b/common_syms/link_rfu_2.txt @@ -1,3 +1,3 @@ -gHostRFUtgtGnameBuffer +gHostRfuGameData Rfu -gHostRFUtgtUnameBuffer +gHostRfuUsername diff --git a/include/link_rfu.h b/include/link_rfu.h index 1792781ff..1e4a72c6c 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -57,7 +57,7 @@ #define RFU_RECV_FINISHED 2 // RfuTgtData.gname is read as these structs. -struct GFtgtGnameSub +struct RfuGameCompatibilityData { u16 language:4; u16 hasNews:1; @@ -71,9 +71,9 @@ struct GFtgtGnameSub u8 playerTrainerId[2]; }; -struct __attribute__((packed, aligned(2))) GFtgtGname +struct __attribute__((packed, aligned(2))) RfuGameData { - struct GFtgtGnameSub unk_00; + struct RfuGameCompatibilityData unk_00; u8 child_sprite_gender[RFU_CHILD_MAX]; // u8 sprite_idx:3; // u8 gender:1; // u8 unk_4:3 @@ -139,7 +139,7 @@ struct RfuUnusedQueue /* 0x203 */ vu8 full; }; -typedef struct UnkRfuStruct_2 +struct RfuManager { /* 0x000 */ void (*RfuFunc)(void); /* 0x004 */ u16 state; @@ -204,11 +204,11 @@ typedef struct UnkRfuStruct_2 /* 0x9a1 */ u8 unk_ce9; /* 0x9a2 */ u8 unk_cea[RFU_CHILD_MAX]; /* 0x9a6 */ u8 unk_cee[RFU_CHILD_MAX]; -} GF_RFU_MANAGER; // size: 0x9AC +}; // size: 0x9AC -extern struct GFtgtGname gHostRFUtgtGnameBuffer; -extern u8 gHostRFUtgtUnameBuffer[]; -extern GF_RFU_MANAGER Rfu; +extern struct RfuGameData gHostRfuGameData; +extern u8 gHostRfuUsername[]; +extern struct RfuManager Rfu; // GameFreak signatures void AddTextPrinterToWindow1(const u8 *str); @@ -246,7 +246,7 @@ void LinkRfu_Shutdown(void); void LinkRfu_CreateIdleTask(void); bool8 ToggleLMANlinkRecovery(bool32 enable); void var_800D_set_xB(void); -struct GFtgtGname *GetHostRFUtgtGname(void); +struct RfuGameData *GetHostRFUtgtGname(void); void UpdateWirelessStatusIndicatorSprite(void); void InitRFU(void); bool32 RfuHasErrored(void); @@ -262,7 +262,7 @@ bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *dest); void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *dest); bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue * queue, u8 *dest); void RfuSendQueue_Enqueue(struct RfuSendQueue * queue, u8 *src); -void InitHostRFUtgtGname(struct GFtgtGname *data, u8 activity, bool32 started, s32 child_sprite_genders); +void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 started, s32 child_sprite_genders); void UpdateGameData_GroupLockedIn(bool8 started); bool32 IsRfuSerialNumberValid(u32 serialNo); bool8 IsRfuRecoveringFromLinkLoss(void); @@ -277,7 +277,7 @@ u32 WaitSendByteToPartnerByIdAndName(u16 a0, const u8 *a1); void SetHostRFUtgtGname(u8 activity, u32 child_sprite_genders, u32 a2); void InitializeRfuLinkManager_LinkLeader(u32 availSlots); void RequestDisconnectSlotByTrainerNameAndId(const u8 *trainerName, u16 trainerId); -void LinkRfu3_SetGnameUnameFromStaticBuffers(struct GFtgtGname *gname, u8 *uname); +void LinkRfu3_SetGnameUnameFromStaticBuffers(struct RfuGameData *gname, u8 *uname); void InitializeRfuLinkManager_JoinGroup(void); void SendLeaveGroupNotice(void); void CreateTask_RfuReconnectWithParent(const u8 *src, u16 trainerId); @@ -292,10 +292,10 @@ void RfuUpdatePlayerGnameStateAndSend(u32 type, u32 species, u32 level); bool32 IsUnionRoomListenTaskActive(void); void InitializeRfuLinkManager_EnterUnionRoom(void); void sub_80FBD6C(u32 a0); -void sub_80FC114(const u8 *name, struct GFtgtGname *structPtr, u8 a2); +void sub_80FC114(const u8 *name, struct RfuGameData *structPtr, u8 a2); bool32 PlayerHasMetTrainerBefore(u16 id, u8 *name); -bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *gname, u8 *uname, u8 idx); -bool8 LinkRfu_GetNameIfSerial7F7D(struct GFtgtGname *gname, u8 *uname, u8 idx); +bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx); +bool8 LinkRfu_GetNameIfSerial7F7D(struct RfuGameData *gname, u8 *uname, u8 idx); bool32 RfuHasFoundNewLeader(void); void Rfu_UnionRoomChat_StopLinkManager(void); void sub_80FB9D0(void); diff --git a/include/trade.h b/include/trade.h index 036c470a1..ede68b05d 100644 --- a/include/trade.h +++ b/include/trade.h @@ -15,8 +15,8 @@ extern const u8 gText_GenderlessSymbol[]; extern const u16 gTradeOrHatchMonShadowTilemap[]; void CB2_ReturnFromLinkTrade(void); s32 Trade_CalcLinkPlayerCompatibilityParam(void); -s32 CanRegisterMonForTradingBoard(struct GFtgtGnameSub rfuPlayer, u16 species2, u16 species, u8 isEventLegal); -s32 GetUnionRoomTradeMessageId(struct GFtgtGnameSub rfuPlayer, struct GFtgtGnameSub rfuPartner, u16 playerSpecies2, u16 partnerSpecies, u8 requestedType, u16 playerSpecies, u8 isEventLegal); +s32 CanRegisterMonForTradingBoard(struct RfuGameCompatibilityData rfuPlayer, u16 species2, u16 species, u8 isEventLegal); +s32 GetUnionRoomTradeMessageId(struct RfuGameCompatibilityData rfuPlayer, struct RfuGameCompatibilityData rfuPartner, u16 playerSpecies2, u16 partnerSpecies, u8 requestedType, u16 playerSpecies, u8 isEventLegal); void CB2_ReturnToTradeMenuFromSummary(void); #endif //GUARD_TRADE_H diff --git a/include/union_room.h b/include/union_room.h index d520e8763..c39513ec2 100644 --- a/include/union_room.h +++ b/include/union_room.h @@ -14,7 +14,7 @@ struct UnionGnameUnamePair { - struct GFtgtGname gname; + struct RfuGameData gname; u8 ALIGNED(4) uname[PLAYER_NAME_LENGTH + 1]; }; @@ -158,7 +158,7 @@ struct UnionRoomTrade u32 personality; }; -extern struct GFtgtGnameSub gPartnerTgtGnameSub; +extern struct RfuGameCompatibilityData gPartnerTgtGnameSub; extern u16 gUnionRoomOfferedSpecies; extern u8 gUnionRoomRequestedMonType; diff --git a/src/link_rfu_2.c b/src/link_rfu_2.c index 2cac8210a..3d5f5b11e 100644 --- a/src/link_rfu_2.c +++ b/src/link_rfu_2.c @@ -13,37 +13,37 @@ struct SioInfo { - char magic[15]; // PokemonSioInfo + char magic[sizeof("PokemonSioInfo")]; u8 playerCount; u8 linkPlayerIdx[RFU_CHILD_MAX]; struct LinkPlayer linkPlayers[MAX_RFU_PLAYERS]; - u8 fill_a0[0x5c]; + u8 filler[92]; }; struct RfuDebug { - u8 fill_00[6]; - u16 unk_06; - u8 fill_08[6]; - vu8 unk_0e; - u8 unk_0f; - u8 fill_10[0x54]; - u16 unk_64; - u8 fill_66[0x1d]; - u8 unk_83; - u8 fill_84[0x58]; + u8 unused0[6]; + u16 recvCount; + u8 unused1[6]; + vu8 unkFlag; + bool8 childJoined; + u8 unused2[84]; + u16 blockSendFailures; + u8 unused3[29]; + u8 blockSendTime; + u8 unused4[88]; }; static EWRAM_DATA INIT_PARAM sRfuReqConfig = {}; static EWRAM_DATA struct RfuDebug sRfuDebug = {}; -static u32 gf_rfu_REQ_api[RFU_API_BUFF_SIZE_RAM / 4]; -static u8 sResendBlock8[14]; -static u16 sResendBlock16[7]; +static u32 sRfuAPIBuffer[RFU_API_BUFF_SIZE_RAM / 4]; +static u8 sResendBlock8[CMD_LENGTH * 2]; +static u16 sResendBlock16[CMD_LENGTH]; -struct GFtgtGname gHostRFUtgtGnameBuffer; -GF_RFU_MANAGER Rfu; -u8 gHostRFUtgtUnameBuffer[PLAYER_NAME_LENGTH + 1]; +struct RfuGameData gHostRfuGameData; +struct RfuManager Rfu; +u8 gHostRfuUsername[PLAYER_NAME_LENGTH + 1]; static void sub_80F8AA4(void); static void sub_80F8AEC(void); @@ -80,8 +80,8 @@ static const INIT_PARAM sRfuReqConfigTemplate = { .availSlot_flag = 0, .mboot_flag = 0, .serialNo = 0x0002, - .gameName = (void *)&gHostRFUtgtGnameBuffer, - .userName = gHostRFUtgtUnameBuffer, + .gameName = (void *)&gHostRfuGameData, + .userName = gHostRfuUsername, .fastSearchParent_flag = TRUE, .linkRecovery_enable = FALSE, .linkRecovery_period = 600, @@ -257,7 +257,7 @@ void InitRFU(void) void InitRFUAPI(void) { - if (!rfu_initializeAPI(gf_rfu_REQ_api, RFU_API_BUFF_SIZE_RAM, gIntrTable + 1, TRUE)) + if (!rfu_initializeAPI(sRfuAPIBuffer, RFU_API_BUFF_SIZE_RAM, gIntrTable + 1, TRUE)) { gLinkType = 0; // ClearSavedLinkPlayers(); // Em fix @@ -402,10 +402,10 @@ static void Task_JoinGroupSearchForParent(u8 taskId) rfu_UNI_setSendData(bmChildSlot, Rfu.lastCmdBeforeCommInterrupt, sizeof(Rfu.lastCmdBeforeCommInterrupt)); gTasks[taskId].data[1] = 8; DestroyTask(taskId); - if (sRfuDebug.unk_0f == 0) + if (!sRfuDebug.childJoined) { Debug_PrintEmpty(); - sRfuDebug.unk_0f++; + sRfuDebug.childJoined++; } CreateTask(sub_80FA834, 5); break; @@ -523,7 +523,7 @@ static void MscCallback_Child(u16 unused) { Rfu.sem_UNI_SendRecv++; RfuRecvQueue_Enqueue(&Rfu.recvQueue, Rfu.unk_c3f); - sRfuDebug.unk_06++; + sRfuDebug.recvCount++; UpdateBackupQueue(); rfu_UNI_readySendData(Rfu.child_slot); rfu_UNI_clearRecvNewDataFlag(Rfu.child_slot); @@ -662,7 +662,7 @@ static void MoveRecvCmdsToRfuBuffer(void) for (i = 0; i < MAX_RFU_PLAYERS; i++) { - GF_RFU_MANAGER *ptr = &Rfu; + struct RfuManager *ptr = &Rfu; for (j = 0; j < CMD_LENGTH - 1; j++) { ptr->recvCmds[i][j][1] = gRecvCmds[i][j] >> 8; @@ -797,7 +797,7 @@ static bool32 sub_80F9204(void) if ((lman.parentAck_flag & Rfu.bm_PartnerFlags) == Rfu.bm_PartnerFlags) { Rfu.unk_cdc = 0; - sRfuDebug.unk_06++; + sRfuDebug.recvCount++; flags = lman.acceptSlot_flag; for (i = 0; i < RFU_CHILD_MAX; i++) { @@ -833,7 +833,7 @@ static bool32 sub_80F9204(void) CallRfuFunc(); if (Rfu.bmChatLeaderMaybe && !Rfu.linkClosing) { - sRfuDebug.unk_0e = FALSE; + sRfuDebug.unkFlag = FALSE; rfu_clearSlot(TYPE_UNI_SEND | TYPE_UNI_RECV, Rfu.unk_cda); for (i = 0; i < RFU_CHILD_MAX; i++) { @@ -1000,9 +1000,9 @@ static void RfuFunc_SendKeysToRfu(void) } } -struct GFtgtGname *GetHostRFUtgtGname(void) +struct RfuGameData *GetHostRFUtgtGname(void) { - return &gHostRFUtgtGnameBuffer; + return &gHostRfuGameData; } bool32 IsSendingKeysToRfu(void) @@ -1239,7 +1239,7 @@ bool32 Rfu_InitBlockSend(const u8 *src, size_t size) return FALSE; if (Rfu.sendBlock.sending != 0) { - sRfuDebug.unk_83++; + sRfuDebug.blockSendTime++; return FALSE; } sizeHasModulo = (size % 12) != 0; @@ -1308,7 +1308,7 @@ static void SendLastBlock(void) if (Rfu.recvBlock[mpId].receivedFlags != sAllBlocksReceived[Rfu.recvBlock[mpId].count]) { HandleSendFailure(mpId, Rfu.recvBlock[mpId].receivedFlags); - sRfuDebug.unk_64++; + sRfuDebug.blockSendFailures++; } else Rfu.RfuFunc = NULL; @@ -1965,44 +1965,44 @@ bool32 LinkRfuMain2(void) static void CopyPlayerNameToUnameBuffer(void) { - StringCopy(gHostRFUtgtUnameBuffer, gSaveBlock2Ptr->playerName); + StringCopy(gHostRfuUsername, gSaveBlock2Ptr->playerName); } void ClearAndInitHostRFUtgtGname(void) { - memset(&gHostRFUtgtGnameBuffer, 0, RFU_GAME_NAME_LENGTH); - InitHostRFUtgtGname(&gHostRFUtgtGnameBuffer, ACTIVITY_NONE, FALSE, 0); + memset(&gHostRfuGameData, 0, RFU_GAME_NAME_LENGTH); + InitHostRFUtgtGname(&gHostRfuGameData, ACTIVITY_NONE, FALSE, 0); } void SetHostRFUtgtGname(u8 activity, u32 child_sprite_genders, u32 started) { - InitHostRFUtgtGname(&gHostRFUtgtGnameBuffer, activity, started, child_sprite_genders); + InitHostRFUtgtGname(&gHostRfuGameData, activity, started, child_sprite_genders); } void SetGnameBufferWonderFlags(bool32 hasNews, bool32 hasCard) { - gHostRFUtgtGnameBuffer.unk_00.hasNews = hasNews; - gHostRFUtgtGnameBuffer.unk_00.hasCard = hasCard; + gHostRfuGameData.unk_00.hasNews = hasNews; + gHostRfuGameData.unk_00.hasCard = hasCard; } void RfuUpdatePlayerGnameStateAndSend(u32 type, u32 species, u32 level) { - gHostRFUtgtGnameBuffer.type = type; - gHostRFUtgtGnameBuffer.species = species; - gHostRFUtgtGnameBuffer.level = level; + gHostRfuGameData.type = type; + gHostRfuGameData.species = species; + gHostRfuGameData.level = level; } void UpdateGameData_GroupLockedIn(bool8 started) { - gHostRFUtgtGnameBuffer.started = started; - rfu_REQ_configGameData(0, 0x0002, (void *)&gHostRFUtgtGnameBuffer, gHostRFUtgtUnameBuffer); + gHostRfuGameData.started = started; + rfu_REQ_configGameData(0, 0x0002, (void *)&gHostRfuGameData, gHostRfuUsername); } void UpdateGameDataWithActivitySpriteGendersFlag(u8 activity, u32 child_sprite_genders, u32 started) { if (activity) SetHostRFUtgtGname(activity, child_sprite_genders, started); - rfu_REQ_configGameData(0, 0x0002, (void *)&gHostRFUtgtGnameBuffer, gHostRFUtgtUnameBuffer); + rfu_REQ_configGameData(0, 0x0002, (void *)&gHostRfuGameData, gHostRfuUsername); } void sub_80FB030(u32 linkPlayerCount) @@ -2086,7 +2086,7 @@ static void LmanCallback_Parent2(u8 msg, u8 param_count) { if ((lman.param[0] >> i) & 1) { - struct GFtgtGname *structPtr = (void *)&gRfuLinkStatus->partner[i].gname; + struct RfuGameData *structPtr = (void *)&gRfuLinkStatus->partner[i].gname; if (structPtr->activity == GetHostRFUtgtGname()->activity) { Rfu.partnerSendStatuses[i] = RFU_STATUS_OK; @@ -2254,7 +2254,7 @@ static u8 GetNewChildrenInUnionRoomChat(s32 bmNewChildSlot) { if ((bmNewChildSlot >> i) & 1) { - struct GFtgtGname *structPtr = (void *)&gRfuLinkStatus->partner[i].gname; + struct RfuGameData *structPtr = (void *)&gRfuLinkStatus->partner[i].gname; if (structPtr->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) ret |= (1 << i); } @@ -2564,7 +2564,7 @@ static u8 GetPartnerIndexByNameAndTrainerID(const u8 *trainerName, u16 trainerId for (i = 0; i < RFU_CHILD_MAX; i++) { - u16 partnerTrainerId = ReadU16(((struct GFtgtGname *)gRfuLinkStatus->partner[i].gname)->unk_00.playerTrainerId); + u16 partnerTrainerId = ReadU16(((struct RfuGameData *)gRfuLinkStatus->partner[i].gname)->unk_00.playerTrainerId); if (IsRfuSerialNumberValid(gRfuLinkStatus->partner[i].serialNo) && !StringCompare(trainerName, gRfuLinkStatus->partner[i].uname) && trainerId == partnerTrainerId) @@ -2696,7 +2696,7 @@ void CreateTask_RfuReconnectWithParent(const u8 *trainerName, u16 trainerId) data[8] = trainerId; } -static bool32 ShouldRejectPartnerConnectionBasedOnActivity(s16 activity, struct GFtgtGname *partnerGname) +static bool32 ShouldRejectPartnerConnectionBasedOnActivity(s16 activity, struct RfuGameData *partnerGname) { if (GetHostRFUtgtGname()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) { @@ -2709,7 +2709,7 @@ static bool32 ShouldRejectPartnerConnectionBasedOnActivity(s16 activity, struct } else if (activity == (ACTIVITY_TRADE | IN_UNION_ROOM)) { - struct GFtgtGname *myTradeGname = (struct GFtgtGname *)&Rfu.tgtData.gname; + struct RfuGameData *myTradeGname = (struct RfuGameData *)&Rfu.tgtData.gname; if (myTradeGname->species == SPECIES_EGG) { if (partnerGname->species == myTradeGname->species) @@ -2741,11 +2741,11 @@ static void sub_80FC028(u8 taskId) if (Rfu.parentId != 0 && lman.parent_child == MODE_CHILD) { - u16 trainerId = ReadU16(((struct GFtgtGname *)&Rfu.tgtData.gname)->unk_00.playerTrainerId); + u16 trainerId = ReadU16(((struct RfuGameData *)&Rfu.tgtData.gname)->unk_00.playerTrainerId); u8 id = GetPartnerIndexByNameAndTrainerID(Rfu.tgtData.uname, trainerId); if (id != 0xFF) { - if (!ShouldRejectPartnerConnectionBasedOnActivity(gTasks[taskId].data[1], (struct GFtgtGname *)&gRfuLinkStatus->partner[id].gname)) + if (!ShouldRejectPartnerConnectionBasedOnActivity(gTasks[taskId].data[1], (struct RfuGameData *)&gRfuLinkStatus->partner[id].gname)) { if (gRfuLinkStatus->partner[id].slot != 0xFF && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[id].id, 90)) { @@ -2762,7 +2762,7 @@ static void sub_80FC028(u8 taskId) } } -void sub_80FC114(const u8 *name, struct GFtgtGname *structPtr, u8 activity) +void sub_80FC114(const u8 *name, struct RfuGameData *structPtr, u8 activity) { u8 taskId, taskId2; diff --git a/src/link_rfu_3.c b/src/link_rfu_3.c index de0a63490..fb6828053 100644 --- a/src/link_rfu_3.c +++ b/src/link_rfu_3.c @@ -661,7 +661,7 @@ static u8 GetConnectedChildStrength(u8 maxFlags) return 0; } -void InitHostRFUtgtGname(struct GFtgtGname *data, u8 activity, bool32 started, s32 child_sprite_genders) +void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 started, s32 child_sprite_genders) { s32 i; @@ -694,7 +694,7 @@ void InitHostRFUtgtGname(struct GFtgtGname *data, u8 activity, bool32 started, s * Otherwise, blanks these. * ========================================================== */ -bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *gname, u8 *uname, u8 idx) +bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx) { bool8 retVal; @@ -735,7 +735,7 @@ bool8 LinkRfu_GetNameIfCompatible(struct GFtgtGname *gname, u8 *uname, u8 idx) * which comes from ??? * ========================================================== */ -bool8 LinkRfu_GetNameIfSerial7F7D(struct GFtgtGname *gname, u8 *uname, u8 idx) +bool8 LinkRfu_GetNameIfSerial7F7D(struct RfuGameData *gname, u8 *uname, u8 idx) { bool8 retVal = FALSE; if (gRfuLinkStatus->partner[idx].serialNo == RFU_SERIAL_7F7D) @@ -752,10 +752,10 @@ bool8 LinkRfu_GetNameIfSerial7F7D(struct GFtgtGname *gname, u8 *uname, u8 idx) return retVal; } -void LinkRfu3_SetGnameUnameFromStaticBuffers(struct GFtgtGname *gname, u8 *uname) +void LinkRfu3_SetGnameUnameFromStaticBuffers(struct RfuGameData *gname, u8 *uname) { - memcpy(gname, &gHostRFUtgtGnameBuffer, RFU_GAME_NAME_LENGTH); - memcpy(uname, gHostRFUtgtUnameBuffer, RFU_USER_NAME_LENGTH); + memcpy(gname, &gHostRfuGameData, RFU_GAME_NAME_LENGTH); + memcpy(uname, gHostRfuUsername, RFU_USER_NAME_LENGTH); } #define sNextAnimNum data[0] diff --git a/src/party_menu.c b/src/party_menu.c index ee2800801..ad8300a9f 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -3874,7 +3874,7 @@ static void CursorCB_Register(u8 taskId) u16 species = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES); u8 isEventLegal = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_EVENT_LEGAL); - switch (CanRegisterMonForTradingBoard(*(struct GFtgtGnameSub *)GetHostRFUtgtGname(), species2, species, isEventLegal)) + switch (CanRegisterMonForTradingBoard(*(struct RfuGameCompatibilityData *)GetHostRFUtgtGname(), species2, species, isEventLegal)) { case CANT_REGISTER_MON: StringExpandPlaceholders(gStringVar4, gText_PkmnCantBeTradedNow); @@ -3900,7 +3900,7 @@ static void CursorCB_Trade1(u8 taskId) u16 species2 = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES2); u16 species = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES); u8 isEventLegal = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_EVENT_LEGAL); - u32 stringId = GetUnionRoomTradeMessageId(*(struct GFtgtGnameSub *)GetHostRFUtgtGname(), gPartnerTgtGnameSub, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal); + u32 stringId = GetUnionRoomTradeMessageId(*(struct RfuGameCompatibilityData *)GetHostRFUtgtGname(), gPartnerTgtGnameSub, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal); if (stringId != UR_TRADE_MSG_NONE) { diff --git a/src/rfu_union_tool.c b/src/rfu_union_tool.c index d6c1c411e..0d848a69e 100644 --- a/src/rfu_union_tool.c +++ b/src/rfu_union_tool.c @@ -466,7 +466,7 @@ void MakeGroupAssemblyAreasPassable(void) } } -static u8 UnionPartnerObjectGetFacing(u32 member, u32 group, struct GFtgtGname * gname) +static u8 UnionPartnerObjectGetFacing(u32 member, u32 group, struct RfuGameData * gname) { if (member != 0) { @@ -487,7 +487,7 @@ static u32 RfuUnionGroupMemberIsInvisible(u32 group, u32 member) return RfuUnionObjectIsInvisible(5 * group + member - 0x38); } -static void SpawnGroupMember(u32 groupNo, u32 memberNo, u8 direction, struct GFtgtGname * gname) +static void SpawnGroupMember(u32 groupNo, u32 memberNo, u8 direction, struct RfuGameData * gname) { s32 x, y; s32 objId = 5 * groupNo + memberNo; @@ -510,7 +510,7 @@ static void DespawnGroupMember(u32 group, u32 member) MapGridSetMetatileImpassabilityAt(x, y, FALSE); } -static void AssembleGroup(u32 group, struct GFtgtGname * gname) +static void AssembleGroup(u32 group, struct RfuGameData * gname) { s16 x, y, x2, y2; s32 i; @@ -538,7 +538,7 @@ static void AssembleGroup(u32 group, struct GFtgtGname * gname) } } -static void SpawnGroupLeaderAndMembers(u32 group, struct GFtgtGname * gname) +static void SpawnGroupLeaderAndMembers(u32 group, struct RfuGameData * gname) { u32 i; switch (gname->activity) @@ -566,7 +566,7 @@ static void SpawnGroupLeaderAndMembers(u32 group, struct GFtgtGname * gname) } } -static void DespawnGroupLeaderAndMembers(u32 group, struct GFtgtGname * gname) +static void DespawnGroupLeaderAndMembers(u32 group, struct RfuGameData * gname) { s32 i; DespawnGroupLeader(group); diff --git a/src/trade.c b/src/trade.c index 392a23061..92d14090d 100644 --- a/src/trade.c +++ b/src/trade.c @@ -2730,7 +2730,7 @@ static bool32 IsDeoxysOrMewUntradable(u16 species, bool8 isEventLegal) return FALSE; } -int GetUnionRoomTradeMessageId(struct GFtgtGnameSub playerSub, struct GFtgtGnameSub partnerSub, u16 species1, u16 species2, u8 type, u16 species3, u8 isEventLegal) +int GetUnionRoomTradeMessageId(struct RfuGameCompatibilityData playerSub, struct RfuGameCompatibilityData partnerSub, u16 species1, u16 species2, u8 type, u16 species3, u8 isEventLegal) { u8 playerHasNationalDex = playerSub.hasNationalDex; u8 playerIsChampion = playerSub.isChampion; @@ -2810,7 +2810,7 @@ int GetUnionRoomTradeMessageId(struct GFtgtGnameSub playerSub, struct GFtgtGname return 0; } -int CanRegisterMonForTradingBoard(struct GFtgtGnameSub playerSub, u16 species2, u16 species, u8 isEventLegal) +int CanRegisterMonForTradingBoard(struct RfuGameCompatibilityData playerSub, u16 species2, u16 species, u8 isEventLegal) { u8 canTradeEggAndNational = playerSub.hasNationalDex; diff --git a/src/union_room.c b/src/union_room.c index cc7df613a..00baa9802 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -53,7 +53,7 @@ static EWRAM_DATA u8 sPlayerCurrActivity = 0; static EWRAM_DATA u8 sPlayerActivityGroupSize = 0; static EWRAM_DATA union UnkUnion_Main sUnionRoomMain = {}; static EWRAM_DATA u32 sUnref_203B060 = 0; -EWRAM_DATA struct GFtgtGnameSub gPartnerTgtGnameSub = {}; +EWRAM_DATA struct RfuGameCompatibilityData gPartnerTgtGnameSub = {}; EWRAM_DATA u16 gUnionRoomOfferedSpecies = SPECIES_NONE; EWRAM_DATA u8 gUnionRoomRequestedMonType = TYPE_NORMAL; static EWRAM_DATA struct UnionRoomTrade sUnionRoomTrade = {}; @@ -86,7 +86,7 @@ static bool32 UnionRoom_HandleContactFromOtherPlayer(struct UnkStruct_URoom * uR static void Task_InitUnionRoom(u8 taskId); static u8 HandlePlayerListUpdate(void); static u8 CreateTask_SearchForChildOrParent(struct UnkStruct_Main4 * main4, struct UnkStruct_Main4 * arg1, u32 arg2); -static bool32 GetGnameWonderFlagByLinkGroup(struct GFtgtGname * gname, s16 linkGroup); +static bool32 GetGnameWonderFlagByLinkGroup(struct RfuGameData * gname, s16 linkGroup); static u8 CreateTask_ListenForPartnersWithCompatibleSerialNos(struct UnkStruct_Main4 * main4, u32 linkGroup); static u8 CreateTask_ListenForPartnersWithSerial7F7D(struct UnkStruct_Main4 * main4, u32 linkGroup); static bool32 UR_PrintFieldMessage(const u8 * str); @@ -3719,7 +3719,7 @@ static void Task_ListenForPartnersWithCompatibleSerialNos(u8 taskId) } } -static bool32 GetGnameWonderFlagByLinkGroup(struct GFtgtGname * gname, s16 linkGroup) +static bool32 GetGnameWonderFlagByLinkGroup(struct RfuGameData * gname, s16 linkGroup) { if (linkGroup == LINK_GROUP_WONDER_CARD) { @@ -4315,7 +4315,7 @@ static void nullsub_92(u8 windowId, u32 itemId, u8 y) { } -static void TradeBoardPrintItemInfo(u8 windowId, u8 y, struct GFtgtGname * gname, const u8 * uname, u8 colorIdx) +static void TradeBoardPrintItemInfo(u8 windowId, u8 y, struct RfuGameData * gname, const u8 * uname, u8 colorIdx) { u8 level_t[4]; u16 species = gname->species; @@ -4339,7 +4339,7 @@ static void TradeBoardPrintItemInfo(u8 windowId, u8 y, struct GFtgtGname * gname static void TradeBoardListMenuItemPrintFunc(u8 windowId, u32 itemId, u8 y) { struct UnkStruct_Leader * leader = sUnionRoomMain.leader; - struct GFtgtGname * rfu; + struct RfuGameData * rfu; s32 i, j; u8 uname[RFU_USER_NAME_LENGTH]; From edc478c1c47202e582737294b10fd1c630a3b199 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Sat, 8 Oct 2022 20:15:22 -0400 Subject: [PATCH 02/12] Sync -num_tiles flags --- tools/gbagfx/gfx.c | 32 ++++++++++++++++++++++++++------ tools/gbagfx/gfx.h | 8 +++++++- tools/gbagfx/main.c | 9 ++++++++- tools/gbagfx/options.h | 2 ++ 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/tools/gbagfx/gfx.c b/tools/gbagfx/gfx.c index b28bb4021..4fbf9b7d3 100644 --- a/tools/gbagfx/gfx.c +++ b/tools/gbagfx/gfx.c @@ -397,7 +397,7 @@ void ReadImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, int free(buffer); } -void WriteImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors) +void WriteImage(char *path, enum NumTilesMode numTilesMode, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors) { int tileSize = bitDepth * 8; @@ -424,7 +424,8 @@ void WriteImage(char *path, int numTiles, int bitDepth, int metatileWidth, int m FATAL_ERROR("The specified number of tiles (%d) is greater than the maximum possible value (%d).\n", numTiles, maxNumTiles); int bufferSize = numTiles * tileSize; - unsigned char *buffer = malloc(bufferSize); + int maxBufferSize = maxNumTiles * tileSize; + unsigned char *buffer = malloc(maxBufferSize); if (buffer == NULL) FATAL_ERROR("Failed to allocate memory for pixels.\n"); @@ -433,17 +434,36 @@ void WriteImage(char *path, int numTiles, int bitDepth, int metatileWidth, int m switch (bitDepth) { case 1: - ConvertToTiles1Bpp(image->pixels, buffer, numTiles, metatilesWide, metatileWidth, metatileHeight, invertColors); + ConvertToTiles1Bpp(image->pixels, buffer, maxNumTiles, metatilesWide, metatileWidth, metatileHeight, invertColors); break; case 4: - ConvertToTiles4Bpp(image->pixels, buffer, numTiles, metatilesWide, metatileWidth, metatileHeight, invertColors); + ConvertToTiles4Bpp(image->pixels, buffer, maxNumTiles, metatilesWide, metatileWidth, metatileHeight, invertColors); break; case 8: - ConvertToTiles8Bpp(image->pixels, buffer, numTiles, metatilesWide, metatileWidth, metatileHeight, invertColors); + ConvertToTiles8Bpp(image->pixels, buffer, maxNumTiles, metatilesWide, metatileWidth, metatileHeight, invertColors); break; } - WriteWholeFile(path, buffer, bufferSize); + bool zeroPadded = true; + for (int i = bufferSize; i < maxBufferSize && zeroPadded; i++) { + if (buffer[i] != 0) + { + switch (numTilesMode) + { + case NUM_TILES_IGNORE: + break; + case NUM_TILES_WARN: + fprintf(stderr, "Ignoring -num_tiles %d because tile %d contains non-transparent pixels.\n", numTiles, 1 + i / tileSize); + zeroPadded = false; + break; + case NUM_TILES_ERROR: + FATAL_ERROR("Tile %d contains non-transparent pixels.\n", 1 + i / tileSize); + break; + } + } + } + + WriteWholeFile(path, buffer, zeroPadded ? bufferSize : maxBufferSize); free(buffer); } diff --git a/tools/gbagfx/gfx.h b/tools/gbagfx/gfx.h index edb9e62c4..f1dbfcf4f 100644 --- a/tools/gbagfx/gfx.h +++ b/tools/gbagfx/gfx.h @@ -44,8 +44,14 @@ struct Image { bool isAffine; }; +enum NumTilesMode { + NUM_TILES_IGNORE, + NUM_TILES_WARN, + NUM_TILES_ERROR, +}; + void ReadImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors); -void WriteImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors); +void WriteImage(char *path, enum NumTilesMode numTilesMode, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors); void FreeImage(struct Image *image); void ReadGbaPalette(char *path, struct Palette *palette); void WriteGbaPalette(char *path, struct Palette *palette); diff --git a/tools/gbagfx/main.c b/tools/gbagfx/main.c index cf3031696..5d4faacab 100644 --- a/tools/gbagfx/main.c +++ b/tools/gbagfx/main.c @@ -77,7 +77,7 @@ void ConvertPngToGba(char *inputPath, char *outputPath, struct PngToGbaOptions * ReadPng(inputPath, &image); - WriteImage(outputPath, options->numTiles, options->bitDepth, options->metatileWidth, options->metatileHeight, &image, !image.hasPalette); + WriteImage(outputPath, options->numTilesMode, options->numTiles, options->bitDepth, options->metatileWidth, options->metatileHeight, &image, !image.hasPalette); FreeImage(&image); } @@ -179,6 +179,7 @@ void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **a char *outputFileExtension = GetFileExtensionAfterDot(outputPath); int bitDepth = outputFileExtension[0] - '0'; struct PngToGbaOptions options; + options.numTilesMode = NUM_TILES_IGNORE; options.numTiles = 0; options.bitDepth = bitDepth; options.metatileWidth = 1; @@ -203,6 +204,12 @@ void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **a if (options.numTiles < 1) FATAL_ERROR("Number of tiles must be positive.\n"); } + else if (strcmp(option, "-Wnum_tiles") == 0) { + options.numTilesMode = NUM_TILES_WARN; + } + else if (strcmp(option, "-Werror=num_tiles") == 0) { + options.numTilesMode = NUM_TILES_ERROR; + } else if (strcmp(option, "-mwidth") == 0) { if (i + 1 >= argc) diff --git a/tools/gbagfx/options.h b/tools/gbagfx/options.h index 3b038f572..250b72345 100644 --- a/tools/gbagfx/options.h +++ b/tools/gbagfx/options.h @@ -4,6 +4,7 @@ #define OPTIONS_H #include +#include "gfx.h" struct GbaToPngOptions { char *paletteFilePath; @@ -18,6 +19,7 @@ struct GbaToPngOptions { struct PngToGbaOptions { int numTiles; + enum NumTilesMode numTilesMode; int bitDepth; int metatileWidth; int metatileHeight; From 7178aa8b99a78d08726110aa954c951095e2f78c Mon Sep 17 00:00:00 2001 From: GriffinR Date: Sat, 8 Oct 2022 20:44:08 -0400 Subject: [PATCH 03/12] Set unused tiles to transparent, document adjacent files --- graphics/item_pc/{unk_8E85458.bin => bg.bin} | Bin graphics/item_pc/{unk_8E85408.pal => bg.pal} | 0 graphics/item_pc/bg.png | Bin 0 -> 807 bytes graphics/item_pc/unk_8E85090.png | Bin 746 -> 0 bytes graphics/ss_anne/smoke.png | Bin 0 -> 315 bytes graphics/ss_anne/unk_8479838.png | Bin 188 -> 0 bytes graphics/ss_anne/unk_8479A38.png | Bin 271 -> 0 bytes graphics/ss_anne/wake.png | Bin 0 -> 244 bytes graphics/teachy_tv/tiles.png | Bin 1761 -> 1760 bytes .../tm_case/{unk_8E84D90.png => disc.png} | Bin .../{unk_8E84F20.pal => disc_types_1.pal} | 0 .../{unk_8E85068.pal => disc_types_2.pal} | 0 graphics/tm_case/{unk_8E99118.png => hm.png} | Bin .../tm_case/{unk_8E84A24.bin => menu.bin} | Bin .../{unk_8E84D20.pal => menu_female.pal} | 0 .../{unk_8E84CB0.pal => menu_male.pal} | 0 .../tm_case/{unk_8E84B70.bin => tm_case.bin} | Bin graphics/tm_case/tm_case.png | Bin 0 -> 1012 bytes graphics/tm_case/unk_8E845D8.png | Bin 951 -> 0 bytes graphics_file_rules.mk | 250 +++++++++--------- include/graphics.h | 18 +- src/graphics.c | 24 +- src/ss_anne.c | 4 +- src/tm_case.c | 37 +-- tileset_rules.mk | 134 +++++----- 25 files changed, 235 insertions(+), 232 deletions(-) rename graphics/item_pc/{unk_8E85458.bin => bg.bin} (100%) rename graphics/item_pc/{unk_8E85408.pal => bg.pal} (100%) create mode 100644 graphics/item_pc/bg.png delete mode 100644 graphics/item_pc/unk_8E85090.png create mode 100644 graphics/ss_anne/smoke.png delete mode 100644 graphics/ss_anne/unk_8479838.png delete mode 100644 graphics/ss_anne/unk_8479A38.png create mode 100644 graphics/ss_anne/wake.png rename graphics/tm_case/{unk_8E84D90.png => disc.png} (100%) rename graphics/tm_case/{unk_8E84F20.pal => disc_types_1.pal} (100%) rename graphics/tm_case/{unk_8E85068.pal => disc_types_2.pal} (100%) rename graphics/tm_case/{unk_8E99118.png => hm.png} (100%) rename graphics/tm_case/{unk_8E84A24.bin => menu.bin} (100%) rename graphics/tm_case/{unk_8E84D20.pal => menu_female.pal} (100%) rename graphics/tm_case/{unk_8E84CB0.pal => menu_male.pal} (100%) rename graphics/tm_case/{unk_8E84B70.bin => tm_case.bin} (100%) create mode 100644 graphics/tm_case/tm_case.png delete mode 100644 graphics/tm_case/unk_8E845D8.png diff --git a/graphics/item_pc/unk_8E85458.bin b/graphics/item_pc/bg.bin similarity index 100% rename from graphics/item_pc/unk_8E85458.bin rename to graphics/item_pc/bg.bin diff --git a/graphics/item_pc/unk_8E85408.pal b/graphics/item_pc/bg.pal similarity index 100% rename from graphics/item_pc/unk_8E85408.pal rename to graphics/item_pc/bg.pal diff --git a/graphics/item_pc/bg.png b/graphics/item_pc/bg.png new file mode 100644 index 0000000000000000000000000000000000000000..4db6a6bcbc7f4407b8eed2ff5d7aef89e2c28d91 GIT binary patch literal 807 zcmV+?1K9kDP)S7??v}7${13iH4 z6V&z%tjvntXe!VSMO41W_vlB8vWDab*p$hSpZHI*QaUH0T#Yc$uHr=GbB2i>;A&uV z5e7y!mtRYa2V7oLd(r^38QzLPj)R87AU}ReF&40DYB0Zu_JG?;2Y(EC&Mt7))nNgD zOQ2%I5Zi&caDXlw&`n^_Kmxo_d`n>%f`Gpi&q)}t4Mzw7_oUvYdSsB(e*a8yPwEYT zZXH4~fV#TDuEAgcb#;RP!Ul1Rut5wmWN@bF7=HKr=l&w0K`txUPQ>wp9Z+&(z!tke zqU6?sA-+zWD0w*0kobT&UTAoiI#Kd~qM;7hUw}RAdnU= z+rA8dsr!JlNFm@4T;5P)2(W>TYXwrh3HCoTP4%f5?=)Fvx|}Z-Q0^BB7kUy$A2fad z_A>&O%Iv}>2@euBnRwhqqF%|kr9 z=pc<9^9m{Nct;;4$_9%5fJ}+}_=zGZ8D31DL%Cg00D-bl`I=Em54c^q+=qdM%iZUQ zQUmU8xV>lrjv0QdLC%AQ{UE=8%P9_UYHqMsOxJ)bFrka3JhKlxZcRiWzZw8BEU6ud zdk@%(f!quR4J@D&kXtIl5(V-D@=VG=Z8Smzq$l^b)eDO}t=EqrJ-Igmrge$MiYglh zHwUW~)-??Z2piNb!Ui?SkimOI&+vA=erQY*Mo%l+p4Ill6#%_3Xe)i70KK$mC~pcc zpf?8@iaMaS7a4x#UO;b9GBg1N>al>$ zQJ`;Ps$StTUxxs$dOtP!cmViW9JiKxe|h5bP?< zswWTVju;rg*@YR&r>p`2CRS~McSEqdA-nu3z*qyFJ_Bc$Vwi|wNCpJD(+^RcZ5bHz z=tlzu7$RfCWWvBu41>Ns>8Dtp;{1^f->i)(VJJXv51OJvuh-&xEpvgIpGH43|=Vr?t0C>|L2C{a*y*O==SFaV2m$wzD ceIpzB3qTndJYBc9ZU6uP07*qoM6N<$f|f@?mjD0& diff --git a/graphics/ss_anne/smoke.png b/graphics/ss_anne/smoke.png new file mode 100644 index 0000000000000000000000000000000000000000..5560247873a1899b9b9b78babc2202a244d7e808 GIT binary patch literal 315 zcmV-B0mS}^P)G4{<$tdv?(Qfk%J?rLg_gNv-qw0r;m{}2!urC*hD0002S zNkl6@F7{3f^#%4L5VeO+o_}wpJu#yjzUkuf;yB`8~|O zyK?mbdAiA$_7CuFgIq)jVul&HvJ@xH*8*9T96fETQ&YGMEY N002ovPDHLkV1jDsg_-~W literal 0 HcmV?d00001 diff --git a/graphics/ss_anne/unk_8479838.png b/graphics/ss_anne/unk_8479838.png deleted file mode 100644 index e7d0d8c44e47da28b5eac793aab7f3a89d432ecd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^0zmA*0wfqdKXdg4Qq7(&jv*Qo=T6wo+hD-s5_zyS zJ8jX9Tfg}yNIiN|Bh)paA;f>8{rf$0Yi_GIC~%1BavWf>|Krj$b9>y31OunzO#MtY z|L@$k4A9=P#Y9EzYQ5)u2c7hfnHOu9g85>WS!c*Kgc^f7)x9>uq`oa+as7pUXO@geCygiASXX diff --git a/graphics/ss_anne/unk_8479A38.png b/graphics/ss_anne/unk_8479A38.png deleted file mode 100644 index 98fbc8d9710804158618579484e2b5f24a6a1a6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 271 zcmV+q0r38bP)IDVBnWRCl9!72fry4YRfQhx|F?ty95M6xaisMYatA3v@XhQGFOsF%J zh-5gvu5QJt?)^eumo8r*%d96*DT5ZQ0^oP$aCSG%$i>9Nu;qqcdB2#3E-Ix)et;>T z+p7GDyA`dE((*7$mLfccR?Ze*_R;{J5${KyBxEne_{e=UofGml)Keo&Tyy>hJ^;%N Vo!X^08+8Bx002ovPDHLkV1l$eb8`Ry diff --git a/graphics/ss_anne/wake.png b/graphics/ss_anne/wake.png new file mode 100644 index 0000000000000000000000000000000000000000..b7ce6763fba36308c99e366a5f17afb583fd7951 GIT binary patch literal 244 zcmVG4{<$tdv?(Qfk%J?rLg_gNv-qw0r;m{}2!urC*hD0001g zNkl(Xn23a0BVtkgUpeZ^YFQNJRdWLfPWSRQYr*Ng0D|8A u3B&_l4`{!_Z4NX!q1LciR3o2tzNk0o3%=<}y$lxs0000{k=tddZb_!E3Z z0v&cMNQb{}<+)Cj+SI4Vbbp#cdzx-(wSNduG3L1@!;jhlwivK^ zjO|<619TJ#&|PwYMy@zd0^lRI>tz7Fi!RW}l~V~g#lh)*37~66-mt6Ob&~*_Dcbaw z1N82N2WaJT0lp{Tz%koMz@G_70E~(N%mo29F@ho>$pNSUx_9BLfU!d^F!)4~10{eu z$SWzXu*s1SZhu4D7nK(;B;XGMh$*oE@Hg6S>}>25lDHy(WT&$IaxK8dv&!~bfXd4? zJ=m_id^Qj850Rb391PIC4@Vz0@$uR+fm*d4V-D+wc|WbQLpQssl!69zh;K-CoFI{^;AJK)y^06il) zfS2_BQ-1;3ni2qswKhRz+F(tzCB-&pdE)_7>!g`Af;L^KW!_Td`dixwTCz|JBdL7< z)rChQ0Nh;nAlsuo>$OjowNYNP!Oq&(SS|!SfQ6qUd-m2TqmnkzVw<&Z3tujfC$A$19m1Iq{ z<^Y)QcJMj?*k%y(6$=^xLpP7w;l@v-Xp>8L1VA_TDvsd+*B%hu;uvGXhoNmq)1bpH zp73IlZt<)iV3$?|bV>ki0`wd}2Hy6z#(&QlZlghmaf!BRKcFn~a`*4#=)sW*+d!D7 zSfGI`lIw#z(wbY^)W+TZNdS)F>41l|TyRI*?Q+9{^dbNb=Wo9CYUTcXV$$($*@sVd zuDzbs+?nqH4|Lk=Pkf}GjfIfeXgvPn`?Cfo{I%A5?iDAz*pMTa{$c;;FD?Ss7|`Sw#c9%s$zUOR=1NmH>QHwSwRQWjXkFf1g4RiU35yR8|4p5LNI4M^^#> z-w0;_ZXPh8$GO8K#0UW3Ubam?0x>eNHJl+JE;8?Wi~#0=2bil>0B&dzfw2K#_9DQ} z17P{yjop7U3+M+xBkl|{05|rN%mgTZto<}_fVduF7H0vJ1oYx-E{B=IBTLjVWN{Wi zF~kT)0?;--oJ?-<1pvkni+IHgK;hYkH_oYeOcekaLntE5!zKexuxm5(g$*$j08~gW zVu%0$guBb2us1S>A^?-XDL4;HSb+o7*BADI>rez-iXz&OHr4hu0qC8pgLC13?8}GW zJfPnTN$^FyiYr)gN{suS#r@fj=l2qL>Jy6_a?fYrE)M|rd0UwBDFyv`*83H5$;fld zHDCZFA*7|@?MGU3!nrhO&Vjz%N0m3a3DBv{ea5*DUilK!7n>jh3)cYZec_W^E^{UhKmn0mX$ljVQbEpL{YWMAO`0000J_!;jhlHW;ve zg#8=Z19TJ#(5K`A&0KSy1i(k^*NXsp8(pB8YbO$Lf|FBw0pQe(yy2;GpX&rzPtm5g z7@)T=JU}a#3-CPw2aecA0{%=u0$@}GU@i!-ju8|ANe(~-(7g*^1&keXfx#z=94G-a zL0(C5g-s5HaDN}#zNo!;Apw67KrD$0z~5-QwzalZNaB(JlC9e2%as6Y&uW`10ctN- z^kB30^4UDVKUmT-fVAC$B&Zeuln@@Y3}CbNY)g4>G;pR(*N^KwMZKwerU@IliQE4q zr9Sj{AD^M@*Xt6Hl>jarK(FHtoB`BPl=mhr2W$&~&VK<|ssN`=ZE8)uhJe2$puPm) z2=pERVDRR1?tctGfxg|;7ch8jgZuZ(0Kb$1F#Fm#z=^5^ye|Ws8W?=afOH0MkASdn zJT2uTpy|tspSW=L;gf2PH4`OgQ9pWs5d#Z=eJXkVr!s(E0H~XSd?&#EcL)4h0njs& z19(Z_KYtaFttbJISZfnhrU$HvzNFaaEN?tuYMr#QgP=_-wai44N_RG(9$~rCq0V{Xa150Kla{0NSLGu?dQM-eCZ72l#&ofZI52HxC#DKs$KV z#<7lt58D9vRt7lE10ob34cM7q#)IBLMz!n*oNYIRL~POt}x| zX@3W7ngg(faQu(~U9M)DdoBROQoul@UILCewOs*_1@k%V8U`Gf0dOUh0pK?1_^v}| zn*(6JJHhJ!V4FeAS1f1*4Ba~Fgoa;8(I%Jh2!LViRh+{Eu00^Q#WBW&4@2LOmO+n(St)1j)AaF zu|NY?BsT_6q!o{}sg0-olK>pU(*X}Fx!|t0+r@?j=|uos&fk3R)zahn#-!`rvJao^ zTzfsMxjWwh9_Y5$pZH2Y8w(+`(RlpDk7o^T_-n0q+$&Cau^~q;$2nnS&*Zcn@qdOA z3AfJXLzLgieEj+C_$vW|cAf)d{`HBHIsQ)oKA`z%{KM|gUt9#NF`&gSiqoVutpdCo zyYO}cpp_*_rtD38>#PL4rC82BO8~y9T0!uDvK;)oyGx-5MF1jUDysl)h${GrqbmV` zZ-g@dw+# z0kC}U#_qqF1@r^pAf5~}05|uO%mgTZt^G1^fVdxG7H0vJ1oYx-E{B=ID@)WdWN{Wi zF~kT)0?;u&oJ=0^1pvkni+IHwK;hko4d+z6rV0RzArukTVT%FBIJA}d!iE?M04gLG zF+>0W!rf(1*c%x`5r9eH6r6`GtiS;p>kIq9btnQZMGJy6xa?fYrE)M|r`B<3pEd}Fw)%zWC$;fld zHDCZFA*AKN+mE#7gmY=moCAG%jw)|-6QEO@`x@uI@XD8%zBmLKU=R>@lpx^v8~$!h zf`{l`5gexaE}JEIX>np$ za^oW)*Bc2pBDH1X=K3dp#00000NkvXXu0mjf DlGYF4 diff --git a/graphics/tm_case/unk_8E84D90.png b/graphics/tm_case/disc.png similarity index 100% rename from graphics/tm_case/unk_8E84D90.png rename to graphics/tm_case/disc.png diff --git a/graphics/tm_case/unk_8E84F20.pal b/graphics/tm_case/disc_types_1.pal similarity index 100% rename from graphics/tm_case/unk_8E84F20.pal rename to graphics/tm_case/disc_types_1.pal diff --git a/graphics/tm_case/unk_8E85068.pal b/graphics/tm_case/disc_types_2.pal similarity index 100% rename from graphics/tm_case/unk_8E85068.pal rename to graphics/tm_case/disc_types_2.pal diff --git a/graphics/tm_case/unk_8E99118.png b/graphics/tm_case/hm.png similarity index 100% rename from graphics/tm_case/unk_8E99118.png rename to graphics/tm_case/hm.png diff --git a/graphics/tm_case/unk_8E84A24.bin b/graphics/tm_case/menu.bin similarity index 100% rename from graphics/tm_case/unk_8E84A24.bin rename to graphics/tm_case/menu.bin diff --git a/graphics/tm_case/unk_8E84D20.pal b/graphics/tm_case/menu_female.pal similarity index 100% rename from graphics/tm_case/unk_8E84D20.pal rename to graphics/tm_case/menu_female.pal diff --git a/graphics/tm_case/unk_8E84CB0.pal b/graphics/tm_case/menu_male.pal similarity index 100% rename from graphics/tm_case/unk_8E84CB0.pal rename to graphics/tm_case/menu_male.pal diff --git a/graphics/tm_case/unk_8E84B70.bin b/graphics/tm_case/tm_case.bin similarity index 100% rename from graphics/tm_case/unk_8E84B70.bin rename to graphics/tm_case/tm_case.bin diff --git a/graphics/tm_case/tm_case.png b/graphics/tm_case/tm_case.png new file mode 100644 index 0000000000000000000000000000000000000000..ce013967e2ae10760838705505a6634d187cbb1a GIT binary patch literal 1012 zcmVDm4Fh+)sEmU2*v|W?UduTv(%NS3lqfLioted54HF+$Y?RYF$ zg;2U#XS}x(okB^Ws)j&nl16<$?#_}dB@haIC)s-Lx%YQDUrq?9pj17qgYQ0;s0Ys0 zK(DI)8<0@d0|ymAS!q7L8w}n&gW3QxtczX`pZB3e@0Fyg0@xsnK#cYEL(XsmP-(zX z-GZUi1CH7*7;-5v+J*sXGn$_Da>cqtHwSbXpt3-PflBEr81}p0vT|ud!U?u30G>BF zNv};Xeu^n1*||0nA7@b1MigmTxA)rpjeO4ODg4*XTKHDQ<%J)zy$;AKxIJ3 zycK{1%PJtzCE$z0D!~4+%CTwzzozUI?V1AM{qjbGiDQSn#82n+SXc)$qBFpH>kqTl z5TAs}tH*Z+uW1_`UMIhP(|#~EpW~kZIL?F9Js7@=fbPoxlbC@$4-~uB&>55g z4;9t`VK)F&SVI|j;y4~ETJDxM9Q6ypCj>y@B0vUN1U@^?Jy1M%UBw1i0|NX%U-|}u zMt}n5ky2B%z&p`4K=_dwc?c^8eX1#15U_@DjPtZwEf?ERtD-?pqHv^8fd-f%JTDkz zJXwSi51OZ15EcwFj>eIijftT56vP^2yjaYY26Rn*Hb^wYQ4|5db8t}$Xov-6rriU5 zC@0sc|3H!(&yzq5XVP;;TZB&tgl9Q i1VqDLjqVEETz>%(Gcw2;GSzng0000HV%7{;%(3Y9t-BT=DDl?{88b2fx3;Yf^Wl9L!SnU$r4u^mt{qD<-74OuGco~>Ph zg%u;gh!iWzKVaUE^TnU7sE~N3i~W0_d!Lj2#v%dv1x-<>j{}sb2lh9>v`YUCuu1j6 zX$4TUOn<%}kKcXmX-olbFm1`^Zvic|%#gUSOA>dDKD!wo>C16Iv)4uu}D>MG}u zNrBNy4oIifwARPvXo*<{m@z;yK!pQIYULcxW(T4qcCb0YRRzHN+WXw~%rSe5ZQ6<* zv;~|%2I$cFXa{~$&N32$Pf%3D{*|qasjJ4FCyRRe-G};KE52 zV45$+ss(}?nJpGI0^n8aMu$|UEpQDEW#PQGOIh0=@p!-UJzQe$I2o@K{VLmPbAzBy*2wMWs!Z;LxuW=lr z#WK3q4#$%m@EifKh!7wLl?R^1@o%vB6h)F9;0y=|?meBP5Htc5FyE!@p$ps-ixlu) zP$NI!#Gp^vLl*>$gEzo^mdj;?ZOBI6LG@j4DA58PU483^1W>AtRi_~+Gd+JU zT_1RU*I0SIg}|2h`D+s}gbxgr5~>jh%uG-4VjJzfu1^HP3XW4;Yaj>^@O*#B1Whx1 zH!(B6hnKj&?{|slDm6UBCrafW%}^ zl4>B~?3Ny&>8DZ#fbl5OWi?RJ`riTT%(qkJU-~-pX>>OrSszqh{|g{lXFiSY25eMy Z{|~29B7fdUcNzcy002ovPDHLkV1h#Lu$TY< diff --git a/graphics_file_rules.mk b/graphics_file_rules.mk index 0aa81586d..d9ac26cfa 100644 --- a/graphics_file_rules.mk +++ b/graphics_file_rules.mk @@ -100,13 +100,13 @@ graphics/title_screen/pokemon_logo.gbapal: %.gbapal: %.pal $(GFX) $< $@ -num_colors 224 graphics/pokemon_jump/bg.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 63 + $(GFX) $< $@ -num_tiles 63 -Wnum_tiles $(MISCGFXDIR)/japanese_hof.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 29 + $(GFX) $< $@ -num_tiles 29 -Wnum_tiles $(MISCGFXDIR)/markings2.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 25 + $(GFX) $< $@ -num_tiles 25 -Wnum_tiles $(INTERFACEGFXDIR)/menu.gbapal: $(INTERFACEGFXDIR)/menu_0.gbapal \ $(INTERFACEGFXDIR)/menu_1.gbapal @@ -150,13 +150,13 @@ $(UNUSEDGFXDIR)/redyellowgreen_frame.bin: $(UNUSEDGFXDIR)/red_frame.bin \ @cat $^ >$@ $(UNUSEDGFXDIR)/color_frames.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 353 + $(GFX) $< $@ -num_tiles 353 -Wnum_tiles $(BATINTGFXDIR)/unused_window2bar.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 5 + $(GFX) $< $@ -num_tiles 5 -Wnum_tiles $(BATINTGFXDIR)/level_up_banner.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 36 + $(GFX) $< $@ -num_tiles 36 -Wnum_tiles $(BATINTGFXDIR)/window.gbapal: $(BATINTGFXDIR)/window1.gbapal $(BATINTGFXDIR)/window2.gbapal cat $^ > $@ @@ -175,7 +175,7 @@ $(UNUSEDGFXDIR)/old_contest_2.4bpp: $(UNUSEDGFXDIR)/old_contest_2_1.4bpp \ @cat $^ >$@ $(UNKNOWNGFXDIR)/unknown_D196E4.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 36 + $(GFX) $< $@ -num_tiles 36 -Wnum_tiles $(BTLANMSPRGFXDIR)/ice_crystals.4bpp: $(BTLANMSPRGFXDIR)/ice_crystals_0.4bpp \ $(BTLANMSPRGFXDIR)/ice_crystals_1.4bpp \ @@ -197,13 +197,13 @@ $(BTLANMSPRGFXDIR)/spark.4bpp: $(BTLANMSPRGFXDIR)/spark_0.4bpp \ @cat $^ >$@ $(MASKSGFXDIR)/unknown_D2EC24.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 14 + $(GFX) $< $@ -num_tiles 14 -Wnum_tiles $(BATTRANSGFXDIR)/vs_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 16 + $(GFX) $< $@ -num_tiles 16 -Wnum_tiles $(INTERFACEGFXDIR)/party_menu_misc.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 62 + $(GFX) $< $@ -num_tiles 62 -Wnum_tiles $(TYPESGFXDIR)/move_types.4bpp: $(types:%=$(TYPESGFXDIR)/%.4bpp) $(contest_types:%=$(TYPESGFXDIR)/contest_%.4bpp) @cat $^ >$@ @@ -214,29 +214,29 @@ $(TYPESGFXDIR)/move_types.gbapal: $(TYPESGFXDIR)/move_types_1.gbapal \ @cat $^ >$@ $(INTERFACEGFXDIR)/bag_screen.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 53 + $(GFX) $< $@ -num_tiles 53 -Wnum_tiles $(RAYQUAZAGFXDIR)/rayquaza.8bpp: %.8bpp: %.png - $(GFX) $< $@ -num_tiles 227 + $(GFX) $< $@ -num_tiles 227 -Wnum_tiles $(RAYQUAZAGFXDIR)/overcast.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 313 + $(GFX) $< $@ -num_tiles 313 -Wnum_tiles $(RAYQUAZAGFXDIR)/rayquaza_fly1.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 124 + $(GFX) $< $@ -num_tiles 124 -Wnum_tiles $(RAYQUAZAGFXDIR)/rayquaza_tail_fix.4bpp: $(RAYQUAZAGFXDIR)/rayquaza_tail.4bpp cp $< $@ head -c 12 /dev/zero >> $@ $(RAYQUAZAGFXDIR)/chase_streaks.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 19 + $(GFX) $< $@ -num_tiles 19 -Wnum_tiles $(RAYQUAZAGFXDIR)/rayquaza_chase.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 155 + $(GFX) $< $@ -num_tiles 155 -Wnum_tiles graphics/picture_frame/frame5.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 86 + $(GFX) $< $@ -num_tiles 86 -Wnum_tiles $(ROULETTEGFXDIR)/roulette_tilt.4bpp: $(ROULETTEGFXDIR)/shroomish.4bpp \ $(ROULETTEGFXDIR)/tailow.4bpp @@ -249,10 +249,10 @@ $(ROULETTEGFXDIR)/poke_icons2.4bpp: $(ROULETTEGFXDIR)/wynaut.4bpp \ @cat $^ >$@ $(BATTRANSGFXDIR)/85BBC14.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 53 + $(GFX) $< $@ -num_tiles 53 -Wnum_tiles $(BATTRANSGFXDIR)/rayquaza.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 938 + $(GFX) $< $@ -num_tiles 938 -Wnum_tiles $(BATTRANSGFXDIR)/frontier_square_1.4bpp: $(BATTRANSGFXDIR)/frontier_squares_blanktiles.4bpp \ $(BATTRANSGFXDIR)/frontier_squares_1.4bpp @@ -275,16 +275,16 @@ $(SLOTMACHINEGFXDIR)/reel_time_gfx.4bpp: $(SLOTMACHINEGFXDIR)/reel_time_pikachu. @cat $^ >$@ $(UNUSEDGFXDIR)/intro_birch_beauty.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 822 + $(GFX) $< $@ -num_tiles 822 -Wnum_tiles $(PSSGFXDIR)/forest_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 55 + $(GFX) $< $@ -num_tiles 55 -Wnum_tiles $(PSSGFXDIR)/forest.4bpp: $(PSSGFXDIR)/forest_frame.4bpp $(PSSGFXDIR)/forest_bg.4bpp @cat $^ >$@ $(PSSGFXDIR)/city_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 52 + $(GFX) $< $@ -num_tiles 52 -Wnum_tiles $(PSSGFXDIR)/city.4bpp: $(PSSGFXDIR)/city_frame.4bpp $(PSSGFXDIR)/city_bg.4bpp @cat $^ >$@ @@ -293,97 +293,97 @@ $(PSSGFXDIR)/desert.4bpp: $(PSSGFXDIR)/desert_frame.4bpp $(PSSGFXDIR)/desert_bg. @cat $^ >$@ $(PSSGFXDIR)/savanna_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 45 + $(GFX) $< $@ -num_tiles 45 -Wnum_tiles $(PSSGFXDIR)/savanna_bg.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 23 + $(GFX) $< $@ -num_tiles 23 -Wnum_tiles $(PSSGFXDIR)/savanna.4bpp: $(PSSGFXDIR)/savanna_frame.4bpp $(PSSGFXDIR)/savanna_bg.4bpp @cat $^ >$@ $(PSSGFXDIR)/crag_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 49 + $(GFX) $< $@ -num_tiles 49 -Wnum_tiles $(PSSGFXDIR)/crag.4bpp: $(PSSGFXDIR)/crag_frame.4bpp $(PSSGFXDIR)/crag_bg.4bpp @cat $^ >$@ $(PSSGFXDIR)/volcano_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 56 + $(GFX) $< $@ -num_tiles 56 -Wnum_tiles $(PSSGFXDIR)/volcano.4bpp: $(PSSGFXDIR)/volcano_frame.4bpp $(PSSGFXDIR)/volcano_bg.4bpp @cat $^ >$@ $(PSSGFXDIR)/snow_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 57 + $(GFX) $< $@ -num_tiles 57 -Wnum_tiles $(PSSGFXDIR)/snow.4bpp: $(PSSGFXDIR)/snow_frame.4bpp $(PSSGFXDIR)/snow_bg.4bpp @cat $^ >$@ $(PSSGFXDIR)/cave_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 55 + $(GFX) $< $@ -num_tiles 55 -Wnum_tiles $(PSSGFXDIR)/cave.4bpp: $(PSSGFXDIR)/cave_frame.4bpp $(PSSGFXDIR)/cave_bg.4bpp @cat $^ >$@ $(PSSGFXDIR)/beach_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 46 + $(GFX) $< $@ -num_tiles 46 -Wnum_tiles $(PSSGFXDIR)/beach_bg.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 23 + $(GFX) $< $@ -num_tiles 23 -Wnum_tiles $(PSSGFXDIR)/beach.4bpp: $(PSSGFXDIR)/beach_frame.4bpp $(PSSGFXDIR)/beach_bg.4bpp @cat $^ >$@ $(PSSGFXDIR)/seafloor_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 54 + $(GFX) $< $@ -num_tiles 54 -Wnum_tiles $(PSSGFXDIR)/seafloor.4bpp: $(PSSGFXDIR)/seafloor_frame.4bpp $(PSSGFXDIR)/seafloor_bg.4bpp @cat $^ >$@ $(PSSGFXDIR)/river_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 51 + $(GFX) $< $@ -num_tiles 51 -Wnum_tiles $(PSSGFXDIR)/river_bg.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 11 + $(GFX) $< $@ -num_tiles 11 -Wnum_tiles $(PSSGFXDIR)/river.4bpp: $(PSSGFXDIR)/river_frame.4bpp $(PSSGFXDIR)/river_bg.4bpp @cat $^ >$@ $(PSSGFXDIR)/sky_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 45 + $(GFX) $< $@ -num_tiles 45 -Wnum_tiles $(PSSGFXDIR)/sky.4bpp: $(PSSGFXDIR)/sky_frame.4bpp $(PSSGFXDIR)/sky_bg.4bpp @cat $^ >$@ $(PSSGFXDIR)/polkadot_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 54 + $(GFX) $< $@ -num_tiles 54 -Wnum_tiles $(PSSGFXDIR)/polkadot.4bpp: $(PSSGFXDIR)/polkadot_frame.4bpp $(PSSGFXDIR)/polkadot_bg.4bpp @cat $^ >$@ $(PSSGFXDIR)/pokecenter_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 35 + $(GFX) $< $@ -num_tiles 35 -Wnum_tiles $(PSSGFXDIR)/pokecenter.4bpp: $(PSSGFXDIR)/pokecenter_frame.4bpp $(PSSGFXDIR)/pokecenter_bg.4bpp @cat $^ >$@ $(PSSGFXDIR)/machine_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 33 + $(GFX) $< $@ -num_tiles 33 -Wnum_tiles $(PSSGFXDIR)/machine.4bpp: $(PSSGFXDIR)/machine_frame.4bpp $(PSSGFXDIR)/machine_bg.4bpp @cat $^ >$@ $(PSSGFXDIR)/plain_frame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 18 + $(GFX) $< $@ -num_tiles 18 -Wnum_tiles $(PSSGFXDIR)/plain.4bpp: $(PSSGFXDIR)/plain_frame.4bpp $(PSSGFXDIR)/plain_bg.4bpp @cat $^ >$@ $(PSSGFXDIR)/friends_frame1.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 57 + $(GFX) $< $@ -num_tiles 57 -Wnum_tiles $(PSSGFXDIR)/friends_frame2.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 57 + $(GFX) $< $@ -num_tiles 57 -Wnum_tiles $(PSSGFXDIR)/zigzagoon.4bpp: $(PSSGFXDIR)/friends_frame1.4bpp $(PSSGFXDIR)/zigzagoon_bg.4bpp @cat $^ >$@ @@ -449,70 +449,70 @@ $(FIELDEFFECTSGFXDIR)/pics/tree_disguise.4bpp: %.4bpp: %.png $(GFX) $< $@ -mwidth 2 -mheight 4 $(INTERFACEGFXDIR)/selector_outline.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 8 + $(GFX) $< $@ -num_tiles 8 -Wnum_tiles $(BATTRANSGFXDIR)/frontier_transition.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 43 + $(GFX) $< $@ -num_tiles 43 -Wnum_tiles -graphics/tm_case/unk_8E845D8.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 91 +graphics/tm_case/tm_case.4bpp: %.4bpp: %.png + $(GFX) $< $@ -num_tiles 91 -Wnum_tiles $(PKNAVGFXDIR)/header.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 53 + $(GFX) $< $@ -num_tiles 53 -Wnum_tiles $(PKNAVGFXDIR)/outline.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 53 + $(GFX) $< $@ -num_tiles 53 -Wnum_tiles $(PKNAVGFXDIR)/ui_matchcall.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 13 + $(GFX) $< $@ -num_tiles 13 -Wnum_tiles $(INTERFACEGFXDIR)/region_map.8bpp: %.8bpp: %.png - $(GFX) $< $@ -num_tiles 232 + $(GFX) $< $@ -num_tiles 232 -Wnum_tiles $(INTERFACEGFXDIR)/region_map_affine.8bpp: %.8bpp: %.png - $(GFX) $< $@ -num_tiles 233 + $(GFX) $< $@ -num_tiles 233 -Wnum_tiles $(MISCGFXDIR)/birch_help.4bpp: $(MISCGFXDIR)/birch_bag.4bpp $(MISCGFXDIR)/birch_grass.4bpp @cat $^ >$@ $(FAMECHECKERGFXDIR)/spinning_pokeball.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 15 + $(GFX) $< $@ -num_tiles 15 -Wnum_tiles $(FAMECHECKERGFXDIR)/bg.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 165 + $(GFX) $< $@ -num_tiles 165 -Wnum_tiles graphics/seagallop/water.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 41 + $(GFX) $< $@ -num_tiles 41 -Wnum_tiles graphics/link/321start.4bpp: %.4bpp: %.png $(GFX) $< $@ -mwidth 4 -mheight 4 $(TEXTWINDOWGFXDIR)/unk_8470B0C.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 19 + $(GFX) $< $@ -num_tiles 19 -Wnum_tiles $(SLOTMACHINEGFXDIR)/unk_8466620.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 66 + $(GFX) $< $@ -num_tiles 66 -Wnum_tiles $(SLOTMACHINEGFXDIR)/unk_84659d0.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 138 + $(GFX) $< $@ -num_tiles 138 -Wnum_tiles $(TEACHYTVGFXDIR)/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 233 + $(GFX) $< $@ -num_tiles 233 -Wnum_tiles -$(SSANNEGFXDIR)/unk_8479A38.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 17 +$(SSANNEGFXDIR)/smoke.4bpp: %.4bpp: %.png + $(GFX) $< $@ -num_tiles 17 -Wnum_tiles -$(ITEMPCGFXDIR)/unk_8E85090.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 82 +$(ITEMPCGFXDIR)/bg.4bpp: %.4bpp: %.png + $(GFX) $< $@ -num_tiles 82 -Wnum_tiles $(TITLESCREENGFXDIR)/firered/box_art_mon.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 135 + $(GFX) $< $@ -num_tiles 135 -Wnum_tiles $(TITLESCREENGFXDIR)/leafgreen/box_art_mon.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 123 + $(GFX) $< $@ -num_tiles 123 -Wnum_tiles $(CREDITSGFXDIR)/unk_8EAE548.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 77 + $(GFX) $< $@ -num_tiles 77 -Wnum_tiles POKEDEXAREAMARKERSDATADIR := graphics/pokedex/area_markers @@ -535,188 +535,188 @@ graphics/misc/emoticons.4bpp: %.4bpp: %.png $(GFX) $< $@ -mwidth 2 -mheight 2 $(ITEMMENUGFXDIR)/bag_tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 55 + $(GFX) $< $@ -num_tiles 55 -Wnum_tiles $(INTROGFXDIR)/scene_1/grass.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 397 + $(GFX) $< $@ -num_tiles 397 -Wnum_tiles $(INTROGFXDIR)/scene_2/plants.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 17 + $(GFX) $< $@ -num_tiles 17 -Wnum_tiles $(INTROGFXDIR)/scene_2/nidorino_close.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 170 + $(GFX) $< $@ -num_tiles 170 -Wnum_tiles $(INTROGFXDIR)/scene_2/gengar_close.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 114 + $(GFX) $< $@ -num_tiles 114 -Wnum_tiles $(INTROGFXDIR)/scene_3/gengar_anim.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 348 + $(GFX) $< $@ -num_tiles 348 -Wnum_tiles $(BATTLETERRAINGFXDIR)/building/terrain.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 77 + $(GFX) $< $@ -num_tiles 77 -Wnum_tiles $(BATTLETERRAINGFXDIR)/cave/anim.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 106 + $(GFX) $< $@ -num_tiles 106 -Wnum_tiles $(BATTLETERRAINGFXDIR)/cave/terrain.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 84 + $(GFX) $< $@ -num_tiles 84 -Wnum_tiles $(BATTLETERRAINGFXDIR)/grass/terrain.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 98 + $(GFX) $< $@ -num_tiles 98 -Wnum_tiles $(BATTLETERRAINGFXDIR)/indoor/terrain.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 77 + $(GFX) $< $@ -num_tiles 77 -Wnum_tiles $(BATTLETERRAINGFXDIR)/longgrass/anim.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 133 + $(GFX) $< $@ -num_tiles 133 -Wnum_tiles $(BATTLETERRAINGFXDIR)/longgrass/terrain.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 98 + $(GFX) $< $@ -num_tiles 98 -Wnum_tiles $(BATTLETERRAINGFXDIR)/mountain/anim.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 47 + $(GFX) $< $@ -num_tiles 47 -Wnum_tiles $(BATTLETERRAINGFXDIR)/pond/anim.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 36 + $(GFX) $< $@ -num_tiles 36 -Wnum_tiles $(BATTLETERRAINGFXDIR)/pond/terrain.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 75 + $(GFX) $< $@ -num_tiles 75 -Wnum_tiles $(BATTLETERRAINGFXDIR)/sand/terrain.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 83 + $(GFX) $< $@ -num_tiles 83 -Wnum_tiles $(BATTLETERRAINGFXDIR)/underwater/anim.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 26 + $(GFX) $< $@ -num_tiles 26 -Wnum_tiles $(BATTLETERRAINGFXDIR)/underwater/terrain.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 85 + $(GFX) $< $@ -num_tiles 85 -Wnum_tiles $(BATTLETERRAINGFXDIR)/water/terrain.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 81 + $(GFX) $< $@ -num_tiles 81 -Wnum_tiles $(BERRYPOUCHGFXDIR)/background.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 52 + $(GFX) $< $@ -num_tiles 52 -Wnum_tiles $(HALLOFFAMEGFXDIR)/hall_of_fame.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 29 + $(GFX) $< $@ -num_tiles 29 -Wnum_tiles $(TILESETGFXDIR)/primary/general/anim/water_current_landwatersedge/7.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 47 + $(GFX) $< $@ -num_tiles 47 -Wnum_tiles $(MAPPREVIEWGFXDIR)/altering_cave/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 391 + $(GFX) $< $@ -num_tiles 391 -Wnum_tiles $(MAPPREVIEWGFXDIR)/berry_forest/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 395 + $(GFX) $< $@ -num_tiles 395 -Wnum_tiles $(MAPPREVIEWGFXDIR)/digletts_cave/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 398 + $(GFX) $< $@ -num_tiles 398 -Wnum_tiles $(MAPPREVIEWGFXDIR)/dotted_hole/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 317 + $(GFX) $< $@ -num_tiles 317 -Wnum_tiles $(MAPPREVIEWGFXDIR)/icefall_cave/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 399 + $(GFX) $< $@ -num_tiles 399 -Wnum_tiles $(MAPPREVIEWGFXDIR)/lost_cave/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 404 + $(GFX) $< $@ -num_tiles 404 -Wnum_tiles $(MAPPREVIEWGFXDIR)/monean_chamber/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 326 + $(GFX) $< $@ -num_tiles 326 -Wnum_tiles $(MAPPREVIEWGFXDIR)/mt_ember/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 355 + $(GFX) $< $@ -num_tiles 355 -Wnum_tiles $(MAPPREVIEWGFXDIR)/mt_moon/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 364 + $(GFX) $< $@ -num_tiles 364 -Wnum_tiles $(MAPPREVIEWGFXDIR)/pokemon_mansion/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 388 + $(GFX) $< $@ -num_tiles 388 -Wnum_tiles $(MAPPREVIEWGFXDIR)/pokemon_tower/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 290 + $(GFX) $< $@ -num_tiles 290 -Wnum_tiles $(MAPPREVIEWGFXDIR)/power_plant/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 368 + $(GFX) $< $@ -num_tiles 368 -Wnum_tiles $(MAPPREVIEWGFXDIR)/rock_tunnel/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 407 + $(GFX) $< $@ -num_tiles 407 -Wnum_tiles $(MAPPREVIEWGFXDIR)/rocket_hideout/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 194 + $(GFX) $< $@ -num_tiles 194 -Wnum_tiles $(MAPPREVIEWGFXDIR)/rocket_warehouse/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 234 + $(GFX) $< $@ -num_tiles 234 -Wnum_tiles $(MAPPREVIEWGFXDIR)/safari_zone/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 330 + $(GFX) $< $@ -num_tiles 330 -Wnum_tiles $(MAPPREVIEWGFXDIR)/seafoam_islands/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 408 + $(GFX) $< $@ -num_tiles 408 -Wnum_tiles $(MAPPREVIEWGFXDIR)/silph_co/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 355 + $(GFX) $< $@ -num_tiles 355 -Wnum_tiles $(MAPPREVIEWGFXDIR)/victory_road/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 375 + $(GFX) $< $@ -num_tiles 375 -Wnum_tiles $(MAPPREVIEWGFXDIR)/viridian_forest/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 389 + $(GFX) $< $@ -num_tiles 389 -Wnum_tiles $(NAMINGGFXDIR)/cursor.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 5 + $(GFX) $< $@ -num_tiles 5 -Wnum_tiles $(NAMINGGFXDIR)/cursor_squished.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 5 + $(GFX) $< $@ -num_tiles 5 -Wnum_tiles $(NAMINGGFXDIR)/cursor_filled.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 5 + $(GFX) $< $@ -num_tiles 5 -Wnum_tiles $(WALLPAPERGFXDIR)/beach/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 60 + $(GFX) $< $@ -num_tiles 60 -Wnum_tiles $(WALLPAPERGFXDIR)/cave/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 61 + $(GFX) $< $@ -num_tiles 61 -Wnum_tiles $(WALLPAPERGFXDIR)/city/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 40 + $(GFX) $< $@ -num_tiles 40 -Wnum_tiles $(WALLPAPERGFXDIR)/crag/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 54 + $(GFX) $< $@ -num_tiles 54 -Wnum_tiles $(WALLPAPERGFXDIR)/desert/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 52 + $(GFX) $< $@ -num_tiles 52 -Wnum_tiles $(WALLPAPERGFXDIR)/forest/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 53 + $(GFX) $< $@ -num_tiles 53 -Wnum_tiles $(WALLPAPERGFXDIR)/pokecenter/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 57 + $(GFX) $< $@ -num_tiles 57 -Wnum_tiles $(WALLPAPERGFXDIR)/river/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 63 + $(GFX) $< $@ -num_tiles 63 -Wnum_tiles $(WALLPAPERGFXDIR)/savanna/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 45 + $(GFX) $< $@ -num_tiles 45 -Wnum_tiles $(WALLPAPERGFXDIR)/seafloor/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 53 + $(GFX) $< $@ -num_tiles 53 -Wnum_tiles $(WALLPAPERGFXDIR)/simple/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 25 + $(GFX) $< $@ -num_tiles 25 -Wnum_tiles $(WALLPAPERGFXDIR)/sky/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 52 + $(GFX) $< $@ -num_tiles 52 -Wnum_tiles $(WALLPAPERGFXDIR)/snow/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 51 + $(GFX) $< $@ -num_tiles 51 -Wnum_tiles $(WALLPAPERGFXDIR)/stars/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 37 + $(GFX) $< $@ -num_tiles 37 -Wnum_tiles $(WALLPAPERGFXDIR)/tiles/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 31 + $(GFX) $< $@ -num_tiles 31 -Wnum_tiles $(WALLPAPERGFXDIR)/volcano/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 57 + $(GFX) $< $@ -num_tiles 57 -Wnum_tiles diff --git a/include/graphics.h b/include/graphics.h index c486aa058..5efc885bc 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -2866,15 +2866,15 @@ extern const u16 gFameCheckerBg3Tilemap[0x400]; extern const u16 gFameCheckerBg2Tilemap[0x400]; // tm_case -extern const u32 gUnknown_8E845D8[]; -extern const u32 gUnknown_8E84A24[]; -extern const u32 gUnknown_8E84B70[]; -extern const u32 gUnknown_8E84CB0[]; -extern const u32 gUnknown_8E84D20[]; -extern const u32 gTMCase_TMSpriteGfx[]; -extern const u32 gUnknown_8E84F20[]; -extern const u32 gUnknown_8E85068[]; -extern const u8 gUnknown_8E99118[]; +extern const u32 gTMCase_Gfx[]; +extern const u32 gTMCaseMenu_Tilemap[]; +extern const u32 gTMCase_Tilemap[]; +extern const u32 gTMCaseMenu_Male_Pal[]; +extern const u32 gTMCaseMenu_Female_Pal[]; +extern const u32 gTMCaseDisc_Gfx[]; +extern const u32 gTMCaseDiscTypes1_Pal[]; +extern const u32 gTMCaseDiscTypes2_Pal[]; +extern const u8 gTMCaseHM_Gfx[]; extern const u16 gTMCaseMainWindowPalette[]; // egg_hatch diff --git a/src/graphics.c b/src/graphics.c index 440083539..b4ab91a60 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -1123,18 +1123,18 @@ const u32 gBag_Pal[] = INCBIN_U32("graphics/interface/bag.gbapal.lz"); const u32 gSwapLine_Gfx[] = INCBIN_U32("graphics/interface/bag_swap.4bpp.lz"); const u32 gSwapLine_Pal[] = INCBIN_U32("graphics/interface/bag_swap.gbapal.lz"); -const u32 gUnknown_8E845D8[] = INCBIN_U32("graphics/tm_case/unk_8E845D8.4bpp.lz"); -const u32 gUnknown_8E84A24[] = INCBIN_U32("graphics/tm_case/unk_8E84A24.bin.lz"); -const u32 gUnknown_8E84B70[] = INCBIN_U32("graphics/tm_case/unk_8E84B70.bin.lz"); -const u32 gUnknown_8E84CB0[] = INCBIN_U32("graphics/tm_case/unk_8E84CB0.gbapal.lz"); -const u32 gUnknown_8E84D20[] = INCBIN_U32("graphics/tm_case/unk_8E84D20.gbapal.lz"); -const u32 gTMCase_TMSpriteGfx[] = INCBIN_U32("graphics/tm_case/unk_8E84D90.4bpp.lz"); -const u32 gUnknown_8E84F20[] = INCBIN_U32("graphics/tm_case/unk_8E84F20.gbapal.lz"); -const u32 gUnknown_8E85068[] = INCBIN_U32("graphics/tm_case/unk_8E85068.gbapal.lz"); +const u32 gTMCase_Gfx[] = INCBIN_U32("graphics/tm_case/tm_case.4bpp.lz"); +const u32 gTMCaseMenu_Tilemap[] = INCBIN_U32("graphics/tm_case/menu.bin.lz"); +const u32 gTMCase_Tilemap[] = INCBIN_U32("graphics/tm_case/tm_case.bin.lz"); +const u32 gTMCaseMenu_Male_Pal[] = INCBIN_U32("graphics/tm_case/menu_male.gbapal.lz"); +const u32 gTMCaseMenu_Female_Pal[] = INCBIN_U32("graphics/tm_case/menu_female.gbapal.lz"); +const u32 gTMCaseDisc_Gfx[] = INCBIN_U32("graphics/tm_case/disc.4bpp.lz"); +const u32 gTMCaseDiscTypes1_Pal[] = INCBIN_U32("graphics/tm_case/disc_types_1.gbapal.lz"); +const u32 gTMCaseDiscTypes2_Pal[] = INCBIN_U32("graphics/tm_case/disc_types_2.gbapal.lz"); -const u8 gItemPcTiles[] = INCBIN_U8("graphics/item_pc/unk_8E85090.4bpp.lz"); -const u32 gItemPcBgPals[] = INCBIN_U32("graphics/item_pc/unk_8E85408.gbapal.lz"); -const u8 gItemPcTilemap[] = INCBIN_U8("graphics/item_pc/unk_8E85458.bin.lz"); +const u8 gItemPcTiles[] = INCBIN_U8("graphics/item_pc/bg.4bpp.lz"); +const u32 gItemPcBgPals[] = INCBIN_U32("graphics/item_pc/bg.gbapal.lz"); +const u8 gItemPcTilemap[] = INCBIN_U8("graphics/item_pc/bg.bin.lz"); const u32 gBerryPouchSpriteTiles[] = INCBIN_U32("graphics/berry_pouch/berry_pouch.4bpp.lz"); const u8 gBerryPouchBgGfx[] = INCBIN_U8("graphics/berry_pouch/background.4bpp.lz"); @@ -1212,7 +1212,7 @@ const u32 gNamingScreenPageSwapButton_Gfx[] = INCBIN_U32("graphics/naming_screen const u32 gNamingScreenInputArrow_Gfx[] = INCBIN_U32("graphics/naming_screen/input_arrow.4bpp"); const u32 gNamingScreenUnderscore_Gfx[] = INCBIN_U32("graphics/naming_screen/underscore.4bpp"); -const u8 gUnknown_8E99118[] = INCBIN_U8("graphics/tm_case/unk_8E99118.4bpp"); +const u8 gTMCaseHM_Gfx[] = INCBIN_U8("graphics/tm_case/hm.4bpp"); const u16 gKantoTrainerCard_Pal[] = INCBIN_U16("graphics/trainer_card/0star.gbapal"); const u32 gKantoTrainerCard_Gfx[] = INCBIN_U32("graphics/trainer_card/card.4bpp.lz"); diff --git a/src/ss_anne.c b/src/ss_anne.c index ce46bc6f6..71335915a 100644 --- a/src/ss_anne.c +++ b/src/ss_anne.c @@ -18,8 +18,8 @@ static void WakeSpriteCallback(struct Sprite *sprite); static void CreateSmokeSprite(void); static void SmokeSpriteCallback(struct Sprite *sprite); -static const u16 sWakeTiles[] = INCBIN_U16("graphics/ss_anne/unk_8479838.4bpp"); -static const u16 sSmokeTiles[] = INCBIN_U16("graphics/ss_anne/unk_8479A38.4bpp"); +static const u16 sWakeTiles[] = INCBIN_U16("graphics/ss_anne/wake.4bpp"); +static const u16 sSmokeTiles[] = INCBIN_U16("graphics/ss_anne/smoke.4bpp"); static const struct SpriteSheet sSpriteSheets[] = { {(const void *)sWakeTiles, sizeof(sWakeTiles), SPRITE_TAG_WAKE}, diff --git a/src/tm_case.c b/src/tm_case.c index 73807c670..8ef9e7fbb 100644 --- a/src/tm_case.c +++ b/src/tm_case.c @@ -226,7 +226,7 @@ static const union AnimCmd *const sTMSpriteAnims[] = { }; static const struct CompressedSpriteSheet sTMSpriteSheet = { - (const void *)gTMCase_TMSpriteGfx, + (const void *)gTMCaseDisc_Gfx, 0x400, TM_CASE_TM_TAG }; @@ -241,7 +241,7 @@ static const struct SpriteTemplate sTMSpriteTemplate = { SpriteCallbackDummy }; -static const u16 sTMSpritePaletteOffsetByType[] = { +static const u16 sTMSpritePaletteOffsetByType[NUMBER_OF_MON_TYPES] = { [TYPE_NORMAL] = 0x000, [TYPE_FIRE] = 0x010, [TYPE_WATER] = 0x020, @@ -440,25 +440,25 @@ static bool8 HandleLoadTMCaseGraphicsAndPalettes(void) { case 0: ResetTempTileDataBuffers(); - DecompressAndCopyTileDataToVram(1, gUnknown_8E845D8, 0, 0, 0); + DecompressAndCopyTileDataToVram(1, gTMCase_Gfx, 0, 0, 0); sTMCaseDynamicResources->seqId++; break; case 1: if (FreeTempTileDataBuffersIfPossible() != TRUE) { - LZDecompressWram(gUnknown_8E84A24, sTilemapBuffer); + LZDecompressWram(gTMCaseMenu_Tilemap, sTilemapBuffer); sTMCaseDynamicResources->seqId++; } break; case 2: - LZDecompressWram(gUnknown_8E84B70, GetBgTilemapBuffer(1)); + LZDecompressWram(gTMCase_Tilemap, GetBgTilemapBuffer(1)); sTMCaseDynamicResources->seqId++; break; case 3: if (gSaveBlock2Ptr->playerGender == MALE) - LoadCompressedPalette(gUnknown_8E84CB0, 0, 0x80); + LoadCompressedPalette(gTMCaseMenu_Male_Pal, 0, 0x80); else - LoadCompressedPalette(gUnknown_8E84D20, 0, 0x80); + LoadCompressedPalette(gTMCaseMenu_Female_Pal, 0, 0x80); sTMCaseDynamicResources->seqId++; break; case 4: @@ -1387,7 +1387,7 @@ static void TMCase_MoveCursor_UpdatePrintedTMInfo(u16 itemId) static void PlaceHMTileInWindow(u8 windowId, u8 x, u8 y) { - BlitBitmapToWindow(windowId, gUnknown_8E99118, x, y, 16, 12); + BlitBitmapToWindow(windowId, gTMCaseHM_Gfx, x, y, 16, 12); } static void HandlePrintMoneyOnHand(void) @@ -1423,7 +1423,7 @@ static void RemoveTMContextMenu(u8 * a0) static u8 CreateTMSprite(u16 itemId) { u8 spriteId = CreateSprite(&sTMSpriteTemplate, 0x29, 0x2E, 0); - u8 r5; + u8 tmIdx; if (itemId == ITEM_NONE) { UpdateTMSpritePosition(&gSprites[spriteId], 0xFF); @@ -1431,17 +1431,17 @@ static u8 CreateTMSprite(u16 itemId) } else { - r5 = itemId - 33; - SetTMSpriteAnim(&gSprites[spriteId], r5); + tmIdx = itemId - ITEM_TM01; + SetTMSpriteAnim(&gSprites[spriteId], tmIdx); TintTMSpriteByType(gBattleMoves[ItemIdToBattleMoveId(itemId)].type); - UpdateTMSpritePosition(&gSprites[spriteId], r5); + UpdateTMSpritePosition(&gSprites[spriteId], tmIdx); return spriteId; } } static void SetTMSpriteAnim(struct Sprite *sprite, u8 idx) { - if (idx >= 50) + if (idx >= NUM_TECHNICAL_MACHINES) StartSpriteAnim(sprite, 1); else StartSpriteAnim(sprite, 0); @@ -1517,14 +1517,17 @@ static void SpriteCB_MoveTMSpriteInCase(struct Sprite *sprite) } } +// - 1 excludes TYPE_MYSTERY +#define NUM_TM_COLORS ((NUMBER_OF_MON_TYPES - 1) * 16) + static void LoadTMTypePalettes(void) { struct SpritePalette spritePalette; - sTMSpritePaletteBuffer = Alloc(0x110 * sizeof(u16)); - LZDecompressWram(gUnknown_8E84F20, sTMSpritePaletteBuffer); - LZDecompressWram(gUnknown_8E85068, sTMSpritePaletteBuffer + 0x100); - spritePalette.data = sTMSpritePaletteBuffer + 0x110; + sTMSpritePaletteBuffer = Alloc(NUM_TM_COLORS * sizeof(u16)); + LZDecompressWram(gTMCaseDiscTypes1_Pal, sTMSpritePaletteBuffer); // Decompress the first 16 + LZDecompressWram(gTMCaseDiscTypes2_Pal, sTMSpritePaletteBuffer + 0x100); // Decompress the rest (Only 17 total, this is just Dragon type) + spritePalette.data = sTMSpritePaletteBuffer + NUM_TM_COLORS; spritePalette.tag = TM_CASE_TM_TAG; LoadSpritePalette(&spritePalette); } diff --git a/tileset_rules.mk b/tileset_rules.mk index 707bceb8d..a868248cf 100644 --- a/tileset_rules.mk +++ b/tileset_rules.mk @@ -1,202 +1,202 @@ TILESETGFXDIR := data/tilesets $(TILESETGFXDIR)/primary/building/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 640 + $(GFX) $< $@ -num_tiles 640 -Wnum_tiles $(TILESETGFXDIR)/primary/general/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 640 + $(GFX) $< $@ -num_tiles 640 -Wnum_tiles $(TILESETGFXDIR)/secondary/pallet_town/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 76 + $(GFX) $< $@ -num_tiles 76 -Wnum_tiles $(TILESETGFXDIR)/secondary/lavender_town/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 256 + $(GFX) $< $@ -num_tiles 256 -Wnum_tiles $(TILESETGFXDIR)/secondary/cinnabar_island/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 128 + $(GFX) $< $@ -num_tiles 128 -Wnum_tiles $(TILESETGFXDIR)/secondary/pokemon_center/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 376 + $(GFX) $< $@ -num_tiles 376 -Wnum_tiles $(TILESETGFXDIR)/secondary/cable_club/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 632 + $(GFX) $< $@ -num_tiles 632 -Wnum_tiles $(TILESETGFXDIR)/secondary/fuchsia_gym/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 92 + $(GFX) $< $@ -num_tiles 92 -Wnum_tiles $(TILESETGFXDIR)/secondary/pewter_gym/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 207 + $(GFX) $< $@ -num_tiles 207 -Wnum_tiles $(TILESETGFXDIR)/secondary/saffron_gym/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 82 + $(GFX) $< $@ -num_tiles 82 -Wnum_tiles $(TILESETGFXDIR)/secondary/viridian_forest/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 101 + $(GFX) $< $@ -num_tiles 101 -Wnum_tiles $(TILESETGFXDIR)/secondary/seafoam_islands/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 318 + $(GFX) $< $@ -num_tiles 318 -Wnum_tiles $(TILESETGFXDIR)/secondary/generic_building_2/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 152 + $(GFX) $< $@ -num_tiles 152 -Wnum_tiles $(TILESETGFXDIR)/secondary/underground_path/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 50 + $(GFX) $< $@ -num_tiles 50 -Wnum_tiles $(TILESETGFXDIR)/secondary/restaurant_hotel/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 76 + $(GFX) $< $@ -num_tiles 76 -Wnum_tiles $(TILESETGFXDIR)/secondary/burgled_house/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 172 + $(GFX) $< $@ -num_tiles 172 -Wnum_tiles $(TILESETGFXDIR)/secondary/berry_forest/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 101 + $(GFX) $< $@ -num_tiles 101 -Wnum_tiles $(TILESETGFXDIR)/secondary/sevii_islands_45/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 374 + $(GFX) $< $@ -num_tiles 374 -Wnum_tiles $(TILESETGFXDIR)/secondary/pokemon_league/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 340 + $(GFX) $< $@ -num_tiles 340 -Wnum_tiles $(TILESETGFXDIR)/secondary/viridian_city/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 112 + $(GFX) $< $@ -num_tiles 112 -Wnum_tiles $(TILESETGFXDIR)/secondary/vermilion_city/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 140 + $(GFX) $< $@ -num_tiles 140 -Wnum_tiles $(TILESETGFXDIR)/secondary/indigo_plateau/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 247 + $(GFX) $< $@ -num_tiles 247 -Wnum_tiles $(TILESETGFXDIR)/secondary/cave/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 256 + $(GFX) $< $@ -num_tiles 256 -Wnum_tiles $(TILESETGFXDIR)/secondary/bike_shop/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 60 + $(GFX) $< $@ -num_tiles 60 -Wnum_tiles $(TILESETGFXDIR)/secondary/viridian_gym/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 90 + $(GFX) $< $@ -num_tiles 90 -Wnum_tiles $(TILESETGFXDIR)/secondary/cerulean_gym/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 119 + $(GFX) $< $@ -num_tiles 119 -Wnum_tiles $(TILESETGFXDIR)/secondary/cinnabar_gym/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 146 + $(GFX) $< $@ -num_tiles 146 -Wnum_tiles $(TILESETGFXDIR)/secondary/unused_gatehouse_1/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 144 + $(GFX) $< $@ -num_tiles 144 -Wnum_tiles $(TILESETGFXDIR)/secondary/unused_gatehouse_2/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 144 + $(GFX) $< $@ -num_tiles 144 -Wnum_tiles $(TILESETGFXDIR)/secondary/power_plant/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 80 + $(GFX) $< $@ -num_tiles 80 -Wnum_tiles $(TILESETGFXDIR)/secondary/pokemon_tower/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 128 + $(GFX) $< $@ -num_tiles 128 -Wnum_tiles $(TILESETGFXDIR)/secondary/school/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 50 + $(GFX) $< $@ -num_tiles 50 -Wnum_tiles $(TILESETGFXDIR)/secondary/dummy_3/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 2 + $(GFX) $< $@ -num_tiles 2 -Wnum_tiles $(TILESETGFXDIR)/secondary/navel_rock/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 282 + $(GFX) $< $@ -num_tiles 282 -Wnum_tiles $(TILESETGFXDIR)/secondary/sevii_islands_67/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 374 + $(GFX) $< $@ -num_tiles 374 -Wnum_tiles $(TILESETGFXDIR)/secondary/hall_of_fame/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 208 + $(GFX) $< $@ -num_tiles 208 -Wnum_tiles $(TILESETGFXDIR)/secondary/pewter_city/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 280 + $(GFX) $< $@ -num_tiles 280 -Wnum_tiles $(TILESETGFXDIR)/secondary/celadon_city/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 244 + $(GFX) $< $@ -num_tiles 244 -Wnum_tiles $(TILESETGFXDIR)/secondary/saffron_city/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 262 + $(GFX) $< $@ -num_tiles 262 -Wnum_tiles $(TILESETGFXDIR)/secondary/dummy_1/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 2 + $(GFX) $< $@ -num_tiles 2 -Wnum_tiles $(TILESETGFXDIR)/secondary/generic_building_1/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 63 + $(GFX) $< $@ -num_tiles 63 -Wnum_tiles $(TILESETGFXDIR)/secondary/hoenn_building/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 383 + $(GFX) $< $@ -num_tiles 383 -Wnum_tiles $(TILESETGFXDIR)/secondary/vermilion_gym/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 247 + $(GFX) $< $@ -num_tiles 247 -Wnum_tiles $(TILESETGFXDIR)/secondary/ss_anne/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 245 + $(GFX) $< $@ -num_tiles 245 -Wnum_tiles $(TILESETGFXDIR)/secondary/rock_tunnel/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 256 + $(GFX) $< $@ -num_tiles 256 -Wnum_tiles $(TILESETGFXDIR)/secondary/cerulean_cave/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 246 + $(GFX) $< $@ -num_tiles 246 -Wnum_tiles $(TILESETGFXDIR)/secondary/sea_cottage/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 68 + $(GFX) $< $@ -num_tiles 68 -Wnum_tiles $(TILESETGFXDIR)/secondary/safari_zone_building/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 90 + $(GFX) $< $@ -num_tiles 90 -Wnum_tiles $(TILESETGFXDIR)/secondary/fan_club_daycare/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 85 + $(GFX) $< $@ -num_tiles 85 -Wnum_tiles $(TILESETGFXDIR)/secondary/dummy_4/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 2 + $(GFX) $< $@ -num_tiles 2 -Wnum_tiles $(TILESETGFXDIR)/secondary/tanoby_ruins/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 74 + $(GFX) $< $@ -num_tiles 74 -Wnum_tiles $(TILESETGFXDIR)/secondary/trainer_tower/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 343 + $(GFX) $< $@ -num_tiles 343 -Wnum_tiles $(TILESETGFXDIR)/secondary/cerulean_city/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 158 + $(GFX) $< $@ -num_tiles 158 -Wnum_tiles $(TILESETGFXDIR)/secondary/fuchsia_city/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 191 + $(GFX) $< $@ -num_tiles 191 -Wnum_tiles $(TILESETGFXDIR)/secondary/mart/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 36 + $(GFX) $< $@ -num_tiles 36 -Wnum_tiles $(TILESETGFXDIR)/secondary/museum/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 137 + $(GFX) $< $@ -num_tiles 137 -Wnum_tiles $(TILESETGFXDIR)/secondary/lab/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 102 + $(GFX) $< $@ -num_tiles 102 -Wnum_tiles $(TILESETGFXDIR)/secondary/game_corner/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 171 + $(GFX) $< $@ -num_tiles 171 -Wnum_tiles $(TILESETGFXDIR)/secondary/celadon_gym/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 103 + $(GFX) $< $@ -num_tiles 103 -Wnum_tiles $(TILESETGFXDIR)/secondary/dummy_2/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 2 + $(GFX) $< $@ -num_tiles 2 -Wnum_tiles $(TILESETGFXDIR)/secondary/digletts_cave/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 248 + $(GFX) $< $@ -num_tiles 248 -Wnum_tiles $(TILESETGFXDIR)/secondary/department_store/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 201 + $(GFX) $< $@ -num_tiles 201 -Wnum_tiles $(TILESETGFXDIR)/secondary/pokemon_mansion/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 350 + $(GFX) $< $@ -num_tiles 350 -Wnum_tiles $(TILESETGFXDIR)/secondary/condominiums/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 384 + $(GFX) $< $@ -num_tiles 384 -Wnum_tiles $(TILESETGFXDIR)/secondary/mt_ember/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 288 + $(GFX) $< $@ -num_tiles 288 -Wnum_tiles $(TILESETGFXDIR)/secondary/sevii_islands_123/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 374 + $(GFX) $< $@ -num_tiles 374 -Wnum_tiles $(TILESETGFXDIR)/secondary/island_harbor/tiles.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 165 + $(GFX) $< $@ -num_tiles 165 -Wnum_tiles From b3c47d0059c20fbdaf2f16c26971259e006e70e4 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 7 Nov 2022 10:59:49 -0500 Subject: [PATCH 04/12] Finish syncing link_rfu_2 --- common_syms/link_rfu_2.txt | 2 +- include/gba/types.h | 3 + include/link.h | 3 +- include/link_rfu.h | 246 ++- include/mystery_gift_menu.h | 2 +- src/battle_controllers.c | 2 +- src/berry_crush.c | 6 +- src/link.c | 28 +- src/link_rfu_2.c | 2148 ++++++++++---------- src/link_rfu_3.c | 84 +- src/main.c | 2 +- src/mystery_gift_menu.c | 6 +- src/overworld.c | 2 +- src/party_menu.c | 4 +- src/pokemon_jump.c | 2 +- src/rfu_union_tool.c | 8 +- src/trade.c | 8 +- src/union_room.c | 204 +- src/union_room_chat.c | 30 +- src/wireless_communication_status_screen.c | 2 +- 20 files changed, 1437 insertions(+), 1355 deletions(-) diff --git a/common_syms/link_rfu_2.txt b/common_syms/link_rfu_2.txt index abd9a5f93..3a84c23bf 100644 --- a/common_syms/link_rfu_2.txt +++ b/common_syms/link_rfu_2.txt @@ -1,3 +1,3 @@ gHostRfuGameData -Rfu +gRfu gHostRfuUsername diff --git a/include/gba/types.h b/include/gba/types.h index 7163f925f..35d02e263 100644 --- a/include/gba/types.h +++ b/include/gba/types.h @@ -27,6 +27,9 @@ typedef double f64; typedef u8 bool8; typedef u16 bool16; typedef u32 bool32; +typedef vu8 vbool8; +typedef vu16 vbool16; +typedef vu32 vbool32; struct BgCnt { diff --git a/include/link.h b/include/link.h index 74a94920c..1ac0913a2 100644 --- a/include/link.h +++ b/include/link.h @@ -250,7 +250,7 @@ void SetSuppressLinkErrorMessage(bool8); bool8 HasLinkErrorOccurred(void); void ResetSerial(void); u32 LinkMain1(u8 *, u16 *, u16[MAX_RFU_PLAYERS][CMD_LENGTH]); -void RFUVSync(void); +void RfuVSync(void); void Timer3Intr(void); void SerialCB(void); u8 GetLinkPlayerCount(void); @@ -258,7 +258,6 @@ bool32 InUnionRoom(void); void SetLinkStandbyCallback(void); void SetWirelessCommType1(void); -void LinkRfu_DestroyIdleTask(void); void SetCloseLinkCallback(void); void OpenLink(void); bool8 IsLinkMaster(void); diff --git a/include/link_rfu.h b/include/link_rfu.h index e22414786..f203d30a3 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -6,33 +6,29 @@ #include "link.h" #include "AgbRfu_LinkManager.h" -#define RFUCMD_MASK 0xFF00 +#define RFUCMD_MASK 0xFF00 -#define RFUCMD_SEND_PACKET 0x2F00 -#define RFUCMD_READY_CLOSE_LINK 0x5f00 -#define RFUCMD_READY_EXIT_STANDBY 0x6600 -#define RFUCMD_PLAYERS_LIST 0x7700 -#define RFUCMD_PLAYERS_LIST_2 0x7800 -#define RFUCMD_SEND_BLOCK_INIT 0x8800 -#define RFUCMD_SEND_BLOCK_STEP 0x8900 -#define RFUCMD_SEND_BLOCK_REQ 0xa100 -#define RFUCMD_SEND_HELD_KEYS 0xbe00 -#define RFUCMD_PARENT_DISCONNECT 0xed00 -#define RFUCMD_CHILD_DISCONNECT 0xee00 +#define RFUCMD_SEND_PACKET 0x2F00 +#define RFUCMD_BLENDER_SEND_KEYS 0x4400 +#define RFUCMD_READY_CLOSE_LINK 0x5F00 +#define RFUCMD_READY_EXIT_STANDBY 0x6600 +#define RFUCMD_SEND_PLAYER_IDS 0x7700 +#define RFUCMD_SEND_PLAYER_IDS_NEW 0x7800 +#define RFUCMD_SEND_BLOCK_INIT 0x8800 +#define RFUCMD_SEND_BLOCK 0x8900 +#define RFUCMD_SEND_BLOCK_REQ 0xA100 +#define RFUCMD_SEND_HELD_KEYS 0xBE00 +#define RFUCMD_DISCONNECT 0xED00 +#define RFUCMD_DISCONNECT_PARENT 0xEE00 -#define RFU_PACKET_SIZE 6 - -#define RFU_SERIAL_7F7D 0x7F7D +#define RFU_SERIAL_GAME 0x0002 // Serial number for Pokémon game (FRLG or Emerald) +#define RFU_SERIAL_WONDER_DISTRIBUTOR 0x7F7D // Serial number for distributing Wonder Cards / News +#define RFU_SERIAL_END 0xFFFF +#define COMM_SLOT_LENGTH 14 #define RECV_QUEUE_NUM_SLOTS 20 -#define RECV_QUEUE_SLOT_LENGTH (14 * MAX_RFU_PLAYERS) - #define SEND_QUEUE_NUM_SLOTS 40 -#define SEND_QUEUE_SLOT_LENGTH 14 - #define BACKUP_QUEUE_NUM_SLOTS 2 -#define BACKUP_QUEUE_SLOT_LENGTH 14 - #define UNUSED_QUEUE_NUM_SLOTS 2 #define UNUSED_QUEUE_SLOT_LENGTH 256 @@ -48,13 +44,40 @@ #define RFU_STATUS_WAIT_ACK_JOIN_GROUP 7 #define RFU_STATUS_LEAVE_GROUP_NOTICE 8 #define RFU_STATUS_LEAVE_GROUP 9 -#define RFU_STATUS_10 10 -#define RFU_STATUS_11 11 +#define RFU_STATUS_CHILD_LEAVE_READY 10 +#define RFU_STATUS_CHILD_LEAVE 11 #define RFU_STATUS_ACK_JOIN_GROUP 12 -#define RFU_RECV_IDLE 0 -#define RFU_RECV_RECEIVING 1 -#define RFU_RECV_FINISHED 2 +// Values for disconnectMode +enum { + RFU_DISCONNECT_NONE, + RFU_DISCONNECT_ERROR, + RFU_DISCONNECT_NORMAL, +}; + +// Values for errorState +enum { + RFU_ERROR_STATE_NONE, + RFU_ERROR_STATE_OCCURRED, + RFU_ERROR_STATE_PROCESSED, + RFU_ERROR_STATE_DISCONNECTING, + RFU_ERROR_STATE_IGNORE, +}; + +// These error flags are set in errorInfo, and given as +// the uppermost 16 bits of 'status' for sLinkErrorBuffer. +// The first 8 bits are reserved for the link manager msg +// when the error occurred, and the last 8 bits are this +// sequence of presumably meaningful error flags, but +// ultimately sLinkErrorBuffer's status is never read. +#define F_RFU_ERROR_1 (1 << 8) +#define F_RFU_ERROR_2 (1 << 9) // Never set +#define F_RFU_ERROR_3 (1 << 10) // Never set +#define F_RFU_ERROR_4 (1 << 11) // Never set +#define F_RFU_ERROR_5 (1 << 12) +#define F_RFU_ERROR_6 (1 << 13) +#define F_RFU_ERROR_7 (1 << 14) +#define F_RFU_ERROR_8 (1 << 15) // RfuTgtData.gname is read as these structs. struct RfuGameCompatibilityData @@ -62,36 +85,47 @@ struct RfuGameCompatibilityData u16 language:4; u16 hasNews:1; u16 hasCard:1; - u16 unknown:1; + u16 unknown:1; // Never read u16 isChampion:1; u16 hasNationalDex:1; u16 gameClear:1; u16 version:4; - u16 unk_01_6:2; + u16 unused:2; u8 playerTrainerId[2]; }; +// This struct is sent via the Wireless Adapter as the game name or "gname" data. +// Gname is only applicable during Wireless Single Game Pak Multiplay, when the +// adapter needs this data for connection. Per the RFU manual, during "normal" +// wireless play (the kind the Pokémon games use) the gname data can be used for +// anything the developers want. This struct is what GF decided to use it for. +// It can be up to 13 bytes in size (RFU_GAME_NAME_LENGTH). +// The player's name is sent separately as the username ("uname"), and does not +// use a struct (gHostRfuUsername). struct __attribute__((packed, aligned(2))) RfuGameData { - struct RfuGameCompatibilityData unk_00; - u8 child_sprite_gender[RFU_CHILD_MAX]; // u8 sprite_idx:3; - // u8 gender:1; - // u8 unk_4:3 - // u8 active:1 - u16 species:10; - u16 type:6; + struct RfuGameCompatibilityData compatibility; + u8 partnerInfo[RFU_CHILD_MAX]; + u16 tradeSpecies:10; + u16 tradeType:6; u8 activity:7; - u8 started:1; + u8 startedActivity:1; u8 playerGender:1; - u8 level:7; + u8 tradeLevel:7; u8 padding; -}; // size: RFU_GNAME_SIZE - -struct Padded_U8 -{ - u8 value; }; +// Constants for getting/setting information in 'partnerInfo' of RfuGameData. +// This data is used to determine what the link partners look like from +// the host's perspective. +// Bits 0-2 are a shortened trainerId +// Bit 3 is the player's gender +// Bits 4-6 are unknown/unused +// Bit 7 is an 'active' flag +#define PINFO_TID_MASK 0x7 +#define PINFO_GENDER_SHIFT 3 +#define PINFO_ACTIVE_FLAG (1 << 7) + struct RfuBlockSend { /* 0x00 */ u16 next; @@ -106,7 +140,7 @@ struct RfuBlockSend struct RfuRecvQueue { - /* 0x000 */ u8 slots[RECV_QUEUE_NUM_SLOTS][RECV_QUEUE_SLOT_LENGTH]; + /* 0x000 */ u8 slots[RECV_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH * MAX_RFU_PLAYERS]; /* 0x578 */ vu8 recv_slot; /* 0x579 */ vu8 send_slot; /* 0x57a */ vu8 count; @@ -115,7 +149,7 @@ struct RfuRecvQueue struct RfuSendQueue { - /* 0x000 */ u8 slots[SEND_QUEUE_NUM_SLOTS][SEND_QUEUE_SLOT_LENGTH]; + /* 0x000 */ u8 slots[SEND_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH]; /* 0x230 */ vu8 recv_slot; /* 0x231 */ vu8 send_slot; /* 0x232 */ vu8 count; @@ -124,7 +158,7 @@ struct RfuSendQueue struct RfuBackupQueue { - /* 0x00 */ u8 slots[BACKUP_QUEUE_NUM_SLOTS][BACKUP_QUEUE_SLOT_LENGTH]; + /* 0x00 */ u8 slots[BACKUP_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH]; /* 0x1c */ vu8 recv_slot; /* 0x1d */ vu8 send_slot; /* 0x1e */ vu8 count; @@ -141,24 +175,24 @@ struct RfuUnusedQueue struct RfuManager { - /* 0x000 */ void (*RfuFunc)(void); + /* 0x000 */ void (*callback)(void); /* 0x004 */ u16 state; - /* 0x006 */ u8 filler_06[4]; - /* 0x00a */ u16 linkman_msg; - /* 0x00c */ u8 parent_child; + /* 0x006 */ u8 unused1[4]; + /* 0x00a */ u16 errorInfo; + /* 0x00c */ u8 parentChild; /* 0x00d */ u8 playerCount; - /* 0x00e */ u8 unk_0e; - /* 0x00f */ u8 unk_0f; - /* 0x010 */ u16 linkman_param[2]; - /* 0x014 */ u8 main_UNI_recvBuffer[RFU_CHILD_MAX][14]; - /* 0x04c */ u8 lastCmdBeforeCommInterrupt[14]; - /* 0x05a */ u8 cmdA100_blockRequestType; + /* 0x00e */ bool8 runParentMain2; + /* 0x00f */ u8 unused2; + /* 0x010 */ u16 errorParams[2]; + /* 0x014 */ u8 childRecvBuffer[RFU_CHILD_MAX][COMM_SLOT_LENGTH]; + /* 0x04c */ u8 childSendBuffer[COMM_SLOT_LENGTH]; + /* 0x05a */ u8 blockRequestType; /* 0x05b */ u8 sendBlockInitDelay; /* 0x05c */ bool8 blockReceived[MAX_RFU_PLAYERS]; /* 0x061 */ u8 numBlocksReceived[MAX_RFU_PLAYERS]; /* 0x066 */ u8 idleTaskId; /* 0x067 */ u8 searchTaskId; - /* 0x068 */ u8 filler_68[4]; + /* 0x068 */ u8 unused3[4]; /* 0x06c */ struct RfuBlockSend sendBlock; /* 0x080 */ struct RfuBlockSend recvBlock[MAX_RFU_PLAYERS]; /* 0x0e4 */ bool8 readyCloseLink[MAX_RFU_PLAYERS]; @@ -170,45 +204,45 @@ struct RfuManager /* 0x0f2 */ u16 packet[RFU_PACKET_SIZE]; /* 0x0fe */ u16 resendExitStandbyTimer; /* 0x100 */ u16 resendExitStandbyCount; - /* 0x102 */ u8 unk_102; - /* 0x104 */ struct RfuTgtData tgtData; + /* 0x102 */ u8 childSendCmdId; + /* 0x104 */ struct RfuTgtData parent; /* 0x124 */ struct RfuRecvQueue recvQueue; /* 0x6a0 */ struct RfuSendQueue sendQueue; /* 0x8d4 */ struct RfuBackupQueue backupQueue; /* 0x8f4 */ vu8 linkRecovered; - /* 0x8f5 */ u8 reconnectedParentIdx; - /* 0x8f6 */ vu8 child_slot; - /* 0x8f7 */ u8 unk_c3f[70]; + /* 0x8f5 */ u8 reconnectParentId; + /* 0x8f6 */ vu8 childSlot; + /* 0x8f7 */ u8 childRecvQueue[COMM_SLOT_LENGTH * MAX_RFU_PLAYERS]; /* 0x93d */ u8 sendStatus; /* 0x93e */ u8 recvStatus; - /* 0x93f */ u8 recvCmds[MAX_RFU_PLAYERS][7][2]; + /* 0x93f */ u8 recvCmds[MAX_RFU_PLAYERS][CMD_LENGTH - 1][2]; /* 0x985 */ u8 parentId; /* 0x986 */ u8 multiplayerId; // childId - /* 0x987 */ u8 unk_ccf; - /* 0x988 */ vu8 sem_UNI_SendRecv; + /* 0x987 */ u8 connectParentFailures; + /* 0x988 */ vu8 childSendCount; /* 0x989 */ u8 partnerSendStatuses[RFU_CHILD_MAX]; /* 0x98d */ u8 partnerRecvStatuses[RFU_CHILD_MAX]; - /* 0x991 */ u8 linkClosing; - /* 0x992 */ u8 unk_cda; - /* 0x993 */ volatile bool8 unk_cdb; - /* 0x994 */ volatile bool8 unk_cdc; - /* 0x995 */ u8 unk_cdd; + /* 0x991 */ bool8 stopNewConnections; + /* 0x992 */ u8 parentSendSlot; + /* 0x993 */ vbool8 parentFinished; + /* 0x994 */ vbool8 parentMain2Failed; + /* 0x995 */ u8 unused5; /* 0x996 */ u8 linkPlayerIdx[RFU_CHILD_MAX]; - /* 0x99a */ u8 bm_PartnerFlags; - /* 0x99b */ u8 bm_DisconnectSlot; - /* 0x99c */ u8 unk_ce4; - /* 0x99d */ u8 bmChatLeaderMaybe; - /* 0x99e */ u8 unionRoomChatters; + /* 0x99a */ u8 parentSlots; + /* 0x99b */ u8 disconnectSlots; + /* 0x99c */ u8 disconnectMode; + /* 0x99d */ u8 nextChildBits; + /* 0x99e */ u8 newChildQueue; /* 0x99f */ u8 acceptSlot_flag; - /* 0x9a0 */ bool8 foundNewLeaderMaybe; - /* 0x9a1 */ u8 unk_ce9; - /* 0x9a2 */ u8 unk_cea[RFU_CHILD_MAX]; - /* 0x9a6 */ u8 unk_cee[RFU_CHILD_MAX]; + /* 0x9a0 */ bool8 playerExchangeActive; + /* 0x9a1 */ u8 incomingChild; + /* 0x9a2 */ u8 numChildRecvErrors[RFU_CHILD_MAX]; + /* 0x9a6 */ u8 childRecvIds[RFU_CHILD_MAX]; }; // size: 0x9AC extern struct RfuGameData gHostRfuGameData; extern u8 gHostRfuUsername[]; -extern struct RfuManager Rfu; +extern struct RfuManager gRfu; // GameFreak signatures void AddTextPrinterToWindow1(const u8 *str); @@ -223,14 +257,14 @@ void MEvent_CreateTask_CardOrNewsOverWireless(u32 arg0); void MEvent_CreateTask_Leader(u32 arg0); void Rfu_SendPacket(void *data); u8 CreateTask_ListenToWireless(void); -void LinkRfu_DestroyIdleTask(void); +void DestroyTask_RfuIdle(void); void InitRFUAPI(void); -void sub_80FB128(bool32 a0); +void RfuSetIgnoreError(bool32 enable); bool32 IsSendingKeysToRfu(void); void ClearLinkRfuCallback(void); -u8 GetRfuPlayerCount(void); +u8 Rfu_GetLinkPlayerCount(void); void StartSendingKeysToRfu(void); -u8 LinkRfu_GetMultiplayerId(void); +u8 Rfu_GetMultiplayerId(void); bool32 Rfu_InitBlockSend(const u8 * src, size_t size); bool8 Rfu_SendBlockRequest(u8 blockRequestType); u8 Rfu_GetBlockReceivedStatus(void); @@ -238,15 +272,15 @@ void Rfu_SetBlockReceivedFlag(u8 linkPlayerId); void Rfu_ResetBlockReceivedFlag(u8 linkPlayerId); bool8 Rfu_IsMaster(void); void ResetLinkRfuGFLayer(void); -bool32 LinkRfuMain1(void); -bool32 LinkRfuMain2(void); +bool32 RfuMain1(void); +bool32 RfuMain2(void); bool32 IsRfuRecvQueueEmpty(void); u32 GetRfuRecvQueueLength(void); void LinkRfu_Shutdown(void); -void LinkRfu_CreateIdleTask(void); -bool8 ToggleLMANlinkRecovery(bool32 enable); +void CreateTask_RfuIdle(void); +bool8 Rfu_SetLinkRecovery(bool32 enable); void var_800D_set_xB(void); -struct RfuGameData *GetHostRFUtgtGname(void); +struct RfuGameData *GetHostRfuGameData(void); void UpdateWirelessStatusIndicatorSprite(void); void InitRFU(void); bool32 RfuHasErrored(void); @@ -262,44 +296,44 @@ bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *dest); void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *dest); bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue * queue, u8 *dest); void RfuSendQueue_Enqueue(struct RfuSendQueue * queue, u8 *src); -void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 started, s32 child_sprite_genders); +void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 started, s32 partnerInfo); void UpdateGameData_GroupLockedIn(bool8 started); bool32 IsRfuSerialNumberValid(u32 serialNo); bool8 IsRfuRecoveringFromLinkLoss(void); bool8 LmanAcceptSlotFlagIsNotZero(void); void LinkRfu_StopManagerAndFinalizeSlots(void); -bool32 sub_80FA5D4(void); -bool32 sub_80FC1CC(void); +bool32 RfuTryDisconnectLeavingChildren(void); +bool32 IsRfuCommunicatingWithAllChildren(void); bool32 WaitRfuState(bool32 a0); -bool32 CheckTrainerHasLeftByIdAndName(u16 trainerId, const u8 *trainerName); -void SendByteToPartnerByIdAndName(u8 a0, u16 a1, const u8 *a2); -u32 WaitSendByteToPartnerByIdAndName(u16 a0, const u8 *a1); -void SetHostRFUtgtGname(u8 activity, u32 child_sprite_genders, u32 a2); +bool32 HasTrainerLeftPartnersList(u16 trainerId, const u8 *trainerName); +void SendRfuStatusToPartner(u8 status, u16 trainerId, const u8 *name); +u32 WaitSendRfuStatusToPartner(u16 trainerId, const u8 *name); +void SetHostRfuGameData(u8 activity, u32 partnerInfo, bool32 startedActivity); void InitializeRfuLinkManager_LinkLeader(u32 availSlots); void RequestDisconnectSlotByTrainerNameAndId(const u8 *trainerName, u16 trainerId); void LinkRfu3_SetGnameUnameFromStaticBuffers(struct RfuGameData *gname, u8 *uname); void InitializeRfuLinkManager_JoinGroup(void); void SendLeaveGroupNotice(void); void CreateTask_RfuReconnectWithParent(const u8 *src, u16 trainerId); -void UpdateGameDataWithActivitySpriteGendersFlag(u8 activity, u32 child_sprite_genders, u32 started); +void UpdateGameData_SetActivity(u8 activity, u32 partnerInfo, u32 startedActivity); void RecordMixTrainerNames(void); void LinkRfu_CreateConnectionAsParent(); void LinkRfu_StopManagerBeforeEnteringChat(); -void SetGnameBufferWonderFlags(bool32 hasNews, bool32 hasCard); -void ClearAndInitHostRFUtgtGname(void); -void sub_80F8FA0(void); -void RfuUpdatePlayerGnameStateAndSend(u32 type, u32 species, u32 level); +void SetHostRfuWonderFlags(bool32 hasNews, bool32 hasCard); +void ResetHostRfuGameData(void); +void StopUnionRoomLinkManager(void); +void SetTradeBoardRegisteredMonInfo(u32 type, u32 species, u32 level); bool32 IsUnionRoomListenTaskActive(void); void InitializeRfuLinkManager_EnterUnionRoom(void); -void sub_80FBD6C(u32 a0); -void sub_80FC114(const u8 *name, struct RfuGameData *structPtr, u8 a2); +void Rfu_DisconnectPlayerById(u32 playerIdx); +void TryConnectToUnionRoomParent(const u8 *name, struct RfuGameData *parent, u8 activity); bool32 PlayerHasMetTrainerBefore(u16 id, u8 *name); bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx); bool8 LinkRfu_GetNameIfSerial7F7D(struct RfuGameData *gname, u8 *uname, u8 idx); -bool32 RfuHasFoundNewLeader(void); -void Rfu_UnionRoomChat_StopLinkManager(void); -void sub_80FB9D0(void); -void sub_80FB030(u32 a0); +bool32 Rfu_IsPlayerExchangeActive(void); +void Rfu_StopPartnerSearch(void); +void RfuSetNormalDisconnectMode(void); +void SetUnionRoomChatPlayerData(u32 numPlayers); void ClearRecvCommands(void); #include "mevent_server.h" diff --git a/include/mystery_gift_menu.h b/include/mystery_gift_menu.h index bd790b36e..a25cc598f 100644 --- a/include/mystery_gift_menu.h +++ b/include/mystery_gift_menu.h @@ -6,7 +6,7 @@ extern bool8 gGiftIsFromEReader; void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void); void PrintMysteryGiftOrEReaderTopMenu(bool8, bool32); void c2_mystery_gift(void); -void c2_mystery_gift_e_reader_run(void); +void CB2_MysteryGiftEReader(void); s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str); void MG_DrawTextBorder(u8 windowId); u16 GetMysteryGiftBaseBlock(void); diff --git a/src/battle_controllers.c b/src/battle_controllers.c index ba56b0db1..e877a1c08 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -519,7 +519,7 @@ void TryReceiveLinkBattleData(void) if (gReceivedRemoteLinkPlayers != 0 && (gBattleTypeFlags & BATTLE_TYPE_LINK_IN_BATTLE) && (gLinkPlayers[0].linkType == 0x2211)) { - LinkRfu_DestroyIdleTask(); + DestroyTask_RfuIdle(); for (i = 0; i < GetLinkPlayerCount(); i++) { if (GetBlockReceivedStatus() & gBitTable[i]) diff --git a/src/berry_crush.c b/src/berry_crush.c index d116a112f..ec58ece26 100644 --- a/src/berry_crush.c +++ b/src/berry_crush.c @@ -969,9 +969,9 @@ static u32 QuitBerryCrush(MainCallback callback) #define ERROR_EXIT(exitCallback) \ { \ SetMainCallback2(exitCallback); \ - Rfu.linkman_param[0] = 0; \ - Rfu.linkman_param[1] = 0; \ - Rfu.errorState = 1; \ + gRfu.errorParams[0] = 0; \ + gRfu.errorParams[1] = 0; \ + gRfu.errorState = 1; \ } diff --git a/src/link.c b/src/link.c index 6473de242..e60ebed00 100644 --- a/src/link.c +++ b/src/link.c @@ -227,7 +227,7 @@ bool8 IsWirelessAdapterConnected(void) SetWirelessCommType1(); InitRFUAPI(); - sub_80FB128(TRUE); + RfuSetIgnoreError(TRUE); if (rfu_LMAN_REQBN_softReset_and_checkID() == RFU_ID) { rfu_REQ_stopMode(); @@ -748,21 +748,16 @@ void ClearLinkCallback(void) void ClearLinkCallback_2(void) { if (gWirelessCommType) - { ClearLinkRfuCallback(); - } else - { gLinkCallback = NULL; - } } u8 GetLinkPlayerCount(void) { if (gWirelessCommType) - { - return GetRfuPlayerCount(); - } + return Rfu_GetLinkPlayerCount(); + return EXTRACT_PLAYER_COUNT(gLinkStatus); } @@ -977,7 +972,7 @@ u8 GetMultiplayerId(void) { if (gWirelessCommType == 1) { - return LinkRfu_GetMultiplayerId(); + return Rfu_GetMultiplayerId(); } return SIO_MULTI_CNT->id; } @@ -1647,10 +1642,11 @@ void LinkPlayerFromBlock(u32 who) } } +// When this function returns TRUE the callbacks are skipped bool8 HandleLinkConnection(void) { - bool32 r4; - bool32 r5; + bool32 main1Failed; + bool32 main2Failed; if (gWirelessCommType == 0) { @@ -1663,14 +1659,14 @@ bool8 HandleLinkConnection(void) } else { - r4 = LinkRfuMain1(); - r5 = LinkRfuMain2(); + main1Failed = RfuMain1(); // Always returns FALSE + main2Failed = RfuMain2(); if (IsSendingKeysOverCable() == TRUE) { - if (r4 == TRUE || IsRfuRecvQueueEmpty() || r5) - { + // This will never be reached. + // IsSendingKeysOverCable is always FALSE for wireless communication + if (main1Failed == TRUE || IsRfuRecvQueueEmpty() || main2Failed) return TRUE; - } } } return FALSE; diff --git a/src/link_rfu_2.c b/src/link_rfu_2.c index 649836276..9257f04b1 100644 --- a/src/link_rfu_2.c +++ b/src/link_rfu_2.c @@ -11,6 +11,40 @@ #include "task.h" #include "constants/union_room.h" +enum { + RFUSTATE_INIT, + RFUSTATE_INIT_END, + RFUSTATE_PARENT_CONNECT, + RFUSTATE_PARENT_CONNECT_END, + RFUSTATE_STOP_MANAGER, + RFUSTATE_STOP_MANAGER_END, + RFUSTATE_CHILD_CONNECT, + RFUSTATE_CHILD_CONNECT_END, + RFUSTATE_UNUSED, + RFUSTATE_RECONNECTED, + RFUSTATE_CONNECTED, + RFUSTATE_CHILD_TRY_JOIN, + RFUSTATE_CHILD_JOINED, + RFUSTATE_UR_PLAYER_EXCHANGE, + RFUSTATE_UR_STOP_MANAGER, + RFUSTATE_UR_STOP_MANAGER_END, + RFUSTATE_UR_FINALIZE, +}; +// These states are used for different purposes +// depending on the link mode (parent, child, union room) +#define RFUSTATE_PARENT_FINALIZE_START 17 +#define RFUSTATE_PARENT_FINALIZE 18 +#define RFUSTATE_UR_CONNECT 17 +#define RFUSTATE_UR_CONNECT_END 18 +#define RFUSTATE_FINALIZED 20 + +// States for the 'receiving' field of RfuBlockSend +enum { + RECV_STATE_READY, + RECV_STATE_RECEIVING, + RECV_STATE_FINISHED, +}; + struct SioInfo { char magic[sizeof("PokemonSioInfo")]; @@ -42,13 +76,13 @@ static u8 sResendBlock8[CMD_LENGTH * 2]; static u16 sResendBlock16[CMD_LENGTH]; struct RfuGameData gHostRfuGameData; -struct RfuManager Rfu; +struct RfuManager gRfu; u8 gHostRfuUsername[PLAYER_NAME_LENGTH + 1]; -static void sub_80F8AA4(void); -static void sub_80F8AEC(void); -static void MscCallback_Child(u16 a0); -static void MSCCallback_SetUnkCDB(u16 a0); +static void InitChildRecvBuffers(void); +static void InitParentSendData(void); +static void MscCallback_Child(u16 REQ_commandID); +static void MSCCallback_Parent(u16 REQ_commandID); static void UpdateBackupQueue(void); static void RfuHandleReceiveCommand(u8 unused); static void ResetSendDataManager(struct RfuBlockSend *data); @@ -58,28 +92,28 @@ static void SendNextBlock(void); static void SendLastBlock(void); static void CallRfuFunc(void); static void UpdateChildStatuses(void); -static s32 GetRfuRecvStatus(void); -static void sub_80FA834(u8 taskId); +static s32 GetJoinGroupStatus(void); +static void Task_PlayerExchange(u8 taskId); static void ClearSelectedLinkPlayerIds(u16 disconnectMask); -static void ValidateAndReceivePokemonSioInfo(void *a0); -static void Task_ExchangeLinkPlayers(u8 taskId); -static void sub_80FACF0(u8 taskId); -static void GetLinkmanErrorParams(u32 msg); -static void sub_80FB564(s32 bmConnectedFlag); -static void sub_80FBB74(void); +static void ValidateAndReceivePokemonSioInfo(void *recvBuffer); +static void Task_PlayerExchangeUpdate(u8 taskId); +static void Task_PlayerExchangeChat(u8 taskId); +static void RfuSetErrorParams(u32 errorInfo); +static void ParentResetChildRecvMetadata(s32 slot); +static void CB2_RfuIdle(void); static u8 GetPartnerIndexByNameAndTrainerID(const u8 *trainerName, u16 trainerId); static void RfuReqDisconnectSlot(u32 bmDisconnectSlot); -static void sub_80FBE20(u32 a0, u32 a1); -static void sub_80FC028(u8 taskId); +static void SendDisconnectCommand(u32 playersToDisconnect, u32 disconnectMode); +static void Task_TryConnectToUnionRoomParent(u8 taskId); static void Debug_PrintEmpty(void); -static void Task_idle(u8 taskId); +static void Task_Idle(u8 taskId); static const INIT_PARAM sRfuReqConfigTemplate = { .maxMFrame = 4, .MC_TimerCount = 32, .availSlot_flag = 0, .mboot_flag = 0, - .serialNo = 0x0002, + .serialNo = RFU_SERIAL_GAME, .gameName = (void *)&gHostRfuGameData, .userName = gHostRfuUsername, .fastSearchParent_flag = TRUE, @@ -95,76 +129,82 @@ static const u8 sAvailSlots[] = { [4] = AVAIL_SLOT4 }; +#define BLOCK_MASK(bitNum)((1 << (bitNum)) - 1) static const u32 sAllBlocksReceived[] = { - 0x000000, - 0x000001, - 0x000003, - 0x000007, - 0x00000f, - 0x00001f, - 0x00003f, - 0x00007f, - 0x0000ff, - 0x0001ff, - 0x0003ff, - 0x0007ff, - 0x000fff, - 0x001fff, - 0x003fff, - 0x007fff, - 0x00ffff, - 0x01ffff, - 0x03ffff, - 0x07ffff, - 0x0fffff, - 0x1fffff, - 0x3fffff, - 0x7fffff, - 0xffffff + BLOCK_MASK(0), + BLOCK_MASK(1), + BLOCK_MASK(2), + BLOCK_MASK(3), + BLOCK_MASK(4), + BLOCK_MASK(5), + BLOCK_MASK(6), + BLOCK_MASK(7), + BLOCK_MASK(8), + BLOCK_MASK(9), + BLOCK_MASK(10), + BLOCK_MASK(11), + BLOCK_MASK(12), + BLOCK_MASK(13), + BLOCK_MASK(14), + BLOCK_MASK(15), + BLOCK_MASK(16), + BLOCK_MASK(17), + BLOCK_MASK(18), + BLOCK_MASK(19), + BLOCK_MASK(20), + BLOCK_MASK(21), + BLOCK_MASK(22), + BLOCK_MASK(23), + BLOCK_MASK(24), }; +#undef BLOCK_MASK -static const u8 gUnknown_843EC38[] = { +static const u8 sSlotToLinkPlayerTableId[] = { 0, 0, 1, 1, 2, 2, 2, 2, 3 }; -static const u8 sNumSetBits[] = { - [0x0] = 0, - [0x1] = 1, - [0x2] = 1, - [0x3] = 2, - [0x4] = 1, - [0x5] = 2, - [0x6] = 2, - [0x7] = 3, - [0x8] = 1, - [0x9] = 2, - [0xA] = 2, - [0xB] = 3, - [0xC] = 2, - [0xD] = 3, - [0xE] = 3, - [0xF] = 4 +// Effectively just returns the number of bits set in the index value +// Used for masks of the other players, MAX_RFU_PLAYERS - 1 excludes self +static const u8 sPlayerBitsToCount[1 << (MAX_RFU_PLAYERS - 1)] = { + 0, // 0000 + 1, // 0001 + 1, // 0010 + 2, // 0011 + 1, // 0100 + 2, // 0101 + 2, // 0110 + 3, // 0111 + 1, // 1000 + 2, // 1001 + 2, // 1010 + 3, // 1011 + 2, // 1100 + 3, // 1101 + 3, // 1110 + 4 // 1111 }; -static const u8 sNumTrailingZeroes[] = { - [0x0] = 0, - [0x1] = 0, - [0x2] = 1, - [0x3] = 0, - [0x4] = 2, - [0x5] = 0, - [0x6] = 1, - [0x7] = 0, - [0x8] = 3, - [0x9] = 0, - [0xA] = 1, - [0xB] = 0, - [0xC] = 2, - [0xD] = 0, - [0xE] = 1, - [0xF] = 0 +// If the 4 bits representing child slots were an array, this table +// would return the index of the most recently set bit +static const u8 sPlayerBitsToNewChildIdx[1 << (MAX_RFU_PLAYERS - 1)] = { + 0, // 0000 + 0, // 0001 + 1, // 0010 + 0, // 0011 + 2, // 0100 + 0, // 0101 + 1, // 0110 + 0, // 0111 + 3, // 1000 + 0, // 1001 + 1, // 1010 + 0, // 1011 + 2, // 1100 + 0, // 1101 + 1, // 1110 + 0 // 1111 }; static const struct BlockRequest sBlockRequests[] = { @@ -176,12 +216,12 @@ static const struct BlockRequest sBlockRequests[] = { }; static const u16 sAcceptedSerialNos[] = { - 0x0002, // Pokemon FR/LG/EM - RFU_SERIAL_7F7D, - 0xFFFF + RFU_SERIAL_GAME, + RFU_SERIAL_WONDER_DISTRIBUTOR, + RFU_SERIAL_END }; -static const char sUnref_843EC92[][15] = { +static const char sASCII_RfuCmds[][15] = { "RFU WAIT", "RFU BOOT", "RFU ERROR", @@ -195,7 +235,7 @@ static const char sUnref_843EC92[][15] = { "RFU CP POLL" }; -static const char sUnref_843ED37[][16] = { +static const char sASCII_RecoverCmds[][16] = { " ", "RECOVER START ", "DISSCONECT ", @@ -203,18 +243,19 @@ static const char sUnref_843ED37[][16] = { "RECOVER FAILED" }; -static const TaskFunc gUnknown_843ED88[] = { - sub_80FA834, - Task_ExchangeLinkPlayers, - sub_80FACF0 +// List of additional tasks to destroy (if active) when the RFU shuts down +static const TaskFunc sShutdownTasks[] = { + Task_PlayerExchange, + Task_PlayerExchangeUpdate, + Task_PlayerExchangeChat }; static void Debug_PrintString(const void *string, u8 x, u8 y) { - // debug? + } -static void Debug_PrintNum(u16 num, u8 x, u8 y, u8 ndigits) +static void Debug_PrintNum(u16 num, u8 x, u8 y, u8 numDigits) { } @@ -222,21 +263,17 @@ static void Debug_PrintNum(u16 num, u8 x, u8 y, u8 ndigits) void ResetLinkRfuGFLayer(void) { s32 i; - u8 errorState_bak = Rfu.errorState; - CpuFill16(0, &Rfu, sizeof Rfu); - Rfu.parent_child = MODE_NEUTRAL; - Rfu.errorState = errorState_bak; - if (Rfu.errorState != 4) - { - Rfu.errorState = 0; - } + u8 errorState = gRfu.errorState; + CpuFill16(0, &gRfu, sizeof gRfu); + gRfu.parentChild = MODE_NEUTRAL; + gRfu.errorState = errorState; + if (gRfu.errorState != RFU_ERROR_STATE_IGNORE) + gRfu.errorState = RFU_ERROR_STATE_NONE; for (i = 0; i < MAX_RFU_PLAYERS; i++) - { - ResetSendDataManager(&Rfu.recvBlock[i]); - } - ResetSendDataManager(&Rfu.sendBlock); - RfuRecvQueue_Reset(&Rfu.recvQueue); - RfuSendQueue_Reset(&Rfu.sendQueue); + ResetSendDataManager(&gRfu.recvBlock[i]); + ResetSendDataManager(&gRfu.sendBlock); + RfuRecvQueue_Reset(&gRfu.recvQueue); + RfuSendQueue_Reset(&gRfu.sendQueue); CpuFill16(0, gSendCmd, sizeof gSendCmd); CpuFill16(0, gRecvCmds, sizeof gRecvCmds); CpuFill16(0, gLinkPlayers, sizeof gLinkPlayers); @@ -257,149 +294,145 @@ void InitRFU(void) void InitRFUAPI(void) { - if (!rfu_initializeAPI(sRfuAPIBuffer, RFU_API_BUFF_SIZE_RAM, gIntrTable + 1, TRUE)) + if (!rfu_initializeAPI(sRfuAPIBuffer, RFU_API_BUFF_SIZE_RAM, &gIntrTable[1], TRUE)) { gLinkType = 0; // ClearSavedLinkPlayers(); // Em fix - sub_80FB128(FALSE); + RfuSetIgnoreError(FALSE); ResetLinkRfuGFLayer(); - rfu_setTimerInterrupt(3, gIntrTable + 2); + rfu_setTimerInterrupt(3, &gIntrTable[2]); } } -static void Task_LinkLeaderSearchForChildren(u8 taskId) +static void Task_ParentSearchForChildren(u8 taskId) { UpdateChildStatuses(); - switch (Rfu.state) + switch (gRfu.state) { - case 0: + case RFUSTATE_INIT: rfu_LMAN_initializeRFU(&sRfuReqConfig); - Rfu.state = 1; + gRfu.state = RFUSTATE_INIT_END; gTasks[taskId].data[1] = 1; break; - case 1: + case RFUSTATE_INIT_END: break; - case 2: - rfu_LMAN_establishConnection(Rfu.parent_child, 0, 240, (u16 *)sAcceptedSerialNos); - Rfu.state = 3; + case RFUSTATE_PARENT_CONNECT: + rfu_LMAN_establishConnection(gRfu.parentChild, 0, 240, (u16 *)sAcceptedSerialNos); + gRfu.state = RFUSTATE_PARENT_CONNECT_END; gTasks[taskId].data[1] = 6; break; - case 3: + case RFUSTATE_PARENT_CONNECT_END: break; - case 4: + case RFUSTATE_STOP_MANAGER: rfu_LMAN_stopManager(FALSE); - Rfu.state = 5; + gRfu.state = RFUSTATE_STOP_MANAGER_END; break; - case 5: + case RFUSTATE_STOP_MANAGER_END: break; - case 18: - Rfu.unk_cdb = FALSE; - rfu_LMAN_setMSCCallback(MSCCallback_SetUnkCDB); - sub_80F8AA4(); - sub_80F8AEC(); - Rfu.state = 20; + case RFUSTATE_PARENT_FINALIZE: + gRfu.parentFinished = FALSE; + rfu_LMAN_setMSCCallback(MSCCallback_Parent); + InitChildRecvBuffers(); + InitParentSendData(); + gRfu.state = RFUSTATE_FINALIZED; gTasks[taskId].data[1] = 8; - CreateTask(sub_80FA834, 5); + CreateTask(Task_PlayerExchange, 5); DestroyTask(taskId); break; } } -static u8 CountTrailingZeroes(u8 acceptSlot) +static u8 Rfu_GetIndexOfNewestChild(u8 bits) { - return sNumTrailingZeroes[acceptSlot]; + return sPlayerBitsToNewChildIdx[bits]; } -static void ReassignPartnerIds(s32 before, s32 after) +static void SetLinkPlayerIdsFromSlots(s32 baseSlots, s32 addSlots) { u8 i; - u8 r4 = 1; - s32 beforeBak = before; - s32 r6 = 0; - if (after == -1) + u8 baseId = 1; + s32 baseSlotsCopy = baseSlots; + s32 newId = 0; + if (addSlots == -1) { - // First Time Init - // UB: linkPlayerIdx may be uninitialized - for (i = 0; i < RFU_CHILD_MAX; before >>= 1, i++) + // Initialize + for (i = 0; i < RFU_CHILD_MAX; baseSlots >>= 1, i++) { - if (before & 1) + if (baseSlots & 1) { - Rfu.linkPlayerIdx[i] = r4; - r4++; + gRfu.linkPlayerIdx[i] = baseId; + baseId++; } } } else { - // Delete before flags - for (i = 0; i < RFU_CHILD_MAX; beforeBak >>= 1, i++) + // Clear id for any empty slot + for (i = 0; i < RFU_CHILD_MAX; baseSlotsCopy >>= 1, i++) { - if (!(beforeBak & 1)) - { - Rfu.linkPlayerIdx[i] = 0; - } + if (!(baseSlotsCopy & 1)) + gRfu.linkPlayerIdx[i] = 0; } - // Get highest retained index - for (r4 = 4; r4 != 0; r4--) + + // Get starting id by checking existing slots + for (baseId = RFU_CHILD_MAX; baseId != 0; baseId--) { - for (i = 0; i < RFU_CHILD_MAX && Rfu.linkPlayerIdx[i] != r4; i++); - if (i == 4) - { - r6 = r4; - } + for (i = 0; i < RFU_CHILD_MAX && gRfu.linkPlayerIdx[i] != baseId; i++) + ; + if (i == RFU_CHILD_MAX) + newId = baseId; } - // Replace with new flags - for (after &= ~before, i = 0; i < RFU_CHILD_MAX; after >>= 1, i++) + + // Set id for new slots + for (addSlots &= ~baseSlots, i = 0; i < RFU_CHILD_MAX; addSlots >>= 1, i++) { - if (after & 1) - { - Rfu.linkPlayerIdx[i] = r6++; - } + if (addSlots & 1) + gRfu.linkPlayerIdx[i] = newId++; } } } -static void Task_JoinGroupSearchForParent(u8 taskId) +static void Task_ChildSearchForParent(u8 taskId) { - switch (Rfu.state) + switch (gRfu.state) { - case 0: + case RFUSTATE_INIT: rfu_LMAN_initializeRFU((INIT_PARAM*)&sRfuReqConfigTemplate); - Rfu.state = 1; + gRfu.state = RFUSTATE_INIT_END; gTasks[taskId].data[1] = 1; break; - case 1: + case RFUSTATE_INIT_END: break; - case 6: - rfu_LMAN_establishConnection(Rfu.parent_child, 0, 240, (u16 *)sAcceptedSerialNos); - Rfu.state = 7; + case RFUSTATE_CHILD_CONNECT: + rfu_LMAN_establishConnection(gRfu.parentChild, 0, 240, (u16 *)sAcceptedSerialNos); + gRfu.state = RFUSTATE_CHILD_CONNECT_END; gTasks[taskId].data[1] = 7; break; - case 7: + case RFUSTATE_CHILD_CONNECT_END: break; - case 9: + case RFUSTATE_RECONNECTED: gTasks[taskId].data[1] = 10; break; - case 11: - switch (GetRfuRecvStatus()) + case RFUSTATE_CHILD_TRY_JOIN: + switch (GetJoinGroupStatus()) { case RFU_STATUS_JOIN_GROUP_OK: - Rfu.state = 12; + gRfu.state = RFUSTATE_CHILD_JOINED; break; case RFU_STATUS_JOIN_GROUP_NO: case RFU_STATUS_LEAVE_GROUP: rfu_LMAN_requestChangeAgbClockMaster(); - Rfu.unk_ce4 = 2; + gRfu.disconnectMode = RFU_DISCONNECT_NORMAL; DestroyTask(taskId); break; } break; - case 12: + case RFUSTATE_CHILD_JOINED: { - u8 bmChildSlot = 1 << Rfu.child_slot; - rfu_clearSlot(TYPE_NI_SEND | TYPE_NI_RECV, Rfu.child_slot); - rfu_setRecvBuffer(TYPE_UNI, Rfu.child_slot, Rfu.unk_c3f, sizeof(Rfu.unk_c3f)); - rfu_UNI_setSendData(bmChildSlot, Rfu.lastCmdBeforeCommInterrupt, sizeof(Rfu.lastCmdBeforeCommInterrupt)); + u8 bmChildSlot = 1 << gRfu.childSlot; + rfu_clearSlot(TYPE_NI_SEND | TYPE_NI_RECV, gRfu.childSlot); + rfu_setRecvBuffer(TYPE_UNI, gRfu.childSlot, gRfu.childRecvQueue, sizeof(gRfu.childRecvQueue)); + rfu_UNI_setSendData(bmChildSlot, gRfu.childSendBuffer, sizeof(gRfu.childSendBuffer)); gTasks[taskId].data[1] = 8; DestroyTask(taskId); if (!sRfuDebug.childJoined) @@ -407,13 +440,13 @@ static void Task_JoinGroupSearchForParent(u8 taskId) Debug_PrintEmpty(); sRfuDebug.childJoined++; } - CreateTask(sub_80FA834, 5); + CreateTask(Task_PlayerExchange, 5); break; } } } -static void sub_80F8AA4(void) +static void InitChildRecvBuffers(void) { u8 i; u8 acceptSlot = lman.acceptSlot_flag; @@ -421,79 +454,77 @@ static void sub_80F8AA4(void) { if (acceptSlot & 1) { - rfu_setRecvBuffer(TYPE_UNI, i, Rfu.main_UNI_recvBuffer[i], sizeof(Rfu.main_UNI_recvBuffer[i])); + rfu_setRecvBuffer(TYPE_UNI, i, gRfu.childRecvBuffer[i], sizeof(gRfu.childRecvBuffer[i])); rfu_clearSlot(TYPE_UNI_SEND | TYPE_UNI_RECV, i); } acceptSlot >>= 1; } } -static void sub_80F8AEC(void) +static void InitParentSendData(void) { u8 acceptSlot = lman.acceptSlot_flag; - rfu_UNI_setSendData(acceptSlot, Rfu.recvCmds, sizeof(Rfu.recvCmds)); - Rfu.unk_cda = CountTrailingZeroes(acceptSlot); - Rfu.bm_PartnerFlags = acceptSlot; - ReassignPartnerIds(acceptSlot, -1); - Rfu.parent_child = MODE_PARENT; + rfu_UNI_setSendData(acceptSlot, gRfu.recvCmds, sizeof(gRfu.recvCmds)); + gRfu.parentSendSlot = Rfu_GetIndexOfNewestChild(acceptSlot); + gRfu.parentSlots = acceptSlot; + SetLinkPlayerIdsFromSlots(acceptSlot, -1); + gRfu.parentChild = MODE_PARENT; } -static void Task_LinkRfu_UnionRoomListen(u8 taskId) +#define tConnectingForChat data[7] + +static void Task_UnionRoomListen(u8 taskId) { - if (GetHostRFUtgtGname()->activity == (ACTIVITY_PLYRTALK | IN_UNION_ROOM) && RfuGetStatus() == 4) + if (GetHostRfuGameData()->activity == (ACTIVITY_PLYRTALK | IN_UNION_ROOM) && RfuGetStatus() == RFU_STATUS_NEW_CHILD_DETECTED) { rfu_REQ_disconnect(lman.acceptSlot_flag); rfu_waitREQComplete(); RfuSetStatus(RFU_STATUS_OK, 0); } - switch (Rfu.state) + switch (gRfu.state) { - case 0: + case RFUSTATE_INIT: rfu_LMAN_initializeRFU(&sRfuReqConfig); - Rfu.state = 1; + gRfu.state = RFUSTATE_INIT_END; gTasks[taskId].data[1] = 1; break; - case 1: + case RFUSTATE_INIT_END: break; - case 17: + case RFUSTATE_UR_CONNECT: rfu_LMAN_establishConnection(MODE_P_C_SWITCH, 0, 240, (u16 *)sAcceptedSerialNos); rfu_LMAN_setMSCCallback(MscCallback_Child); - Rfu.state = 18; + gRfu.state = RFUSTATE_UR_CONNECT_END; break; - case 18: + case RFUSTATE_UR_CONNECT_END: break; - case 13: - if (rfu_UNI_setSendData(1 << Rfu.child_slot, Rfu.lastCmdBeforeCommInterrupt, sizeof(Rfu.lastCmdBeforeCommInterrupt)) == 0) + case RFUSTATE_UR_PLAYER_EXCHANGE: + if (rfu_UNI_setSendData(1 << gRfu.childSlot, gRfu.childSendBuffer, sizeof(gRfu.childSendBuffer)) == 0) { - Rfu.parent_child = MODE_CHILD; + gRfu.parentChild = MODE_CHILD; DestroyTask(taskId); - if (gTasks[taskId].data[7]) - { - CreateTask(sub_80FACF0, 1); - } + if (gTasks[taskId].tConnectingForChat) + CreateTask(Task_PlayerExchangeChat, 1); else - { - CreateTask(sub_80FA834, 5); - } + CreateTask(Task_PlayerExchange, 5); } break; - case 14: - rfu_LMAN_stopManager(0); - Rfu.state = 15; + case RFUSTATE_UR_STOP_MANAGER: + rfu_LMAN_stopManager(FALSE); + gRfu.state = RFUSTATE_UR_STOP_MANAGER_END; break; - case 15: + case RFUSTATE_UR_STOP_MANAGER_END: break; - case 16: - Rfu.unk_cdb = FALSE; - rfu_LMAN_setMSCCallback(MSCCallback_SetUnkCDB); - UpdateGameData_GroupLockedIn(1); - sub_80F8AA4(); - sub_80F8AEC(); - Rfu.state = 20; + case RFUSTATE_UR_FINALIZE: + gRfu.parentFinished = FALSE; + rfu_LMAN_setMSCCallback(MSCCallback_Parent); + UpdateGameData_GroupLockedIn(TRUE); + InitChildRecvBuffers(); + InitParentSendData(); + gRfu.state = RFUSTATE_FINALIZED; gTasks[taskId].data[1] = 8; - Rfu.parent_child = MODE_PARENT; - CreateTask(sub_80FA834, 5); - Rfu.foundNewLeaderMaybe = TRUE; + gRfu.parentChild = MODE_PARENT; + CreateTask(Task_PlayerExchange, 5); + gRfu.playerExchangeActive = TRUE; DestroyTask(taskId); break; } @@ -509,31 +540,32 @@ void LinkRfu_StopManagerBeforeEnteringChat(void) rfu_LMAN_stopManager(FALSE); } -static void MscCallback_Child(u16 unused) +// Argument is provided by the RFU and is unused. +static void MscCallback_Child(u16 REQ_commandID) { s32 i; - for (i = 0; i < BACKUP_QUEUE_SLOT_LENGTH; i++) - { - Rfu.lastCmdBeforeCommInterrupt[i] = 0; - } + for (i = 0; i < COMM_SLOT_LENGTH; i++) + gRfu.childSendBuffer[i] = 0; + rfu_REQ_recvData(); rfu_waitREQComplete(); - if (gRfuSlotStatusUNI[Rfu.child_slot]->recv.newDataFlag) + if (gRfuSlotStatusUNI[gRfu.childSlot]->recv.newDataFlag) { - Rfu.sem_UNI_SendRecv++; - RfuRecvQueue_Enqueue(&Rfu.recvQueue, Rfu.unk_c3f); + gRfu.childSendCount++; + RfuRecvQueue_Enqueue(&gRfu.recvQueue, gRfu.childRecvQueue); sRfuDebug.recvCount++; UpdateBackupQueue(); - rfu_UNI_readySendData(Rfu.child_slot); - rfu_UNI_clearRecvNewDataFlag(Rfu.child_slot); + rfu_UNI_readySendData(gRfu.childSlot); + rfu_UNI_clearRecvNewDataFlag(gRfu.childSlot); } rfu_LMAN_REQ_sendData(TRUE); } -static void MSCCallback_SetUnkCDB(u16 unused) +// Argument is provided by the RFU and is unused. +static void MSCCallback_Parent(u16 REQ_commandID) { - Rfu.unk_cdb = TRUE; + gRfu.parentFinished = TRUE; } void LinkRfu_Shutdown(void) @@ -544,125 +576,125 @@ void LinkRfu_Shutdown(void) return; rfu_LMAN_powerDownRFU(); - if (Rfu.parent_child == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) { - if (FuncIsActiveTask(Task_LinkLeaderSearchForChildren) == TRUE) + // Stop parent searching for children + if (FuncIsActiveTask(Task_ParentSearchForChildren) == TRUE) { - DestroyTask(Rfu.searchTaskId); + DestroyTask(gRfu.searchTaskId); ResetLinkRfuGFLayer(); } } - else if (Rfu.parent_child == MODE_CHILD) + else if (gRfu.parentChild == MODE_CHILD) { - if (FuncIsActiveTask(Task_JoinGroupSearchForParent) == TRUE) + // Stop child searching for parent + if (FuncIsActiveTask(Task_ChildSearchForParent) == TRUE) { - DestroyTask(Rfu.searchTaskId); + DestroyTask(gRfu.searchTaskId); ResetLinkRfuGFLayer(); } } - else if (Rfu.parent_child == 2) + else if (gRfu.parentChild == MODE_P_C_SWITCH) { - if (FuncIsActiveTask(Task_LinkRfu_UnionRoomListen) == TRUE) + // Stop parent-child switching mode (union room) + if (FuncIsActiveTask(Task_UnionRoomListen) == TRUE) { - DestroyTask(Rfu.searchTaskId); + DestroyTask(gRfu.searchTaskId); ResetLinkRfuGFLayer(); } } - for (i = 0; i < NELEMS(gUnknown_843ED88); i++) + + // Destroy additional tasks + for (i = 0; i < ARRAY_COUNT(sShutdownTasks); i++) { - if (FuncIsActiveTask(gUnknown_843ED88[i]) == TRUE) - { - DestroyTask(FindTaskIdByFunc(gUnknown_843ED88[i])); - } + if (FuncIsActiveTask(sShutdownTasks[i]) == TRUE) + DestroyTask(FindTaskIdByFunc(sShutdownTasks[i])); } } -static void CreateTask_LinkLeaderSearchForChildren(void) +static void CreateTask_ParentSearchForChildren(void) { if (QL_IS_PLAYBACK_STATE) return; - Rfu.searchTaskId = CreateTask(Task_LinkLeaderSearchForChildren, 1); + gRfu.searchTaskId = CreateTask(Task_ParentSearchForChildren, 1); } -static bool8 ContactedByParentAttemptingToReconnect(void) +// If no parent ID (or if child connection not ready) can't reconnect with parent yet +static bool8 CanTryReconnectParent(void) { - if (Rfu.state == 7 && Rfu.parentId) + if (gRfu.state == RFUSTATE_CHILD_CONNECT_END && gRfu.parentId) + return TRUE; + return FALSE; +} + +static bool32 TryReconnectParent(void) +{ + if (gRfu.state == RFUSTATE_CHILD_CONNECT_END && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[gRfu.reconnectParentId].id, 240)) { + gRfu.state = RFUSTATE_RECONNECTED; return TRUE; } return FALSE; } -static bool32 IsParentSuccessfullyReconnected(void) -{ - if (Rfu.state == 7 && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[Rfu.reconnectedParentIdx].id, 240)) - { - Rfu.state = 9; - return TRUE; - } - return FALSE; -} - -static void CreateTask_JoinGroupSearchForParent(void) +static void CreateTask_ChildSearchForParent(void) { if (QL_IS_PLAYBACK_STATE) return; - Rfu.searchTaskId = CreateTask(Task_JoinGroupSearchForParent, 1); + gRfu.searchTaskId = CreateTask(Task_ChildSearchForParent, 1); } bool8 LmanAcceptSlotFlagIsNotZero(void) { if (lman.acceptSlot_flag) - { return TRUE; - } return FALSE; } void LinkRfu_StopManagerAndFinalizeSlots(void) { - Rfu.state = 4; - Rfu.acceptSlot_flag = lman.acceptSlot_flag; + gRfu.state = RFUSTATE_STOP_MANAGER; + gRfu.acceptSlot_flag = lman.acceptSlot_flag; } bool32 WaitRfuState(bool32 force) { - if (Rfu.state == 17 || force) + if (gRfu.state == RFUSTATE_PARENT_FINALIZE_START || force) { - Rfu.state = 18; + gRfu.state = RFUSTATE_PARENT_FINALIZE; return TRUE; } return FALSE; } -void sub_80F8FA0(void) +void StopUnionRoomLinkManager(void) { - Rfu.state = 14; + gRfu.state = RFUSTATE_UR_STOP_MANAGER; } // Unused -static void sub_80F8FAC(u8 a0) +static void ReadySendDataForSlots(u8 slots) { u8 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (a0 & 1) + if (slots & 1) { rfu_UNI_readySendData(i); break; } - a0 >>= 1; + slots >>= 1; } } -static void MoveRecvCmdsToRfuBuffer(void) +static void ReadAllPlayerRecvCmds(void) { s32 i, j; for (i = 0; i < MAX_RFU_PLAYERS; i++) { - struct RfuManager *ptr = &Rfu; + struct RfuManager *ptr = &gRfu; for (j = 0; j < CMD_LENGTH - 1; j++) { ptr->recvCmds[i][j][1] = gRecvCmds[i][j] >> 8; @@ -672,37 +704,31 @@ static void MoveRecvCmdsToRfuBuffer(void) CpuFill16(0, gRecvCmds, sizeof gRecvCmds); } -static void MoveSendCmdToFirstRecvCmd(void) +static void MoveSendCmdToRecv(void) { s32 i; for (i = 0; i < CMD_LENGTH - 1; i++) - { gRecvCmds[0][i] = gSendCmd[i]; - } + for (i = 0; i < CMD_LENGTH - 1; i++) - { gSendCmd[i] = 0; - } } static void UpdateBackupQueue(void) { - if (Rfu.linkRecovered) + if (gRfu.linkRecovered) { - bool8 backupEmpty = RfuBackupQueue_Dequeue(&Rfu.backupQueue, Rfu.lastCmdBeforeCommInterrupt); - if (Rfu.backupQueue.count == 0) - { - Rfu.linkRecovered = FALSE; - } + bool8 backupEmpty = RfuBackupQueue_Dequeue(&gRfu.backupQueue, gRfu.childSendBuffer); + if (gRfu.backupQueue.count == 0) + gRfu.linkRecovered = FALSE; + if (backupEmpty) - { return; - } } - if (!Rfu.linkRecovered) + if (!gRfu.linkRecovered) { - RfuSendQueue_Dequeue(&Rfu.sendQueue, Rfu.lastCmdBeforeCommInterrupt); - RfuBackupQueue_Enqueue(&Rfu.backupQueue, Rfu.lastCmdBeforeCommInterrupt); + RfuSendQueue_Dequeue(&gRfu.sendQueue, gRfu.childSendBuffer); + RfuBackupQueue_Enqueue(&gRfu.backupQueue, gRfu.childSendBuffer); } } @@ -712,25 +738,19 @@ bool32 IsRfuRecvQueueEmpty(void) s32 j; if (gRfuLinkStatus->sendSlotUNIFlag == 0) - { return FALSE; - } + for (i = 0; i < MAX_RFU_PLAYERS; i++) - { for (j = 0; j < CMD_LENGTH - 1; j++) - { if (gRecvCmds[i][j] != 0) - { return FALSE; - } - } - } + return TRUE; } -static bool32 sub_80F911C(void) +static bool32 RfuMain1_Parent(void) { - if (Rfu.state < 20) + if (gRfu.state < RFUSTATE_FINALIZED) { rfu_REQ_recvData(); rfu_waitREQComplete(); @@ -738,19 +758,19 @@ static bool32 sub_80F911C(void) } else { - Rfu.unk_cdb = FALSE; - if ((Rfu.bm_PartnerFlags & gRfuLinkStatus->connSlotFlag) == Rfu.bm_PartnerFlags && (Rfu.bm_PartnerFlags & gRfuLinkStatus->connSlotFlag)) + gRfu.parentFinished = FALSE; + if ((gRfu.parentSlots & gRfuLinkStatus->connSlotFlag) == gRfu.parentSlots && (gRfu.parentSlots & gRfuLinkStatus->connSlotFlag)) { - if (!Rfu.unk_cdc) + if (!gRfu.parentMain2Failed) { - if (Rfu.bm_DisconnectSlot) + if (gRfu.disconnectSlots) { - RfuReqDisconnectSlot(Rfu.bm_DisconnectSlot); - Rfu.bm_DisconnectSlot = 0; - if (Rfu.unk_ce4 == 1) + RfuReqDisconnectSlot(gRfu.disconnectSlots); + gRfu.disconnectSlots = 0; + if (gRfu.disconnectMode == RFU_DISCONNECT_ERROR) { - RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, 0x8000); - GetLinkmanErrorParams(0x8000); + RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_8); + RfuSetErrorParams(F_RFU_ERROR_8); return FALSE; } if (!lman.acceptSlot_flag) @@ -760,67 +780,65 @@ static bool32 sub_80F911C(void) return FALSE; } } - MoveRecvCmdsToRfuBuffer(); - rfu_UNI_readySendData(Rfu.unk_cda); + ReadAllPlayerRecvCmds(); + rfu_UNI_readySendData(gRfu.parentSendSlot); rfu_LMAN_REQ_sendData(TRUE); } else { rfu_REQ_PARENT_resumeRetransmitAndChange(); } - Rfu.unk_0e = TRUE; + gRfu.runParentMain2 = TRUE; } } return FALSE; } -static bool32 sub_80F9204(void) +static bool32 RfuMain2_Parent(void) { u16 i; u16 flags; u8 r0; u16 j; - u8 retval; + bool8 failed; - if (Rfu.state >= 20 && Rfu.unk_0e == TRUE) + if (gRfu.state >= RFUSTATE_FINALIZED && gRfu.runParentMain2 == TRUE) { rfu_waitREQComplete(); - while (!Rfu.unk_cdb) + while (!gRfu.parentFinished) { - if (Rfu.errorState != 0) - { + if (gRfu.errorState != RFU_ERROR_STATE_NONE) return FALSE; - } } rfu_REQ_recvData(); rfu_waitREQComplete(); - if ((lman.parentAck_flag & Rfu.bm_PartnerFlags) == Rfu.bm_PartnerFlags) + if ((lman.parentAck_flag & gRfu.parentSlots) == gRfu.parentSlots) { - Rfu.unk_cdc = 0; + gRfu.parentMain2Failed = FALSE; sRfuDebug.recvCount++; flags = lman.acceptSlot_flag; for (i = 0; i < RFU_CHILD_MAX; i++) { if (flags & 1) { - if (Rfu.main_UNI_recvBuffer[i][1]) + if (gRfu.childRecvBuffer[i][1]) { - if (Rfu.unk_cee[i] != 0xFF && (Rfu.main_UNI_recvBuffer[i][0] >> 5) != ((Rfu.unk_cee[i] + 1) & 7)) + if (gRfu.childRecvIds[i] != 0xFF && (gRfu.childRecvBuffer[i][0] >> 5) != ((gRfu.childRecvIds[i] + 1) & 7)) { - if (++Rfu.unk_cea[i] > 4) - GetLinkmanErrorParams(0x8100); + if (++gRfu.numChildRecvErrors[i] > 4) + RfuSetErrorParams(F_RFU_ERROR_8 | F_RFU_ERROR_1); } else { - Rfu.unk_cee[i] = Rfu.main_UNI_recvBuffer[i][0] / 32; - Rfu.unk_cea[i] = 0; - Rfu.main_UNI_recvBuffer[i][0] &= 0x1f; - r0 = Rfu.linkPlayerIdx[i]; - for (j = 0; j < 7; j++) + gRfu.childRecvIds[i] = gRfu.childRecvBuffer[i][0] / 32; + gRfu.numChildRecvErrors[i] = 0; + gRfu.childRecvBuffer[i][0] &= 0x1f; + r0 = gRfu.linkPlayerIdx[i]; + for (j = 0; j < CMD_LENGTH - 1; j++) { - gRecvCmds[r0][j] = (Rfu.main_UNI_recvBuffer[i][(j << 1) + 1] << 8) | Rfu.main_UNI_recvBuffer[i][(j << 1) + 0]; - Rfu.main_UNI_recvBuffer[i][(j << 1) + 1] = 0; - Rfu.main_UNI_recvBuffer[i][(j << 1) + 0] = 0; + gRecvCmds[r0][j] = (gRfu.childRecvBuffer[i][(j << 1) + 1] << 8) | gRfu.childRecvBuffer[i][(j << 1) + 0]; + gRfu.childRecvBuffer[i][(j << 1) + 1] = 0; + gRfu.childRecvBuffer[i][(j << 1) + 0] = 0; } } } @@ -828,62 +846,60 @@ static bool32 sub_80F9204(void) } flags >>= 1; } - MoveSendCmdToFirstRecvCmd(); + MoveSendCmdToRecv(); RfuHandleReceiveCommand(0); CallRfuFunc(); - if (Rfu.bmChatLeaderMaybe && !Rfu.linkClosing) + if (gRfu.nextChildBits && !gRfu.stopNewConnections) { sRfuDebug.unkFlag = FALSE; - rfu_clearSlot(TYPE_UNI_SEND | TYPE_UNI_RECV, Rfu.unk_cda); + rfu_clearSlot(TYPE_UNI_SEND | TYPE_UNI_RECV, gRfu.parentSendSlot); for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((Rfu.bmChatLeaderMaybe >> i) & 1) - { - rfu_setRecvBuffer(TYPE_UNI, i, Rfu.main_UNI_recvBuffer[i], sizeof(Rfu.main_UNI_recvBuffer[i])); - } + if ((gRfu.nextChildBits >> i) & 1) + rfu_setRecvBuffer(TYPE_UNI, i, gRfu.childRecvBuffer[i], sizeof(gRfu.childRecvBuffer[i])); } - ReassignPartnerIds(Rfu.bm_PartnerFlags, Rfu.bm_PartnerFlags | Rfu.bmChatLeaderMaybe); - Rfu.unk_ce9 = Rfu.bmChatLeaderMaybe; - Rfu.bm_PartnerFlags |= Rfu.bmChatLeaderMaybe; - Rfu.bmChatLeaderMaybe = 0; - rfu_UNI_setSendData(Rfu.bm_PartnerFlags, Rfu.recvCmds, sizeof(Rfu.recvCmds)); - Rfu.unk_cda = CountTrailingZeroes(Rfu.bm_PartnerFlags); - CreateTask(Task_ExchangeLinkPlayers, 0); + SetLinkPlayerIdsFromSlots(gRfu.parentSlots, gRfu.parentSlots | gRfu.nextChildBits); + gRfu.incomingChild = gRfu.nextChildBits; + gRfu.parentSlots |= gRfu.nextChildBits; + gRfu.nextChildBits = 0; + rfu_UNI_setSendData(gRfu.parentSlots, gRfu.recvCmds, sizeof(gRfu.recvCmds)); + gRfu.parentSendSlot = Rfu_GetIndexOfNewestChild(gRfu.parentSlots); + CreateTask(Task_PlayerExchangeUpdate, 0); } } else { - Rfu.unk_cdc = 1; - Rfu.unk_0e = FALSE; + gRfu.parentMain2Failed = TRUE; + gRfu.runParentMain2 = FALSE; } - Rfu.unk_0e = FALSE; + gRfu.runParentMain2 = FALSE; } - retval = Rfu.unk_cdc; - return gRfuLinkStatus->sendSlotUNIFlag ? retval & 1 : FALSE; + failed = gRfu.parentMain2Failed; + return gRfuLinkStatus->sendSlotUNIFlag ? failed & 1 : FALSE; } -static void RfuBufferSendCmd(u16 *sendCmd, u8 *rfuSendBuf) +static void ChildBuildSendCmd(u16 *sendCmd, u8 *dst) { s32 i; if (sendCmd[0]) { - sendCmd[0] |= (Rfu.unk_102 << 5); - Rfu.unk_102 = (Rfu.unk_102 + 1) & 7; - for (i = 0; i < 7; i++) + sendCmd[0] |= (gRfu.childSendCmdId << 5); + gRfu.childSendCmdId = (gRfu.childSendCmdId + 1) & 7; + for (i = 0; i < CMD_LENGTH - 1; i++) { - rfuSendBuf[2 * i + 1] = sendCmd[i] >> 8; - rfuSendBuf[2 * i + 0] = sendCmd[i]; + dst[2 * i + 1] = sendCmd[i] >> 8; + dst[2 * i + 0] = sendCmd[i]; } } else { - for (i = 0; i < 14; i++) - rfuSendBuf[i] = 0; + for (i = 0; i < 2 * (CMD_LENGTH - 1); i++) + dst[i] = 0; } } -static bool32 RfuProcessEnqueuedRecvBlock(void) +static bool32 RfuMain1_Child(void) { u8 i; u8 j; @@ -891,16 +907,17 @@ static bool32 RfuProcessEnqueuedRecvBlock(void) u8 sendBuf[2 * (CMD_LENGTH - 1)]; u8 status; - RfuRecvQueue_Dequeue(&Rfu.recvQueue, recvBuf); + RfuRecvQueue_Dequeue(&gRfu.recvQueue, recvBuf); for (i = 0; i < MAX_RFU_PLAYERS; i++) { for (j = 0; j < CMD_LENGTH - 1; j++) { - gRecvCmds[i][j] = (recvBuf[i * 14 + (j << 1) + 1] << 8) | recvBuf[i * 14 + (j << 1) + 0]; + gRecvCmds[i][j] = (recvBuf[i * COMM_SLOT_LENGTH + (j * 2) + 1] << 8) + | recvBuf[i * COMM_SLOT_LENGTH + (j * 2) + 0]; } } RfuHandleReceiveCommand(0); - if (lman.childClockSlave_flag == 0 && Rfu.unk_ce4) + if (lman.childClockSlave_flag == 0 && gRfu.disconnectMode != RFU_DISCONNECT_NONE) { rfu_REQ_disconnect(gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag); rfu_waitREQComplete(); @@ -908,24 +925,24 @@ static bool32 RfuProcessEnqueuedRecvBlock(void) if (status != RFU_STATUS_FATAL_ERROR && status != RFU_STATUS_JOIN_GROUP_NO && status != RFU_STATUS_LEAVE_GROUP) - RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, 0x9000); + RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_8); rfu_clearAllSlot(); gReceivedRemoteLinkPlayers = FALSE; - Rfu.RfuFunc = NULL; - if (Rfu.unk_ce4 == 1) + gRfu.callback = NULL; + if (gRfu.disconnectMode == RFU_DISCONNECT_ERROR) { - RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, 0x9000); - GetLinkmanErrorParams(0x9000); + RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_8); + RfuSetErrorParams(F_RFU_ERROR_5 | F_RFU_ERROR_8); } lman.state = lman.next_state = 0; - Rfu.unk_ce4 = 0; + gRfu.disconnectMode = RFU_DISCONNECT_NONE; } - if (Rfu.sem_UNI_SendRecv) + if (gRfu.childSendCount) { - Rfu.sem_UNI_SendRecv--; + gRfu.childSendCount--; CallRfuFunc(); - RfuBufferSendCmd(gSendCmd, sendBuf); - RfuSendQueue_Enqueue(&Rfu.sendQueue, sendBuf); + ChildBuildSendCmd(gSendCmd, sendBuf); + RfuSendQueue_Enqueue(&gRfu.sendQueue, sendBuf); for (i = 0; i < CMD_LENGTH - 1; i++) gSendCmd[i] = 0; } @@ -936,25 +953,26 @@ static void HandleSendFailure(u8 unused, u32 flags) { s32 i, j, temp; - const u8 *payload = Rfu.sendBlock.payload; - for (i = 0; i < Rfu.sendBlock.count; i++) + const u8 *payload = gRfu.sendBlock.payload; + for (i = 0; i < gRfu.sendBlock.count; i++) { if (!(flags & 1)) { - sResendBlock16[0] = RFUCMD_SEND_BLOCK_STEP | i; - for (j = 0; j < 7; j++) + sResendBlock16[0] = RFUCMD_SEND_BLOCK | i; + for (j = 0; j < CMD_LENGTH - 1; j++) { - temp = j << 1; - sResendBlock16[j + 1] = (payload[12 * i + temp + 1] << 8) | payload[12 * i + temp + 0]; + temp = j * 2; + sResendBlock16[j + 1] = (payload[(COMM_SLOT_LENGTH - 2) * i + temp + 1] << 8) + | payload[(COMM_SLOT_LENGTH - 2) * i + temp + 0]; } - for (j = 0; j < 7; j++) + for (j = 0; j < CMD_LENGTH - 1; j++) { - temp = j << 1; + temp = j * 2; sResendBlock8[temp + 1] = sResendBlock16[j] >> 8; sResendBlock8[temp + 0] = sResendBlock16[j]; } - RfuSendQueue_Enqueue(&Rfu.sendQueue, sResendBlock8); - Rfu.sendBlock.failedFlags |= (1 << i); + RfuSendQueue_Enqueue(&gRfu.sendQueue, sResendBlock8); + gRfu.sendBlock.failedFlags |= (1 << i); } flags >>= 1; } @@ -962,32 +980,30 @@ static void HandleSendFailure(u8 unused, u32 flags) void Rfu_SetBlockReceivedFlag(u8 linkPlayerId) { - if (Rfu.parent_child == MODE_PARENT && linkPlayerId != 0) - Rfu.numBlocksReceived[linkPlayerId] = 1; + if (gRfu.parentChild == MODE_PARENT && linkPlayerId != 0) + gRfu.numBlocksReceived[linkPlayerId] = 1; else - Rfu.blockReceived[linkPlayerId] = TRUE; + gRfu.blockReceived[linkPlayerId] = TRUE; } void Rfu_ResetBlockReceivedFlag(u8 linkPlayerId) { - Rfu.blockReceived[linkPlayerId] = FALSE; - Rfu.recvBlock[linkPlayerId].receiving = RFU_RECV_IDLE; + gRfu.blockReceived[linkPlayerId] = FALSE; + gRfu.recvBlock[linkPlayerId].receiving = RECV_STATE_READY; } -static u8 RfuChildSetReceivedPlayerOrder(const u8 *template) +static u8 LoadLinkPlayerIds(const u8 *ids) { u8 i; - if (Rfu.parent_child == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) return FALSE; for (i = 0; i < RFU_CHILD_MAX; i++) - { - Rfu.linkPlayerIdx[i] = template[i]; - } - return template[Rfu.child_slot]; + gRfu.linkPlayerIdx[i] = ids[i]; + return ids[gRfu.childSlot]; } -static void RfuFunc_SendKeysToRfu(void) +static void SendKeysToRfu(void) { static u8 heldKeyCount; if (gReceivedRemoteLinkPlayers @@ -1000,27 +1016,49 @@ static void RfuFunc_SendKeysToRfu(void) } } -struct RfuGameData *GetHostRFUtgtGname(void) +struct RfuGameData *GetHostRfuGameData(void) { return &gHostRfuGameData; } bool32 IsSendingKeysToRfu(void) { - return Rfu.RfuFunc == RfuFunc_SendKeysToRfu; + return gRfu.callback == SendKeysToRfu; } void StartSendingKeysToRfu(void) { +// This is the original symbol and field name, which is baked into the assert below +#define Rfu gRfu +#define RfuFunc callback AGB_ASSERT_EX(Rfu.RfuFunc == NULL, ABSPATH("rfu.c"), 1473); - Rfu.RfuFunc = RfuFunc_SendKeysToRfu; +#undef RfuFunc +#undef Rfu + + gRfu.callback = SendKeysToRfu; } void ClearLinkRfuCallback(void) { - Rfu.RfuFunc = NULL; + gRfu.callback = NULL; } +/* +static void Rfu_BerryBlenderSendHeldKeys(void) +{ + RfuPrepareSendBuffer(RFUCMD_BLENDER_SEND_KEYS); + if (GetMultiplayerId() == 0) + gSendCmd[BLENDER_COMM_ARROW_POS] = GetBlenderArrowPosition(); + gBerryBlenderKeySendAttempts++; +} + +void Rfu_SetBerryBlenderLinkCallback(void) +{ + if (gRfu.callback == NULL) + gRfu.callback = Rfu_BerryBlenderSendHeldKeys; +} +*/ + static void RfuHandleReceiveCommand(u8 unused) { u16 i; @@ -1028,42 +1066,42 @@ static void RfuHandleReceiveCommand(u8 unused) for (i = 0; i < MAX_RFU_PLAYERS; i++) { - switch (gRecvCmds[i][0] & 0xff00) + switch (gRecvCmds[i][0] & RFUCMD_MASK) { - case RFUCMD_PLAYERS_LIST_2: - if (Rfu.parent_child == MODE_CHILD && gReceivedRemoteLinkPlayers) + case RFUCMD_SEND_PLAYER_IDS_NEW: + if (gRfu.parentChild == MODE_CHILD && gReceivedRemoteLinkPlayers) return; // fallthrough - case RFUCMD_PLAYERS_LIST: + case RFUCMD_SEND_PLAYER_IDS: if (gRfuLinkStatus->parentChild == MODE_CHILD) { - Rfu.playerCount = gRecvCmds[i][1]; - Rfu.multiplayerId = RfuChildSetReceivedPlayerOrder((u8 *)(gRecvCmds[i] + 2)); + gRfu.playerCount = gRecvCmds[i][1]; + gRfu.multiplayerId = LoadLinkPlayerIds((u8 *)(gRecvCmds[i] + 2)); } break; case RFUCMD_SEND_BLOCK_INIT: - if (Rfu.recvBlock[i].receiving == RFU_RECV_IDLE) + if (gRfu.recvBlock[i].receiving == RECV_STATE_READY) { - Rfu.recvBlock[i].next = 0; - Rfu.recvBlock[i].count = gRecvCmds[i][1]; - Rfu.recvBlock[i].owner = gRecvCmds[i][2]; - Rfu.recvBlock[i].receivedFlags = 0; - Rfu.recvBlock[i].receiving = RFU_RECV_RECEIVING; - Rfu.blockReceived[i] = FALSE; + gRfu.recvBlock[i].next = 0; + gRfu.recvBlock[i].count = gRecvCmds[i][1]; + gRfu.recvBlock[i].owner = gRecvCmds[i][2]; + gRfu.recvBlock[i].receivedFlags = 0; + gRfu.recvBlock[i].receiving = RECV_STATE_RECEIVING; + gRfu.blockReceived[i] = FALSE; } break; - case RFUCMD_SEND_BLOCK_STEP: - if (Rfu.recvBlock[i].receiving == RFU_RECV_RECEIVING) + case RFUCMD_SEND_BLOCK: + if (gRfu.recvBlock[i].receiving == RECV_STATE_RECEIVING) { - Rfu.recvBlock[i].next = gRecvCmds[i][0] & 0xff; - Rfu.recvBlock[i].receivedFlags |= (1 << Rfu.recvBlock[i].next); + gRfu.recvBlock[i].next = gRecvCmds[i][0] & ~RFUCMD_MASK; + gRfu.recvBlock[i].receivedFlags |= (1 << gRfu.recvBlock[i].next); for (j = 0; j < 6; j++) - gBlockRecvBuffer[i][Rfu.recvBlock[i].next * 6 + j] = gRecvCmds[i][j + 1]; - if (Rfu.recvBlock[i].receivedFlags == sAllBlocksReceived[Rfu.recvBlock[i].count]) + gBlockRecvBuffer[i][gRfu.recvBlock[i].next * 6 + j] = gRecvCmds[i][j + 1]; + if (gRfu.recvBlock[i].receivedFlags == sAllBlocksReceived[gRfu.recvBlock[i].count]) { - Rfu.recvBlock[i].receiving = RFU_RECV_FINISHED; + gRfu.recvBlock[i].receiving = RECV_STATE_FINISHED; Rfu_SetBlockReceivedFlag(i); - if (GetHostRFUtgtGname()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM) && gReceivedRemoteLinkPlayers && Rfu.parent_child == MODE_CHILD) + if (GetHostRfuGameData()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM) && gReceivedRemoteLinkPlayers && gRfu.parentChild == MODE_CHILD) ValidateAndReceivePokemonSioInfo(gBlockRecvBuffer); } } @@ -1072,67 +1110,70 @@ static void RfuHandleReceiveCommand(u8 unused) Rfu_InitBlockSend(sBlockRequests[gRecvCmds[i][1]].address, (u16)sBlockRequests[gRecvCmds[i][1]].size); break; case RFUCMD_READY_CLOSE_LINK: - Rfu.readyCloseLink[i] = TRUE; + gRfu.readyCloseLink[i] = TRUE; break; case RFUCMD_READY_EXIT_STANDBY: - if (Rfu.resendExitStandbyCount == gRecvCmds[i][1]) - Rfu.readyExitStandby[i] = TRUE; + if (gRfu.resendExitStandbyCount == gRecvCmds[i][1]) + gRfu.readyExitStandby[i] = TRUE; break; - case RFUCMD_PARENT_DISCONNECT: - if (Rfu.parent_child == MODE_CHILD) + case RFUCMD_DISCONNECT: + if (gRfu.parentChild == MODE_CHILD) { + // Disconnect child if (gReceivedRemoteLinkPlayers) { if (gRecvCmds[i][1] & gRfuLinkStatus->connSlotFlag) { gReceivedRemoteLinkPlayers = FALSE; rfu_LMAN_requestChangeAgbClockMaster(); - Rfu.unk_ce4 = gRecvCmds[i][2]; + gRfu.disconnectMode = gRecvCmds[i][2]; } - Rfu.playerCount = gRecvCmds[i][3]; + gRfu.playerCount = gRecvCmds[i][3]; ClearSelectedLinkPlayerIds(gRecvCmds[i][1]); } } else { - RfuPrepareSendBuffer(RFUCMD_CHILD_DISCONNECT); + // Disconnect parent + RfuPrepareSendBuffer(RFUCMD_DISCONNECT_PARENT); gSendCmd[1] = gRecvCmds[i][1]; gSendCmd[2] = gRecvCmds[i][2]; gSendCmd[3] = gRecvCmds[i][3]; } break; - case RFUCMD_CHILD_DISCONNECT: - if (Rfu.parent_child == MODE_PARENT) + case RFUCMD_DISCONNECT_PARENT: + if (gRfu.parentChild == MODE_PARENT) { - Rfu.bm_DisconnectSlot |= gRecvCmds[i][1]; - Rfu.unk_ce4 = gRecvCmds[i][2]; + gRfu.disconnectSlots |= gRecvCmds[i][1]; + gRfu.disconnectMode = gRecvCmds[i][2]; ClearSelectedLinkPlayerIds(gRecvCmds[i][1]); } break; + //case RFUCMD_BLENDER_SEND_KEYS: case RFUCMD_SEND_HELD_KEYS: gLinkPartnersHeldKeys[i] = gRecvCmds[i][1]; break; } - if (Rfu.parent_child == MODE_PARENT && Rfu.numBlocksReceived[i]) + if (gRfu.parentChild == MODE_PARENT && gRfu.numBlocksReceived[i]) { - if (Rfu.numBlocksReceived[i] == 4) + if (gRfu.numBlocksReceived[i] == 4) { - Rfu.blockReceived[i] = TRUE; - Rfu.numBlocksReceived[i] = 0; + gRfu.blockReceived[i] = TRUE; + gRfu.numBlocksReceived[i] = 0; } else - Rfu.numBlocksReceived[i]++; + gRfu.numBlocksReceived[i]++; } } } -static bool8 AreNoPlayersReceiving(void) +static bool8 AreAllPlayersReadyToReceive(void) { s32 i; - for (i = 0; i < 5; i++) + for (i = 0; i < MAX_RFU_PLAYERS; i++) { - if (Rfu.recvBlock[i].receiving != RFU_RECV_IDLE) + if (gRfu.recvBlock[i].receiving != RECV_STATE_READY) return FALSE; } return TRUE; @@ -1142,9 +1183,9 @@ static bool8 AreAllPlayersFinishedReceiving(void) { s32 i; - for (i = 0; i < Rfu.playerCount; i++) + for (i = 0; i < gRfu.playerCount; i++) { - if (Rfu.recvBlock[i].receiving != RFU_RECV_FINISHED || Rfu.blockReceived[i] != TRUE) + if (gRfu.recvBlock[i].receiving != RECV_STATE_FINISHED || gRfu.blockReceived[i] != TRUE) return FALSE; } return TRUE; @@ -1156,9 +1197,9 @@ static void ResetSendDataManager(struct RfuBlockSend *data) data->count = 0; data->payload = NULL; data->receivedFlags = 0; - data->sending = 0; + data->sending = FALSE; data->owner = 0; - data->receiving = RFU_RECV_IDLE; + data->receiving = RECV_STATE_READY; } u8 Rfu_GetBlockReceivedStatus(void) @@ -1166,12 +1207,10 @@ u8 Rfu_GetBlockReceivedStatus(void) u8 flags = 0; s32 i; - for (i = 0; i < 5; i++) + for (i = 0; i < MAX_RFU_PLAYERS; i++) { - if (Rfu.recvBlock[i].receiving == RFU_RECV_FINISHED && Rfu.blockReceived[i] == TRUE) - { + if (gRfu.recvBlock[i].receiving == RECV_STATE_FINISHED && gRfu.blockReceived[i] == TRUE) flags |= (1 << i); - } } return flags; } @@ -1186,36 +1225,35 @@ static void RfuPrepareSendBuffer(u16 command) switch (command) { case RFUCMD_SEND_BLOCK_INIT: - gSendCmd[1] = Rfu.sendBlock.count; - gSendCmd[2] = Rfu.sendBlock.owner + 0x80; + gSendCmd[1] = gRfu.sendBlock.count; + gSendCmd[2] = gRfu.sendBlock.owner + 0x80; break; case RFUCMD_SEND_BLOCK_REQ: - if (AreNoPlayersReceiving()) - gSendCmd[1] = Rfu.cmdA100_blockRequestType; + if (AreAllPlayersReadyToReceive()) + gSendCmd[1] = gRfu.blockRequestType; break; - case RFUCMD_PLAYERS_LIST: - case RFUCMD_PLAYERS_LIST_2: - tmp = Rfu.bm_PartnerFlags ^ Rfu.bm_DisconnectSlot; - Rfu.playerCount = sNumSetBits[tmp] + 1; - gSendCmd[1] = Rfu.playerCount; - buff = (u8 *)(gSendCmd + 2); + case RFUCMD_SEND_PLAYER_IDS: + case RFUCMD_SEND_PLAYER_IDS_NEW: + tmp = gRfu.parentSlots ^ gRfu.disconnectSlots; + gRfu.playerCount = sPlayerBitsToCount[tmp] + 1; + gSendCmd[1] = gRfu.playerCount; + buff = (u8 *)&gSendCmd[2]; for (i = 0; i < RFU_CHILD_MAX; i++) - buff[i] = Rfu.linkPlayerIdx[i]; + buff[i] = gRfu.linkPlayerIdx[i]; break; case RFUCMD_READY_EXIT_STANDBY: case RFUCMD_READY_CLOSE_LINK: - gSendCmd[1] = Rfu.resendExitStandbyCount; + gSendCmd[1] = gRfu.resendExitStandbyCount; break; case RFUCMD_SEND_PACKET: - for (i = 0; i < 6; i++) - gSendCmd[1 + i] = Rfu.packet[i]; + for (i = 0; i < RFU_PACKET_SIZE; i++) + gSendCmd[1 + i] = gRfu.packet[i]; break; case RFUCMD_SEND_HELD_KEYS: gSendCmd[1] = gHeldKeyCodeToSend; break; - case RFUCMD_CHILD_DISCONNECT: - break; - case RFUCMD_PARENT_DISCONNECT: + case RFUCMD_DISCONNECT_PARENT: + case RFUCMD_DISCONNECT: break; } } @@ -1224,40 +1262,41 @@ void Rfu_SendPacket(void *data) { if (IsSendCmdComplete() && !RfuHasErrored()) { - memcpy(Rfu.packet, data, sizeof(Rfu.packet)); + memcpy(gRfu.packet, data, sizeof(gRfu.packet)); RfuPrepareSendBuffer(RFUCMD_SEND_PACKET); } } bool32 Rfu_InitBlockSend(const u8 *src, size_t size) { - bool8 sizeHasModulo; + bool8 round; AGB_ASSERT_EX(size<=252, ABSPATH("rfu.c"), 1793); - if (Rfu.RfuFunc != NULL) + + if (gRfu.callback != NULL) return FALSE; if (gSendCmd[0] != 0) return FALSE; - if (Rfu.sendBlock.sending != 0) + if (gRfu.sendBlock.sending) { sRfuDebug.blockSendTime++; return FALSE; } - sizeHasModulo = (size % 12) != 0; - Rfu.sendBlock.owner = GetMultiplayerId(); - Rfu.sendBlock.sending = 1; - Rfu.sendBlock.count = (size / 12) + sizeHasModulo; - Rfu.sendBlock.next = 0; - if (size > 0x100) // should never be reached - Rfu.sendBlock.payload = src; + round = (size % 12) != 0; + gRfu.sendBlock.owner = GetMultiplayerId(); + gRfu.sendBlock.sending = TRUE; + gRfu.sendBlock.count = (size / 12) + round; + gRfu.sendBlock.next = 0; + if (size > BLOCK_BUFFER_SIZE) + gRfu.sendBlock.payload = src; else { if (src != gBlockSendBuffer) memcpy(gBlockSendBuffer, src, size); - Rfu.sendBlock.payload = gBlockSendBuffer; + gRfu.sendBlock.payload = gBlockSendBuffer; } RfuPrepareSendBuffer(RFUCMD_SEND_BLOCK_INIT); - Rfu.RfuFunc = HandleBlockSend; - Rfu.sendBlockInitDelay = 0; + gRfu.callback = HandleBlockSend; + gRfu.sendBlockInitDelay = 0; return TRUE; } @@ -1266,139 +1305,141 @@ static void HandleBlockSend(void) if (IsSendCmdComplete()) { RfuPrepareSendBuffer(RFUCMD_SEND_BLOCK_INIT); - if (Rfu.parent_child == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) { - if (++Rfu.sendBlockInitDelay > 2) - Rfu.RfuFunc = SendNextBlock; + if (++gRfu.sendBlockInitDelay > 2) + gRfu.callback = SendNextBlock; } else { - if ((gRecvCmds[GetMultiplayerId()][0] & 0xff00) == RFUCMD_SEND_BLOCK_INIT) - Rfu.RfuFunc = SendNextBlock; + if ((gRecvCmds[GetMultiplayerId()][0] & RFUCMD_MASK) == RFUCMD_SEND_BLOCK_INIT) + gRfu.callback = SendNextBlock; } } } static void SendNextBlock(void) { s32 i; - const u8 *src = Rfu.sendBlock.payload; - gSendCmd[0] = RFUCMD_SEND_BLOCK_STEP | Rfu.sendBlock.next; - for (i = 0; i < 7; i++) - gSendCmd[i + 1] = (src[(i << 1) + Rfu.sendBlock.next * 12 + 1] << 8) | src[(i << 1) + Rfu.sendBlock.next * 12 + 0]; - Rfu.sendBlock.next++; - if (Rfu.sendBlock.count <= Rfu.sendBlock.next) + const u8 *src = gRfu.sendBlock.payload; + gSendCmd[0] = RFUCMD_SEND_BLOCK | gRfu.sendBlock.next; + for (i = 0; i < CMD_LENGTH - 1; i++) + gSendCmd[i + 1] = (src[(i << 1) + gRfu.sendBlock.next * 12 + 1] << 8) | src[(i << 1) + gRfu.sendBlock.next * 12 + 0]; + gRfu.sendBlock.next++; + if (gRfu.sendBlock.count <= gRfu.sendBlock.next) { - Rfu.sendBlock.sending = 0; - Rfu.RfuFunc = SendLastBlock; + gRfu.sendBlock.sending = FALSE; + gRfu.callback = SendLastBlock; } } static void SendLastBlock(void) { - const u8 *src = Rfu.sendBlock.payload; + const u8 *src = gRfu.sendBlock.payload; u8 mpId = GetMultiplayerId(); s32 i; - if (Rfu.parent_child == MODE_CHILD) + if (gRfu.parentChild == MODE_CHILD) { - gSendCmd[0] = RFUCMD_SEND_BLOCK_STEP | (Rfu.sendBlock.count - 1); - for (i = 0; i < 7; i++) - gSendCmd[i + 1] = (src[(i << 1) + (Rfu.sendBlock.count - 1) * 12 + 1] << 8) | src[(i << 1) + (Rfu.sendBlock.count - 1) * 12 + 0]; - if ((u8)gRecvCmds[mpId][0] == Rfu.sendBlock.count - 1) + gSendCmd[0] = RFUCMD_SEND_BLOCK | (gRfu.sendBlock.count - 1); + for (i = 0; i < CMD_LENGTH - 1; i++) + gSendCmd[i + 1] = (src[(i << 1) + (gRfu.sendBlock.count - 1) * 12 + 1] << 8) | src[(i << 1) + (gRfu.sendBlock.count - 1) * 12 + 0]; + if ((u8)gRecvCmds[mpId][0] == gRfu.sendBlock.count - 1) { - if (Rfu.recvBlock[mpId].receivedFlags != sAllBlocksReceived[Rfu.recvBlock[mpId].count]) + if (gRfu.recvBlock[mpId].receivedFlags != sAllBlocksReceived[gRfu.recvBlock[mpId].count]) { - HandleSendFailure(mpId, Rfu.recvBlock[mpId].receivedFlags); + HandleSendFailure(mpId, gRfu.recvBlock[mpId].receivedFlags); sRfuDebug.blockSendFailures++; } else - Rfu.RfuFunc = NULL; + gRfu.callback = NULL; } } else - Rfu.RfuFunc = NULL; + gRfu.callback = NULL; } bool8 Rfu_SendBlockRequest(u8 blockRequestType) { - Rfu.cmdA100_blockRequestType = blockRequestType; + gRfu.blockRequestType = blockRequestType; RfuPrepareSendBuffer(RFUCMD_SEND_BLOCK_REQ); return TRUE; } -static void OnDisconnect_PowerDownRfu(void) +static void RfuShutdownAfterDisconnect(void) { rfu_clearAllSlot(); rfu_LMAN_powerDownRFU(); gReceivedRemoteLinkPlayers = FALSE; - Rfu.isShuttingDown = TRUE; - Rfu.RfuFunc = NULL; + gRfu.isShuttingDown = TRUE; + gRfu.callback = NULL; } static void DisconnectRfu(void) { rfu_REQ_disconnect(gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag); rfu_waitREQComplete(); - OnDisconnect_PowerDownRfu(); + RfuShutdownAfterDisconnect(); } static void TryDisconnectRfu(void) { - if (Rfu.parent_child == MODE_CHILD) + if (gRfu.parentChild == MODE_CHILD) { rfu_LMAN_requestChangeAgbClockMaster(); - Rfu.unk_ce4 = 2; + gRfu.disconnectMode = RFU_DISCONNECT_NORMAL; } else - Rfu.RfuFunc = DisconnectRfu; + gRfu.callback = DisconnectRfu; } void LinkRfu_FatalError(void) { rfu_LMAN_requestChangeAgbClockMaster(); - Rfu.unk_ce4 = 1; - Rfu.bm_DisconnectSlot = gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag; + gRfu.disconnectMode = RFU_DISCONNECT_ERROR; + gRfu.disconnectSlots = gRfuLinkStatus->connSlotFlag | gRfuLinkStatus->linkLossSlotFlag; } // RFU equivalent of LinkCB_WaitCloseLink static void WaitAllReadyToCloseLink(void) { s32 i; - u8 playerCount = Rfu.playerCount; + u8 playerCount = gRfu.playerCount; s32 count = 0; + // Wait for all players to be ready for (i = 0; i < MAX_RFU_PLAYERS; i++) { - if (Rfu.readyCloseLink[i]) + if (gRfu.readyCloseLink[i]) count++; } if (count == playerCount) { + // All ready, close link gBattleTypeFlags &= ~(BATTLE_TYPE_LINK_IN_BATTLE | 0xFFFF0000); - if (Rfu.parent_child == MODE_CHILD) + if (gRfu.parentChild == MODE_CHILD) { - Rfu.errorState = 3; + gRfu.errorState = RFU_ERROR_STATE_DISCONNECTING; TryDisconnectRfu(); } else - Rfu.RfuFunc = TryDisconnectRfu; + gRfu.callback = TryDisconnectRfu; } } static void SendReadyCloseLink(void) { - if (IsSendCmdComplete() && !Rfu.foundNewLeaderMaybe) + if (IsSendCmdComplete() && !gRfu.playerExchangeActive) { RfuPrepareSendBuffer(RFUCMD_READY_CLOSE_LINK); - Rfu.RfuFunc = WaitAllReadyToCloseLink; + gRfu.callback = WaitAllReadyToCloseLink; } } static void Task_TryReadyCloseLink(u8 taskId) { - if (Rfu.RfuFunc == NULL) + if (gRfu.callback == NULL) { - Rfu.linkClosing = TRUE; - Rfu.RfuFunc = SendReadyCloseLink; + gRfu.stopNewConnections = TRUE; + gRfu.callback = SendReadyCloseLink; DestroyTask(taskId); } } @@ -1416,34 +1457,34 @@ static void SendReadyExitStandbyUntilAllReady(void) if (GetMultiplayerId() != 0) // child { - if (Rfu.recvQueue.count == 0 && Rfu.resendExitStandbyTimer > 60) + if (gRfu.recvQueue.count == 0 && gRfu.resendExitStandbyTimer > 60) { RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); - Rfu.resendExitStandbyTimer = 0; + gRfu.resendExitStandbyTimer = 0; } } playerCount = GetLinkPlayerCount(); for (i = 0; i < playerCount; i++) { - if (Rfu.readyExitStandby[i] == 0) + if (!gRfu.readyExitStandby[i]) break; } if (i == playerCount) { for (i = 0; i < MAX_RFU_PLAYERS; i++) - Rfu.readyExitStandby[i] = 0; - Rfu.resendExitStandbyCount++; - Rfu.RfuFunc = NULL; + gRfu.readyExitStandby[i] = FALSE; + gRfu.resendExitStandbyCount++; + gRfu.callback = NULL; } - Rfu.resendExitStandbyTimer++; + gRfu.resendExitStandbyTimer++; } static void LinkLeaderReadyToExitStandby(void) { - if (Rfu.recvQueue.count == 0 && IsSendCmdComplete()) + if (gRfu.recvQueue.count == 0 && IsSendCmdComplete()) { RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); - Rfu.RfuFunc = SendReadyExitStandbyUntilAllReady; + gRfu.callback = SendReadyExitStandbyUntilAllReady; } } @@ -1453,28 +1494,30 @@ static void Rfu_LinkStandby(void) u8 i; u8 playerCount; - if (GetMultiplayerId() != 0) // child + if (GetMultiplayerId() != 0) { - if (Rfu.recvQueue.count == 0 && IsSendCmdComplete()) + // Not link leader, send exit standby when ready + if (gRfu.recvQueue.count == 0 && IsSendCmdComplete()) { RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); - Rfu.RfuFunc = SendReadyExitStandbyUntilAllReady; + gRfu.callback = SendReadyExitStandbyUntilAllReady; } } - else // parent + else { + // Link leader, wait for all members to send exit ready playerCount = GetLinkPlayerCount(); for (i = 1; i < playerCount; i++) { - if (Rfu.readyExitStandby[i] == 0) + if (!gRfu.readyExitStandby[i]) break; } if (i == playerCount) { - if (Rfu.recvQueue.count == 0 && IsSendCmdComplete()) + if (gRfu.recvQueue.count == 0 && IsSendCmdComplete()) { RfuPrepareSendBuffer(RFUCMD_READY_EXIT_STANDBY); - Rfu.RfuFunc = LinkLeaderReadyToExitStandby; + gRfu.callback = LinkLeaderReadyToExitStandby; } } } @@ -1482,10 +1525,10 @@ static void Rfu_LinkStandby(void) void Rfu_SetLinkStandbyCallback(void) { - if (Rfu.RfuFunc == NULL) + if (gRfu.callback == NULL) { - Rfu.RfuFunc = Rfu_LinkStandby; - Rfu.resendExitStandbyTimer = 0; + gRfu.callback = Rfu_LinkStandby; + gRfu.resendExitStandbyTimer = 0; } } @@ -1494,13 +1537,13 @@ bool32 IsRfuSerialNumberValid(u32 serialNo) s32 i; for (i = 0; sAcceptedSerialNos[i] != serialNo; i++) { - if (sAcceptedSerialNos[i] == 0xFFFF) + if (sAcceptedSerialNos[i] == RFU_SERIAL_END) return FALSE; } return TRUE; } -u8 ToggleLMANlinkRecovery(bool32 enable) +u8 Rfu_SetLinkRecovery(bool32 enable) { if (!enable) return rfu_LMAN_setLinkRecovery(FALSE, 0); @@ -1508,121 +1551,129 @@ u8 ToggleLMANlinkRecovery(bool32 enable) return 0; } -void Rfu_UnionRoomChat_StopLinkManager(void) +void Rfu_StopPartnerSearch(void) { - Rfu.linkClosing = TRUE; + gRfu.stopNewConnections = TRUE; rfu_LMAN_stopManager(FALSE); } -u8 LinkRfu_GetMultiplayerId(void) +u8 Rfu_GetMultiplayerId(void) { - if (Rfu.parent_child == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) return 0; - return Rfu.multiplayerId; + return gRfu.multiplayerId; } -u8 GetRfuPlayerCount(void) +u8 Rfu_GetLinkPlayerCount(void) { - return Rfu.playerCount; + return gRfu.playerCount; } bool8 IsLinkRfuTaskFinished(void) { - return Rfu.RfuFunc != NULL ? FALSE : TRUE; + return gRfu.callback != NULL ? FALSE : TRUE; } static void CallRfuFunc(void) { - if (Rfu.RfuFunc != NULL) - Rfu.RfuFunc(); + if (gRfu.callback != NULL) + gRfu.callback(); } static bool8 CheckForLeavingGroupMembers(void) { s32 i; - bool8 retval = FALSE; + bool8 memberLeft = FALSE; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (Rfu.partnerSendStatuses[i] < RFU_STATUS_JOIN_GROUP_OK - || Rfu.partnerSendStatuses[i] > RFU_STATUS_JOIN_GROUP_NO) + if (gRfu.partnerSendStatuses[i] < RFU_STATUS_JOIN_GROUP_OK + || gRfu.partnerSendStatuses[i] > RFU_STATUS_JOIN_GROUP_NO) { - if (gRfuSlotStatusNI[i]->recv.state == SLOT_STATE_RECV_SUCCESS || gRfuSlotStatusNI[i]->recv.state == SLOT_STATE_RECV_SUCCESS_AND_SENDSIDE_UNKNOWN) + if (gRfuSlotStatusNI[i]->recv.state == SLOT_STATE_RECV_SUCCESS + || gRfuSlotStatusNI[i]->recv.state == SLOT_STATE_RECV_SUCCESS_AND_SENDSIDE_UNKNOWN) { - if (Rfu.partnerRecvStatuses[i] == RFU_STATUS_LEAVE_GROUP_NOTICE) + if (gRfu.partnerRecvStatuses[i] == RFU_STATUS_LEAVE_GROUP_NOTICE) { - Rfu.partnerSendStatuses[i] = RFU_STATUS_LEAVE_GROUP; - Rfu.partnerRecvStatuses[i] = RFU_STATUS_10; + gRfu.partnerSendStatuses[i] = RFU_STATUS_LEAVE_GROUP; + gRfu.partnerRecvStatuses[i] = RFU_STATUS_CHILD_LEAVE_READY; rfu_clearSlot(TYPE_NI_RECV, i); - rfu_NI_setSendData(1 << i, 8, &Rfu.partnerSendStatuses[i], 1); - retval = TRUE; + rfu_NI_setSendData(1 << i, 8, &gRfu.partnerSendStatuses[i], 1); + memberLeft = TRUE; } } - else if (gRfuSlotStatusNI[Rfu.child_slot]->recv.state == SLOT_STATE_RECV_FAILED) + else if (gRfuSlotStatusNI[gRfu.childSlot]->recv.state == SLOT_STATE_RECV_FAILED) { rfu_clearSlot(TYPE_NI_RECV, i); } } } - return retval; + return memberLeft; } -bool32 sub_80FA5D4(void) +bool32 RfuTryDisconnectLeavingChildren(void) { - u8 flags = 0; + u8 childrenLeaving = 0; s32 i; + + // Check all children, get those waiting to be disconnected for (i = 0; i < RFU_CHILD_MAX; i++) { - if (Rfu.partnerRecvStatuses[i] == RFU_STATUS_11) + if (gRfu.partnerRecvStatuses[i] == RFU_STATUS_CHILD_LEAVE) { - flags |= (1 << i); - Rfu.partnerRecvStatuses[i] = RFU_STATUS_OK; + childrenLeaving |= (1 << i); + gRfu.partnerRecvStatuses[i] = RFU_STATUS_OK; } } - if (flags) + + // Disconnect any leaving children + if (childrenLeaving) { - rfu_REQ_disconnect(flags); + rfu_REQ_disconnect(childrenLeaving); rfu_waitREQComplete(); } + + // Return true if any children have left or are still waiting to leave for (i = 0; i < RFU_CHILD_MAX; i++) { - if (Rfu.partnerRecvStatuses[i] == RFU_STATUS_10 || Rfu.partnerRecvStatuses[i] == RFU_STATUS_11) + if (gRfu.partnerRecvStatuses[i] == RFU_STATUS_CHILD_LEAVE_READY + || gRfu.partnerRecvStatuses[i] == RFU_STATUS_CHILD_LEAVE) return TRUE; } return FALSE; } -bool32 CheckTrainerHasLeftByIdAndName(u16 trainerId, const u8 *trainerName) +bool32 HasTrainerLeftPartnersList(u16 trainerId, const u8 *name) { - u8 r1 = GetPartnerIndexByNameAndTrainerID(trainerName, trainerId); - if (r1 == 0xFF) + u8 idx = GetPartnerIndexByNameAndTrainerID(name, trainerId); + if (idx == 0xFF) return TRUE; - if (Rfu.partnerSendStatuses[r1] == RFU_STATUS_LEAVE_GROUP) + if (gRfu.partnerSendStatuses[idx] == RFU_STATUS_LEAVE_GROUP) return TRUE; return FALSE; } -void SendByteToPartnerByIdAndName(u8 value, u16 trainerId, const u8 *trainerName) +void SendRfuStatusToPartner(u8 status, u16 trainerId, const u8 *name) { - u8 slotNo = GetPartnerIndexByNameAndTrainerID(trainerName, trainerId); - Rfu.partnerSendStatuses[slotNo] = value; - rfu_clearSlot(TYPE_NI_SEND, slotNo); - rfu_NI_setSendData(1 << slotNo, 8, Rfu.partnerSendStatuses + slotNo, 1); + u8 idx = GetPartnerIndexByNameAndTrainerID(name, trainerId); + gRfu.partnerSendStatuses[idx] = status; + rfu_clearSlot(TYPE_NI_SEND, idx); + rfu_NI_setSendData(1 << idx, 8, &gRfu.partnerSendStatuses[idx], 1); } void SendLeaveGroupNotice(void) { - Rfu.sendStatus = RFU_STATUS_LEAVE_GROUP_NOTICE; - rfu_clearSlot(TYPE_NI_SEND, Rfu.child_slot); - rfu_NI_setSendData(1 << Rfu.child_slot, 8, &Rfu.sendStatus, 1); + gRfu.sendStatus = RFU_STATUS_LEAVE_GROUP_NOTICE; + rfu_clearSlot(TYPE_NI_SEND, gRfu.childSlot); + rfu_NI_setSendData(1 << gRfu.childSlot, 8, &gRfu.sendStatus, 1); } -u32 WaitSendByteToPartnerByIdAndName(u16 trainerId, const u8 *trainerName) +u32 WaitSendRfuStatusToPartner(u16 trainerId, const u8 *name) { - u8 r0 = GetPartnerIndexByNameAndTrainerID(trainerName, trainerId); - if (r0 == 0xFF) + u8 idx = GetPartnerIndexByNameAndTrainerID(name, trainerId); + if (idx == 0xFF) return 2; - if (gRfuSlotStatusNI[r0]->send.state == SLOT_STATE_READY) + if (gRfuSlotStatusNI[idx]->send.state == SLOT_STATE_READY) return 1; return 0; } @@ -1634,114 +1685,119 @@ static void UpdateChildStatuses(void) CheckForLeavingGroupMembers(); for (i = 0; i < RFU_CHILD_MAX; i++) { - if (gRfuSlotStatusNI[i]->send.state == SLOT_STATE_SEND_SUCCESS || gRfuSlotStatusNI[i]->send.state == SLOT_STATE_SEND_FAILED) + if (gRfuSlotStatusNI[i]->send.state == SLOT_STATE_SEND_SUCCESS + || gRfuSlotStatusNI[i]->send.state == SLOT_STATE_SEND_FAILED) { - if (Rfu.partnerRecvStatuses[i] == RFU_STATUS_10) - Rfu.partnerRecvStatuses[i] = RFU_STATUS_11; + if (gRfu.partnerRecvStatuses[i] == RFU_STATUS_CHILD_LEAVE_READY) + gRfu.partnerRecvStatuses[i] = RFU_STATUS_CHILD_LEAVE; rfu_clearSlot(TYPE_NI_SEND, i); } } } -static s32 GetRfuRecvStatus(void) +static s32 GetJoinGroupStatus(void) { - s32 retval = RFU_STATUS_OK; - if (Rfu.sendStatus == RFU_STATUS_LEAVE_GROUP_NOTICE) + s32 status = RFU_STATUS_OK; + if (gRfu.sendStatus == RFU_STATUS_LEAVE_GROUP_NOTICE) { - if (gRfuSlotStatusNI[Rfu.child_slot]->send.state == SLOT_STATE_SEND_SUCCESS || gRfuSlotStatusNI[Rfu.child_slot]->send.state == SLOT_STATE_SEND_FAILED) - rfu_clearSlot(TYPE_NI_SEND, Rfu.child_slot); + if (gRfuSlotStatusNI[gRfu.childSlot]->send.state == SLOT_STATE_SEND_SUCCESS + || gRfuSlotStatusNI[gRfu.childSlot]->send.state == SLOT_STATE_SEND_FAILED) + rfu_clearSlot(TYPE_NI_SEND, gRfu.childSlot); } - if (gRfuSlotStatusNI[Rfu.child_slot]->recv.state == SLOT_STATE_RECV_SUCCESS || gRfuSlotStatusNI[Rfu.child_slot]->recv.state == SLOT_STATE_RECV_SUCCESS_AND_SENDSIDE_UNKNOWN) + if (gRfuSlotStatusNI[gRfu.childSlot]->recv.state == SLOT_STATE_RECV_SUCCESS + || gRfuSlotStatusNI[gRfu.childSlot]->recv.state == SLOT_STATE_RECV_SUCCESS_AND_SENDSIDE_UNKNOWN) { - rfu_clearSlot(TYPE_NI_RECV, Rfu.child_slot); - RfuSetStatus(Rfu.recvStatus, 0); - retval = Rfu.recvStatus; + rfu_clearSlot(TYPE_NI_RECV, gRfu.childSlot); + RfuSetStatus(gRfu.recvStatus, 0); + status = gRfu.recvStatus; } - else if (gRfuSlotStatusNI[Rfu.child_slot]->recv.state == SLOT_STATE_RECV_FAILED) + else if (gRfuSlotStatusNI[gRfu.childSlot]->recv.state == SLOT_STATE_RECV_FAILED) { - rfu_clearSlot(TYPE_NI_RECV, Rfu.child_slot); - retval = RFU_STATUS_JOIN_GROUP_NO; + rfu_clearSlot(TYPE_NI_RECV, gRfu.childSlot); + status = RFU_STATUS_JOIN_GROUP_NO; } - return retval; + return status; } -static void sub_80FA834(u8 taskId) +#define tState data[0] + +static void Task_PlayerExchange(u8 taskId) { s32 i; - if (Rfu.status == RFU_STATUS_FATAL_ERROR || Rfu.status == RFU_STATUS_CONNECTION_ERROR) + if (gRfu.status == RFU_STATUS_FATAL_ERROR || gRfu.status == RFU_STATUS_CONNECTION_ERROR) { - Rfu.foundNewLeaderMaybe = FALSE; + gRfu.playerExchangeActive = FALSE; DestroyTask(taskId); } - switch (gTasks[taskId].data[0]) + switch (gTasks[taskId].tState) { case 0: - if (AreNoPlayersReceiving()) + if (AreAllPlayersReadyToReceive()) { ResetBlockReceivedFlags(); LocalLinkPlayerToBlock(); - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; } break; case 1: - if (Rfu.parent_child == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) { if (gReceivedRemoteLinkPlayers) - RfuPrepareSendBuffer(RFUCMD_PLAYERS_LIST_2); + RfuPrepareSendBuffer(RFUCMD_SEND_PLAYER_IDS_NEW); else - RfuPrepareSendBuffer(RFUCMD_PLAYERS_LIST); - gTasks[taskId].data[0] = 101; + RfuPrepareSendBuffer(RFUCMD_SEND_PLAYER_IDS); + gTasks[taskId].tState = 101; } else - gTasks[taskId].data[0] = 2; + gTasks[taskId].tState = 2; break; case 101: if (IsSendCmdComplete()) - gTasks[taskId].data[0] = 2; + gTasks[taskId].tState = 2; break; case 2: - if (Rfu.playerCount) - gTasks[taskId].data[0]++; + if (gRfu.playerCount) + gTasks[taskId].tState++; break; case 3: - if (Rfu.parent_child == MODE_PARENT) + if (gRfu.parentChild == MODE_PARENT) { - if (AreNoPlayersReceiving()) + if (AreAllPlayersReadyToReceive()) { - Rfu.cmdA100_blockRequestType = BLOCK_REQ_SIZE_NONE; + gRfu.blockRequestType = BLOCK_REQ_SIZE_NONE; RfuPrepareSendBuffer(RFUCMD_SEND_BLOCK_REQ); - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; } } else - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 4: if (AreAllPlayersFinishedReceiving()) - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 5: - for (i = 0; i < Rfu.playerCount; i++) + for (i = 0; i < gRfu.playerCount; i++) { LinkPlayerFromBlock(i); Rfu_ResetBlockReceivedFlag(i); } - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 6: DestroyTask(taskId); gReceivedRemoteLinkPlayers = TRUE; - Rfu.foundNewLeaderMaybe = FALSE; + gRfu.playerExchangeActive = FALSE; rfu_LMAN_setLinkRecovery(1, 600); - if (Rfu.unionRoomChatters) + if (gRfu.newChildQueue) { for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((Rfu.unionRoomChatters >> i) & 1) + if ((gRfu.newChildQueue >> i) & 1) { - Rfu.bmChatLeaderMaybe = 1 << i; - Rfu.unionRoomChatters ^= (1 << i); + gRfu.nextChildBits = 1 << i; + gRfu.newChildQueue ^= (1 << i); } } } @@ -1749,33 +1805,59 @@ static void sub_80FA834(u8 taskId) } } -static void ClearSelectedLinkPlayerIds(u16 disconnectMask) +static void ClearSelectedLinkPlayerIds(u16 selected) { s32 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((disconnectMask >> i) & 1) - Rfu.linkPlayerIdx[i] = 0; + if ((selected >> i) & 1) + gRfu.linkPlayerIdx[i] = 0; } } -static void ReceiveRfuLinkPlayers(const struct SioInfo *chunk) +static void ReceiveRfuLinkPlayers(const struct SioInfo *sioInfo) { s32 i; - Rfu.playerCount = chunk->playerCount; + gRfu.playerCount = sioInfo->playerCount; for (i = 0; i < RFU_CHILD_MAX; i++) - Rfu.linkPlayerIdx[i] = chunk->linkPlayerIdx[i]; + gRfu.linkPlayerIdx[i] = sioInfo->linkPlayerIdx[i]; for (i = 0; i < MAX_RFU_PLAYERS; i++) { - gLinkPlayers[i] = chunk->linkPlayers[i]; + gLinkPlayers[i] = sioInfo->linkPlayers[i]; ConvertLinkPlayerName(gLinkPlayers + i); } } +// Could be relocated to top of file, but would also require relocating assert strings +static const char sASCII_PokemonSioInfo[] = "PokemonSioInfo"; +static const u8 sText_Akito[] = _(" あきと"); // Presumably "Akito Mori", one of Game Freak's programmers +static const char sASCII_LinkLossDisconnect[] = "LINK LOSS DISCONNECT!"; +static const char sASCII_LinkLossRecoveryNow[] = "LINK LOSS RECOVERY NOW"; +ALIGNED(4) static const char sASCII_30Spaces[] = {" "}; +static const char sASCII_15Spaces[] = {" "}; +static const char sASCII_8Spaces[] = {" "}; +ALIGNED(4) static const char sASCII_Space[] = {" "}; +static const char sASCII_Asterisk[] = {"*"}; +static const char sASCII_NowSlot[] = "NOWSLOT"; + +static const char sASCII_ClockCmds[][12] = { + " ", + "CLOCK DRIFT", + "BUSY SEND ", + "CMD REJECT ", + "CLOCK SLAVE" +}; + +static const char sASCII_ChildParentSearch[][8] = { + "CHILD ", + "PARENT", + "SEARCH" +}; + static void ValidateAndReceivePokemonSioInfo(void *recvBuffer) { - if (strcmp("PokemonSioInfo", recvBuffer) == 0) + if (strcmp(sASCII_PokemonSioInfo, recvBuffer) == 0) { ReceiveRfuLinkPlayers(recvBuffer); CpuFill16(0, recvBuffer, sizeof(struct SioInfo)); @@ -1783,75 +1865,76 @@ static void ValidateAndReceivePokemonSioInfo(void *recvBuffer) } } -static void Task_ExchangeLinkPlayers(u8 taskId) +// Equivalent to Task_PlayerExchange, but for when new children arrive after the first exchange +static void Task_PlayerExchangeUpdate(u8 taskId) { s32 i; - struct LinkPlayerBlock *r2; - struct SioInfo *r5; - u8 r4 = Rfu.linkPlayerIdx[gUnknown_843EC38[Rfu.unk_ce9]]; - if (Rfu.status == 1 || Rfu.status == 2) + struct LinkPlayerBlock *playerBlock; + struct SioInfo *sio; + u8 playerId = gRfu.linkPlayerIdx[sSlotToLinkPlayerTableId[gRfu.incomingChild]]; + if (gRfu.status == RFU_STATUS_FATAL_ERROR || gRfu.status == RFU_STATUS_CONNECTION_ERROR) { - Rfu.foundNewLeaderMaybe = FALSE; + gRfu.playerExchangeActive = FALSE; DestroyTask(taskId); } - switch (gTasks[taskId].data[0]) + switch (gTasks[taskId].tState) { case 0: if (IsSendCmdComplete()) { - ResetBlockReceivedFlag(r4); - RfuPrepareSendBuffer(RFUCMD_PLAYERS_LIST_2); - gTasks[taskId].data[0]++; + ResetBlockReceivedFlag(playerId); + RfuPrepareSendBuffer(RFUCMD_SEND_PLAYER_IDS_NEW); + gTasks[taskId].tState++; } break; case 1: if (IsSendCmdComplete()) - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 2: - if ((GetBlockReceivedStatus() >> r4) & 1) + if ((GetBlockReceivedStatus() >> playerId) & 1) { - ResetBlockReceivedFlag(r4); - r2 = (struct LinkPlayerBlock *)gBlockRecvBuffer[r4]; - gLinkPlayers[r4] = r2->linkPlayer; - ConvertLinkPlayerName(gLinkPlayers + r4); - gTasks[taskId].data[0]++; + ResetBlockReceivedFlag(playerId); + playerBlock = (struct LinkPlayerBlock *)gBlockRecvBuffer[playerId]; + gLinkPlayers[playerId] = playerBlock->linkPlayer; + ConvertLinkPlayerName(&gLinkPlayers[playerId]); + gTasks[taskId].tState++; } break; case 3: // Prepare send block - r5 = (struct SioInfo *)gBlockSendBuffer; - memcpy(r5->magic, "PokemonSioInfo", sizeof("PokemonSioInfo")); - r5->playerCount = Rfu.playerCount; + sio = (struct SioInfo *)gBlockSendBuffer; + memcpy(sio->magic, sASCII_PokemonSioInfo, sizeof sASCII_PokemonSioInfo); + sio->playerCount = gRfu.playerCount; for (i = 0; i < RFU_CHILD_MAX; i++) - r5->linkPlayerIdx[i] = Rfu.linkPlayerIdx[i]; - memcpy(r5->linkPlayers, gLinkPlayers, sizeof gLinkPlayers); - gTasks[taskId].data[0]++; + sio->linkPlayerIdx[i] = gRfu.linkPlayerIdx[i]; + memcpy(sio->linkPlayers, gLinkPlayers, sizeof gLinkPlayers); + gTasks[taskId].tState++; // fallthrough case 4: - r5 = (struct SioInfo *)gBlockSendBuffer; - r5->playerCount = Rfu.playerCount; + sio = (struct SioInfo *)gBlockSendBuffer; + sio->playerCount = gRfu.playerCount; for (i = 0; i < RFU_CHILD_MAX; i++) - r5->linkPlayerIdx[i] = Rfu.linkPlayerIdx[i]; - memcpy(r5->linkPlayers, gLinkPlayers, sizeof gLinkPlayers); + sio->linkPlayerIdx[i] = gRfu.linkPlayerIdx[i]; + memcpy(sio->linkPlayers, gLinkPlayers, sizeof gLinkPlayers); if (SendBlock(0, gBlockSendBuffer, 0xa0)) - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 5: if (IsLinkTaskFinished() && GetBlockReceivedStatus() & 1) { CpuFill16(0, gBlockRecvBuffer, sizeof(struct SioInfo)); ResetBlockReceivedFlag(0); - Rfu.foundNewLeaderMaybe = FALSE; - if (Rfu.unionRoomChatters) + gRfu.playerExchangeActive = FALSE; + if (gRfu.newChildQueue) { for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((Rfu.unionRoomChatters >> i) & 1) + if ((gRfu.newChildQueue >> i) & 1) { - Rfu.bmChatLeaderMaybe = 1 << i; - Rfu.unionRoomChatters ^= (1 << i); - Rfu.foundNewLeaderMaybe = TRUE; + gRfu.nextChildBits = 1 << i; + gRfu.newChildQueue ^= (1 << i); + gRfu.playerExchangeActive = TRUE; break; } } @@ -1862,23 +1945,24 @@ static void Task_ExchangeLinkPlayers(u8 taskId) } } -static void sub_80FACF0(u8 taskId) +// Equivalent to Task_PlayerExchange but for chatting with a Union Room partner +static void Task_PlayerExchangeChat(u8 taskId) { - if (Rfu.status == RFU_STATUS_FATAL_ERROR || Rfu.status == RFU_STATUS_CONNECTION_ERROR) + if (gRfu.status == RFU_STATUS_FATAL_ERROR || gRfu.status == RFU_STATUS_CONNECTION_ERROR) DestroyTask(taskId); - switch (gTasks[taskId].data[0]) + switch (gTasks[taskId].tState) { case 0: - if (Rfu.playerCount != 0) + if (gRfu.playerCount != 0) { LocalLinkPlayerToBlock(); SendBlock(0, gBlockSendBuffer, sizeof(struct LinkPlayerBlock)); - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; } break; case 1: if (IsLinkTaskFinished()) - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 2: if (GetBlockReceivedStatus() & 1) @@ -1894,31 +1978,31 @@ static void sub_80FACF0(u8 taskId) static void RfuCheckErrorStatus(void) { - if (Rfu.errorState == 1 && lman.childClockSlave_flag == 0) + if (gRfu.errorState == RFU_ERROR_STATE_OCCURRED && lman.childClockSlave_flag == 0) { - if (gMain.callback2 == c2_mystery_gift_e_reader_run) + if (gMain.callback2 == CB2_MysteryGiftEReader) gWirelessCommType = 2; SetMainCallback2(CB2_LinkError); gMain.savedCallback = CB2_LinkError; SetLinkErrorFromRfu( - (Rfu.linkman_msg << 16) | (Rfu.linkman_param[0] << 8) | Rfu.linkman_param[1], - Rfu.recvQueue.count, - Rfu.sendQueue.count, + (gRfu.errorInfo << 16) | (gRfu.errorParams[0] << 8) | gRfu.errorParams[1], + gRfu.recvQueue.count, + gRfu.sendQueue.count, RfuGetStatus() == RFU_STATUS_CONNECTION_ERROR ); - Rfu.errorState = 2; + gRfu.errorState = RFU_ERROR_STATE_PROCESSED; CloseLink(); } - else if (Rfu.sendQueue.full == TRUE || Rfu.recvQueue.full == TRUE) + else if (gRfu.sendQueue.full == TRUE || gRfu.recvQueue.full == TRUE) { if (lman.childClockSlave_flag) rfu_LMAN_requestChangeAgbClockMaster(); - RfuSetStatus(RFU_STATUS_FATAL_ERROR, 0x7000); - GetLinkmanErrorParams(0x7000); + RfuSetStatus(RFU_STATUS_FATAL_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_6 | F_RFU_ERROR_7); + RfuSetErrorParams(F_RFU_ERROR_5 | F_RFU_ERROR_6 | F_RFU_ERROR_7); } } -static void rfu_REQ_recvData_then_sendData(void) +static void RfuMain1_UnionRoom(void) { if (lman.parent_child == MODE_PARENT) { @@ -1928,180 +2012,183 @@ static void rfu_REQ_recvData_then_sendData(void) } } -bool32 LinkRfuMain1(void) +// Rfu equivalent of LinkMain1 +bool32 RfuMain1(void) { bool32 retval = FALSE; - Rfu.parentId = 0; + gRfu.parentId = 0; rfu_LMAN_manager_entity(Random()); - if (!Rfu.isShuttingDown) + if (!gRfu.isShuttingDown) { - switch (Rfu.parent_child) + switch (gRfu.parentChild) { case MODE_PARENT: - sub_80F911C(); + RfuMain1_Parent(); break; case MODE_CHILD: - retval = RfuProcessEnqueuedRecvBlock(); + retval = RfuMain1_Child(); break; case MODE_P_C_SWITCH: - rfu_REQ_recvData_then_sendData(); + RfuMain1_UnionRoom(); break; } } return retval; } -bool32 LinkRfuMain2(void) +// Rfu equivalent of LinkMain2 +bool32 RfuMain2(void) { bool32 retval = FALSE; - if (!Rfu.isShuttingDown) + if (!gRfu.isShuttingDown) { - if (Rfu.parent_child == MODE_PARENT) - retval = sub_80F9204(); + if (gRfu.parentChild == MODE_PARENT) + retval = RfuMain2_Parent(); RfuCheckErrorStatus(); } return retval; } -static void CopyPlayerNameToUnameBuffer(void) +static void SetHostRfuUsername(void) { StringCopy(gHostRfuUsername, gSaveBlock2Ptr->playerName); } -void ClearAndInitHostRFUtgtGname(void) +void ResetHostRfuGameData(void) { memset(&gHostRfuGameData, 0, RFU_GAME_NAME_LENGTH); InitHostRFUtgtGname(&gHostRfuGameData, ACTIVITY_NONE, FALSE, 0); } -void SetHostRFUtgtGname(u8 activity, u32 child_sprite_genders, u32 started) +void SetHostRfuGameData(u8 activity, u32 partnerInfo, u32 startedActivity) { - InitHostRFUtgtGname(&gHostRfuGameData, activity, started, child_sprite_genders); + InitHostRFUtgtGname(&gHostRfuGameData, activity, startedActivity, partnerInfo); } -void SetGnameBufferWonderFlags(bool32 hasNews, bool32 hasCard) +void SetHostRfuWonderFlags(bool32 hasNews, bool32 hasCard) { - gHostRfuGameData.unk_00.hasNews = hasNews; - gHostRfuGameData.unk_00.hasCard = hasCard; + gHostRfuGameData.compatibility.hasNews = hasNews; + gHostRfuGameData.compatibility.hasCard = hasCard; } -void RfuUpdatePlayerGnameStateAndSend(u32 type, u32 species, u32 level) +void SetTradeBoardRegisteredMonInfo(u32 type, u32 species, u32 level) { - gHostRfuGameData.type = type; - gHostRfuGameData.species = species; - gHostRfuGameData.level = level; + gHostRfuGameData.tradeType = type; + gHostRfuGameData.tradeSpecies = species; + gHostRfuGameData.tradeLevel = level; } -void UpdateGameData_GroupLockedIn(bool8 started) +void UpdateGameData_GroupLockedIn(bool8 startedActivity) { - gHostRfuGameData.started = started; - rfu_REQ_configGameData(0, 0x0002, (void *)&gHostRfuGameData, gHostRfuUsername); + gHostRfuGameData.startedActivity = startedActivity; + rfu_REQ_configGameData(0, RFU_SERIAL_GAME, (void *)&gHostRfuGameData, gHostRfuUsername); } -void UpdateGameDataWithActivitySpriteGendersFlag(u8 activity, u32 child_sprite_genders, u32 started) +void UpdateGameData_SetActivity(u8 activity, u32 partnerInfo, u32 startedActivity) { - if (activity) - SetHostRFUtgtGname(activity, child_sprite_genders, started); - rfu_REQ_configGameData(0, 0x0002, (void *)&gHostRfuGameData, gHostRfuUsername); + if (activity != ACTIVITY_NONE) + SetHostRfuGameData(activity, partnerInfo, startedActivity); + rfu_REQ_configGameData(0, RFU_SERIAL_GAME, (void *)&gHostRfuGameData, gHostRfuUsername); } -void sub_80FB030(u32 linkPlayerCount) +void SetUnionRoomChatPlayerData(u32 numPlayers) { s32 i; u32 numConnectedChildren; - u32 child_sprite_genders; - s32 bm_child_slots; + u32 partnerInfo; + s32 slots; - if (GetHostRFUtgtGname()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) + if (GetHostRfuGameData()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) { numConnectedChildren = 0; - child_sprite_genders = 0; - bm_child_slots = Rfu.bm_PartnerFlags ^ Rfu.bm_DisconnectSlot; + partnerInfo = 0; + slots = gRfu.parentSlots ^ gRfu.disconnectSlots; for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((bm_child_slots >> i) & 1) + if ((slots >> i) & 1) { - // The 0x80 prevents this element from being incorrectly read as a 0. - child_sprite_genders |= (( - 0x80 | ((gLinkPlayers[Rfu.linkPlayerIdx[i]].gender & 1) << 3) | (gLinkPlayers[Rfu.linkPlayerIdx[i]].trainerId & 7) - ) << (numConnectedChildren << 3)); + // Only trainerId is shifted by the number of children, so the active flag and gender + // are only ever set for the first child + partnerInfo |= ((PINFO_ACTIVE_FLAG + | ((gLinkPlayers[gRfu.linkPlayerIdx[i]].gender & 1) << PINFO_GENDER_SHIFT) + | (gLinkPlayers[gRfu.linkPlayerIdx[i]].trainerId & PINFO_TID_MASK)) << (numConnectedChildren * 8)); numConnectedChildren++; - if (numConnectedChildren == linkPlayerCount - 1) + if (numConnectedChildren == numPlayers - 1) break; } } - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_CHAT | IN_UNION_ROOM, child_sprite_genders, 0); + UpdateGameData_SetActivity(ACTIVITY_CHAT | IN_UNION_ROOM, partnerInfo, FALSE); } } -static void GetLinkmanErrorParams(u32 msg) +static void RfuSetErrorParams(u32 errorInfo) { - if (Rfu.errorState == 0) + if (gRfu.errorState == RFU_ERROR_STATE_NONE) { - Rfu.linkman_param[0] = lman.param[0]; - Rfu.linkman_param[1] = lman.param[1]; - Rfu.linkman_msg = msg; - Rfu.errorState = 1; + gRfu.errorParams[0] = lman.param[0]; + gRfu.errorParams[1] = lman.param[1]; + gRfu.errorInfo = errorInfo; + gRfu.errorState = RFU_ERROR_STATE_OCCURRED; } } static void ResetErrorState(void) { - Rfu.errorState = 0; + gRfu.errorState = RFU_ERROR_STATE_NONE; } -void sub_80FB128(bool32 a0) +void RfuSetIgnoreError(bool32 enable) { - if (!a0) - Rfu.errorState = 0; + if (!enable) + gRfu.errorState = RFU_ERROR_STATE_NONE; else - Rfu.errorState = 4; + gRfu.errorState = RFU_ERROR_STATE_IGNORE; } -static void sub_80FB154(void) +static void DisconnectNewChild(void) { - sub_80FBE20(lman.acceptSlot_flag, 1); - Rfu.RfuFunc = NULL; + SendDisconnectCommand(lman.acceptSlot_flag, RFU_DISCONNECT_ERROR); + gRfu.callback = NULL; } -static void sub_80FB174(void) +static void StartDisconnectNewChild(void) { - Rfu.RfuFunc = sub_80FB154; + gRfu.callback = DisconnectNewChild; } -static void LmanCallback_Parent2(u8 msg, u8 param_count) +static void LinkManagerCB_Parent(u8 msg, u8 param_count) { u8 i; - u8 bmDisconnectFlag = 0; + u8 disconnectFlag = 0; switch (msg) { case LMAN_MSG_INITIALIZE_COMPLETED: - Rfu.state = 2; + gRfu.state = RFUSTATE_PARENT_CONNECT; break; case LMAN_MSG_NEW_CHILD_CONNECT_DETECTED: break; case LMAN_MSG_NEW_CHILD_CONNECT_ACCEPTED: - sub_80FB564(lman.param[0]); + ParentResetChildRecvMetadata(lman.param[0]); for (i = 0; i < RFU_CHILD_MAX; i++) { if ((lman.param[0] >> i) & 1) { struct RfuGameData *structPtr = (void *)&gRfuLinkStatus->partner[i].gname; - if (structPtr->activity == GetHostRFUtgtGname()->activity) + if (structPtr->activity == GetHostRfuGameData()->activity) { - Rfu.partnerSendStatuses[i] = RFU_STATUS_OK; - Rfu.partnerRecvStatuses[i] = RFU_STATUS_OK; - rfu_setRecvBuffer(TYPE_NI, i, Rfu.partnerRecvStatuses + i, 1); + gRfu.partnerSendStatuses[i] = RFU_STATUS_OK; + gRfu.partnerRecvStatuses[i] = RFU_STATUS_OK; + rfu_setRecvBuffer(TYPE_NI, i, &gRfu.partnerRecvStatuses[i], sizeof(gRfu.partnerRecvStatuses[0])); } else { - bmDisconnectFlag |= (1 << i); + disconnectFlag |= (1 << i); } } } - if (bmDisconnectFlag) + if (disconnectFlag) { - rfu_REQ_disconnect(bmDisconnectFlag); + rfu_REQ_disconnect(disconnectFlag); rfu_waitREQComplete(); } break; @@ -2110,106 +2197,103 @@ static void LmanCallback_Parent2(u8 msg, u8 param_count) case LMAN_MSG_SEARCH_CHILD_PERIOD_EXPIRED: break; case LMAN_MSG_END_WAIT_CHILD_NAME: - if (Rfu.acceptSlot_flag != lman.acceptSlot_flag) + if (gRfu.acceptSlot_flag != lman.acceptSlot_flag) { - rfu_REQ_disconnect(Rfu.acceptSlot_flag ^ lman.acceptSlot_flag); + rfu_REQ_disconnect(gRfu.acceptSlot_flag ^ lman.acceptSlot_flag); rfu_waitREQComplete(); } - Rfu.state = 17; + gRfu.state = RFUSTATE_PARENT_FINALIZE_START; break; case LMAN_MSG_LINK_LOSS_DETECTED_AND_START_RECOVERY: - Rfu.linkLossRecoveryState = 1; + gRfu.linkLossRecoveryState = 1; break; case LMAN_MSG_LINK_RECOVERY_SUCCESSED: - Rfu.linkLossRecoveryState = 3; + gRfu.linkLossRecoveryState = 3; break; case LMAN_MSG_LINK_LOSS_DETECTED_AND_DISCONNECTED: case LMAN_MSG_LINK_RECOVERY_FAILED_AND_DISCONNECTED: - Rfu.linkLossRecoveryState = 4; - Rfu.bm_PartnerFlags &= ~lman.param[0]; + gRfu.linkLossRecoveryState = 4; + gRfu.parentSlots &= ~lman.param[0]; if (gReceivedRemoteLinkPlayers == 1) { - if (Rfu.bm_PartnerFlags == 0) - GetLinkmanErrorParams(msg); + if (gRfu.parentSlots == 0) + RfuSetErrorParams(msg); else - sub_80FB174(); + StartDisconnectNewChild(); } RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, msg); break; - case 0x34: - break; + case 0x34: // ? Not a valid LMAN_MSG value case LMAN_MSG_RFU_POWER_DOWN: case LMAN_MSG_MANAGER_STOPPED: case LMAN_MSG_MANAGER_FORCED_STOPPED_AND_RFU_RESET: break; case LMAN_MSG_LMAN_API_ERROR_RETURN: RfuSetStatus(RFU_STATUS_FATAL_ERROR, msg); - GetLinkmanErrorParams(msg); - Rfu.isShuttingDown = TRUE; + RfuSetErrorParams(msg); + gRfu.isShuttingDown = TRUE; break; case LMAN_MSG_REQ_API_ERROR: case LMAN_MSG_WATCH_DOG_TIMER_ERROR: case LMAN_MSG_CLOCK_SLAVE_MS_CHANGE_ERROR_BY_DMA: case LMAN_MSG_RFU_FATAL_ERROR: - GetLinkmanErrorParams(msg); + RfuSetErrorParams(msg); RfuSetStatus(RFU_STATUS_FATAL_ERROR, msg); - Rfu.unk_cdb = TRUE; + gRfu.parentFinished = TRUE; break; } } -static const u8 unref_843EDF3[] = _(" あきと"); - -static void LmanCallback_Child(u8 msg, u8 param_count) +static void LinkManagerCB_Child(u8 msg, u8 param_count) { switch (msg) { case LMAN_MSG_INITIALIZE_COMPLETED: - Rfu.state = 6; + gRfu.state = RFUSTATE_CHILD_CONNECT; break; case LMAN_MSG_PARENT_FOUND: - Rfu.parentId = lman.param[0]; + gRfu.parentId = lman.param[0]; break; case LMAN_MSG_SEARCH_PARENT_PERIOD_EXPIRED: break; case LMAN_MSG_CONNECT_PARENT_SUCCESSED: - Rfu.child_slot = lman.param[0]; + gRfu.childSlot = lman.param[0]; break; case LMAN_MSG_CONNECT_PARENT_FAILED: RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, msg); break; case LMAN_MSG_CHILD_NAME_SEND_COMPLETED: - Rfu.state = 11; - Rfu.sendStatus = RFU_STATUS_OK; - Rfu.recvStatus = RFU_STATUS_OK; - rfu_setRecvBuffer(TYPE_NI, Rfu.child_slot, &Rfu.recvStatus, 1); - rfu_setRecvBuffer(TYPE_UNI, Rfu.child_slot, Rfu.unk_c3f, sizeof(Rfu.unk_c3f)); + gRfu.state = RFUSTATE_CHILD_TRY_JOIN; + gRfu.sendStatus = RFU_STATUS_OK; + gRfu.recvStatus = RFU_STATUS_OK; + rfu_setRecvBuffer(TYPE_NI, gRfu.childSlot, &gRfu.recvStatus, sizeof(gRfu.recvStatus)); + rfu_setRecvBuffer(TYPE_UNI, gRfu.childSlot, gRfu.childRecvQueue, sizeof(gRfu.childRecvQueue)); break; case LMAN_MSG_CHILD_NAME_SEND_FAILED_AND_DISCONNECTED: RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, msg); break; case LMAN_MSG_LINK_LOSS_DETECTED_AND_DISCONNECTED: - Rfu.linkLossRecoveryState = 2; - if (Rfu.recvStatus == RFU_STATUS_JOIN_GROUP_NO) + gRfu.linkLossRecoveryState = 2; + if (gRfu.recvStatus == RFU_STATUS_JOIN_GROUP_NO) break; case LMAN_MSG_LINK_RECOVERY_FAILED_AND_DISCONNECTED: - if (Rfu.linkLossRecoveryState != 2) - Rfu.linkLossRecoveryState = 4; - if (Rfu.recvStatus != RFU_STATUS_LEAVE_GROUP) + if (gRfu.linkLossRecoveryState != 2) + gRfu.linkLossRecoveryState = 4; + if (gRfu.recvStatus != RFU_STATUS_LEAVE_GROUP) RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, msg); - Debug_PrintString("LINK LOSS DISCONNECT!", 5, 5); + Debug_PrintString(sASCII_LinkLossDisconnect, 5, 5); if (gReceivedRemoteLinkPlayers == 1) - GetLinkmanErrorParams(msg); + RfuSetErrorParams(msg); break; case LMAN_MSG_LINK_LOSS_DETECTED_AND_START_RECOVERY: - Rfu.linkLossRecoveryState = 1; - Debug_PrintString("LINK LOSS RECOVERY NOW", 5, 5); + gRfu.linkLossRecoveryState = 1; + Debug_PrintString(sASCII_LinkLossRecoveryNow, 5, 5); break; case LMAN_MSG_LINK_RECOVERY_SUCCESSED: - Rfu.linkLossRecoveryState = 3; - Rfu.linkRecovered = 1; + gRfu.linkLossRecoveryState = 3; + gRfu.linkRecovered = TRUE; break; - case 0x34: + case 0x34: // ? Not a valid LMAN_MSG value break; case LMAN_MSG_RFU_POWER_DOWN: case LMAN_MSG_MANAGER_STOPPED: @@ -2217,45 +2301,45 @@ static void LmanCallback_Child(u8 msg, u8 param_count) break; case LMAN_MSG_LMAN_API_ERROR_RETURN: RfuSetStatus(RFU_STATUS_FATAL_ERROR, msg); - GetLinkmanErrorParams(msg); - Rfu.isShuttingDown = TRUE; + RfuSetErrorParams(msg); + gRfu.isShuttingDown = TRUE; break; case LMAN_MSG_REQ_API_ERROR: case LMAN_MSG_WATCH_DOG_TIMER_ERROR: case LMAN_MSG_CLOCK_SLAVE_MS_CHANGE_ERROR_BY_DMA: case LMAN_MSG_RFU_FATAL_ERROR: RfuSetStatus(RFU_STATUS_FATAL_ERROR, msg); - GetLinkmanErrorParams(msg); - Rfu.unk_cdb = TRUE; + RfuSetErrorParams(msg); + gRfu.parentFinished = TRUE; break; } } -static void sub_80FB564(s32 bmConnectedFlag) +static void ParentResetChildRecvMetadata(s32 slot) { s32 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((bmConnectedFlag >> i) & 1) + if ((slot >> i) & 1) { - Rfu.unk_cea[i] = 0; - Rfu.unk_cee[i] = 0xFF; + gRfu.numChildRecvErrors[i] = 0; + gRfu.childRecvIds[i] = 0xFF; } } } -static u8 GetNewChildrenInUnionRoomChat(s32 bmNewChildSlot) +static u8 GetNewChildrenInUnionRoomChat(s32 emptySlotMask) { u8 ret = 0; u8 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((bmNewChildSlot >> i) & 1) + if ((emptySlotMask >> i) & 1) { - struct RfuGameData *structPtr = (void *)&gRfuLinkStatus->partner[i].gname; - if (structPtr->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) + struct RfuGameData *data = (void *)&gRfuLinkStatus->partner[i].gname; + if (data->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) ret |= (1 << i); } } @@ -2263,77 +2347,77 @@ static u8 GetNewChildrenInUnionRoomChat(s32 bmNewChildSlot) return ret; } -static void LmanCallback_Parent(u8 msg, u8 param_count) +static void LinkManagerCB_UnionRoom(u8 msg, u8 param_count) { - u8 r1; + u8 acceptSlot; switch (msg) { case LMAN_MSG_INITIALIZE_COMPLETED: - Rfu.state = 17; + gRfu.state = RFUSTATE_UR_CONNECT; break; case LMAN_MSG_NEW_CHILD_CONNECT_DETECTED: RfuSetStatus(RFU_STATUS_NEW_CHILD_DETECTED, 0); break; case LMAN_MSG_NEW_CHILD_CONNECT_ACCEPTED: - if (GetHostRFUtgtGname()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM) && !Rfu.linkClosing) + if (GetHostRfuGameData()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM) && !gRfu.stopNewConnections) { - u8 bmAcceptSlot = GetNewChildrenInUnionRoomChat(lman.param[0]); - if (bmAcceptSlot != 0) + u8 newChildren = GetNewChildrenInUnionRoomChat(lman.param[0]); + if (newChildren != 0) { - r1 = 1 << CountTrailingZeroes(bmAcceptSlot); - if (Rfu.unionRoomChatters == 0 && !Rfu.foundNewLeaderMaybe) + acceptSlot = 1 << Rfu_GetIndexOfNewestChild(newChildren); + if (gRfu.newChildQueue == 0 && !gRfu.playerExchangeActive) { - Rfu.bmChatLeaderMaybe = r1; - Rfu.unionRoomChatters |= (r1 ^ bmAcceptSlot); - Rfu.foundNewLeaderMaybe = TRUE; + gRfu.nextChildBits = acceptSlot; + gRfu.newChildQueue |= (acceptSlot ^ newChildren); + gRfu.playerExchangeActive = TRUE; } else { - Rfu.unionRoomChatters |= bmAcceptSlot; + gRfu.newChildQueue |= newChildren; } } - if (bmAcceptSlot != lman.param[0]) + if (newChildren != lman.param[0]) { - Rfu.bm_DisconnectSlot |= (bmAcceptSlot ^ lman.param[0]); - Rfu.unk_ce4 = 2; + gRfu.disconnectSlots |= (newChildren ^ lman.param[0]); + gRfu.disconnectMode = RFU_DISCONNECT_NORMAL; } } - else if (GetHostRFUtgtGname()->activity == (ACTIVITY_PLYRTALK | IN_UNION_ROOM)) + else if (GetHostRfuGameData()->activity == (ACTIVITY_PLYRTALK | IN_UNION_ROOM)) { rfu_REQ_disconnect(lman.acceptSlot_flag); rfu_waitREQComplete(); } - sub_80FB564(lman.param[0]); + ParentResetChildRecvMetadata(lman.param[0]); break; case LMAN_MSG_NEW_CHILD_CONNECT_REJECTED: break; case LMAN_MSG_SEARCH_CHILD_PERIOD_EXPIRED: break; case LMAN_MSG_END_WAIT_CHILD_NAME: - if (GetHostRFUtgtGname()->activity != (ACTIVITY_CHAT | IN_UNION_ROOM) && lman.acceptCount > 1) + if (GetHostRfuGameData()->activity != (ACTIVITY_CHAT | IN_UNION_ROOM) && lman.acceptCount > 1) { - r1 = 1 << CountTrailingZeroes(lman.param[0]); - rfu_REQ_disconnect(lman.acceptSlot_flag ^ r1); + acceptSlot = 1 << Rfu_GetIndexOfNewestChild(lman.param[0]); + rfu_REQ_disconnect(lman.acceptSlot_flag ^ acceptSlot); rfu_waitREQComplete(); } - if (Rfu.state == 15) - Rfu.state = 16; + if (gRfu.state == RFUSTATE_UR_STOP_MANAGER_END) + gRfu.state = RFUSTATE_UR_FINALIZE; break; case LMAN_MSG_PARENT_FOUND: - Rfu.parentId = lman.param[0]; + gRfu.parentId = lman.param[0]; break; case LMAN_MSG_SEARCH_PARENT_PERIOD_EXPIRED: break; case LMAN_MSG_CONNECT_PARENT_SUCCESSED: - Rfu.child_slot = lman.param[0]; + gRfu.childSlot = lman.param[0]; break; case LMAN_MSG_CONNECT_PARENT_FAILED: - Rfu.state = 18; - if (Rfu.unk_ccf < 2) + gRfu.state = RFUSTATE_UR_CONNECT_END; + if (gRfu.connectParentFailures < 2) { - Rfu.unk_ccf++; - CreateTask(sub_80FC028, 2); + gRfu.connectParentFailures++; + CreateTask(Task_TryConnectToUnionRoomParent, 2); } else { @@ -2341,52 +2425,54 @@ static void LmanCallback_Parent(u8 msg, u8 param_count) } break; case LMAN_MSG_CHILD_NAME_SEND_COMPLETED: - Rfu.state = 13; + gRfu.state = RFUSTATE_UR_PLAYER_EXCHANGE; RfuSetStatus(RFU_STATUS_CHILD_SEND_COMPLETE, 0); - rfu_setRecvBuffer(TYPE_UNI, Rfu.child_slot, Rfu.unk_c3f, sizeof(Rfu.unk_c3f)); + rfu_setRecvBuffer(TYPE_UNI, gRfu.childSlot, gRfu.childRecvQueue, sizeof(gRfu.childRecvQueue)); break; case LMAN_MSG_CHILD_NAME_SEND_FAILED_AND_DISCONNECTED: RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, msg); break; case LMAN_MSG_LINK_LOSS_DETECTED_AND_START_RECOVERY: if (lman.acceptSlot_flag & lman.param[0]) - Rfu.linkLossRecoveryState = 1; + gRfu.linkLossRecoveryState = 1; break; case LMAN_MSG_LINK_RECOVERY_SUCCESSED: - Rfu.linkLossRecoveryState = 3; + gRfu.linkLossRecoveryState = 3; if (gRfuLinkStatus->parentChild == MODE_CHILD) - Rfu.linkRecovered = 1; + gRfu.linkRecovered = TRUE; break; case LMAN_MSG_LINK_LOSS_DETECTED_AND_DISCONNECTED: - Rfu.linkLossRecoveryState = 2; + gRfu.linkLossRecoveryState = 2; // fallthrough case LMAN_MSG_LINK_RECOVERY_FAILED_AND_DISCONNECTED: - if (Rfu.linkLossRecoveryState != 2) - Rfu.linkLossRecoveryState = 4; - if (Rfu.parent_child == MODE_PARENT) + if (gRfu.linkLossRecoveryState != 2) + gRfu.linkLossRecoveryState = 4; + if (gRfu.parentChild == MODE_PARENT) { if (gReceivedRemoteLinkPlayers == 1) { - Rfu.bm_PartnerFlags &= ~(lman.param[0]); - if (Rfu.bm_PartnerFlags == 0) - GetLinkmanErrorParams(msg); + gRfu.parentSlots &= ~(lman.param[0]); + if (gRfu.parentSlots == 0) + RfuSetErrorParams(msg); else - sub_80FB174(); + StartDisconnectNewChild(); } } - else if (Rfu.unk_ce4 != 2 && gReceivedRemoteLinkPlayers == 1) + else if (gRfu.disconnectMode != RFU_DISCONNECT_NORMAL && gReceivedRemoteLinkPlayers == 1) { - GetLinkmanErrorParams(msg); + RfuSetErrorParams(msg); rfu_LMAN_stopManager(0); } - if (gRfuLinkStatus->parentChild == MODE_NEUTRAL && lman.pcswitch_flag == 0 && FuncIsActiveTask(Task_LinkRfu_UnionRoomListen) == TRUE) - Rfu.state = 17; + if (gRfuLinkStatus->parentChild == MODE_NEUTRAL + && lman.pcswitch_flag == 0 && + FuncIsActiveTask(Task_UnionRoomListen) == TRUE) + gRfu.state = RFUSTATE_UR_CONNECT; RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, msg); break; case LMAN_MSG_LINK_DISCONNECTED_BY_USER: - Rfu.bm_DisconnectSlot = 0; + gRfu.disconnectSlots = 0; break; case LMAN_MSG_RFU_POWER_DOWN: case LMAN_MSG_MANAGER_STOPPED: @@ -2394,34 +2480,34 @@ static void LmanCallback_Parent(u8 msg, u8 param_count) break; case LMAN_MSG_LMAN_API_ERROR_RETURN: RfuSetStatus(RFU_STATUS_FATAL_ERROR, msg); - GetLinkmanErrorParams(msg); - Rfu.isShuttingDown = TRUE; + RfuSetErrorParams(msg); + gRfu.isShuttingDown = TRUE; break; case LMAN_MSG_REQ_API_ERROR: case LMAN_MSG_WATCH_DOG_TIMER_ERROR: case LMAN_MSG_CLOCK_SLAVE_MS_CHANGE_ERROR_BY_DMA: case LMAN_MSG_RFU_FATAL_ERROR: - GetLinkmanErrorParams(msg); + RfuSetErrorParams(msg); RfuSetStatus(RFU_STATUS_FATAL_ERROR, msg); - Rfu.unk_cdb = FALSE; + gRfu.parentFinished = FALSE; break; } } -void sub_80FB9D0(void) +void RfuSetNormalDisconnectMode(void) { - Rfu.unk_ce4 = 2; + gRfu.disconnectMode = RFU_DISCONNECT_NORMAL; } -void RfuSetStatus(u8 status, u16 msg) +void RfuSetStatus(u8 status, u16 errorInfo) { - Rfu.status = status; - Rfu.linkman_msg = msg; + gRfu.status = status; + gRfu.errorInfo = errorInfo; } u8 RfuGetStatus(void) { - return Rfu.status; + return gRfu.status; } bool32 RfuHasErrored(void) @@ -2433,17 +2519,17 @@ bool32 RfuHasErrored(void) return FALSE; } -bool32 RfuHasFoundNewLeader(void) +bool32 Rfu_IsPlayerExchangeActive(void) { - return Rfu.foundNewLeaderMaybe; + return gRfu.playerExchangeActive; } bool8 Rfu_IsMaster(void) { - return Rfu.parent_child; + return gRfu.parentChild; } -void RFUVSync(void) +void RfuVSync(void) { rfu_LMAN_syncVBlank(); } @@ -2453,14 +2539,15 @@ void ClearRecvCommands(void) CpuFill32(0, gRecvCmds, sizeof(gRecvCmds)); } -static void sub_80FBA64(void) +static void VBlank_RfuIdle(void) { LoadOam(); ProcessSpriteCopyRequests(); TransferPlttBuffer(); } -static void sub_80FBA78(void) +// Unused +static void Debug_RfuIdle(void) { s32 i; @@ -2468,14 +2555,14 @@ static void sub_80FBA78(void) FreeAllSpritePalettes(); ResetTasks(); ResetPaletteFade(); - SetVBlankCallback(sub_80FBA64); + SetVBlankCallback(VBlank_RfuIdle); if (IsWirelessAdapterConnected()) { gLinkType = LINKTYPE_TRADE; SetWirelessCommType1(); OpenLink(); SeedRng(gMain.vblankCounter2); - for (i = 0; i < RFU_CHILD_MAX; i++) + for (i = 0; i < TRAINER_ID_LENGTH; i++) gSaveBlock2Ptr->playerTrainerId[i] = Random() % 256; SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_BG0_ON | DISPCNT_BG2_ON | DISPCNT_OBJ_1D_MAP); @@ -2483,29 +2570,29 @@ static void sub_80FBA78(void) AnimateSprites(); BuildOamBuffer(); UpdatePaletteFade(); - LinkRfu_CreateIdleTask(); - SetMainCallback2(sub_80FBB74); + CreateTask_RfuIdle(); + SetMainCallback2(CB2_RfuIdle); } } bool32 IsUnionRoomListenTaskActive(void) { - return FuncIsActiveTask(Task_LinkRfu_UnionRoomListen); + return FuncIsActiveTask(Task_UnionRoomListen); } -void LinkRfu_CreateIdleTask(void) +void CreateTask_RfuIdle(void) { - if (!FuncIsActiveTask(Task_idle)) - Rfu.idleTaskId = CreateTask(Task_idle, 0); + if (!FuncIsActiveTask(Task_Idle)) + gRfu.idleTaskId = CreateTask(Task_Idle, 0); } -void LinkRfu_DestroyIdleTask(void) +void DestroyTask_RfuIdle(void) { - if (FuncIsActiveTask(Task_idle) == TRUE) - DestroyTask(Rfu.idleTaskId); + if (FuncIsActiveTask(Task_Idle) == TRUE) + DestroyTask(gRfu.idleTaskId); } -static void sub_80FBB74(void) +static void CB2_RfuIdle(void) { RunTasks(); AnimateSprites(); @@ -2513,35 +2600,35 @@ static void sub_80FBB74(void) UpdatePaletteFade(); } -void InitializeRfuLinkManager_LinkLeader(u32 availSlots) +void InitializeRfuLinkManager_LinkLeader(u32 groupMax) { - Rfu.parent_child = MODE_PARENT; - CopyPlayerNameToUnameBuffer(); - rfu_LMAN_initializeManager(LmanCallback_Parent2, NULL); + gRfu.parentChild = MODE_PARENT; + SetHostRfuUsername(); + rfu_LMAN_initializeManager(LinkManagerCB_Parent, NULL); sRfuReqConfig = sRfuReqConfigTemplate; - sRfuReqConfig.availSlot_flag = sAvailSlots[availSlots - 1]; - CreateTask_LinkLeaderSearchForChildren(); + sRfuReqConfig.availSlot_flag = sAvailSlots[groupMax - 1]; + CreateTask_ParentSearchForChildren(); } void InitializeRfuLinkManager_JoinGroup(void) { - Rfu.parent_child = MODE_CHILD; - CopyPlayerNameToUnameBuffer(); - rfu_LMAN_initializeManager(LmanCallback_Child, MscCallback_Child); - CreateTask_JoinGroupSearchForParent(); + gRfu.parentChild = MODE_CHILD; + SetHostRfuUsername(); + rfu_LMAN_initializeManager(LinkManagerCB_Child, MscCallback_Child); + CreateTask_ChildSearchForParent(); } void InitializeRfuLinkManager_EnterUnionRoom(void) { if (QL_IS_PLAYBACK_STATE) return; - Rfu.parent_child = 2; - CopyPlayerNameToUnameBuffer(); - rfu_LMAN_initializeManager(LmanCallback_Parent, NULL); + gRfu.parentChild = MODE_P_C_SWITCH; + SetHostRfuUsername(); + rfu_LMAN_initializeManager(LinkManagerCB_UnionRoom, NULL); sRfuReqConfig = sRfuReqConfigTemplate; sRfuReqConfig.linkRecovery_enable = 0; sRfuReqConfig.linkRecovery_period = 600; - Rfu.searchTaskId = CreateTask(Task_LinkRfu_UnionRoomListen, 1); + gRfu.searchTaskId = CreateTask(Task_UnionRoomListen, 1); } static u16 ReadU16(const void *ptr) @@ -2557,169 +2644,186 @@ static u16 ReadU16(const void *ptr) * Returns 0xFF if not found. * ================================================================ */ -static u8 GetPartnerIndexByNameAndTrainerID(const u8 *trainerName, u16 trainerId) +static u8 GetPartnerIndexByNameAndTrainerID(const u8 *name, u16 trainerId) { u8 i; - u8 ret = 0xFF; + u8 idx = 0xFF; for (i = 0; i < RFU_CHILD_MAX; i++) { - u16 partnerTrainerId = ReadU16(((struct RfuGameData *)gRfuLinkStatus->partner[i].gname)->unk_00.playerTrainerId); + u16 partnerTrainerId = ReadU16(((struct RfuGameData *)gRfuLinkStatus->partner[i].gname)->compatibility.playerTrainerId); if (IsRfuSerialNumberValid(gRfuLinkStatus->partner[i].serialNo) - && !StringCompare(trainerName, gRfuLinkStatus->partner[i].uname) + && !StringCompare(name, gRfuLinkStatus->partner[i].uname) && trainerId == partnerTrainerId) { - ret = i; + idx = i; if (gRfuLinkStatus->partner[i].slot != 0xFF) break; } } - return ret; + return idx; } -static void RfuReqDisconnectSlot(u32 bmDisconnectSlot) +static void RfuReqDisconnectSlot(u32 slot) { - rfu_REQ_disconnect(bmDisconnectSlot); + rfu_REQ_disconnect(slot); rfu_waitREQComplete(); - Rfu.bm_PartnerFlags &= ~(bmDisconnectSlot); - rfu_clearSlot(TYPE_UNI_SEND, Rfu.unk_cda); - rfu_UNI_setSendData(Rfu.bm_PartnerFlags, Rfu.recvCmds, 70); - Rfu.unk_cda = CountTrailingZeroes(Rfu.bm_PartnerFlags); + gRfu.parentSlots &= ~slot; + rfu_clearSlot(TYPE_UNI_SEND, gRfu.parentSendSlot); + rfu_UNI_setSendData(gRfu.parentSlots, gRfu.recvCmds, sizeof(gRfu.recvCmds)); + gRfu.parentSendSlot = Rfu_GetIndexOfNewestChild(gRfu.parentSlots); } void RequestDisconnectSlotByTrainerNameAndId(const u8 *trainerName, u16 trainerId) { - u8 var = GetPartnerIndexByNameAndTrainerID(trainerName, trainerId); - if (var != 0xFF) - RfuReqDisconnectSlot(1 << var); + u8 index = GetPartnerIndexByNameAndTrainerID(trainerName, trainerId); + if (index != 0xFF) + RfuReqDisconnectSlot(1 << index); } -void sub_80FBD6C(u32 a0) +void Rfu_DisconnectPlayerById(u32 playerIdx) { - if (a0 != 0) + if (playerIdx != 0) { s32 i; - u8 var = 0; + u8 toDisconnect = 0; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (Rfu.linkPlayerIdx[i] == a0 && (Rfu.bm_PartnerFlags >> i) & 1) - var |= 1 << i; + if (gRfu.linkPlayerIdx[i] == playerIdx && (gRfu.parentSlots >> i) & 1) + toDisconnect |= 1 << i; } - if (var) - sub_80FBE20(var, 2); + if (toDisconnect) + SendDisconnectCommand(toDisconnect, RFU_DISCONNECT_NORMAL); } } -static void sub_80FBDB8(u8 taskId) +#define tDisconnectPlayers data[0] +#define tDisconnectMode data[1] + +static void Task_SendDisconnectCommand(u8 taskId) { - if (IsSendCmdComplete() && !Rfu.foundNewLeaderMaybe) + if (IsSendCmdComplete() && !gRfu.playerExchangeActive) { - RfuPrepareSendBuffer(RFUCMD_PARENT_DISCONNECT); - gSendCmd[1] = gTasks[taskId].data[0]; - gSendCmd[2] = gTasks[taskId].data[1]; - Rfu.playerCount -= sNumSetBits[gTasks[taskId].data[0]]; - gSendCmd[3] = Rfu.playerCount; + RfuPrepareSendBuffer(RFUCMD_DISCONNECT); + gSendCmd[1] = gTasks[taskId].tDisconnectPlayers; + gSendCmd[2] = gTasks[taskId].tDisconnectMode; + gRfu.playerCount -= sPlayerBitsToCount[gTasks[taskId].tDisconnectPlayers]; + gSendCmd[3] = gRfu.playerCount; DestroyTask(taskId); } } -static void sub_80FBE20(u32 a0, u32 a1) +static void SendDisconnectCommand(u32 playersToDisconnect, u32 disconnectMode) { - u8 taskId = FindTaskIdByFunc(sub_80FBDB8); - if (taskId == 0xFF) + u8 taskId = FindTaskIdByFunc(Task_SendDisconnectCommand); + if (taskId == TASK_NONE) { - taskId = CreateTask(sub_80FBDB8, 5); - gTasks[taskId].data[0] = a0; + taskId = CreateTask(Task_SendDisconnectCommand, 5); + gTasks[taskId].tDisconnectPlayers = playersToDisconnect; } else { - gTasks[taskId].data[0] |= a0; + // Task is already active, just add the new players to disconnect + gTasks[taskId].tDisconnectPlayers |= playersToDisconnect; } - gTasks[taskId].data[1] = a1; + gTasks[taskId].tDisconnectMode = disconnectMode; } +#undef tDisconnectPlayers +#undef tDisconnectMode + +#define tTime data[15] + static void Task_RfuReconnectWithParent(u8 taskId) { s16 *data = gTasks[taskId].data; - if (ContactedByParentAttemptingToReconnect()) + if (CanTryReconnectParent()) { u8 id = GetPartnerIndexByNameAndTrainerID((u8 *)data, ReadU16(&data[8])); if (id != 0xFF) { if (gRfuLinkStatus->partner[id].slot != 0xFF) { - Rfu.reconnectedParentIdx = id; - if (IsParentSuccessfullyReconnected()) + gRfu.reconnectParentId = id; + if (TryReconnectParent()) DestroyTask(taskId); } - else if (GetHostRFUtgtGname()->activity == ACTIVITY_WCARD2 || GetHostRFUtgtGname()->activity == ACTIVITY_WNEWS2) + else if (GetHostRfuGameData()->activity == ACTIVITY_WCARD2 + || GetHostRfuGameData()->activity == ACTIVITY_WNEWS2) { - data[15]++; + tTime++; } else { - RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, 0x7000); + // Error, unable to reconnect to parent + RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_6 | F_RFU_ERROR_7); DestroyTask(taskId); } } else { - data[15]++; - Rfu.reconnectedParentIdx = id; + tTime++; + gRfu.reconnectParentId = id; } } else { - data[15]++; + tTime++; } - if (data[15] > 240) + if (tTime > 240) { - RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, 0x7000); + // Timeout error + RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_6 | F_RFU_ERROR_7); DestroyTask(taskId); } } -void CreateTask_RfuReconnectWithParent(const u8 *trainerName, u16 trainerId) +#undef tTime + +void CreateTask_RfuReconnectWithParent(const u8 *name, u16 trainerId) { u8 taskId; s16 *data; - Rfu.status = RFU_STATUS_OK; + gRfu.status = RFU_STATUS_OK; taskId = CreateTask(Task_RfuReconnectWithParent, 3); data = gTasks[taskId].data; - StringCopy((u8 *)(data), trainerName); + StringCopy((u8 *)(data), name); data[8] = trainerId; } -static bool32 ShouldRejectPartnerConnectionBasedOnActivity(s16 activity, struct RfuGameData *partnerGname) +static bool32 IsPartnerActivityIncompatible(s16 activity, struct RfuGameData *partner) { - if (GetHostRFUtgtGname()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) + if (GetHostRfuGameData()->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) { - if (partnerGname->activity != (ACTIVITY_CHAT | IN_UNION_ROOM)) + // Host trying to chat, but partner isn't + if (partner->activity != (ACTIVITY_CHAT | IN_UNION_ROOM)) return TRUE; } - else if (partnerGname->activity != IN_UNION_ROOM) + else if (partner->activity != IN_UNION_ROOM) { + // Partner not in union room return TRUE; } else if (activity == (ACTIVITY_TRADE | IN_UNION_ROOM)) { - struct RfuGameData *myTradeGname = (struct RfuGameData *)&Rfu.tgtData.gname; - if (myTradeGname->species == SPECIES_EGG) + // Verify that the trade offered hasn't changed + struct RfuGameData *original = (struct RfuGameData *)&gRfu.parent.gname; + if (original->tradeSpecies == SPECIES_EGG) { - if (partnerGname->species == myTradeGname->species) + if (partner->tradeSpecies == original->tradeSpecies) return FALSE; else return TRUE; } - else if (partnerGname->species != myTradeGname->species - || partnerGname->level != myTradeGname->level - || partnerGname->type != myTradeGname->type) + else if (partner->tradeSpecies != original->tradeSpecies + || partner->tradeLevel != original->tradeLevel + || partner->tradeType != original->tradeType) { return TRUE; } @@ -2728,79 +2832,92 @@ static bool32 ShouldRejectPartnerConnectionBasedOnActivity(s16 activity, struct return FALSE; } -static void sub_80FC028(u8 taskId) +#define tTime data[0] +#define tActivity data[1] + +static void Task_TryConnectToUnionRoomParent(u8 taskId) { - if (Rfu.status == RFU_STATUS_NEW_CHILD_DETECTED) + // Stop task if player is the new parent + if (gRfu.status == RFU_STATUS_NEW_CHILD_DETECTED) DestroyTask(taskId); if (++gTasks[taskId].data[0] > 300) { - RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, 0x7000); + // Timeout error + RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_6 | F_RFU_ERROR_7); DestroyTask(taskId); } - if (Rfu.parentId != 0 && lman.parent_child == MODE_CHILD) + // Check if parent should be searched for + if (gRfu.parentId != 0 && lman.parent_child == MODE_CHILD) { - u16 trainerId = ReadU16(((struct RfuGameData *)&Rfu.tgtData.gname)->unk_00.playerTrainerId); - u8 id = GetPartnerIndexByNameAndTrainerID(Rfu.tgtData.uname, trainerId); + // Search for parent + u16 trainerId = ReadU16(((struct RfuGameData *)&gRfu.parent.gname)->compatibility.playerTrainerId); + u8 id = GetPartnerIndexByNameAndTrainerID(gRfu.parent.uname, trainerId); if (id != 0xFF) { - if (!ShouldRejectPartnerConnectionBasedOnActivity(gTasks[taskId].data[1], (struct RfuGameData *)&gRfuLinkStatus->partner[id].gname)) + // Parent found, try to connect + if (!IsPartnerActivityIncompatible(gTasks[taskId].data[1], (struct RfuGameData *)&gRfuLinkStatus->partner[id].gname)) { if (gRfuLinkStatus->partner[id].slot != 0xFF && !rfu_LMAN_CHILD_connectParent(gRfuLinkStatus->partner[id].id, 90)) { - Rfu.state = 10; + // Succesfully connected to parent + gRfu.state = RFUSTATE_CONNECTED; DestroyTask(taskId); } } else { - RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, 0x7000); + // Incompatible partner activity + RfuSetStatus(RFU_STATUS_CONNECTION_ERROR, F_RFU_ERROR_5 | F_RFU_ERROR_6 | F_RFU_ERROR_7); DestroyTask(taskId); } } } } -void sub_80FC114(const u8 *name, struct RfuGameData *structPtr, u8 activity) +void TryConnectToUnionRoomParent(const u8 *name, struct RfuGameData *parent, u8 activity) { - u8 taskId, taskId2; + u8 taskId, listenTaskId; - Rfu.unk_ccf = 0; - Rfu.status = RFU_STATUS_OK; - StringCopy(Rfu.tgtData.uname, name); - memcpy(Rfu.tgtData.gname, structPtr, RFU_GAME_NAME_LENGTH); + gRfu.connectParentFailures = 0; + gRfu.status = RFU_STATUS_OK; + StringCopy(gRfu.parent.uname, name); + memcpy(gRfu.parent.gname, parent, RFU_GAME_NAME_LENGTH); rfu_LMAN_forceChangeSP(); - taskId = CreateTask(sub_80FC028, 2); - gTasks[taskId].data[1] = activity; - taskId2 = FindTaskIdByFunc(Task_LinkRfu_UnionRoomListen); + taskId = CreateTask(Task_TryConnectToUnionRoomParent, 2); + gTasks[taskId].tActivity = activity; + listenTaskId = FindTaskIdByFunc(Task_UnionRoomListen); if (activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) { - if (taskId2 != 0xFF) - gTasks[taskId2].data[7] = 1; + if (listenTaskId != TASK_NONE) + gTasks[listenTaskId].tConnectingForChat = TRUE; } else { - if (taskId2 != 0xFF) - gTasks[taskId2].data[7] = 0; + if (listenTaskId != TASK_NONE) + gTasks[listenTaskId].tConnectingForChat = FALSE; } } bool8 IsRfuRecoveringFromLinkLoss(void) { - if (Rfu.linkLossRecoveryState == 1) + if (gRfu.linkLossRecoveryState == 1) return TRUE; else return FALSE; } -bool32 sub_80FC1CC(void) +bool32 IsRfuCommunicatingWithAllChildren(void) { s32 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if ((lman.acceptSlot_flag >> i) & 1 && Rfu.partnerSendStatuses[i] == 0) + // RFU_STATUS_OK is the default status. + // If any connected child is receiving a status other + // than OK, then the parent is communicating with them + if ((lman.acceptSlot_flag >> i) & 1 && gRfu.partnerSendStatuses[i] == RFU_STATUS_OK) return FALSE; } @@ -2812,30 +2929,17 @@ static void Debug_PrintEmpty(void) s32 i; for (i = 0; i < 20; i++) - Debug_PrintString(" ", 0, i); + Debug_PrintString(sASCII_30Spaces, 0, i); } -static const char gUnknown_843EE47[16] = { - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - '\0' -}; - -static const char gUnknown_843EE57[9] = { - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - '\0' -}; - -static const char gUnknown_843EE60[] = {' ', '\0'}; -static const char gUnknown_843EE62[] = {'*', '\0'}; - static void Debug_PrintStatus(void) { s32 i, j; - Debug_PrintNum(GetBlockReceivedStatus(), 0x1C, 0x13, 2); - Debug_PrintNum(gRfuLinkStatus->connSlotFlag, 0x14, 1, 1); - Debug_PrintNum(gRfuLinkStatus->linkLossSlotFlag, 0x17, 1, 1); - if (Rfu.parent_child == MODE_PARENT) + Debug_PrintNum(GetBlockReceivedStatus(), 28, 19, 2); + Debug_PrintNum(gRfuLinkStatus->connSlotFlag, 20, 1, 1); + Debug_PrintNum(gRfuLinkStatus->linkLossSlotFlag, 23, 1, 1); + if (gRfu.parentChild == MODE_PARENT) { for (i = 0; i < RFU_CHILD_MAX; i++) { @@ -2843,29 +2947,27 @@ static void Debug_PrintStatus(void) { Debug_PrintNum(gRfuLinkStatus->partner[i].serialNo, 1, i + 3, 4); Debug_PrintString((void *) &gRfuLinkStatus->partner[i].gname, 6, i + 3); - Debug_PrintString(gRfuLinkStatus->partner[i].uname, 0x16, i + 3); + Debug_PrintString(gRfuLinkStatus->partner[i].uname, 22, i + 3); } } for (i = 0; i < RFU_CHILD_MAX; i++) { - for (j = 0; j < 14; j++) - { - Debug_PrintNum(Rfu.main_UNI_recvBuffer[i][j], j * 2, i + 11, 2); - } + for (j = 0; j < COMM_SLOT_LENGTH; j++) + Debug_PrintNum(gRfu.childRecvBuffer[i][j], j * 2, i + 11, 2); } - Debug_PrintString("NOWSLOT", 1, 0xF); + Debug_PrintString(sASCII_NowSlot, 1, 15); } else if (gRfuLinkStatus->connSlotFlag != 0 && gRfuLinkStatus->getNameFlag != 0) { for (i = 0; i < RFU_CHILD_MAX; i++) { Debug_PrintNum(0, 1, i + 3, 4); - Debug_PrintString(gUnknown_843EE47, 6, i + 3); - Debug_PrintString(gUnknown_843EE57, 0x16, i + 3); + Debug_PrintString(sASCII_15Spaces, 6, i + 3); + Debug_PrintString(sASCII_8Spaces, 22, i + 3); } - Debug_PrintNum(gRfuLinkStatus->partner[Rfu.child_slot].serialNo, 1, 3, 4); - Debug_PrintString(gRfuLinkStatus->partner[Rfu.child_slot].gname, 6, 3); - Debug_PrintString(gRfuLinkStatus->partner[Rfu.child_slot].uname, 0x16, 3); + Debug_PrintNum(gRfuLinkStatus->partner[gRfu.childSlot].serialNo, 1, 3, 4); + Debug_PrintString(gRfuLinkStatus->partner[gRfu.childSlot].gname, 6, 3); + Debug_PrintString(gRfuLinkStatus->partner[gRfu.childSlot].uname, 22, 3); } else { @@ -2875,43 +2977,29 @@ static void Debug_PrintStatus(void) { Debug_PrintNum(gRfuLinkStatus->partner[i].serialNo, 1, i + 3, 4); Debug_PrintNum(gRfuLinkStatus->partner[i].id, 6, i + 3, 4); - Debug_PrintString(gRfuLinkStatus->partner[i].uname, 0x16, i + 3); + Debug_PrintString(gRfuLinkStatus->partner[i].uname, 22, i + 3); } } for (; i < RFU_CHILD_MAX; i++) { Debug_PrintNum(0, 1, i + 3, 4); - Debug_PrintString(gUnknown_843EE47, 6, i + 3); - Debug_PrintString(gUnknown_843EE57, 0x16, i + 3); + Debug_PrintString(sASCII_15Spaces, 6, i + 3); + Debug_PrintString(sASCII_8Spaces, 22, i + 3); } } } -static const char gUnknown_843EE6C[][12] = { - " ", - "CLOCK DRIFT", - "BUSY SEND ", - "CMD REJECT ", - "CLOCK SLAVE" -}; - -static const char gUnknown_843EEA8[][8] = { - "CHILD ", - "PARENT", - "SEARCH" -}; - static u32 GetRfuSendQueueLength(void) { - return Rfu.sendQueue.count; + return gRfu.sendQueue.count; } u32 GetRfuRecvQueueLength(void) { - return Rfu.recvQueue.count; + return gRfu.recvQueue.count; } -static void Task_idle(u8 taskId) +static void Task_Idle(u8 taskId) { } diff --git a/src/link_rfu_3.c b/src/link_rfu_3.c index 647658c7e..f47b71829 100644 --- a/src/link_rfu_3.c +++ b/src/link_rfu_3.c @@ -298,10 +298,8 @@ void RfuRecvQueue_Reset(struct RfuRecvQueue *queue) for (i = 0; i < RECV_QUEUE_NUM_SLOTS; i++) { - for (j = 0; j < RECV_QUEUE_SLOT_LENGTH; j++) - { + for (j = 0; j < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; j++) queue->slots[i][j] = 0; - } } queue->send_slot = 0; queue->recv_slot = 0; @@ -316,10 +314,8 @@ void RfuSendQueue_Reset(struct RfuSendQueue *queue) for (i = 0; i < SEND_QUEUE_NUM_SLOTS; i++) { - for (j = 0; j < SEND_QUEUE_SLOT_LENGTH; j++) - { + for (j = 0; j < COMM_SLOT_LENGTH; j++) queue->slots[i][j] = 0; - } } queue->send_slot = 0; queue->recv_slot = 0; @@ -356,26 +352,20 @@ void RfuRecvQueue_Enqueue(struct RfuRecvQueue *queue, u8 *src) imeBak = REG_IME; REG_IME = 0; count = 0; - for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i += RECV_QUEUE_SLOT_LENGTH / MAX_RFU_PLAYERS) + for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i += COMM_SLOT_LENGTH) { if (src[i] == 0 && src[i + 1] == 0) - { count++; - } } if (count != MAX_RFU_PLAYERS) { - for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) queue->slots[queue->recv_slot][i] = src[i]; - } queue->recv_slot++; queue->recv_slot %= RECV_QUEUE_NUM_SLOTS; queue->count++; - for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) src[i] = 0; - } } REG_IME = imeBak; } @@ -394,26 +384,20 @@ void RfuSendQueue_Enqueue(struct RfuSendQueue *queue, u8 *src) { imeBak = REG_IME; REG_IME = 0; - for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++) + for (i = 0; i < COMM_SLOT_LENGTH; i++) { if (src[i] != 0) - { break; - } } - if (i != SEND_QUEUE_SLOT_LENGTH) + if (i != COMM_SLOT_LENGTH) { - for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH; i++) queue->slots[queue->recv_slot][i] = src[i]; - } queue->recv_slot++; queue->recv_slot %= SEND_QUEUE_NUM_SLOTS; queue->count++; - for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH; i++) src[i] = 0; - } } REG_IME = imeBak; } @@ -432,17 +416,13 @@ bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue *queue, u8 *dest) REG_IME = 0; if (queue->recv_slot == queue->send_slot || queue->full) { - for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) dest[i] = 0; - } REG_IME = imeBak; return FALSE; } - for (i = 0; i < RECV_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) dest[i] = queue->slots[queue->send_slot][i]; - } queue->send_slot++; queue->send_slot %= RECV_QUEUE_NUM_SLOTS; queue->count--; @@ -456,15 +436,11 @@ bool8 RfuSendQueue_Dequeue(struct RfuSendQueue *queue, u8 *dest) u16 imeBak; if (queue->recv_slot == queue->send_slot || queue->full) - { return FALSE; - } imeBak = REG_IME; REG_IME = 0; - for (i = 0; i < SEND_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH; i++) dest[i] = queue->slots[queue->send_slot][i]; - } queue->send_slot++; queue->send_slot %= SEND_QUEUE_NUM_SLOTS; queue->count--; @@ -482,10 +458,8 @@ void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *dest) } else { - for (i = 0; i < BACKUP_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH; i++) queue->slots[queue->recv_slot][i] = dest[i]; - } queue->recv_slot++; queue->recv_slot %= BACKUP_QUEUE_NUM_SLOTS; if (queue->count < BACKUP_QUEUE_NUM_SLOTS) @@ -509,10 +483,8 @@ bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *dest) } if (dest != NULL) { - for (i = 0; i < BACKUP_QUEUE_SLOT_LENGTH; i++) - { + for (i = 0; i < COMM_SLOT_LENGTH; i++) dest[i] = queue->slots[queue->send_slot][i]; - } } queue->send_slot++; queue->send_slot %= BACKUP_QUEUE_NUM_SLOTS; @@ -672,30 +644,30 @@ static u8 GetConnectedChildStrength(u8 maxFlags) return 0; } -void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 started, s32 child_sprite_genders) +void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 startedActivity, s32 partnerInfo) { s32 i; for (i = 0; i < 2; i++) { - data->unk_00.playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i]; + data->compatibility.playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i]; } for (i = 0; i < RFU_CHILD_MAX; i++) { - data->child_sprite_gender[i] = child_sprite_genders; - child_sprite_genders >>= 8; + data->partnerInfo[i] = partnerInfo; + partnerInfo >>= 8; } data->playerGender = gSaveBlock2Ptr->playerGender; data->activity = activity; - data->started = started; - data->unk_00.language = GAME_LANGUAGE; - data->unk_00.version = GAME_VERSION; - data->unk_00.hasNews = FALSE; - data->unk_00.hasCard = FALSE; - data->unk_00.unknown = FALSE; - data->unk_00.isChampion = FlagGet(FLAG_SYS_CAN_LINK_WITH_RS); - data->unk_00.hasNationalDex = IsNationalPokedexEnabled(); - data->unk_00.gameClear = FlagGet(FLAG_SYS_GAME_CLEAR); + data->startedActivity = startedActivity; + data->compatibility.language = GAME_LANGUAGE; + data->compatibility.version = GAME_VERSION; + data->compatibility.hasNews = FALSE; + data->compatibility.hasCard = FALSE; + data->compatibility.unknown = FALSE; + data->compatibility.isChampion = FlagGet(FLAG_SYS_CAN_LINK_WITH_RS); + data->compatibility.hasNationalDex = IsNationalPokedexEnabled(); + data->compatibility.gameClear = FlagGet(FLAG_SYS_GAME_CLEAR); } /* @@ -749,7 +721,7 @@ bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx) bool8 LinkRfu_GetNameIfSerial7F7D(struct RfuGameData *gname, u8 *uname, u8 idx) { bool8 retVal = FALSE; - if (gRfuLinkStatus->partner[idx].serialNo == RFU_SERIAL_7F7D) + if (gRfuLinkStatus->partner[idx].serialNo == RFU_SERIAL_WONDER_DISTRIBUTOR) { memcpy(gname, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); memcpy(uname, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); diff --git a/src/main.c b/src/main.c index 368638022..5efaaf6d1 100644 --- a/src/main.c +++ b/src/main.c @@ -358,7 +358,7 @@ extern void ProcessDma3Requests(void); static void VBlankIntr(void) { if (gWirelessCommType) - RFUVSync(); + RfuVSync(); else if (!gLinkVSyncDisabled) LinkVSync(); diff --git a/src/mystery_gift_menu.c b/src/mystery_gift_menu.c index 3dfce13a0..380e0b264 100644 --- a/src/mystery_gift_menu.c +++ b/src/mystery_gift_menu.c @@ -354,7 +354,7 @@ void vblankcb_mystery_gift_e_reader_run(void) TransferPlttBuffer(); } -void c2_mystery_gift_e_reader_run(void) +void CB2_MysteryGiftEReader(void) { RunTasks(); RunTextPrinters(); @@ -434,7 +434,7 @@ void c2_mystery_gift(void) { if (HandleMysteryGiftOrEReaderSetup(0)) { - SetMainCallback2(c2_mystery_gift_e_reader_run); + SetMainCallback2(CB2_MysteryGiftEReader); gGiftIsFromEReader = FALSE; task_add_00_mystery_gift(); } @@ -444,7 +444,7 @@ void c2_ereader(void) { if (HandleMysteryGiftOrEReaderSetup(1)) { - SetMainCallback2(c2_mystery_gift_e_reader_run); + SetMainCallback2(CB2_MysteryGiftEReader); gGiftIsFromEReader = TRUE; task_add_00_ereader(); } diff --git a/src/overworld.c b/src/overworld.c index 8c6037ca3..61e1a1db7 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -3239,7 +3239,7 @@ bool32 IsSendingKeysOverCable(void) static u32 GetLinkSendQueueLength(void) { if (gWirelessCommType != 0) - return Rfu.sendQueue.count; + return gRfu.sendQueue.count; else return gLink.sendQueue.count; } diff --git a/src/party_menu.c b/src/party_menu.c index 7725a3c3d..84b9b5807 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -3851,7 +3851,7 @@ static void CursorCB_Register(u8 taskId) u16 species = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES); u8 isEventLegal = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_EVENT_LEGAL); - switch (CanRegisterMonForTradingBoard(*(struct RfuGameCompatibilityData *)GetHostRFUtgtGname(), species2, species, isEventLegal)) + switch (CanRegisterMonForTradingBoard(*(struct RfuGameCompatibilityData *)GetHostRfuGameData(), species2, species, isEventLegal)) { case CANT_REGISTER_MON: StringExpandPlaceholders(gStringVar4, gText_PkmnCantBeTradedNow); @@ -3877,7 +3877,7 @@ static void CursorCB_Trade1(u8 taskId) u16 species2 = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES2); u16 species = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES); u8 isEventLegal = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_EVENT_LEGAL); - u32 stringId = GetUnionRoomTradeMessageId(*(struct RfuGameCompatibilityData *)GetHostRFUtgtGname(), gPartnerTgtGnameSub, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal); + u32 stringId = GetUnionRoomTradeMessageId(*(struct RfuGameCompatibilityData *)GetHostRfuGameData(), gPartnerTgtGnameSub, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal); if (stringId != UR_TRADE_MSG_NONE) { diff --git a/src/pokemon_jump.c b/src/pokemon_jump.c index 39e13f786..c2e89b8be 100644 --- a/src/pokemon_jump.c +++ b/src/pokemon_jump.c @@ -2540,7 +2540,7 @@ static int GetPlayersAtJumpPeak(void) static bool32 AreLinkQueuesEmpty(void) { - return !Rfu.recvQueue.count && !Rfu.sendQueue.count; + return !gRfu.recvQueue.count && !gRfu.sendQueue.count; } static int GetNumPlayersForBonus(u8 *arg0) diff --git a/src/rfu_union_tool.c b/src/rfu_union_tool.c index dc9782d47..51b6106d5 100644 --- a/src/rfu_union_tool.c +++ b/src/rfu_union_tool.c @@ -524,17 +524,17 @@ static void AssembleGroup(u32 group, struct RfuGameData * gname) { return; } - SpawnGroupMember(group, 0, GetUnionRoomPlayerGraphicsId(gname->playerGender, gname->unk_00.playerTrainerId[0]), gname); + SpawnGroupMember(group, 0, GetUnionRoomPlayerGraphicsId(gname->playerGender, gname->compatibility.playerTrainerId[0]), gname); } for (i = 1; i < 5; i++) { - if (gname->child_sprite_gender[i - 1] == 0) + if (gname->partnerInfo[i - 1] == 0) { DespawnGroupMember(group, i); } else if (IsUnionRoomPlayerFacingTileAt(group, i, x, y) == FALSE && IsUnionRoomPlayerFacingTileAt(group, i, x2, y2) == FALSE) { - SpawnGroupMember(group, i, GetUnionRoomPlayerGraphicsId((gname->child_sprite_gender[i - 1] >> 3) & 1, gname->child_sprite_gender[i - 1] & 7), gname); + SpawnGroupMember(group, i, GetUnionRoomPlayerGraphicsId((gname->partnerInfo[i - 1] >> 3) & 1, gname->partnerInfo[i - 1] & 7), gname); } } } @@ -546,7 +546,7 @@ static void SpawnGroupLeaderAndMembers(u32 group, struct RfuGameData * gname) { case 0x40: case 0x54: - SpawnGroupLeader(group, gname->playerGender, gname->unk_00.playerTrainerId[0]); + SpawnGroupLeader(group, gname->playerGender, gname->compatibility.playerTrainerId[0]); for (i = 0; i < 5; i++) { DespawnGroupMember(group, i); diff --git a/src/trade.c b/src/trade.c index 9687bc988..e8ada5673 100644 --- a/src/trade.c +++ b/src/trade.c @@ -759,7 +759,7 @@ static void CB2_ReturnFromLinkTrade2(void) { SetWirelessCommType1(); OpenLink(); - LinkRfu_CreateIdleTask(); + CreateTask_RfuIdle(); } else { @@ -802,13 +802,13 @@ static void CB2_ReturnFromLinkTrade2(void) case 4: if (gReceivedRemoteLinkPlayers == TRUE && IsLinkPlayerDataExchangeComplete() == TRUE) { - LinkRfu_DestroyIdleTask(); + DestroyTask_RfuIdle(); CalculatePlayerPartyCount(); gMain.state++; sTradeMenuResourcesPtr->loadUISpritesState = 0; if (gWirelessCommType) { - ToggleLMANlinkRecovery(TRUE); + Rfu_SetLinkRecovery(TRUE); SetLinkStandbyCallback(); } } @@ -2019,7 +2019,7 @@ static void TradeMenuCB_12(void) static void TradeMenuCB_16(void) { - if (!ToggleLMANlinkRecovery(FALSE)) + if (!Rfu_SetLinkRecovery(FALSE)) { SetLinkStandbyCallback(); sTradeMenuResourcesPtr->tradeMenuCBnum = 13; diff --git a/src/union_room.c b/src/union_room.c index 5369225de..c4c7e7a27 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -646,12 +646,12 @@ static const u8 sUnref_84570D1[] = _("{DYNAMIC 00}·{DYNAMIC 01}"); #define IntlConvPartnerUname7(dest, arg1) ({ \ StringCopy_PlayerName(dest, (arg1).gname_uname.uname); \ - ConvertInternationalString(dest, (arg1).gname_uname.gname.unk_00.language); \ + ConvertInternationalString(dest, (arg1).gname_uname.gname.compatibility.language); \ }) #define IntlConvPartnerUname(dest, arg1) ({ \ StringCopy(dest, (arg1).gname_uname.uname); \ - ConvertInternationalString(dest, (arg1).gname_uname.gname.unk_00.language); \ + ConvertInternationalString(dest, (arg1).gname_uname.gname.compatibility.language); \ }) #define CopyTrainerCardData(dest, src, _version) ({ \ @@ -744,7 +744,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) case 0: sPlayerCurrActivity = sLinkGroupToActivityAndCapacity[gSpecialVar_0x8004]; sPlayerActivityGroupSize = sLinkGroupToActivityAndCapacity[gSpecialVar_0x8004] >> 8; - SetHostRFUtgtGname(sPlayerCurrActivity, 0, 0); + SetHostRfuGameData(sPlayerCurrActivity, 0, 0); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_LinkLeader(sPlayerActivityGroupSize & 0xF); @@ -819,19 +819,19 @@ static void Task_TryBecomeLinkLeader(u8 taskId) if ((sPlayerActivityGroupSize >> 4) != 0 && data->playerCount > (sPlayerActivityGroupSize >> 4) - 1 && (sPlayerActivityGroupSize & 0xF) != 0 - && sub_80FC1CC() + && IsRfuCommunicatingWithAllChildren() && JOY_NEW(START_BUTTON)) { data->state = 15; LinkRfu_StopManagerAndFinalizeSlots(); } - if (data->state == 6 && sub_80FA5D4()) + if (data->state == 6 && RfuTryDisconnectLeavingChildren()) { data->state = 9; } break; case 9: - if (!sub_80FA5D4()) + if (!RfuTryDisconnectLeavingChildren()) { data->state = 6; data->playerCount = UnionRoomLeaderField0CompactionAndCount(data->field_0); @@ -861,21 +861,21 @@ static void Task_TryBecomeLinkLeader(u8 taskId) } break; case 11: - switch (UnionRoomHandleYesNo(&data->textState, CheckTrainerHasLeftByIdAndName( - ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), + switch (UnionRoomHandleYesNo(&data->textState, HasTrainerLeftPartnersList( + ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname))) { case 0: LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); data->field_19 = 5; - SendByteToPartnerByIdAndName(5, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + SendRfuStatusToPartner(5, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); data->state = 12; break; case 1: case -1: data->field_19 = 6; - SendByteToPartnerByIdAndName(6, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + SendRfuStatusToPartner(6, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); data->state = 12; break; case -3: @@ -884,7 +884,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) } break; case 12: - val = WaitSendByteToPartnerByIdAndName(ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + val = WaitSendRfuStatusToPartner(ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); if (val == 1) { // Xfer complete @@ -918,7 +918,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) else { // Sent "no" - RequestDisconnectSlotByTrainerNameAndId(data->field_0->arr[data->playerCount].gname_uname.uname, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId)); + RequestDisconnectSlotByTrainerNameAndId(data->field_0->arr[data->playerCount].gname_uname.uname, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId)); data->field_0->arr[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; UnionRoomLeaderField0CompactionAndCount(data->field_0); RedrawListMenu(data->listTaskId); @@ -1287,7 +1287,7 @@ static void Task_TryJoinLinkGroup(u8 taskId) switch (data->state) { case 0: - SetHostRFUtgtGname(sLinkGroupToURoomActivity[gSpecialVar_0x8004], 0, 0); + SetHostRfuGameData(sLinkGroupToURoomActivity[gSpecialVar_0x8004], 0, 0); sPlayerCurrActivity = sLinkGroupToURoomActivity[gSpecialVar_0x8004]; SetWirelessCommType1(); OpenLink(); @@ -1343,7 +1343,7 @@ static void Task_TryJoinLinkGroup(u8 taskId) u32 unusedVar; unusedVar = data->field_0->arr[id].gname_uname.gname.activity; - if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[id].gname_uname.gname.started) + if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[id].gname_uname.gname.startedActivity) { u32 var = IsTryingToTradeWithHoennTooSoon(data, id); if (var == 0) @@ -1536,11 +1536,11 @@ static u32 IsTryingToTradeWithHoennTooSoon(struct UnkStruct_Group * arg0, s32 id { struct UnkStruct_x20 * structPtr = &arg0->field_0->arr[id]; - if (sPlayerCurrActivity == ACTIVITY_TRADE && structPtr->gname_uname.gname.unk_00.version != VERSION_FIRE_RED && structPtr->gname_uname.gname.unk_00.version != VERSION_LEAF_GREEN) + if (sPlayerCurrActivity == ACTIVITY_TRADE && structPtr->gname_uname.gname.compatibility.version != VERSION_FIRE_RED && structPtr->gname_uname.gname.compatibility.version != VERSION_LEAF_GREEN) { if (!(gSaveBlock2Ptr->specialSaveWarpFlags & CHAMPION_SAVEWARP)) return 1; - else if (structPtr->gname_uname.gname.unk_00.isChampion) + else if (structPtr->gname_uname.gname.compatibility.isChampion) return 0; } else @@ -1558,8 +1558,8 @@ static void AskToJoinRfuGroup(struct UnkStruct_Group * data, s32 id) CreateWirelessStatusIndicatorSprite(0, 0); RedrawListMenu(data->listTaskId); IntlConvPartnerUname7(gStringVar1, data->field_0->arr[data->leaderId]); - UpdateGameDataWithActivitySpriteGendersFlag(sLinkGroupToURoomActivity[gSpecialVar_0x8004], 0, TRUE); - CreateTask_RfuReconnectWithParent(data->field_0->arr[data->leaderId].gname_uname.uname, ReadAsU16(data->field_0->arr[data->leaderId].gname_uname.gname.unk_00.playerTrainerId)); + UpdateGameData_SetActivity(sLinkGroupToURoomActivity[gSpecialVar_0x8004], 0, TRUE); + CreateTask_RfuReconnectWithParent(data->field_0->arr[data->leaderId].gname_uname.uname, ReadAsU16(data->field_0->arr[data->leaderId].gname_uname.gname.compatibility.playerTrainerId)); } u8 CreateTask_ListenToWireless(void) @@ -1585,11 +1585,11 @@ static void Task_ListenToWireless(u8 taskId) switch (data->state) { case 0: - SetHostRFUtgtGname(0, 0, 0); + SetHostRfuGameData(0, 0, 0); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); - sub_80FB128(TRUE); + RfuSetIgnoreError(TRUE); data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); data->field_0 = AllocZeroed(16 * sizeof(struct UnkStruct_x20)); data->state = 2; @@ -1649,7 +1649,7 @@ static u8 URoomGroupListGetTextColor(struct UnkStruct_Group * data, u32 id) { if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - if (data->field_0->arr[id].gname_uname.gname.started) + if (data->field_0->arr[id].gname_uname.gname.startedActivity) return UR_COLOR_WHT_WHT_LTE; else if (data->field_0->arr[id].field_1A_1) return UR_COLOR_RED_WHT_LTR; @@ -1976,7 +1976,7 @@ static void Task_StartActivity(u8 taskId) else { LinkRfu_StopManagerBeforeEnteringChat(); - SetHostRFUtgtGname(ACTIVITY_CHAT | IN_UNION_ROOM, 0, 1); + SetHostRfuGameData(ACTIVITY_CHAT | IN_UNION_ROOM, 0, 1); } EnterUnionRoomChat(); break; @@ -2076,8 +2076,8 @@ static void Task_MEvent_Leader(u8 taskId) case 0: sPlayerCurrActivity = data->activity; sPlayerActivityGroupSize = 2; - SetHostRFUtgtGname(data->activity, 0, 0); - SetGnameBufferWonderFlags(FALSE, FALSE); + SetHostRfuGameData(data->activity, 0, 0); + SetHostRfuWonderFlags(FALSE, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_LinkLeader(2); @@ -2145,19 +2145,19 @@ static void Task_MEvent_Leader(u8 taskId) data->field_0->arr[data->playerCount].field_1B = 0; RedrawListMenu(data->listTaskId); data->field_19 = 5; - SendByteToPartnerByIdAndName(5, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + SendRfuStatusToPartner(5, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); data->state = 8; break; case 1: case -1: data->field_19 = 6; - SendByteToPartnerByIdAndName(6, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + SendRfuStatusToPartner(6, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); data->state = 8; break; } break; case 8: - val = WaitSendByteToPartnerByIdAndName(ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + val = WaitSendRfuStatusToPartner(ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); if (val == 1) { if (data->field_19 == 5) @@ -2172,7 +2172,7 @@ static void Task_MEvent_Leader(u8 taskId) } else { - RequestDisconnectSlotByTrainerNameAndId(data->field_0->arr[data->playerCount].gname_uname.uname, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.unk_00.playerTrainerId)); + RequestDisconnectSlotByTrainerNameAndId(data->field_0->arr[data->playerCount].gname_uname.uname, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId)); data->field_0->arr[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; UnionRoomLeaderField0CompactionAndCount(data->field_0); RedrawListMenu(data->listTaskId); @@ -2283,7 +2283,7 @@ static void Task_CardOrNewsWithFriend(u8 taskId) switch (data->state) { case 0: - SetHostRFUtgtGname(data->cardOrNews + ACTIVITY_WCARD2, 0, 0); + SetHostRfuGameData(data->cardOrNews + ACTIVITY_WCARD2, 0, 0); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); @@ -2338,14 +2338,14 @@ static void Task_CardOrNewsWithFriend(u8 taskId) u32 unusedVar; unusedVar = data->field_0->arr[id].gname_uname.gname.activity; - if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[id].gname_uname.gname.started) + if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[id].gname_uname.gname.startedActivity) { data->leaderId = id; LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); RedrawListMenu(data->listTaskId); IntlConvPartnerUname(gStringVar1, data->field_0->arr[data->leaderId]); - CreateTask_RfuReconnectWithParent(data->field_0->arr[data->leaderId].gname_uname.uname, ReadAsU16(data->field_0->arr[data->leaderId].gname_uname.gname.unk_00.playerTrainerId)); + CreateTask_RfuReconnectWithParent(data->field_0->arr[data->leaderId].gname_uname.uname, ReadAsU16(data->field_0->arr[data->leaderId].gname_uname.gname.compatibility.playerTrainerId)); PlaySE(SE_POKENAV_ON); data->state = 4; } @@ -2449,7 +2449,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId) switch (data->state) { case 0: - SetHostRFUtgtGname(0, 0, 0); + SetHostRfuGameData(0, 0, 0); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); @@ -2498,7 +2498,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId) id = ListMenu_ProcessInput(data->listTaskId); if (data->refreshTimer > 120) { - if (data->field_0->arr[0].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[0].gname_uname.gname.started) + if (data->field_0->arr[0].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[0].gname_uname.gname.startedActivity) { if (GetGnameWonderFlagByLinkGroup(&data->field_0->arr[0].gname_uname.gname, data->cardOrNews + LINK_GROUP_WONDER_CARD)) { @@ -2506,7 +2506,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId) data->refreshTimer = 0; LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); - CreateTask_RfuReconnectWithParent(data->field_0->arr[0].gname_uname.uname, ReadAsU16(data->field_0->arr[0].gname_uname.gname.unk_00.playerTrainerId)); + CreateTask_RfuReconnectWithParent(data->field_0->arr[0].gname_uname.uname, ReadAsU16(data->field_0->arr[0].gname_uname.gname.compatibility.playerTrainerId)); PlaySE(SE_POKENAV_ON); data->state = 4; } @@ -2608,7 +2608,7 @@ void UnionRoomSpecial(void) { struct UnkStruct_URoom * dataPtr; - ClearAndInitHostRFUtgtGname(); + ResetHostRfuGameData(); CreateTask(Task_RunUnionRoom, 10); // dumb line needed to match @@ -2689,8 +2689,8 @@ static void Task_RunUnionRoom(u8 taskId) data->state = 2; break; case 2: - SetHostRFUtgtGname(IN_UNION_ROOM, 0, 0); - RfuUpdatePlayerGnameStateAndSend(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); + SetHostRfuGameData(IN_UNION_ROOM, 0, 0); + SetTradeBoardRegisteredMonInfo(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_EnterUnionRoom(); @@ -2709,11 +2709,11 @@ static void Task_RunUnionRoom(u8 taskId) switch (sUnionRoomTrade.field_0) { case 1: - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); if (id >= PARTY_SIZE) { ResetUnionRoomTrade(&sUnionRoomTrade); - RfuUpdatePlayerGnameStateAndSend(0, 0, 0); + SetTradeBoardRegisteredMonInfo(0, 0, 0); UnionRoom_ScheduleFieldMessageAndExit(gText_UR_RegistrationCanceled); } else if (!RegisterTradeMonAndGetIsEgg(GetCursorSelectionMonId(), &sUnionRoomTrade)) @@ -2734,7 +2734,7 @@ static void Task_RunUnionRoom(u8 taskId) } else { - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); sPlayerCurrActivity = ACTIVITY_TRADE | IN_UNION_ROOM; RegisterTradeMon(GetCursorSelectionMonId(), &sUnionRoomTrade); data->state = 51; @@ -2753,7 +2753,7 @@ static void Task_RunUnionRoom(u8 taskId) { if (gSpecialVar_Result == 9) { - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); PlaySE(SE_PC_LOGIN); StringCopy(gStringVar1, gSaveBlock2Ptr->playerName); data->state = 42; @@ -2761,7 +2761,7 @@ static void Task_RunUnionRoom(u8 taskId) } else if (gSpecialVar_Result == 11) { - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); data->state = 23; gSpecialVar_Result = 0; } @@ -2786,7 +2786,7 @@ static void Task_RunUnionRoom(u8 taskId) } else if (PlayerIsTalkingToUnionRoomAide()) { - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); PlaySE(SE_PC_LOGIN); UR_EnableScriptContext2AndFreezeObjectEvents(); StringCopy(gStringVar1, gSaveBlock2Ptr->playerName); @@ -2805,8 +2805,8 @@ static void Task_RunUnionRoom(u8 taskId) case 4: data->state = 11; UR_EnableScriptContext2AndFreezeObjectEvents(); - RfuUpdatePlayerGnameStateAndSend(0, 0, 0); - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_NPCTALK | IN_UNION_ROOM, GetActivePartnerSpriteGenderParam(data), FALSE); + SetTradeBoardRegisteredMonInfo(0, 0, 0); + UpdateGameData_SetActivity(ACTIVITY_NPCTALK | IN_UNION_ROOM, GetActivePartnerSpriteGenderParam(data), FALSE); break; } HandleUnionRoomPlayerRefresh(data); @@ -2815,21 +2815,21 @@ static void Task_RunUnionRoom(u8 taskId) case 23: if (!FuncIsActiveTask(Task_StartMenuHandleInput)) { - UpdateGameDataWithActivitySpriteGendersFlag(IN_UNION_ROOM, 0, FALSE); + UpdateGameData_SetActivity(IN_UNION_ROOM, 0, FALSE); data->state = 4; } break; case 24: UR_RunTextPrinters_CheckPrinter0Active(); playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); switch (UnionRoomGetPlayerInteractionResponse(data->field_0, taskData[0], taskData[1], playerGender)) { case 0: data->state = 26; break; case 1: - sub_80FC114(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, sPlayerCurrActivity); + TryConnectToUnionRoomParent(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, sPlayerCurrActivity); data->field_12 = id; // Should be just 0, but won't match any other way. data->state = 25; break; @@ -3014,8 +3014,8 @@ static void Task_RunUnionRoom(u8 taskId) case 0: CopyBgTilemapBufferToVram(0); sPlayerCurrActivity = ACTIVITY_CHAT | IN_UNION_ROOM; - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_CHAT | IN_UNION_ROOM, 0, TRUE); - sub_80FC114(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, sPlayerCurrActivity); + UpdateGameData_SetActivity(ACTIVITY_CHAT | IN_UNION_ROOM, 0, TRUE); + TryConnectToUnionRoomParent(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, sPlayerCurrActivity); data->field_12 = taskData[1]; data->state = 20; taskData[3] = 0; @@ -3044,7 +3044,7 @@ static void Task_RunUnionRoom(u8 taskId) case 1: case 2: playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); if (IsUnionRoomListenTaskActive() == TRUE) UnionRoom_ScheduleFieldMessageAndExit(gTexts_UR_ChatDeclined[playerGender]); else @@ -3060,7 +3060,7 @@ static void Task_RunUnionRoom(u8 taskId) if (RfuHasErrored()) { playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - UpdateGameDataWithActivitySpriteGendersFlag(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); + UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); if (IsUnionRoomListenTaskActive() == TRUE) UnionRoom_ScheduleFieldMessageAndExit(gTexts_UR_ChatDeclined[playerGender]); else @@ -3071,7 +3071,7 @@ static void Task_RunUnionRoom(u8 taskId) break; case 11: PlaySE(SE_DING_DONG); - sub_80F8FA0(); + StopUnionRoomLinkManager(); data->state = 12; data->recvActivityRequest[0] = 0; break; @@ -3107,7 +3107,7 @@ static void Task_RunUnionRoom(u8 taskId) ReceiveUnionRoomActivityPacket(data); if (UnionRoom_HandleContactFromOtherPlayer(data) && JOY_NEW(B_BUTTON)) { - sub_80FBD6C(1); + Rfu_DisconnectPlayerById(1); StringCopy(gStringVar4, gText_UR_ChatEnded); data->state = 36; } @@ -3122,9 +3122,9 @@ static void Task_RunUnionRoom(u8 taskId) case 0: data->playerSendBuffer[0] = ACTIVITY_ACCEPT | IN_UNION_ROOM; if (sPlayerCurrActivity == (ACTIVITY_CHAT | IN_UNION_ROOM)) - UpdateGameDataWithActivitySpriteGendersFlag(sPlayerCurrActivity | IN_UNION_ROOM, GetSinglePartnerSpriteGenderParam(1), FALSE); + UpdateGameData_SetActivity(sPlayerCurrActivity | IN_UNION_ROOM, GetSinglePartnerSpriteGenderParam(1), FALSE); else - UpdateGameDataWithActivitySpriteGendersFlag(sPlayerCurrActivity | IN_UNION_ROOM, GetSinglePartnerSpriteGenderParam(1), TRUE); + UpdateGameData_SetActivity(sPlayerCurrActivity | IN_UNION_ROOM, GetSinglePartnerSpriteGenderParam(1), TRUE); data->field_8->arr[0].field_1B = 0; taskData[3] = 0; @@ -3218,20 +3218,20 @@ static void Task_RunUnionRoom(u8 taskId) } break; case 42: - if (GetHostRFUtgtGname()->species == SPECIES_NONE) + if (GetHostRfuGameData()->tradeSpecies == SPECIES_NONE) { data->state = 43; } else { - if (GetHostRFUtgtGname()->species == SPECIES_EGG) + if (GetHostRfuGameData()->tradeSpecies == SPECIES_EGG) { StringCopy(gStringVar4, gText_UR_CancelRegistrationOfEgg); } else { - StringCopy(gStringVar1, gSpeciesNames[GetHostRFUtgtGname()->species]); - ConvertIntToDecimalStringN(gStringVar2, GetHostRFUtgtGname()->level, STR_CONV_MODE_LEFT_ALIGN, 3); + StringCopy(gStringVar1, gSpeciesNames[GetHostRfuGameData()->tradeSpecies]); + ConvertIntToDecimalStringN(gStringVar2, GetHostRfuGameData()->tradeLevel, STR_CONV_MODE_LEFT_ALIGN, 3); StringExpandPlaceholders(gStringVar4, gText_UR_CancelRegistrationOfMon); } UnionRoom_ScheduleFieldMessageWithFollowupState(44, gStringVar4); @@ -3286,7 +3286,7 @@ static void Task_RunUnionRoom(u8 taskId) case -2: case 18: ResetUnionRoomTrade(&sUnionRoomTrade); - RfuUpdatePlayerGnameStateAndSend(0, 0, 0); + SetTradeBoardRegisteredMonInfo(0, 0, 0); UnionRoom_ScheduleFieldMessageAndExit(gText_UR_RegistrationCanceled); break; default: @@ -3297,7 +3297,7 @@ static void Task_RunUnionRoom(u8 taskId) } break; case 55: - RfuUpdatePlayerGnameStateAndSend(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); + SetTradeBoardRegisteredMonInfo(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); UnionRoom_ScheduleFieldMessageAndExit(gText_UR_RegistraionCompleted); break; case 44: @@ -3316,7 +3316,7 @@ static void Task_RunUnionRoom(u8 taskId) case 56: if (PrintOnTextbox(&data->textState, gText_UR_RegistrationCanceled2)) { - RfuUpdatePlayerGnameStateAndSend(0, 0, 0); + SetTradeBoardRegisteredMonInfo(0, 0, 0); ResetUnionRoomTrade(&sUnionRoomTrade); HandleCancelTrade(TRUE); data->state = 4; @@ -3343,7 +3343,7 @@ static void Task_RunUnionRoom(u8 taskId) data->state = 4; break; default: - switch (IsRequestedTypeAndSpeciesInPlayerParty(data->field_0->arr[var5].gname_uname.gname.type, data->field_0->arr[var5].gname_uname.gname.species)) + switch (IsRequestedTypeAndSpeciesInPlayerParty(data->field_0->arr[var5].gname_uname.gname.tradeType, data->field_0->arr[var5].gname_uname.gname.tradeSpecies)) { case UR_TRADE_MATCH: IntlConvPartnerUname(gStringVar1, data->field_0->arr[var5]); @@ -3352,12 +3352,12 @@ static void Task_RunUnionRoom(u8 taskId) break; case UR_TRADE_NOTYPE: IntlConvPartnerUname(gStringVar1, data->field_0->arr[var5]); - StringCopy(gStringVar2, gTypeNames[data->field_0->arr[var5].gname_uname.gname.type]); + StringCopy(gStringVar2, gTypeNames[data->field_0->arr[var5].gname_uname.gname.tradeType]); UnionRoom_ScheduleFieldMessageWithFollowupState(46, gText_UR_DontHaveTypeTrainerWants); break; case UR_TRADE_NOEGG: IntlConvPartnerUname(gStringVar1, data->field_0->arr[var5]); - StringCopy(gStringVar2, gTypeNames[data->field_0->arr[var5].gname_uname.gname.type]); + StringCopy(gStringVar2, gTypeNames[data->field_0->arr[var5].gname_uname.gname.tradeType]); UnionRoom_ScheduleFieldMessageWithFollowupState(46, gText_UR_DontHaveEggTrainerWants); break; } @@ -3382,9 +3382,9 @@ static void Task_RunUnionRoom(u8 taskId) if (PrintOnTextbox(&data->textState, gText_UR_WhichMonWillYouOffer)) { sUnionRoomTrade.field_0 = 2; - memcpy(&gPartnerTgtGnameSub, &data->field_0->arr[taskData[1]].gname_uname.gname.unk_00, sizeof(gPartnerTgtGnameSub)); - gUnionRoomRequestedMonType = data->field_0->arr[taskData[1]].gname_uname.gname.type; - gUnionRoomOfferedSpecies = data->field_0->arr[taskData[1]].gname_uname.gname.species; + memcpy(&gPartnerTgtGnameSub, &data->field_0->arr[taskData[1]].gname_uname.gname.compatibility, sizeof(gPartnerTgtGnameSub)); + gUnionRoomRequestedMonType = data->field_0->arr[taskData[1]].gname_uname.gname.tradeType; + gUnionRoomOfferedSpecies = data->field_0->arr[taskData[1]].gname_uname.gname.tradeSpecies; gFieldCallback = FieldCB_ContinueScriptUnionRoom; ChooseMonForTradingBoard(PARTY_MENU_TYPE_UNION_ROOM_TRADE, CB2_ReturnToField); BackUpURoomField0ToDecompressionBuffer(data); @@ -3393,7 +3393,7 @@ static void Task_RunUnionRoom(u8 taskId) break; case 51: sPlayerCurrActivity = ACTIVITY_TRADE | IN_UNION_ROOM; - sub_80FC114(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, ACTIVITY_TRADE | IN_UNION_ROOM); + TryConnectToUnionRoomParent(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, ACTIVITY_TRADE | IN_UNION_ROOM); IntlConvPartnerUname(gStringVar1, data->field_0->arr[taskData[1]]); UR_PrintFieldMessage(gTexts_UR_CommunicatingWait[2]); data->state = 25; @@ -3488,11 +3488,11 @@ static void Task_InitUnionRoom(u8 taskId) structPtr->state = 1; break; case 1: - SetHostRFUtgtGname(ACTIVITY_SEARCH, 0, 0); + SetHostRfuGameData(ACTIVITY_SEARCH, 0, 0); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_EnterUnionRoom(); - sub_80FB128(TRUE); + RfuSetIgnoreError(TRUE); structPtr->state = 2; break; case 2: @@ -3519,7 +3519,7 @@ static void Task_InitUnionRoom(u8 taskId) if (structPtr->field_0->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { IntlConvPartnerUname(text, structPtr->field_0->arr[i]); - if (PlayerHasMetTrainerBefore(ReadAsU16(structPtr->field_0->arr[i].gname_uname.gname.unk_00.playerTrainerId), text)) + if (PlayerHasMetTrainerBefore(ReadAsU16(structPtr->field_0->arr[i].gname_uname.gname.compatibility.playerTrainerId), text)) { StringCopy(sUnionRoomPlayerName, text); break; @@ -3659,7 +3659,7 @@ static void Task_SearchForChildOrParent(u8 taskId) { gname_uname = sUnionGnameUnamePair_Dummy; } - if (gname_uname.gname.unk_00.language == LANGUAGE_JAPANESE) + if (gname_uname.gname.compatibility.language == LANGUAGE_JAPANESE) { gname_uname = sUnionGnameUnamePair_Dummy; } @@ -3720,7 +3720,7 @@ static bool32 GetGnameWonderFlagByLinkGroup(struct RfuGameData * gname, s16 link { if (linkGroup == LINK_GROUP_WONDER_CARD) { - if (!gname->unk_00.hasCard) + if (!gname->compatibility.hasCard) { return FALSE; } @@ -3731,7 +3731,7 @@ static bool32 GetGnameWonderFlagByLinkGroup(struct RfuGameData * gname, s16 link } else if (linkGroup == LINK_GROUP_WONDER_NEWS) { - if (!gname->unk_00.hasNews) + if (!gname->compatibility.hasNews) { return FALSE; } @@ -4078,7 +4078,7 @@ static bool8 AreGnameUnameDifferent(struct UnionGnameUnamePair * left, const str for (i = 0; i < 2; i++) { - if (left->gname.unk_00.playerTrainerId[i] != right->gname.unk_00.playerTrainerId[i]) + if (left->gname.compatibility.playerTrainerId[i] != right->gname.compatibility.playerTrainerId[i]) { return TRUE; } @@ -4100,32 +4100,22 @@ static bool32 AreUnionRoomPlayerGnamesDifferent(struct UnionGnameUnamePair * lef s32 i; if (left->gname.activity != right->gname.activity) - { return TRUE; - } - if (left->gname.started != right->gname.started) - { + if (left->gname.startedActivity != right->gname.startedActivity) return TRUE; - } for (i = 0; i < RFU_CHILD_MAX; i++) { - if (left->gname.child_sprite_gender[i] != right->gname.child_sprite_gender[i]) - { + if (left->gname.partnerInfo[i] != right->gname.partnerInfo[i]) return TRUE; - } } - if (left->gname.species != right->gname.species) - { + if (left->gname.tradeSpecies != right->gname.tradeSpecies) return TRUE; - } - if (left->gname.type != right->gname.type) - { + if (left->gname.tradeType != right->gname.tradeType) return TRUE; - } return FALSE; } @@ -4185,7 +4175,7 @@ static void PrintUnionRoomGroupOnWindow(u8 windowId, u8 x, u8 y, struct UnkStruc { IntlConvPartnerUname(uname, *group); UR_AddTextPrinterParameterized(windowId, 2, uname, x, y, colorIdx); - ConvertIntToDecimalStringN(id_str, group->gname_uname.gname.unk_00.playerTrainerId[0] | (group->gname_uname.gname.unk_00.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); + ConvertIntToDecimalStringN(id_str, group->gname_uname.gname.compatibility.playerTrainerId[0] | (group->gname_uname.gname.compatibility.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); StringCopy(gStringVar4, gText_UR_ID); StringAppend(gStringVar4, id_str); x += 77; @@ -4202,7 +4192,7 @@ static void PrintGroupMemberCandidateOnWindowWithColor(u8 windowId, u8 x, u8 y, { IntlConvPartnerUname(uname, *group); UR_AddTextPrinterParameterized(windowId, 2, uname, x, y, colorIdx); - ConvertIntToDecimalStringN(id_str, group->gname_uname.gname.unk_00.playerTrainerId[0] | (group->gname_uname.gname.unk_00.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); + ConvertIntToDecimalStringN(id_str, group->gname_uname.gname.compatibility.playerTrainerId[0] | (group->gname_uname.gname.compatibility.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); StringCopy(gStringVar4, gText_UR_ID); StringAppend(gStringVar4, id_str); x += 71; @@ -4250,7 +4240,7 @@ static u32 ConvPartnerUnameAndGetWhetherMetAlready(struct UnkStruct_x20 * x20) { u8 sp0[30]; IntlConvPartnerUname(sp0, *x20); - return PlayerHasMetTrainerBefore(ReadAsU16(x20->gname_uname.gname.unk_00.playerTrainerId), sp0); + return PlayerHasMetTrainerBefore(ReadAsU16(x20->gname_uname.gname.compatibility.playerTrainerId), sp0); } static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 * main0, u8 overrideGender, u8 playerIdx, u32 playerGender) @@ -4259,10 +4249,10 @@ static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 * main0, struct UnkStruct_x20 * x20 = &main0->arr[playerIdx]; - if (!x20->gname_uname.gname.started && overrideGender == 0) + if (!x20->gname_uname.gname.startedActivity && overrideGender == 0) { IntlConvPartnerUname(gStringVar1, *x20); - metBefore = PlayerHasMetTrainerBefore(ReadAsU16(x20->gname_uname.gname.unk_00.playerTrainerId), gStringVar1); + metBefore = PlayerHasMetTrainerBefore(ReadAsU16(x20->gname_uname.gname.compatibility.playerTrainerId), gStringVar1); if (x20->gname_uname.gname.activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) { StringExpandPlaceholders(gStringVar4, gTexts_UR_JoinChat[metBefore][playerGender]); @@ -4279,7 +4269,7 @@ static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 * main0, IntlConvPartnerUname(gStringVar1, *x20); if (overrideGender != 0) { - playerGender = (x20->gname_uname.gname.unk_00.playerTrainerId[overrideGender + 1] >> 3) & 1; + playerGender = (x20->gname_uname.gname.compatibility.playerTrainerId[overrideGender + 1] >> 3) & 1; } switch (x20->gname_uname.gname.activity & 0x3F) { @@ -4310,9 +4300,9 @@ static void nullsub_92(u8 windowId, u32 itemId, u8 y) static void TradeBoardPrintItemInfo(u8 windowId, u8 y, struct RfuGameData * gname, const u8 * uname, u8 colorIdx) { u8 level_t[4]; - u16 species = gname->species; - u8 type = gname->type; - u8 level = gname->level; + u16 species = gname->tradeSpecies; + u8 type = gname->tradeType; + u8 level = gname->tradeLevel; UR_AddTextPrinterParameterized(windowId, 2, uname, 8, y, colorIdx); if (species == SPECIES_EGG) @@ -4337,8 +4327,8 @@ static void TradeBoardListMenuItemPrintFunc(u8 windowId, u32 itemId, u8 y) if (itemId == -3 && y == sTradeBoardListMenuTemplate.upText_Y) { - rfu = GetHostRFUtgtGname(); - if (rfu->species != SPECIES_NONE) + rfu = GetHostRfuGameData(); + if (rfu->tradeSpecies != SPECIES_NONE) { TradeBoardPrintItemInfo(windowId, y, rfu, gSaveBlock2Ptr->playerName, 5); } @@ -4348,7 +4338,7 @@ static void TradeBoardListMenuItemPrintFunc(u8 windowId, u32 itemId, u8 y) j = 0; for (i = 0; i < UROOM_MAX_GROUP_COUNT; i++) { - if (leader->field_0->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && leader->field_0->arr[i].gname_uname.gname.species != SPECIES_NONE) + if (leader->field_0->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && leader->field_0->arr[i].gname_uname.gname.tradeSpecies != SPECIES_NONE) { j++; } @@ -4369,7 +4359,7 @@ static s32 GetIndexOfNthTradeBoardOffer(struct UnkStruct_x20 * x20, s32 n) for (i = 0; i < UROOM_MAX_GROUP_COUNT; i++) { - if (x20[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && x20[i].gname_uname.gname.species != SPECIES_NONE) + if (x20[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && x20[i].gname_uname.gname.tradeSpecies != SPECIES_NONE) { j++; } @@ -4641,8 +4631,8 @@ static void HandleCancelTrade(bool32 unlockObjs) sPlayerCurrActivity = 0; if (unlockObjs) { - RfuUpdatePlayerGnameStateAndSend(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); - UpdateGameDataWithActivitySpriteGendersFlag(IN_UNION_ROOM, 0, FALSE); + SetTradeBoardRegisteredMonInfo(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); + UpdateGameData_SetActivity(IN_UNION_ROOM, 0, FALSE); } } @@ -4670,7 +4660,7 @@ static u8 GetActivePartnerSpriteGenderParam(struct UnkStruct_URoom * uroom) if (uroom->field_C->arr[i].active) { retVal |= uroom->field_C->arr[i].gname_uname.gname.playerGender << 3; - retVal |= uroom->field_C->arr[i].gname_uname.gname.unk_00.playerTrainerId[0] & 7; + retVal |= uroom->field_C->arr[i].gname_uname.gname.compatibility.playerTrainerId[0] & 7; break; } } diff --git a/src/union_room_chat.c b/src/union_room_chat.c index 191201ec0..a2436575b 100644 --- a/src/union_room_chat.c +++ b/src/union_room_chat.c @@ -324,7 +324,7 @@ static void ChatEntryRoutine_Join(void) sWork->routineState++; // fall through case 1: - if (IsLinkTaskFinished() && !RfuHasFoundNewLeader()) + if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive()) { if (SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer))) sWork->routineState++; @@ -527,14 +527,14 @@ static void ChatEntryRoutine_AskQuitChatting(void) sWork->routineState = 3; break; case 0: - Rfu_UnionRoomChat_StopLinkManager(); + Rfu_StopPartnerSearch(); PrepareSendBuffer_Disband(sWork->sendMessageBuffer); sWork->routineState = 4; break; } break; case 4: - if (IsLinkTaskFinished() && !RfuHasFoundNewLeader() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer))) + if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer))) { if (sWork->multiplayerId == 0) sWork->routineState = 6; @@ -577,15 +577,15 @@ static void ChatEntryRoutine_ExitChat(void) } break; case 3: - if (IsLinkTaskFinished() && !RfuHasFoundNewLeader() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer))) + if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer))) sWork->routineState++; break; case 4: - if ((GetBlockReceivedStatus() & 1) && !RfuHasFoundNewLeader()) + if ((GetBlockReceivedStatus() & 1) && !Rfu_IsPlayerExchangeActive()) sWork->routineState++; break; case 5: - if (IsLinkTaskFinished() && !RfuHasFoundNewLeader()) + if (IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive()) { SetCloseLinkCallback(); sWork->exitDelayTimer = 0; @@ -620,7 +620,7 @@ static void ChatEntryRoutine_Drop(void) } break; case 1: - if (!RunDisplaySubtask(0) && IsLinkTaskFinished() && !RfuHasFoundNewLeader()) + if (!RunDisplaySubtask(0) && IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive()) { SetCloseLinkCallback(); sWork->exitDelayTimer = 0; @@ -666,7 +666,7 @@ static void ChatEntryRoutine_Disbanded(void) } break; case 2: - if (RunDisplaySubtask(0) != TRUE && IsLinkTaskFinished() && !RfuHasFoundNewLeader()) + if (RunDisplaySubtask(0) != TRUE && IsLinkTaskFinished() && !Rfu_IsPlayerExchangeActive()) { SetCloseLinkCallback(); sWork->exitDelayTimer = 0; @@ -704,7 +704,7 @@ static void ChatEntryRoutine_SendMessage(void) sWork->routineState++; // fall through case 1: - if (IsLinkTaskFinished() == TRUE && !RfuHasFoundNewLeader() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer))) + if (IsLinkTaskFinished() == TRUE && !Rfu_IsPlayerExchangeActive() && SendBlock(0, sWork->sendMessageBuffer, sizeof(sWork->sendMessageBuffer))) sWork->routineState++; break; case 2: @@ -1144,7 +1144,7 @@ static void PrepareSendBuffer_Leave(u8 *arg0) arg0[0] = CHAT_MESSAGE_LEAVE; StringCopy(&arg0[1], gSaveBlock2Ptr->playerName); arg0[1 + (PLAYER_NAME_LENGTH + 1)] = sWork->multiplayerId; - sub_80FB9D0(); + RfuSetNormalDisconnectMode(); } static void PrepareSendBuffer_Drop(u8 *arg0) @@ -1355,7 +1355,7 @@ static void Task_ReceiveChatMessage(u8 taskId) } tBlockReceivedStatus = GetBlockReceivedStatus(); - if (!tBlockReceivedStatus && RfuHasFoundNewLeader()) + if (!tBlockReceivedStatus && Rfu_IsPlayerExchangeActive()) return; tI = 0; @@ -1409,13 +1409,13 @@ static void Task_ReceiveChatMessage(u8 taskId) // You're the leader, and the person who left is not you if (GetLinkPlayerCount() == 2) { - Rfu_UnionRoomChat_StopLinkManager(); + Rfu_StopPartnerSearch(); sWork->exitType = CHATEXIT_LEADER_LAST; DestroyTask(taskId); return; } - sub_80FBD6C(tCurrLinkPlayer); + Rfu_DisconnectPlayerById(tCurrLinkPlayer); } tState = 3; @@ -1433,10 +1433,10 @@ static void Task_ReceiveChatMessage(u8 taskId) DestroyTask(taskId); break; case 2: - if (!RfuHasFoundNewLeader()) + if (!Rfu_IsPlayerExchangeActive()) { if (sWork->multiplayerId == 0) - sub_80FB030(sWork->linkPlayerCount); + SetUnionRoomChatPlayerData(sWork->linkPlayerCount); tState = 1; } diff --git a/src/wireless_communication_status_screen.c b/src/wireless_communication_status_screen.c index c9ebe676d..97131a768 100644 --- a/src/wireless_communication_status_screen.c +++ b/src/wireless_communication_status_screen.c @@ -366,7 +366,7 @@ static u32 CountMembersInGroup(struct UnkStruct_x20 * unk20, u32 * counts) k = 0; for (j = 0; j < RFU_CHILD_MAX; j++) { - if (unk20->gname_uname.gname.child_sprite_gender[j] != 0) k++; + if (unk20->gname_uname.gname.partnerInfo[j] != 0) k++; } k++; counts[sCountParams[i][1]] += k; From 75a53efc904d29b416fd7ba5d0b884819d63ff8a Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 7 Nov 2022 14:22:54 -0500 Subject: [PATCH 05/12] Sync link_rfu_3 --- .../wireless_icon.png} | Bin include/link_rfu.h | 33 +- src/link_rfu_2.c | 4 +- src/link_rfu_3.c | 299 ++++++++---------- src/union_room.c | 12 +- 5 files changed, 155 insertions(+), 193 deletions(-) rename graphics/{interface/wireless_link_icon.png => link/wireless_icon.png} (100%) diff --git a/graphics/interface/wireless_link_icon.png b/graphics/link/wireless_icon.png similarity index 100% rename from graphics/interface/wireless_link_icon.png rename to graphics/link/wireless_icon.png diff --git a/include/link_rfu.h b/include/link_rfu.h index f203d30a3..5fe53cfbe 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -29,8 +29,6 @@ #define RECV_QUEUE_NUM_SLOTS 20 #define SEND_QUEUE_NUM_SLOTS 40 #define BACKUP_QUEUE_NUM_SLOTS 2 -#define UNUSED_QUEUE_NUM_SLOTS 2 -#define UNUSED_QUEUE_SLOT_LENGTH 256 #define RFU_PACKET_SIZE 6 @@ -141,8 +139,8 @@ struct RfuBlockSend struct RfuRecvQueue { /* 0x000 */ u8 slots[RECV_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH * MAX_RFU_PLAYERS]; - /* 0x578 */ vu8 recv_slot; - /* 0x579 */ vu8 send_slot; + /* 0x578 */ vu8 recvSlot; + /* 0x579 */ vu8 sendSlot; /* 0x57a */ vu8 count; /* 0x57b */ vu8 full; }; @@ -150,8 +148,8 @@ struct RfuRecvQueue struct RfuSendQueue { /* 0x000 */ u8 slots[SEND_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH]; - /* 0x230 */ vu8 recv_slot; - /* 0x231 */ vu8 send_slot; + /* 0x230 */ vu8 recvSlot; + /* 0x231 */ vu8 sendSlot; /* 0x232 */ vu8 count; /* 0x233 */ vu8 full; }; @@ -159,20 +157,11 @@ struct RfuSendQueue struct RfuBackupQueue { /* 0x00 */ u8 slots[BACKUP_QUEUE_NUM_SLOTS][COMM_SLOT_LENGTH]; - /* 0x1c */ vu8 recv_slot; - /* 0x1d */ vu8 send_slot; + /* 0x1c */ vu8 recvSlot; + /* 0x1d */ vu8 sendSlot; /* 0x1e */ vu8 count; }; -struct RfuUnusedQueue -{ - /* 0x000 */ u8 slots[UNUSED_QUEUE_NUM_SLOTS][UNUSED_QUEUE_SLOT_LENGTH]; - /* 0x200 */ vu8 recv_slot; - /* 0x201 */ vu8 send_slot; - /* 0x202 */ vu8 count; - /* 0x203 */ vu8 full; -}; - struct RfuManager { /* 0x000 */ void (*callback)(void); @@ -296,7 +285,7 @@ bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *dest); void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *dest); bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue * queue, u8 *dest); void RfuSendQueue_Enqueue(struct RfuSendQueue * queue, u8 *src); -void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 started, s32 partnerInfo); +void InitHostRfuGameData(struct RfuGameData *data, u8 activity, bool32 started, s32 partnerInfo); void UpdateGameData_GroupLockedIn(bool8 started); bool32 IsRfuSerialNumberValid(u32 serialNo); bool8 IsRfuRecoveringFromLinkLoss(void); @@ -311,12 +300,12 @@ u32 WaitSendRfuStatusToPartner(u16 trainerId, const u8 *name); void SetHostRfuGameData(u8 activity, u32 partnerInfo, bool32 startedActivity); void InitializeRfuLinkManager_LinkLeader(u32 availSlots); void RequestDisconnectSlotByTrainerNameAndId(const u8 *trainerName, u16 trainerId); -void LinkRfu3_SetGnameUnameFromStaticBuffers(struct RfuGameData *gname, u8 *uname); +void CopyHostRfuGameDataAndUsername(struct RfuGameData *gameData, u8 *username); void InitializeRfuLinkManager_JoinGroup(void); void SendLeaveGroupNotice(void); void CreateTask_RfuReconnectWithParent(const u8 *src, u16 trainerId); void UpdateGameData_SetActivity(u8 activity, u32 partnerInfo, u32 startedActivity); -void RecordMixTrainerNames(void); +void SaveLinkTrainerNames(void); void LinkRfu_CreateConnectionAsParent(); void LinkRfu_StopManagerBeforeEnteringChat(); void SetHostRfuWonderFlags(bool32 hasNews, bool32 hasCard); @@ -328,8 +317,8 @@ void InitializeRfuLinkManager_EnterUnionRoom(void); void Rfu_DisconnectPlayerById(u32 playerIdx); void TryConnectToUnionRoomParent(const u8 *name, struct RfuGameData *parent, u8 activity); bool32 PlayerHasMetTrainerBefore(u16 id, u8 *name); -bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx); -bool8 LinkRfu_GetNameIfSerial7F7D(struct RfuGameData *gname, u8 *uname, u8 idx); +bool8 Rfu_GetCompatiblePlayerData(struct RfuGameData *gameData, u8 *username, u8 idx); +bool8 Rfu_GetWonderDistributorPlayerData(struct RfuGameData *gameData, u8 *username, u8 idx); bool32 Rfu_IsPlayerExchangeActive(void); void Rfu_StopPartnerSearch(void); void RfuSetNormalDisconnectMode(void); diff --git a/src/link_rfu_2.c b/src/link_rfu_2.c index 9257f04b1..480f1874c 100644 --- a/src/link_rfu_2.c +++ b/src/link_rfu_2.c @@ -2057,12 +2057,12 @@ static void SetHostRfuUsername(void) void ResetHostRfuGameData(void) { memset(&gHostRfuGameData, 0, RFU_GAME_NAME_LENGTH); - InitHostRFUtgtGname(&gHostRfuGameData, ACTIVITY_NONE, FALSE, 0); + InitHostRfuGameData(&gHostRfuGameData, ACTIVITY_NONE, FALSE, 0); } void SetHostRfuGameData(u8 activity, u32 partnerInfo, u32 startedActivity) { - InitHostRFUtgtGname(&gHostRfuGameData, activity, startedActivity, partnerInfo); + InitHostRfuGameData(&gHostRfuGameData, activity, startedActivity, partnerInfo); } void SetHostRfuWonderFlags(bool32 hasNews, bool32 hasCard) diff --git a/src/link_rfu_3.c b/src/link_rfu_3.c index f47b71829..21efcaf22 100644 --- a/src/link_rfu_3.c +++ b/src/link_rfu_3.c @@ -6,12 +6,35 @@ #include "link_rfu.h" #include "random.h" -static EWRAM_DATA u8 gWirelessStatusIndicatorSpriteId = 0; +enum { + WIRELESS_STATUS_ANIM_3_BARS, + WIRELESS_STATUS_ANIM_2_BARS, + WIRELESS_STATUS_ANIM_1_BAR, + WIRELESS_STATUS_ANIM_SEARCHING, + WIRELESS_STATUS_ANIM_ERROR, +}; -static const u16 gWirelessLinkIconPalette[] = INCBIN_U16("graphics/interface/wireless_link_icon.gbapal"); +#define TAG_GFX_STATUS_INDICATOR 0xD431 +#define TAG_PAL_STATUS_INDICATOR 0xD432 -static const u32 gWirelessLinkIconPic[] = INCBIN_U32("graphics/interface/wireless_link_icon.4bpp.lz"); +#define UNUSED_QUEUE_NUM_SLOTS 2 +#define UNUSED_QUEUE_SLOT_LENGTH 256 +struct RfuUnusedQueue +{ + u8 slots[UNUSED_QUEUE_NUM_SLOTS][UNUSED_QUEUE_SLOT_LENGTH]; + vu8 recvSlot; + vu8 sendSlot; + vu8 count; + vu8 full; +}; + +static EWRAM_DATA u8 sWirelessStatusIndicatorSpriteId = 0; + +static const u16 sWirelessLinkIconPalette[] = INCBIN_U16("graphics/link/wireless_icon.gbapal"); +static const u32 sWirelessLinkIconPic[] = INCBIN_U32("graphics/link/wireless_icon.4bpp.lz"); + +// Most of the below two tables won't make sense with ASCII encoding. static const u8 sWireless_ASCIItoRSETable[] = { EOS, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x37, @@ -222,8 +245,7 @@ static const struct OamData sWirelessStatusIndicatorOamData = .paletteNum = 0, }; -static const union AnimCmd sWirelessStatusIndicatorAnim0[] = { - // 3 bars +static const union AnimCmd sWirelessStatusIndicator_3Bars[] = { ANIMCMD_FRAME( 4, 5), ANIMCMD_FRAME( 8, 5), ANIMCMD_FRAME(12, 5), @@ -233,8 +255,7 @@ static const union AnimCmd sWirelessStatusIndicatorAnim0[] = { ANIMCMD_JUMP(0) }; -static const union AnimCmd sWirelessStatusIndicatorAnim1[] = { - // 2 bars +static const union AnimCmd sWirelessStatusIndicator_2Bars[] = { ANIMCMD_FRAME( 4, 5), ANIMCMD_FRAME( 8, 5), ANIMCMD_FRAME(12, 10), @@ -242,46 +263,43 @@ static const union AnimCmd sWirelessStatusIndicatorAnim1[] = { ANIMCMD_JUMP(0) }; -static const union AnimCmd sWirelessStatusIndicatorAnim2[] = { - // 1 bar +static const union AnimCmd sWirelessStatusIndicator_1Bar[] = { ANIMCMD_FRAME(4, 5), ANIMCMD_FRAME(8, 5), ANIMCMD_JUMP(0) }; -static const union AnimCmd sWirelessStatusIndicatorAnim3[] = { - // searching +static const union AnimCmd sWirelessStatusIndicator_Searching[] = { ANIMCMD_FRAME( 4, 10), ANIMCMD_FRAME(20, 10), ANIMCMD_JUMP(0) }; -static const union AnimCmd sWirelessStatusIndicatorAnim4[] = { - // error +static const union AnimCmd sWirelessStatusIndicator_Error[] = { ANIMCMD_FRAME(24, 10), ANIMCMD_FRAME( 4, 10), ANIMCMD_JUMP(0) }; static const union AnimCmd *const sWirelessStatusIndicatorAnims[] = { - sWirelessStatusIndicatorAnim0, - sWirelessStatusIndicatorAnim1, - sWirelessStatusIndicatorAnim2, - sWirelessStatusIndicatorAnim3, - sWirelessStatusIndicatorAnim4 + [WIRELESS_STATUS_ANIM_3_BARS] = sWirelessStatusIndicator_3Bars, + [WIRELESS_STATUS_ANIM_2_BARS] = sWirelessStatusIndicator_2Bars, + [WIRELESS_STATUS_ANIM_1_BAR] = sWirelessStatusIndicator_1Bar, + [WIRELESS_STATUS_ANIM_SEARCHING] = sWirelessStatusIndicator_Searching, + [WIRELESS_STATUS_ANIM_ERROR] = sWirelessStatusIndicator_Error }; static const struct CompressedSpriteSheet sWirelessStatusIndicatorSpriteSheet = { - gWirelessLinkIconPic, 0x0380, 0xD431 + sWirelessLinkIconPic, 0x0380, TAG_GFX_STATUS_INDICATOR }; static const struct SpritePalette sWirelessStatusIndicatorSpritePalette = { - gWirelessLinkIconPalette, 0xD432 + sWirelessLinkIconPalette, TAG_PAL_STATUS_INDICATOR }; static const struct SpriteTemplate sWirelessStatusIndicatorSpriteTemplate = { - .tileTag = 0xD431, - .paletteTag = 0xD432, + .tileTag = TAG_GFX_STATUS_INDICATOR, + .paletteTag = TAG_PAL_STATUS_INDICATOR, .oam = &sWirelessStatusIndicatorOamData, .anims = sWirelessStatusIndicatorAnims, .images = NULL, @@ -301,8 +319,8 @@ void RfuRecvQueue_Reset(struct RfuRecvQueue *queue) for (j = 0; j < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; j++) queue->slots[i][j] = 0; } - queue->send_slot = 0; - queue->recv_slot = 0; + queue->sendSlot = 0; + queue->recvSlot = 0; queue->count = 0; queue->full = FALSE; } @@ -317,8 +335,8 @@ void RfuSendQueue_Reset(struct RfuSendQueue *queue) for (j = 0; j < COMM_SLOT_LENGTH; j++) queue->slots[i][j] = 0; } - queue->send_slot = 0; - queue->recv_slot = 0; + queue->sendSlot = 0; + queue->recvSlot = 0; queue->count = 0; queue->full = FALSE; } @@ -331,12 +349,10 @@ static void RfuUnusedQueue_Reset(struct RfuUnusedQueue *queue) for (i = 0; i < UNUSED_QUEUE_NUM_SLOTS; i++) { for (j = 0; j < UNUSED_QUEUE_SLOT_LENGTH; j++) - { queue->slots[i][j] = 0; - } } - queue->send_slot = 0; - queue->recv_slot = 0; + queue->sendSlot = 0; + queue->recvSlot = 0; queue->count = 0; queue->full = FALSE; } @@ -360,9 +376,9 @@ void RfuRecvQueue_Enqueue(struct RfuRecvQueue *queue, u8 *src) if (count != MAX_RFU_PLAYERS) { for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) - queue->slots[queue->recv_slot][i] = src[i]; - queue->recv_slot++; - queue->recv_slot %= RECV_QUEUE_NUM_SLOTS; + queue->slots[queue->recvSlot][i] = src[i]; + queue->recvSlot++; + queue->recvSlot %= RECV_QUEUE_NUM_SLOTS; queue->count++; for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) src[i] = 0; @@ -392,9 +408,9 @@ void RfuSendQueue_Enqueue(struct RfuSendQueue *queue, u8 *src) if (i != COMM_SLOT_LENGTH) { for (i = 0; i < COMM_SLOT_LENGTH; i++) - queue->slots[queue->recv_slot][i] = src[i]; - queue->recv_slot++; - queue->recv_slot %= SEND_QUEUE_NUM_SLOTS; + queue->slots[queue->recvSlot][i] = src[i]; + queue->recvSlot++; + queue->recvSlot %= SEND_QUEUE_NUM_SLOTS; queue->count++; for (i = 0; i < COMM_SLOT_LENGTH; i++) src[i] = 0; @@ -414,7 +430,7 @@ bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue *queue, u8 *dest) imeBak = REG_IME; REG_IME = 0; - if (queue->recv_slot == queue->send_slot || queue->full) + if (queue->recvSlot == queue->sendSlot || queue->full) { for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) dest[i] = 0; @@ -422,9 +438,9 @@ bool8 RfuRecvQueue_Dequeue(struct RfuRecvQueue *queue, u8 *dest) return FALSE; } for (i = 0; i < COMM_SLOT_LENGTH * MAX_RFU_PLAYERS; i++) - dest[i] = queue->slots[queue->send_slot][i]; - queue->send_slot++; - queue->send_slot %= RECV_QUEUE_NUM_SLOTS; + dest[i] = queue->slots[queue->sendSlot][i]; + queue->sendSlot++; + queue->sendSlot %= RECV_QUEUE_NUM_SLOTS; queue->count--; REG_IME = imeBak; return TRUE; @@ -435,14 +451,14 @@ bool8 RfuSendQueue_Dequeue(struct RfuSendQueue *queue, u8 *dest) s32 i; u16 imeBak; - if (queue->recv_slot == queue->send_slot || queue->full) + if (queue->recvSlot == queue->sendSlot || queue->full) return FALSE; imeBak = REG_IME; REG_IME = 0; for (i = 0; i < COMM_SLOT_LENGTH; i++) - dest[i] = queue->slots[queue->send_slot][i]; - queue->send_slot++; - queue->send_slot %= SEND_QUEUE_NUM_SLOTS; + dest[i] = queue->slots[queue->sendSlot][i]; + queue->sendSlot++; + queue->sendSlot %= SEND_QUEUE_NUM_SLOTS; queue->count--; REG_IME = imeBak; return TRUE; @@ -459,17 +475,13 @@ void RfuBackupQueue_Enqueue(struct RfuBackupQueue *queue, const u8 *dest) else { for (i = 0; i < COMM_SLOT_LENGTH; i++) - queue->slots[queue->recv_slot][i] = dest[i]; - queue->recv_slot++; - queue->recv_slot %= BACKUP_QUEUE_NUM_SLOTS; + queue->slots[queue->recvSlot][i] = dest[i]; + queue->recvSlot++; + queue->recvSlot %= BACKUP_QUEUE_NUM_SLOTS; if (queue->count < BACKUP_QUEUE_NUM_SLOTS) - { queue->count++; - } else - { - queue->send_slot = queue->recv_slot; - } + queue->sendSlot = queue->recvSlot; } } @@ -478,16 +490,15 @@ bool8 RfuBackupQueue_Dequeue(struct RfuBackupQueue *queue, u8 *dest) s32 i; if (queue->count == 0) - { return FALSE; - } + if (dest != NULL) { for (i = 0; i < COMM_SLOT_LENGTH; i++) - dest[i] = queue->slots[queue->send_slot][i]; + dest[i] = queue->slots[queue->sendSlot][i]; } - queue->send_slot++; - queue->send_slot %= BACKUP_QUEUE_NUM_SLOTS; + queue->sendSlot++; + queue->sendSlot %= BACKUP_QUEUE_NUM_SLOTS; queue->count--; return TRUE; } @@ -499,11 +510,9 @@ static void RfuUnusedQueue_Dequeue(struct RfuUnusedQueue *queue, u8 *dest) if (queue->count < UNUSED_QUEUE_NUM_SLOTS) { for (i = 0; i < UNUSED_QUEUE_SLOT_LENGTH; i++) - { - queue->slots[queue->recv_slot][i] = dest[i]; - } - queue->recv_slot++; - queue->recv_slot %= UNUSED_QUEUE_NUM_SLOTS; + queue->slots[queue->recvSlot][i] = dest[i]; + queue->recvSlot++; + queue->recvSlot %= UNUSED_QUEUE_NUM_SLOTS; queue->count++; } else @@ -516,16 +525,14 @@ static bool8 RfuUnusedQueue_Enqueue(struct RfuUnusedQueue *queue, u8 *dest) { s32 i; - if (queue->recv_slot == queue->send_slot || queue->full) - { + if (queue->recvSlot == queue->sendSlot || queue->full) return FALSE; - } + for (i = 0; i < UNUSED_QUEUE_SLOT_LENGTH; i++) - { - dest[i] = queue->slots[queue->send_slot][i]; - } - queue->send_slot++; - queue->send_slot %= UNUSED_QUEUE_NUM_SLOTS; + dest[i] = queue->slots[queue->sendSlot][i]; + + queue->sendSlot++; + queue->sendSlot %= UNUSED_QUEUE_NUM_SLOTS; queue->count--; return TRUE; } @@ -593,9 +600,7 @@ static void PkmnStrToASCII(u8 *dest, const u8 *src) s32 i; for (i = 0; src[i] != EOS; i++) - { dest[i] = sWireless_RSEtoASCIITable[src[i]]; - } dest[i] = 0; } @@ -604,9 +609,7 @@ static void ASCIIToPkmnStr(u8 *dest, const u8 *src) s32 i; for (i = 0; src[i] != 0; i++) - { dest[i] = sWireless_ASCIItoRSETable[src[i]]; - } dest[i] = EOS; } @@ -644,18 +647,17 @@ static u8 GetConnectedChildStrength(u8 maxFlags) return 0; } -void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 startedActivity, s32 partnerInfo) +void InitHostRfuGameData(struct RfuGameData *data, u8 activity, bool32 startedActivity, s32 partnerInfo) { s32 i; - for (i = 0; i < 2; i++) - { + for (i = 0; i < (s32)ARRAY_COUNT(data->compatibility.playerTrainerId); i++) data->compatibility.playerTrainerId[i] = gSaveBlock2Ptr->playerTrainerId[i]; - } + for (i = 0; i < RFU_CHILD_MAX; i++) { data->partnerInfo[i] = partnerInfo; - partnerInfo >>= 8; + partnerInfo >>= 8; // Each element is 1 byte } data->playerGender = gSaveBlock2Ptr->playerGender; data->activity = activity; @@ -671,13 +673,13 @@ void InitHostRFUtgtGname(struct RfuGameData *data, u8 activity, bool32 startedAc } /* - * ========================================================== + * ================================================================ * Returns 1 if parent, 0 if child or neutral. - * If partner serial number is valid, copies gname and uname. + * If partner serial number is valid, copies gameData and username. * Otherwise, blanks these. - * ========================================================== + * ================================================================ */ -bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx) +bool8 Rfu_GetCompatiblePlayerData(struct RfuGameData *gameData, u8 *username, u8 idx) { bool8 retVal; @@ -686,13 +688,13 @@ bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx) retVal = TRUE; if (IsRfuSerialNumberValid(gRfuLinkStatus->partner[idx].serialNo) && ((gRfuLinkStatus->getNameFlag >> idx) & 1)) { - memcpy(gname, &gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); - memcpy(uname, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); + memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); + memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); } else { - memset(gname, 0, RFU_GAME_NAME_LENGTH); - memset(uname, 0, RFU_USER_NAME_LENGTH); + memset(gameData, 0, RFU_GAME_NAME_LENGTH); + memset(username, 0, RFU_USER_NAME_LENGTH); } } else @@ -700,45 +702,39 @@ bool8 LinkRfu_GetNameIfCompatible(struct RfuGameData *gname, u8 *uname, u8 idx) retVal = FALSE; if (IsRfuSerialNumberValid(gRfuLinkStatus->partner[idx].serialNo)) { - memcpy(gname, &gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); - memcpy(uname, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); + memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); + memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); } else { - memset(gname, 0, RFU_GAME_NAME_LENGTH); - memset(uname, 0, RFU_USER_NAME_LENGTH); + memset(gameData, 0, RFU_GAME_NAME_LENGTH); + memset(username, 0, RFU_USER_NAME_LENGTH); } } return retVal; } -/* - * ========================================================== - * Specific check for serial number 0x7F7D, - * which comes from ??? - * ========================================================== - */ -bool8 LinkRfu_GetNameIfSerial7F7D(struct RfuGameData *gname, u8 *uname, u8 idx) +bool8 Rfu_GetWonderDistributorPlayerData(struct RfuGameData *gameData, u8 *username, u8 idx) { bool8 retVal = FALSE; if (gRfuLinkStatus->partner[idx].serialNo == RFU_SERIAL_WONDER_DISTRIBUTOR) { - memcpy(gname, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); - memcpy(uname, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); + memcpy(gameData, gRfuLinkStatus->partner[idx].gname, RFU_GAME_NAME_LENGTH); + memcpy(username, gRfuLinkStatus->partner[idx].uname, RFU_USER_NAME_LENGTH); retVal = TRUE; } else { - memset(gname, 0, RFU_GAME_NAME_LENGTH); - memset(uname, 0, RFU_USER_NAME_LENGTH); + memset(gameData, 0, RFU_GAME_NAME_LENGTH); + memset(username, 0, RFU_USER_NAME_LENGTH); } return retVal; } -void LinkRfu3_SetGnameUnameFromStaticBuffers(struct RfuGameData *gname, u8 *uname) +void CopyHostRfuGameDataAndUsername(struct RfuGameData *gameData, u8 *username) { - memcpy(gname, &gHostRfuGameData, RFU_GAME_NAME_LENGTH); - memcpy(uname, gHostRfuUsername, RFU_USER_NAME_LENGTH); + memcpy(gameData, &gHostRfuGameData, RFU_GAME_NAME_LENGTH); + memcpy(username, gHostRfuUsername, RFU_USER_NAME_LENGTH); } #define sNextAnimNum data[0] @@ -765,23 +761,23 @@ void CreateWirelessStatusIndicatorSprite(u8 x, u8 y) gSprites[sprId].sValidator = STATUS_INDICATOR_ACTIVE; gSprites[sprId].sTileStart = GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag); gSprites[sprId].invisible = TRUE; - gWirelessStatusIndicatorSpriteId = sprId; + sWirelessStatusIndicatorSpriteId = sprId; } else { - gWirelessStatusIndicatorSpriteId = CreateSprite(&sWirelessStatusIndicatorSpriteTemplate, x, y, 0); - gSprites[gWirelessStatusIndicatorSpriteId].sValidator = STATUS_INDICATOR_ACTIVE; - gSprites[gWirelessStatusIndicatorSpriteId].sTileStart = GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag); - gSprites[gWirelessStatusIndicatorSpriteId].invisible = TRUE; + sWirelessStatusIndicatorSpriteId = CreateSprite(&sWirelessStatusIndicatorSpriteTemplate, x, y, 0); + gSprites[sWirelessStatusIndicatorSpriteId].sValidator = STATUS_INDICATOR_ACTIVE; + gSprites[sWirelessStatusIndicatorSpriteId].sTileStart = GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag); + gSprites[sWirelessStatusIndicatorSpriteId].invisible = TRUE; } } void DestroyWirelessStatusIndicatorSprite(void) { - if (gSprites[gWirelessStatusIndicatorSpriteId].sValidator == STATUS_INDICATOR_ACTIVE) + if (gSprites[sWirelessStatusIndicatorSpriteId].sValidator == STATUS_INDICATOR_ACTIVE) { - gSprites[gWirelessStatusIndicatorSpriteId].sValidator = 0; - DestroySprite(&gSprites[gWirelessStatusIndicatorSpriteId]); + gSprites[sWirelessStatusIndicatorSpriteId].sValidator = 0; + DestroySprite(&gSprites[sWirelessStatusIndicatorSpriteId]); gMain.oamBuffer[125] = gDummyOamData; CpuCopy16(&gDummyOamData, (struct OamData *)OAM + 125, sizeof(struct OamData)); } @@ -790,11 +786,9 @@ void DestroyWirelessStatusIndicatorSprite(void) void LoadWirelessStatusIndicatorSpriteGfx(void) { if (GetSpriteTileStartByTag(sWirelessStatusIndicatorSpriteSheet.tag) == 0xFFFF) - { LoadCompressedSpriteSheet(&sWirelessStatusIndicatorSpriteSheet); - } LoadSpritePalette(&sWirelessStatusIndicatorSpritePalette); - gWirelessStatusIndicatorSpriteId = 0xFF; + sWirelessStatusIndicatorSpriteId = SPRITE_NONE; } static u8 GetParentSignalStrength(void) @@ -804,19 +798,17 @@ static u8 GetParentSignalStrength(void) for (i = 0; i < RFU_CHILD_MAX; i++) { if (flags & 1) - { return gRfuLinkStatus->strength[i]; - } flags >>= 1; } return 0; } -static void SetAndRestartWirelessStatusIndicatorAnim(struct Sprite *sprite, s32 signalStrengthAnimNum) +static void SetAndRestartWirelessStatusIndicatorAnim(struct Sprite *sprite, s32 animNum) { - if (sprite->sCurrAnimNum != signalStrengthAnimNum) + if (sprite->sCurrAnimNum != animNum) { - sprite->sCurrAnimNum = signalStrengthAnimNum; + sprite->sCurrAnimNum = animNum; sprite->sFrameDelay = 0; sprite->sFrameIdx = 0; } @@ -824,45 +816,38 @@ static void SetAndRestartWirelessStatusIndicatorAnim(struct Sprite *sprite, s32 void UpdateWirelessStatusIndicatorSprite(void) { - if (gWirelessStatusIndicatorSpriteId != 0xFF && gSprites[gWirelessStatusIndicatorSpriteId].sValidator == STATUS_INDICATOR_ACTIVE) + if (sWirelessStatusIndicatorSpriteId != SPRITE_NONE && gSprites[sWirelessStatusIndicatorSpriteId].sValidator == STATUS_INDICATOR_ACTIVE) { - struct Sprite *sprite = &gSprites[gWirelessStatusIndicatorSpriteId]; + struct Sprite *sprite = &gSprites[sWirelessStatusIndicatorSpriteId]; u8 signalStrength = RFU_LINK_ICON_LEVEL4_MAX; u8 i = 0; + + // Get weakest signal strength if (gRfuLinkStatus->parentChild == MODE_PARENT) { for (i = 0; i < GetLinkPlayerCount() - 1; i++) { if (signalStrength >= GetConnectedChildStrength(i + 1)) - { signalStrength = GetConnectedChildStrength(i + 1); - } } } else { signalStrength = GetParentSignalStrength(); } + + // Set signal strength sprite anim number if (IsRfuRecoveringFromLinkLoss() == TRUE) - { - sprite->sNextAnimNum = 4; - } + sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_ERROR; else if (signalStrength <= RFU_LINK_ICON_LEVEL1_MAX) - { - sprite->sNextAnimNum = 3; - } + sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_SEARCHING; else if (signalStrength >= RFU_LINK_ICON_LEVEL2_MIN && signalStrength <= RFU_LINK_ICON_LEVEL2_MAX) - { - sprite->sNextAnimNum = 2; - } + sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_1_BAR; else if (signalStrength >= RFU_LINK_ICON_LEVEL3_MIN && signalStrength <= RFU_LINK_ICON_LEVEL3_MAX) - { - sprite->sNextAnimNum = 1; - } + sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_2_BARS; else if (signalStrength >= RFU_LINK_ICON_LEVEL4_MIN) - { - sprite->sNextAnimNum = 0; - } + sprite->sNextAnimNum = WIRELESS_STATUS_ANIM_3_BARS; + if (sprite->sNextAnimNum != sprite->sSavedAnimNum) { SetAndRestartWirelessStatusIndicatorAnim(sprite, sprite->sNextAnimNum); @@ -873,9 +858,7 @@ void UpdateWirelessStatusIndicatorSprite(void) sprite->sFrameIdx++; sprite->sFrameDelay = 0; if (sprite->anims[sprite->sCurrAnimNum][sprite->sFrameIdx].type == -2) // ANIMCMD_JUMP - { sprite->sFrameIdx = 0; - } } else { @@ -906,7 +889,7 @@ static void CopyTrainerRecord(struct TrainerNameRecord *dest, u32 trainerId, con { int i; dest->trainerId = trainerId; - for (i = 0; i < 7; i++) + for (i = 0; i < PLAYER_NAME_LENGTH; i++) { if (name[i] == EOS) break; @@ -920,9 +903,7 @@ static void ZeroName(u8 *name) s32 i; for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++) - { *name++ = 0; - } } static bool32 NameIsEmpty(const u8 *name) @@ -932,15 +913,13 @@ static bool32 NameIsEmpty(const u8 *name) for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++) { if (*name++ != 0) - { return FALSE; - } } return TRUE; } // Save the currently connected players into the trainer records, shifting all previous records down. -void RecordMixTrainerNames(void) +void SaveLinkTrainerNames(void) { if (gWirelessCommType != 0) { @@ -948,13 +927,13 @@ void RecordMixTrainerNames(void) s32 j; s32 nextSpace; s32 connectedTrainerRecordIndices[5]; - struct TrainerNameRecord *newRecords = AllocZeroed(20 * sizeof(struct TrainerNameRecord)); + struct TrainerNameRecord *newRecords = AllocZeroed(sizeof(gSaveBlock1Ptr->trainerNameRecords)); // Check if we already have a record saved for connected trainers. for (i = 0; i < GetLinkPlayerCount(); i++) { connectedTrainerRecordIndices[i] = -1; - for (j = 0; j < 20; j++) + for (j = 0; j < (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords); j++) { if ((u16)gLinkPlayers[i].trainerId == gSaveBlock1Ptr->trainerNameRecords[j].trainerId && StringCompare(gLinkPlayers[i].name, gSaveBlock1Ptr->trainerNameRecords[j].trainerName) == 0) { @@ -973,29 +952,25 @@ void RecordMixTrainerNames(void) // If we already had a record for this trainer, wipe it so that the next step doesn't duplicate it. if (connectedTrainerRecordIndices[i] >= 0) - { ZeroName(gSaveBlock1Ptr->trainerNameRecords[connectedTrainerRecordIndices[i]].trainerName); - } nextSpace++; } } // Copy all non-empty records to the new list, in the order they appear on the old list. If the list is full, // the last (oldest) records will be dropped. - for (i = 0; i < 20; i++) + for (i = 0; i < (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords); i++) { if (!NameIsEmpty(gSaveBlock1Ptr->trainerNameRecords[i].trainerName)) { CopyTrainerRecord(&newRecords[nextSpace], gSaveBlock1Ptr->trainerNameRecords[i].trainerId, gSaveBlock1Ptr->trainerNameRecords[i].trainerName); - if (++nextSpace >= 20) - { + if (++nextSpace >= (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords)) break; - } } } // Finalize the new list, and clean up. - memcpy(gSaveBlock1Ptr->trainerNameRecords, newRecords, 20 * sizeof(struct TrainerNameRecord)); + memcpy(gSaveBlock1Ptr->trainerNameRecords, newRecords, sizeof(gSaveBlock1Ptr->trainerNameRecords)); Free(newRecords); } } @@ -1004,16 +979,14 @@ bool32 PlayerHasMetTrainerBefore(u16 id, u8 *name) { s32 i; - for (i = 0; i < 20; i++) + for (i = 0; i < (int)ARRAY_COUNT(gSaveBlock1Ptr->trainerNameRecords); i++) { - if (StringCompareN(gSaveBlock1Ptr->trainerNameRecords[i].trainerName, name, 7) == 0 && gSaveBlock1Ptr->trainerNameRecords[i].trainerId == id) - { + if (StringCompareN(gSaveBlock1Ptr->trainerNameRecords[i].trainerName, name, PLAYER_NAME_LENGTH) == 0 + && gSaveBlock1Ptr->trainerNameRecords[i].trainerId == id) return TRUE; - } + if (NameIsEmpty(gSaveBlock1Ptr->trainerNameRecords[i].trainerName)) - { return FALSE; - } } return FALSE; } diff --git a/src/union_room.c b/src/union_room.c index c4c7e7a27..186d09707 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -756,7 +756,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) data->field_8 = AllocZeroed(UROOM_MAX_PARTY_SIZE * sizeof(struct UnkStruct_x20)); BlankUnkStruct_x1CArray(data->field_4->arr, 4); BlankUnkStruct_x20Array(data->field_0->arr, UROOM_MAX_PARTY_SIZE); - LinkRfu3_SetGnameUnameFromStaticBuffers(&data->field_0->arr[0].gname_uname.gname, data->field_0->arr[0].gname_uname.uname); + CopyHostRfuGameDataAndUsername(&data->field_0->arr[0].gname_uname.gname, data->field_0->arr[0].gname_uname.uname); data->field_0->arr[0].field_18 = 0; data->field_0->arr[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; data->field_0->arr[0].field_1A_1 = 0; @@ -1919,7 +1919,7 @@ static void Task_StartActivity(u8 taskId) case ACTIVITY_BPICK: case ACTIVITY_SPINTRADE: case ACTIVITY_ITEMTRADE: - RecordMixTrainerNames(); + SaveLinkTrainerNames(); break; } @@ -2089,7 +2089,7 @@ static void Task_MEvent_Leader(u8 taskId) data->field_8 = AllocZeroed(UROOM_MAX_PARTY_SIZE * sizeof(struct UnkStruct_x20)); BlankUnkStruct_x1CArray(data->field_4->arr, 4); BlankUnkStruct_x20Array(data->field_0->arr, UROOM_MAX_PARTY_SIZE); - LinkRfu3_SetGnameUnameFromStaticBuffers(&data->field_0->arr[0].gname_uname.gname, data->field_0->arr[0].gname_uname.uname); + CopyHostRfuGameDataAndUsername(&data->field_0->arr[0].gname_uname.gname, data->field_0->arr[0].gname_uname.uname); data->field_0->arr[0].field_18 = 0; data->field_0->arr[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; data->field_0->arr[0].field_1A_1 = FALSE; @@ -3654,7 +3654,7 @@ static void Task_SearchForChildOrParent(u8 taskId) for (i = 0; i < RFU_CHILD_MAX; i++) { - parent_child = LinkRfu_GetNameIfCompatible(&gname_uname.gname, gname_uname.uname, i); + parent_child = Rfu_GetCompatiblePlayerData(&gname_uname.gname, gname_uname.uname, i); if (!IsPartnerActivityAcceptable(gname_uname.gname.activity, gTasks[taskId].data[4])) { gname_uname = sUnionGnameUnamePair_Dummy; @@ -3700,7 +3700,7 @@ static void Task_ListenForPartnersWithCompatibleSerialNos(u8 taskId) for (i = 0; i < RFU_CHILD_MAX; i++) { - LinkRfu_GetNameIfCompatible(&ptr[0]->arr[i].gname_uname.gname, ptr[0]->arr[i].gname_uname.uname, i); + Rfu_GetCompatiblePlayerData(&ptr[0]->arr[i].gname_uname.gname, ptr[0]->arr[i].gname_uname.uname, i); if (!IsPartnerActivityAcceptable(ptr[0]->arr[i].gname_uname.gname.activity, gTasks[taskId].data[2])) { ptr[0]->arr[i].gname_uname = sUnionGnameUnamePair_Dummy; @@ -3753,7 +3753,7 @@ static void Task_ListenForPartnersWithSerial7F7D(u8 taskId) for (i = 0; i < RFU_CHILD_MAX; i++) { - if (LinkRfu_GetNameIfSerial7F7D(&ptr[0]->arr[i].gname_uname.gname, ptr[0]->arr[i].gname_uname.uname, i)) + if (Rfu_GetWonderDistributorPlayerData(&ptr[0]->arr[i].gname_uname.gname, ptr[0]->arr[i].gname_uname.uname, i)) { GetGnameWonderFlagByLinkGroup(&ptr[0]->arr[i].gname_uname.gname, gTasks[taskId].data[2]); } From 9983b41c1d0688bcac324336161c8da0f9a78013 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 7 Nov 2022 14:56:34 -0500 Subject: [PATCH 06/12] Sync union room --- data/maps/UnionRoom/scripts.inc | 2 +- data/scripts/cable_club.inc | 2 +- data/specials.inc | 2 +- include/constants/union_room.h | 93 +- include/link_rfu.h | 11 +- include/mevent.h | 4 +- include/mystery_gift_menu.h | 2 +- include/rfu_union_tool.h | 12 +- include/trade.h | 2 +- include/trade_scene.h | 2 +- include/union_room.h | 182 +- src/cable_club.c | 4 +- src/data/union_room.h | 470 +++ src/link_rfu_2.c | 4 +- src/mevent.c | 18 +- src/mystery_gift_menu.c | 69 +- src/party_menu.c | 2 +- src/rfu_union_tool.c | 40 +- src/start_menu.c | 2 +- src/trade.c | 8 +- src/trade_scene.c | 6 +- src/union_room.c | 3456 +++++++++----------- src/wireless_communication_status_screen.c | 56 +- 23 files changed, 2255 insertions(+), 2194 deletions(-) create mode 100644 src/data/union_room.h diff --git a/data/maps/UnionRoom/scripts.inc b/data/maps/UnionRoom/scripts.inc index f75bb1a97..c214b06d3 100644 --- a/data/maps/UnionRoom/scripts.inc +++ b/data/maps/UnionRoom/scripts.inc @@ -29,7 +29,7 @@ UnionRoom_OnResume:: removeobject LOCALID_UNION_ROOM_PLAYER_6 removeobject LOCALID_UNION_ROOM_PLAYER_7 removeobject LOCALID_UNION_ROOM_PLAYER_8 - special UnionRoomSpecial + special RunUnionRoom end UnionRoom_OnTransition:: diff --git a/data/scripts/cable_club.inc b/data/scripts/cable_club.inc index afa923a0a..f725dbaea 100644 --- a/data/scripts/cable_club.inc +++ b/data/scripts/cable_club.inc @@ -796,7 +796,7 @@ CableClub_EventScript_EnterUnionRoom:: special SetCableClubWarp warpspinenter MAP_UNION_ROOM, 7, 11 waitstate - special UnionRoomSpecial + special RunUnionRoom waitstate end diff --git a/data/specials.inc b/data/specials.inc index f16dbb79f..f815d05d6 100644 --- a/data/specials.inc +++ b/data/specials.inc @@ -373,7 +373,7 @@ gSpecials:: def_special IsWirelessAdapterConnected def_special TryBecomeLinkLeader def_special TryJoinLinkGroup - def_special UnionRoomSpecial + def_special RunUnionRoom def_special ShowWirelessCommunicationScreen def_special EnableNationalPokedex def_special SetWalkingIntoSignVars diff --git a/include/constants/union_room.h b/include/constants/union_room.h index b23860645..4016150f0 100644 --- a/include/constants/union_room.h +++ b/include/constants/union_room.h @@ -1,47 +1,51 @@ #ifndef GUARD_CONSTANTS_UNION_ROOM_H #define GUARD_CONSTANTS_UNION_ROOM_H +// The number of possible group leaders visible in the Union Room. +// Note that this is different than the number of people actively +// connected as children via the Wireless Adapter, which cannot +// exceed RFU_CHILD_MAX (4), for a total of 5 including the player. +#define MAX_UNION_ROOM_LEADERS 8 + #define UNION_ROOM_SPAWN_NONE 0 #define UNION_ROOM_SPAWN_IN 1 #define UNION_ROOM_SPAWN_OUT 2 -#define ACTIVITY_NONE 0 -#define ACTIVITY_BATTLE 1 -#define ACTIVITY_DBLBATTLE 2 -#define ACTIVITY_MLTBATTLE 3 -#define ACTIVITY_TRADE 4 -#define ACTIVITY_CHAT 5 -#define ACTIVITY_WCARD 6 -#define ACTIVITY_WNEWS 7 -#define ACTIVITY_CARD 8 -#define ACTIVITY_PJUMP 9 -#define ACTIVITY_BCRUSH 10 -#define ACTIVITY_BPICK 11 -#define ACTIVITY_SEARCH 12 -#define ACTIVITY_SPINTRADE 13 -#define ACTIVITY_ITEMTRADE 14 +#define UNION_ROOM_MAX_LEVEL 30 + +// The number of possible trainer classes for a trainer of a given gender in the Union Room. +// This value is necessarily a power of 2 because of the way it's treated in GetUnionRoomTrainerPic / GetUnionRoomTrainerClass +#define NUM_UNION_ROOM_CLASSES (1 << 3) // 8 + +#define ACTIVITY_NONE 0 +#define ACTIVITY_BATTLE_SINGLE 1 +#define ACTIVITY_BATTLE_DOUBLE 2 +#define ACTIVITY_BATTLE_MULTI 3 +#define ACTIVITY_TRADE 4 +#define ACTIVITY_CHAT 5 +#define ACTIVITY_WONDER_CARD_DUP 6 // Duplicates of later WONDER constants +#define ACTIVITY_WONDER_NEWS_DUP 7 // +#define ACTIVITY_CARD 8 +#define ACTIVITY_POKEMON_JUMP 9 +#define ACTIVITY_BERRY_CRUSH 10 +#define ACTIVITY_BERRY_PICK 11 +#define ACTIVITY_SEARCH 12 +#define ACTIVITY_SPIN_TRADE 13 +#define ACTIVITY_ITEM_TRADE 14 // Replaced with ACTIVITY_BATTLE_TOWER_OPEN in Emerald +#define ACTIVITY_RECORD_CORNER 15 +#define ACTIVITY_BERRY_BLENDER 16 // Player response -#define ACTIVITY_ACCEPT 17 -#define ACTIVITY_DECLINE 18 +#define ACTIVITY_ACCEPT 17 +#define ACTIVITY_DECLINE 18 -#define ACTIVITY_NPCTALK 19 -#define ACTIVITY_PLYRTALK 20 +#define ACTIVITY_NPCTALK 19 +#define ACTIVITY_PLYRTALK 20 -// Duplicate IDs? -#define ACTIVITY_WCARD2 21 -#define ACTIVITY_WNEWS2 22 +#define ACTIVITY_WONDER_CARD 21 +#define ACTIVITY_WONDER_NEWS 22 -#define IN_UNION_ROOM 0x40 - -// Used in UR_AddTextPrinterParameterized -#define UR_COLOR_DKE_WHT_LTE 0 -#define UR_COLOR_RED_WHT_LTR 1 -#define UR_COLOR_GRN_WHT_LTG 2 -#define UR_COLOR_WHT_WHT_LTE 3 -#define UR_COLOR_WHT_DKE_LTE 4 -#define UR_COLOR_GRN_DN6_LTB 5 -#define UR_COLOR_DN5_DN6_LTB 6 +#define IN_UNION_ROOM (1 << 6) #define LINK_GROUP_SINGLE_BATTLE 0 #define LINK_GROUP_DOUBLE_BATTLE 1 @@ -52,9 +56,30 @@ #define LINK_GROUP_BERRY_PICKING 6 #define LINK_GROUP_WONDER_CARD 7 #define LINK_GROUP_WONDER_NEWS 8 -#define NUM_LINK_GROUP_TYPES 9 - #define LINK_GROUP_UNION_ROOM_RESUME 9 #define LINK_GROUP_UNION_ROOM_INIT 10 +#define LINK_GROUP_UNK_11 11 +#define LINK_GROUP_UNK_12 12 +#define NUM_LINK_GROUP_TYPES 13 + +#define UR_TRADE_MATCH 0 +#define UR_TRADE_NOTYPE 1 +#define UR_TRADE_NOEGG 2 + +#define UR_TRADE_READY 0 +#define UR_TRADE_PLAYER_NOT_READY 1 +#define UR_TRADE_PARTNER_NOT_READY 2 + +#define UR_INTERACT_PLAYER_1 1 +#define UR_INTERACT_PLAYER_2 2 +#define UR_INTERACT_PLAYER_3 3 +#define UR_INTERACT_PLAYER_4 4 +#define UR_INTERACT_PLAYER_5 5 +#define UR_INTERACT_PLAYER_6 6 +#define UR_INTERACT_PLAYER_7 7 +#define UR_INTERACT_PLAYER_8 8 +#define UR_INTERACT_ATTENDANT 9 +#define UR_INTERACT_UNUSED 10 +#define UR_INTERACT_START_MENU 11 #endif //GUARD_CONSTANTS_UNION_ROOM_H diff --git a/include/link_rfu.h b/include/link_rfu.h index 5fe53cfbe..47588004c 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -233,17 +233,16 @@ extern struct RfuGameData gHostRfuGameData; extern u8 gHostRfuUsername[]; extern struct RfuManager gRfu; -// GameFreak signatures void AddTextPrinterToWindow1(const u8 *str); -bool32 MG_PrintTextOnWindow1AndWaitButton(u8 * cmdPtr, const u8 * src); +bool32 PrintMysteryGiftMenuMessage(u8 * cmdPtr, const u8 * src); void LinkRfu_FatalError(void); void MG_DrawCheckerboardPattern(void); void Rfu_SetCloseLinkCallback(void); bool8 IsLinkRfuTaskFinished(void); void DestroyWirelessStatusIndicatorSprite(void); -void MEvent_CreateTask_CardOrNewsWithFriend(u32 arg0); -void MEvent_CreateTask_CardOrNewsOverWireless(u32 arg0); -void MEvent_CreateTask_Leader(u32 arg0); +void CreateTask_LinkMysteryGiftWithFriend(u32 arg0); +void CreateTask_LinkMysteryGiftOverWireless(u32 arg0); +void CreateTask_SendMysteryGift(u32 activity); void Rfu_SendPacket(void *data); u8 CreateTask_ListenToWireless(void); void DestroyTask_RfuIdle(void); @@ -268,7 +267,7 @@ u32 GetRfuRecvQueueLength(void); void LinkRfu_Shutdown(void); void CreateTask_RfuIdle(void); bool8 Rfu_SetLinkRecovery(bool32 enable); -void var_800D_set_xB(void); +void SetUsingUnionRoomStartMenu(void); struct RfuGameData *GetHostRfuGameData(void); void UpdateWirelessStatusIndicatorSprite(void); void InitRFU(void); diff --git a/include/mevent.h b/include/mevent.h index 9a273a872..92c664d46 100644 --- a/include/mevent.h +++ b/include/mevent.h @@ -101,8 +101,8 @@ void InitMEventData(void); u16 MEvent_GetBattleCardCount(u32 command); void MysteryGift_TryIncrementStat(u32 eventId, u32 trainerId); u16 *GetMEventProfileECWordsMaybe(void); -void ResetReceivedWonderCardFlag(void); -bool32 MEventHandleReceivedWonderCard(u16 flagId); +void MysteryGift_DisableStats(void); +bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId); u16 GetWonderCardFlagId(void); #endif //GUARD_MEVENT_H diff --git a/include/mystery_gift_menu.h b/include/mystery_gift_menu.h index a25cc598f..82a47fb5f 100644 --- a/include/mystery_gift_menu.h +++ b/include/mystery_gift_menu.h @@ -7,7 +7,7 @@ void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void); void PrintMysteryGiftOrEReaderTopMenu(bool8, bool32); void c2_mystery_gift(void); void CB2_MysteryGiftEReader(void); -s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str); +s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str); void MG_DrawTextBorder(u8 windowId); u16 GetMysteryGiftBaseBlock(void); diff --git a/include/rfu_union_tool.h b/include/rfu_union_tool.h index 7fc7fd4cb..ffecc3f8d 100644 --- a/include/rfu_union_tool.h +++ b/include/rfu_union_tool.h @@ -3,14 +3,14 @@ #include "union_room.h" -u8 ZeroUnionObjWork(struct UnionObj * ptr); -void DeleteUnionObjWorkAndStopTask(void); +u8 ZeroUnionObjWork(struct UnionRoomObject * ptr); +void DestroyUnionRoomPlayerObjects(void); void CreateGroupMemberObjectsInvisible(u8 *spriteIds, s32 group); void DestroyGroupMemberObjects(u8 *spriteIds); void MakeGroupAssemblyAreasPassable(void); -void ScheduleUnionRoomPlayerRefresh(struct UnkStruct_URoom *uroom_p); -void HandleUnionRoomPlayerRefresh(struct UnkStruct_URoom *uroom_p); -bool32 RfuUnionTool_GetGroupAndMemberInFrontOfPlayer(struct UnkStruct_Main0 *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds); -void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct UnkStruct_Main0 *main0_p); +void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p); +void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p); +bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds); +void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct RfuPlayerList *main0_p); #endif //GUARD_UNION_ROOM_PLAYER_AVATAR_H diff --git a/include/trade.h b/include/trade.h index ede68b05d..2380b2213 100644 --- a/include/trade.h +++ b/include/trade.h @@ -13,7 +13,7 @@ extern const u8 gText_FemaleSymbol4[]; extern const u8 gText_GenderlessSymbol[]; extern const u16 gTradeOrHatchMonShadowTilemap[]; -void CB2_ReturnFromLinkTrade(void); +void CB2_StartCreateTradeMenu(void); s32 Trade_CalcLinkPlayerCompatibilityParam(void); s32 CanRegisterMonForTradingBoard(struct RfuGameCompatibilityData rfuPlayer, u16 species2, u16 species, u8 isEventLegal); s32 GetUnionRoomTradeMessageId(struct RfuGameCompatibilityData rfuPlayer, struct RfuGameCompatibilityData rfuPartner, u16 playerSpecies2, u16 partnerSpecies, u8 requestedType, u16 playerSpecies, u8 isEventLegal); diff --git a/include/trade_scene.h b/include/trade_scene.h index 31679eafe..cbe336859 100644 --- a/include/trade_scene.h +++ b/include/trade_scene.h @@ -1,7 +1,7 @@ #ifndef GUARD_TRADE_SCENE_H #define GUARD_TRADE_SCENE_H -void CB2_InitTradeAnim_LinkTrade(void); +void CB2_LinkTrade(void); void CreateInGameTradePokemon(void); void DoInGameTradeScene(void); void DrawTextOnTradeWindow(u8 windowId, const u8 *str, s8 speed); diff --git a/include/union_room.h b/include/union_room.h index c39513ec2..51390c637 100644 --- a/include/union_room.h +++ b/include/union_room.h @@ -3,58 +3,60 @@ #include "global.h" #include "link_rfu.h" +#include "constants/union_room.h" -// Return value of IsRequestedTypeAndSpeciesInPlayerParty -#define UR_TRADE_MATCH 0 -#define UR_TRADE_NOTYPE 1 -#define UR_TRADE_NOEGG 2 +// In the Union Room the player is only ever connected to ≤ 4 other players. +// However, there can be up to MAX_UNION_ROOM_LEADERS (8) object events to +// represent leaders of recently discovered link groups, and each of those groups +// may have up to MAX_RFU_PLAYERS (5) players in it including the leader. +// These players are represented on-screen by NPC sprites drawn around the leader. +// Thus there can be 40 sprites of other players on-screen, in 8 groups of 5. +#define NUM_UNION_ROOM_SPRITES (MAX_UNION_ROOM_LEADERS * MAX_RFU_PLAYERS) -#define UROOM_MAX_GROUP_COUNT 8 -#define UROOM_MAX_PARTY_SIZE 5 +// The maximum number of recently connected players that can be tracked. +// Note that this is significantly less than NUM_UNION_ROOM_SPRITES, i.e. not +// every player that can be shown in the Union Room can be tracked at once. +// Information such as a group member's gender can instead be read from partnerInfo +// of the leader's RfuGameData by tracking at least all of the group leaders. +#define MAX_RFU_PLAYER_LIST_SIZE 16 -struct UnionGnameUnamePair +struct RfuPlayerData { - struct RfuGameData gname; - u8 ALIGNED(4) uname[PLAYER_NAME_LENGTH + 1]; + struct RfuGameData data; + u8 ALIGNED(4) name[RFU_USER_NAME_LENGTH]; }; -struct UnkStruct_x1C +struct RfuPlayer { - struct UnionGnameUnamePair gname_uname; + struct RfuPlayerData rfu; + u16 timeoutCounter; + u8 groupScheduledAnim:2; + bool8 useRedText:1; // Never set + u8 newPlayerCountdown; + u8 unused; +}; + +struct RfuPlayerList +{ + struct RfuPlayer players[0]; // TODO: Should be size MAX_RFU_PLAYER_LIST_SIZE +}; + +struct RfuIncomingPlayer +{ + struct RfuPlayerData rfu; u8 active:1; }; -struct UnkStruct_x20 +struct RfuIncomingPlayerList { - struct UnionGnameUnamePair gname_uname; - u16 field_18; - u8 groupScheduledAnim:2; - bool8 field_1A_1:1; - u8 field_1B; - u32 field_1C; // unused + struct RfuIncomingPlayer players[0]; // TODO: Should be size MAX_RFU_PLAYERS }; -// These arrays are dynamically allocated but must be -// represented as structs to match. -// Don't ask me why. - -// FIXME: Find a way around this. - -struct UnkStruct_Main0 +struct WirelessLink_Leader { - struct UnkStruct_x20 arr[0]; -}; - -struct UnkStruct_Main4 -{ - struct UnkStruct_x1C arr[0]; -}; - -struct UnkStruct_Leader -{ - struct UnkStruct_Main0 * field_0; - struct UnkStruct_Main4 * field_4; - struct UnkStruct_Main0 * field_8; + struct RfuPlayerList * playerList; + struct RfuIncomingPlayerList * incomingPlayerList; + struct RfuPlayerList * playerListBackup; u8 state; u8 textState; u8 delayTimerAfterOk; @@ -63,36 +65,35 @@ struct UnkStruct_Leader u8 nPlayerModeWindowId; u8 listTaskId; u8 playerCount; - u8 messageWindowId; - u8 field_15; - u8 field_16; + u16 yesNoWindowId; + u8 unused; u8 listenTaskId; u8 activity; - u8 field_19; - u16 field_1A; + u8 joinRequestAnswer; + u16 memberConfirmTimeout; }; -struct UnkStruct_Group +struct WirelessLink_Group { - struct UnkStruct_Main0 * field_0; - struct UnkStruct_Main4 * field_4; + struct RfuPlayerList * playerList; + struct RfuIncomingPlayerList * incomingPlayerList; u8 state; u8 textState; - u8 field_A; // unused + u8 delayTimerAfterOk; // unused u8 listWindowId; u8 bButtonCancelWindowId; u8 playerNameAndIdWindowId; u8 listTaskId; u8 leaderId; - u8 field_10; + u8 unused; u8 listenTaskId; - u8 cardOrNews; - u8 field_13; // referenced but never set + bool8 isWonderNews; + bool8 showListMenu; // referenced but never set u8 refreshTimer; u8 delayBeforePrint; }; -struct UnionObj +struct UnionRoomObject { u8 state; u8 gfxId; @@ -100,69 +101,56 @@ struct UnionObj u8 schedAnim; }; -struct UnkStruct_URoom +struct WirelessLink_URoom { - /* 0x000 */ struct UnkStruct_Main0 * field_0; - /* 0x004 */ struct UnkStruct_Main4 * field_4; - /* 0x008 */ struct UnkStruct_Main0 * field_8; - /* 0x00C */ struct UnkStruct_Main4 * field_C; - /* 0x010 */ u16 field_10; - /* 0x012 */ u16 field_12; - /* 0x014 */ u8 state; - /* 0x015 */ u8 stateAfterPrint; - /* 0x016 */ u8 textState; - /* 0x017 */ u8 field_17; - /* 0x018 */ u8 field_18; - /* 0x019 */ u8 field_19; - /* 0x01A */ u8 field_1A; - /* 0x01B */ u8 topListMenuWindowId; - /* 0x01C */ u8 topListMenuListMenuId; - /* 0x01D */ u8 tradeBoardSelectWindowId; - /* 0x01E */ u8 tradeBoardDetailsWindowId; - /* 0x01F */ u8 field_1F; - /* 0x020 */ u8 field_20; - /* 0x021 */ u8 spriteIds[40]; - /* 0x049 */ u8 field_49; - /* 0x04A */ u8 tradeBoardListMenuId; - - // For communication with potential link partners - /* 0x04C */ u16 playerSendBuffer[6]; - /* 0x058 */ u8 activityRequestStrbufs[4][11]; - /* 0x084 */ u16 partnerYesNoResponse; - /* 0x086 */ u16 recvActivityRequest[3]; // activity[, species, level] - /* 0x08C */ struct UnionObj unionObjs[8]; - /* 0x0AC */ u8 trainerCardStrbufs[12][15]; - /* 0x160 */ u8 field_174[48]; - /* 0x190 */ u8 field_1A4[200]; -}; - -union UnkUnion_Main -{ - struct UnkStruct_Leader * leader; - struct UnkStruct_Group * group; - struct UnkStruct_URoom * uRoom; + struct RfuPlayerList * playerList; + struct RfuIncomingPlayerList * incomingChildList; + struct RfuPlayerList * spawnPlayer; + struct RfuIncomingPlayerList * incomingParentList; + u16 unknown; // Never read + u16 unreadPlayerId; + u8 state; + u8 stateAfterPrint; + u8 textState; + u8 filler[4]; + u8 topListMenuWindowId; + u8 topListMenuId; + u8 tradeBoardMainWindowId; + u8 tradeBoardHeaderWindowId; + u8 unused1; + u8 searchTaskId; + u8 spriteIds[NUM_UNION_ROOM_SPRITES]; + u8 unused2; + u8 tradeBoardListMenuId; +// For communication with potential link partners + u16 playerSendBuffer[6]; + u8 activityRequestStrbufs[4][11]; + u16 partnerYesNoResponse; + u16 recvActivityRequest[3]; // activity[, species, level] + struct UnionRoomObject objects[MAX_UNION_ROOM_LEADERS]; + u8 trainerCardStrBuffer[12][15]; + u8 trainerCardColorStrBuffer[48]; + u8 trainerCardMsgStrBuffer[200]; }; struct UnionRoomTrade { - u16 field_0; + u16 state; u16 type; u32 playerPersonality; - u8 field_8; - u8 field_9; + u8 offerPlayerId; u16 playerSpecies; u16 playerLevel; u16 species; u16 level; - u16 field_12; u32 personality; }; -extern struct RfuGameCompatibilityData gPartnerTgtGnameSub; +extern struct RfuGameCompatibilityData gRfuPartnerCompatibilityData; extern u16 gUnionRoomOfferedSpecies; extern u8 gUnionRoomRequestedMonType; void StartUnionRoomBattle(u16 battleFlags); -u8 UnionRoom_CreateTask_CallCB2ReturnFromLinkTrade(void); +u8 CreateTask_CreateTradeMenu(void); #endif //GUARD_UNION_ROOM_H diff --git a/src/cable_club.c b/src/cable_club.c index 1c80945be..b3fbc1f78 100644 --- a/src/cable_club.c +++ b/src/cable_club.c @@ -897,7 +897,7 @@ static void Task_StartWiredTrade(u8 taskId) case 3: if (!gReceivedRemoteLinkPlayers) { - SetMainCallback2(CB2_ReturnFromLinkTrade); + SetMainCallback2(CB2_StartCreateTradeMenu); DestroyTask(taskId); } break; @@ -929,7 +929,7 @@ static void Task_StartWirelessTrade(u8 taskId) case 3: if (IsLinkTaskFinished()) { - UnionRoom_CreateTask_CallCB2ReturnFromLinkTrade(); + CreateTask_CreateTradeMenu(); DestroyTask(taskId); } break; diff --git a/src/data/union_room.h b/src/data/union_room.h new file mode 100644 index 000000000..6c8254d1b --- /dev/null +++ b/src/data/union_room.h @@ -0,0 +1,470 @@ +static const u8 *const sLinkGroupActivityNameTexts[] = { + [ACTIVITY_NONE] = gText_UR_EmptyString, + [ACTIVITY_BATTLE_SINGLE] = gText_UR_SingleBattle, + [ACTIVITY_BATTLE_DOUBLE] = gText_UR_DoubleBattle, + [ACTIVITY_BATTLE_MULTI] = gText_UR_MultiBattle, + [ACTIVITY_TRADE] = gText_UR_PokemonTrades, + [ACTIVITY_CHAT] = gText_UR_Chat, + [ACTIVITY_WONDER_CARD_DUP] = gText_UR_WonderCards, + [ACTIVITY_WONDER_NEWS_DUP] = gText_UR_WonderNews, + [ACTIVITY_CARD] = gText_UR_Cards, + [ACTIVITY_POKEMON_JUMP] = gText_UR_PokemonJump, + [ACTIVITY_BERRY_CRUSH] = gText_UR_BerryCrush, + [ACTIVITY_BERRY_PICK] = gText_UR_BerryPicking, + [ACTIVITY_SEARCH] = gText_UR_Search, + [ACTIVITY_SPIN_TRADE] = gText_UR_SpinTrade, + [ACTIVITY_ITEM_TRADE] = gText_UR_ItemTrade, + [ACTIVITY_RECORD_CORNER] = gText_UR_EmptyString, + [ACTIVITY_BERRY_BLENDER] = gText_UR_EmptyString, + [ACTIVITY_ACCEPT] = gText_UR_EmptyString, + [ACTIVITY_DECLINE] = gText_UR_EmptyString, + [ACTIVITY_NPCTALK] = gText_UR_EmptyString, + [ACTIVITY_PLYRTALK] = gText_UR_EmptyString, + [ACTIVITY_WONDER_CARD] = gText_UR_WonderCards, + [ACTIVITY_WONDER_NEWS] = gText_UR_WonderNews +}; + +static const struct WindowTemplate sWindowTemplate_BButtonCancel = { + .bg = 0, + .tilemapLeft = 0, + .tilemapTop = 0, + .width = 30, + .height = 2, + .paletteNum = 0xF, + .baseBlock = 0x008 +}; + +// Minimum and maximum number of players for a link group +// A minimum of 0 means the min and max are equal +#define LINK_GROUP_CAPACITY(min, max)(((min) << 12) | ((max) << 8)) +#define GROUP_MAX(capacity)(capacity & 0x0F) +#define GROUP_MIN(capacity)(capacity >> 4) +#define GROUP_MIN2(capacity)(capacity & 0xF0) // Unnecessary to have both, but needed to match + +static const u32 sLinkGroupToActivityAndCapacity[] = { + [LINK_GROUP_SINGLE_BATTLE] = ACTIVITY_BATTLE_SINGLE | LINK_GROUP_CAPACITY(0, 2), + [LINK_GROUP_DOUBLE_BATTLE] = ACTIVITY_BATTLE_DOUBLE | LINK_GROUP_CAPACITY(0, 2), + [LINK_GROUP_MULTI_BATTLE] = ACTIVITY_BATTLE_MULTI | LINK_GROUP_CAPACITY(0, 4), + [LINK_GROUP_TRADE] = ACTIVITY_TRADE | LINK_GROUP_CAPACITY(0, 2), + [LINK_GROUP_POKEMON_JUMP] = ACTIVITY_POKEMON_JUMP | LINK_GROUP_CAPACITY(2, 5), + [LINK_GROUP_BERRY_CRUSH] = ACTIVITY_BERRY_CRUSH | LINK_GROUP_CAPACITY(2, 5), + [LINK_GROUP_BERRY_PICKING] = ACTIVITY_BERRY_PICK | LINK_GROUP_CAPACITY(3, 5), + [LINK_GROUP_WONDER_CARD] = ACTIVITY_SPIN_TRADE | LINK_GROUP_CAPACITY(3, 5), + [LINK_GROUP_WONDER_NEWS] = ACTIVITY_ITEM_TRADE | LINK_GROUP_CAPACITY(3, 5) +}; + +static const struct WindowTemplate sWindowTemplate_List_PossibleGroupMembers = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 3, + .width = 13, + .height = 10, + .paletteNum = 15, + .baseBlock = 0x044 +}; + +static const struct WindowTemplate sWindowTemplate_NumPlayerMode = { + .bg = 0, + .tilemapLeft = 16, + .tilemapTop = 3, + .width = 7, + .height = 4, + .paletteNum = 15, + .baseBlock = 0x0C6 +}; + +const struct ListMenuItem sListMenuItems_PossibleGroupMembers[] = { + {gText_UR_EmptyString, 0}, + {gText_UR_EmptyString, 1}, + {gText_UR_EmptyString, 2}, + {gText_UR_EmptyString, 3}, + {gText_UR_EmptyString, 4} +}; + +static const struct ListMenuTemplate sListMenuTemplate_PossibleGroupMembers = { + .items = sListMenuItems_PossibleGroupMembers, + .moveCursorFunc = NULL, + .itemPrintFunc = ItemPrintFunc_PossibleGroupMembers, + .totalItems = ARRAY_COUNT(sListMenuItems_PossibleGroupMembers), + .maxShowed = 5, + .windowId = 0, + .header_X = 0, + .item_X = 1, + .cursor_X = 0, + .upText_Y = 0, + .cursorPal = 2, + .fillValue = 1, + .cursorShadowPal = 3, + .lettersSpacing = 0, + .itemVerticalPadding = 2, + .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, + .fontId = FONT_2, + .cursorKind = 1 +}; + +static const struct WindowTemplate sWindowTemplate_GroupList = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 3, + .width = 17, + .height = 10, + .paletteNum = 15, + .baseBlock = 0x044 +}; + +static const struct WindowTemplate sWindowTemplate_PlayerNameAndId = { + .bg = 0, + .tilemapLeft = 20, + .tilemapTop = 3, + .width = 7, + .height = 4, + .paletteNum = 15, + .baseBlock = 0x0EE +}; + +static const struct ListMenuItem sListMenuItems_UnionRoomGroups[] = { + {gText_UR_EmptyString, 0}, + {gText_UR_EmptyString, 1}, + {gText_UR_EmptyString, 2}, + {gText_UR_EmptyString, 3}, + {gText_UR_EmptyString, 4}, + {gText_UR_EmptyString, 5}, + {gText_UR_EmptyString, 6}, + {gText_UR_EmptyString, 7}, + {gText_UR_EmptyString, 8}, + {gText_UR_EmptyString, 9}, + {gText_UR_EmptyString, 10}, + {gText_UR_EmptyString, 11}, + {gText_UR_EmptyString, 12}, + {gText_UR_EmptyString, 13}, + {gText_UR_EmptyString, 14}, + {gText_UR_EmptyString, 15} +}; + +static const struct ListMenuTemplate sListMenuTemplate_UnionRoomGroups = { + .items = sListMenuItems_UnionRoomGroups, + .moveCursorFunc = ListMenuDefaultCursorMoveFunc, + .itemPrintFunc = ListMenuItemPrintFunc_UnionRoomGroups, + .totalItems = ARRAY_COUNT(sListMenuItems_UnionRoomGroups), + .maxShowed = 5, + .windowId = 0, + .header_X = 0, + .item_X = 8, + .cursor_X = 0, + .upText_Y = 0, + .cursorPal = 2, + .fillValue = 1, + .cursorShadowPal = 3, + .lettersSpacing = 0, + .itemVerticalPadding = 2, + .scrollMultiple = LIST_MULTIPLE_SCROLL_DPAD, + .fontId = FONT_2, + .cursorKind = 0 +}; + +static const struct WindowTemplate sWindowTemplate_InviteToActivity = { + .bg = 0, + .tilemapLeft = 20, + .tilemapTop = 6, + .width = 8, + .height = 7, + .paletteNum = 15, + .baseBlock = 0x001 +}; + +static const struct ListMenuItem sListMenuItems_InviteToActivity[] = { + {gText_UR_Greetings, ACTIVITY_CARD | LINK_GROUP_CAPACITY(0, 2)}, + {gText_UR_Battle, ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM | LINK_GROUP_CAPACITY(0, 2)}, + {gText_UR_Chat2, ACTIVITY_CHAT | IN_UNION_ROOM | LINK_GROUP_CAPACITY(0, 2)}, + {gText_UR_Exit, ACTIVITY_NONE | IN_UNION_ROOM } +}; + +static const struct ListMenuTemplate sListMenuTemplate_InviteToActivity = { + .items = sListMenuItems_InviteToActivity, + .moveCursorFunc = ListMenuDefaultCursorMoveFunc, + .itemPrintFunc = NULL, + .totalItems = ARRAY_COUNT(sListMenuItems_InviteToActivity), + .maxShowed = 4, + .windowId = 0, + .header_X = 0, + .item_X = 8, + .cursor_X = 0, + .upText_Y = 0, + .cursorPal = 2, + .fillValue = 1, + .cursorShadowPal = 3, + .lettersSpacing = 1, + .itemVerticalPadding = 0, + .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, + .fontId = FONT_2, + .cursorKind = 0 +}; + +static const struct WindowTemplate sWindowTemplate_RegisterForTrade = { + .bg = 0, + .tilemapLeft = 18, + .tilemapTop = 8, + .width = 11, + .height = 5, + .paletteNum = 15, + .baseBlock = 0x001 +}; + +static const struct ListMenuItem sListMenuItems_RegisterForTrade[] = { + {gText_Register, 1}, + {gText_UR_Info, 2}, + {gText_UR_Exit, 3} +}; + +static const struct ListMenuTemplate sListMenuTemplate_RegisterForTrade = { + .items = sListMenuItems_RegisterForTrade, + .moveCursorFunc = ListMenuDefaultCursorMoveFunc, + .itemPrintFunc = NULL, + .totalItems = ARRAY_COUNT(sListMenuItems_RegisterForTrade), + .maxShowed = 3, + .windowId = 0, + .header_X = 0, + .item_X = 8, + .cursor_X = 0, + .upText_Y = 0, + .cursorPal = 2, + .fillValue = 1, + .cursorShadowPal = 3, + .lettersSpacing = 1, + .itemVerticalPadding = 0, + .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, + .fontId = FONT_2, + .cursorKind = 0 +}; + +static const struct WindowTemplate sWindowTemplate_TypeNames = { + .bg = 0, + .tilemapLeft = 20, + .tilemapTop = 2, + .width = 9, + .height = 11, + .paletteNum = 15, + .baseBlock = 0x001 +}; + +static const struct ListMenuItem sListMenuItems_TypeNames[NUMBER_OF_MON_TYPES] = { + { gTypeNames[TYPE_NORMAL], TYPE_NORMAL }, + { gTypeNames[TYPE_FIRE], TYPE_FIRE }, + { gTypeNames[TYPE_WATER], TYPE_WATER }, + { gTypeNames[TYPE_ELECTRIC], TYPE_ELECTRIC }, + { gTypeNames[TYPE_GRASS], TYPE_GRASS }, + { gTypeNames[TYPE_ICE], TYPE_ICE }, + { gTypeNames[TYPE_GROUND], TYPE_GROUND }, + { gTypeNames[TYPE_ROCK], TYPE_ROCK }, + { gTypeNames[TYPE_FLYING], TYPE_FLYING }, + { gTypeNames[TYPE_PSYCHIC], TYPE_PSYCHIC }, + { gTypeNames[TYPE_FIGHTING], TYPE_FIGHTING }, + { gTypeNames[TYPE_POISON], TYPE_POISON }, + { gTypeNames[TYPE_BUG], TYPE_BUG }, + { gTypeNames[TYPE_GHOST], TYPE_GHOST }, + { gTypeNames[TYPE_DRAGON], TYPE_DRAGON }, + { gTypeNames[TYPE_STEEL], TYPE_STEEL }, + { gTypeNames[TYPE_DARK], TYPE_DARK }, + { gText_UR_Exit, NUMBER_OF_MON_TYPES } +}; + +static const struct ListMenuTemplate sListMenuTemplate_TypeNames = { + .items = sListMenuItems_TypeNames, + .moveCursorFunc = ListMenuDefaultCursorMoveFunc, + .itemPrintFunc = NULL, + .totalItems = NUMBER_OF_MON_TYPES, + .maxShowed = 6, + .windowId = 0, + .header_X = 0, + .item_X = 8, + .cursor_X = 0, + .upText_Y = 2, + .cursorPal = 2, + .fillValue = 1, + .cursorShadowPal = 3, + .lettersSpacing = 1, + .itemVerticalPadding = 0, + .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, + .fontId = FONT_2, + .cursorKind = 0 +}; + +static const struct WindowTemplate sWindowTemplate_TradingBoardHeader = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 1, + .width = 28, + .height = 2, + .paletteNum = 13, + .baseBlock = 0x001 +}; + +static const struct WindowTemplate sWindowTemplate_TradingBoardMain = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 5, + .width = 28, + .height = 10, + .paletteNum = 13, + .baseBlock = 0x039 +}; + +static const struct ListMenuItem sListMenuItems_TradeBoard[] = { + {gText_UR_EmptyString, -3}, + {gText_UR_EmptyString, 0}, + {gText_UR_EmptyString, 1}, + {gText_UR_EmptyString, 2}, + {gText_UR_EmptyString, 3}, + {gText_UR_EmptyString, 4}, + {gText_UR_EmptyString, 5}, + {gText_UR_EmptyString, 6}, + {gText_UR_EmptyString, 7}, + {gText_UR_Exit2, 8} +}; + +static const struct ListMenuTemplate sListMenuTemplate_TradeBoard = { + .items = sListMenuItems_TradeBoard, + .moveCursorFunc = ListMenuDefaultCursorMoveFunc, + .itemPrintFunc = TradeBoardListMenuItemPrintFunc, + .totalItems = ARRAY_COUNT(sListMenuItems_TradeBoard), + .maxShowed = 5, + .windowId = 0, + .header_X = 0, + .item_X = 12, + .cursor_X = 0, + .upText_Y = 2, + .cursorPal = 14, + .fillValue = 15, + .cursorShadowPal = 13, + .lettersSpacing = 1, + .itemVerticalPadding = 1, + .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, + .fontId = FONT_2, + .cursorKind = 0 +}; + +static const struct WindowTemplate sWindowTemplate_Unused = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 5, + .width = 28, + .height = 10, + .paletteNum = 13, + .baseBlock = 0x039 +}; + +static const struct ListMenuItem sListMenuItems_Unused[] = { + {gText_UR_EmptyString, 0}, + {gText_UR_EmptyString, 1}, + {gText_UR_EmptyString, 2}, + {gText_UR_EmptyString, 3}, + {gText_UR_EmptyString, 4}, + {gText_UR_EmptyString, 5}, + {gText_UR_EmptyString, 6}, + {gText_UR_EmptyString, 7}, + {gText_UR_EmptyString, 8}, + {gText_UR_EmptyString, 9}, + {gText_UR_EmptyString, 10}, + {gText_UR_EmptyString, 11}, + {gText_UR_EmptyString, 12}, + {gText_UR_EmptyString, 13}, + {gText_UR_EmptyString, 14}, + {gText_UR_EmptyString, 15} +}; + +static const struct ListMenuTemplate sListMenuTemplate_Unused = { + .items = sListMenuItems_Unused, + .moveCursorFunc = ListMenuDefaultCursorMoveFunc, + .itemPrintFunc = ItemPrintFunc_Unused, + .totalItems = ARRAY_COUNT(sListMenuItems_Unused), + .maxShowed = 4, + .windowId = 0, + .header_X = 0, + .item_X = 8, + .cursor_X = 1, + .upText_Y = 0, + .cursorPal = 2, + .fillValue = 1, + .cursorShadowPal = 3, + .lettersSpacing = 1, + .itemVerticalPadding = 0, + .scrollMultiple = LIST_MULTIPLE_SCROLL_DPAD, + .fontId = FONT_2, + .cursorKind = 0 +}; + +static const struct RfuPlayerData sRfuPlayerData_Dummy = {}; + +ALIGNED(4) static const u8 sAcceptedActivityIds_SingleBattle[] = {ACTIVITY_BATTLE_SINGLE, 0xFF}; +ALIGNED(4) static const u8 sAcceptedActivityIds_DoubleBattle[] = {ACTIVITY_BATTLE_DOUBLE, 0xFF}; +ALIGNED(4) static const u8 sAcceptedActivityIds_MultiBattle[] = {ACTIVITY_BATTLE_MULTI, 0xFF}; +ALIGNED(4) static const u8 sAcceptedActivityIds_Trade[] = {ACTIVITY_TRADE, 0xFF}; +ALIGNED(4) static const u8 sAcceptedActivityIds_PokemonJump[] = {ACTIVITY_POKEMON_JUMP, 0xFF}; +ALIGNED(4) static const u8 sAcceptedActivityIds_BerryCrush[] = {ACTIVITY_BERRY_CRUSH, 0xFF}; +ALIGNED(4) static const u8 sAcceptedActivityIds_BerryPicking[] = {ACTIVITY_BERRY_PICK, 0xFF}; +ALIGNED(4) static const u8 sAcceptedActivityIds_WonderCard[] = {ACTIVITY_WONDER_CARD, 0xFF}; +ALIGNED(4) static const u8 sAcceptedActivityIds_WonderNews[] = {ACTIVITY_WONDER_NEWS, 0xFF}; +ALIGNED(4) static const u8 sAcceptedActivityIds_Resume[] = { + IN_UNION_ROOM | ACTIVITY_NONE, + IN_UNION_ROOM | ACTIVITY_BATTLE_SINGLE, + IN_UNION_ROOM | ACTIVITY_TRADE, + IN_UNION_ROOM | ACTIVITY_CHAT, + IN_UNION_ROOM | ACTIVITY_CARD, + IN_UNION_ROOM | ACTIVITY_ACCEPT, + IN_UNION_ROOM | ACTIVITY_DECLINE, + IN_UNION_ROOM | ACTIVITY_NPCTALK, + IN_UNION_ROOM | ACTIVITY_PLYRTALK, + 0xFF +}; +ALIGNED(4) static const u8 sAcceptedActivityIds_Init[] = {ACTIVITY_SEARCH, 0xFF}; +ALIGNED(4) static const u8 sAcceptedActivityIds_Unk11[] = { + ACTIVITY_BATTLE_SINGLE, + ACTIVITY_BATTLE_DOUBLE, + ACTIVITY_BATTLE_MULTI, + ACTIVITY_TRADE, + ACTIVITY_POKEMON_JUMP, + ACTIVITY_BERRY_CRUSH, + ACTIVITY_BERRY_PICK, + ACTIVITY_WONDER_CARD, + ACTIVITY_WONDER_NEWS, + ACTIVITY_SPIN_TRADE, + 0xFF +}; +ALIGNED(4) static const u8 sAcceptedActivityIds_Unk12[] = { + ACTIVITY_BATTLE_SINGLE, + ACTIVITY_BATTLE_DOUBLE, + ACTIVITY_BATTLE_MULTI, + ACTIVITY_TRADE, + ACTIVITY_BERRY_CRUSH, + 0xFF +}; + +static const u8 *const sAcceptedActivityIds[NUM_LINK_GROUP_TYPES] = { + [LINK_GROUP_SINGLE_BATTLE] = sAcceptedActivityIds_SingleBattle, + [LINK_GROUP_DOUBLE_BATTLE] = sAcceptedActivityIds_DoubleBattle, + [LINK_GROUP_MULTI_BATTLE] = sAcceptedActivityIds_MultiBattle, + [LINK_GROUP_TRADE] = sAcceptedActivityIds_Trade, + [LINK_GROUP_POKEMON_JUMP] = sAcceptedActivityIds_PokemonJump, + [LINK_GROUP_BERRY_CRUSH] = sAcceptedActivityIds_BerryCrush, + [LINK_GROUP_BERRY_PICKING] = sAcceptedActivityIds_BerryPicking, + [LINK_GROUP_WONDER_CARD] = sAcceptedActivityIds_WonderCard, + [LINK_GROUP_WONDER_NEWS] = sAcceptedActivityIds_WonderNews, + [LINK_GROUP_UNION_ROOM_RESUME] = sAcceptedActivityIds_Resume, + [LINK_GROUP_UNION_ROOM_INIT] = sAcceptedActivityIds_Init, + [LINK_GROUP_UNK_11] = sAcceptedActivityIds_Unk11, + [LINK_GROUP_UNK_12] = sAcceptedActivityIds_Unk12, +}; + +static const u8 sLinkGroupToURoomActivity[] = { + [LINK_GROUP_SINGLE_BATTLE] = ACTIVITY_BATTLE_SINGLE, + [LINK_GROUP_DOUBLE_BATTLE] = ACTIVITY_BATTLE_DOUBLE, + [LINK_GROUP_MULTI_BATTLE] = ACTIVITY_BATTLE_MULTI, + [LINK_GROUP_TRADE] = ACTIVITY_TRADE, + [LINK_GROUP_POKEMON_JUMP] = ACTIVITY_POKEMON_JUMP, + [LINK_GROUP_BERRY_CRUSH] = ACTIVITY_BERRY_CRUSH, + [LINK_GROUP_BERRY_PICKING] = ACTIVITY_BERRY_PICK, + [LINK_GROUP_WONDER_CARD] = ACTIVITY_WONDER_CARD, + [LINK_GROUP_WONDER_NEWS] = ACTIVITY_WONDER_NEWS +}; + +static const u8 sUnref_84570D1[] = _("{DYNAMIC 00}·{DYNAMIC 01}"); diff --git a/src/link_rfu_2.c b/src/link_rfu_2.c index 480f1874c..885af4dd3 100644 --- a/src/link_rfu_2.c +++ b/src/link_rfu_2.c @@ -2752,8 +2752,8 @@ static void Task_RfuReconnectWithParent(u8 taskId) if (TryReconnectParent()) DestroyTask(taskId); } - else if (GetHostRfuGameData()->activity == ACTIVITY_WCARD2 - || GetHostRfuGameData()->activity == ACTIVITY_WNEWS2) + else if (GetHostRfuGameData()->activity == ACTIVITY_WONDER_CARD + || GetHostRfuGameData()->activity == ACTIVITY_WONDER_NEWS) { tTime++; } diff --git a/src/mevent.c b/src/mevent.c index 386437259..d16f85ee1 100644 --- a/src/mevent.c +++ b/src/mevent.c @@ -263,7 +263,7 @@ static void Task_EReaderComm(u8 taskId) switch (data->state) { case 0: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_ReceiveMysteryGiftWithEReader)) + if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_ReceiveMysteryGiftWithEReader)) data->state = 1; break; case 1: @@ -285,7 +285,7 @@ static void Task_EReaderComm(u8 taskId) data->state = 13; break; case 4: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_SelectConnectFromEReaderMenu)) + if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_SelectConnectFromEReaderMenu)) { AddTextPrinterToWindow1(gJPText_SelectConnectWithGBA); ResetDelayTimer(&data->stateAdvanceDelay); @@ -334,7 +334,7 @@ static void Task_EReaderComm(u8 taskId) } break; case 7: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_LinkIsIncorrect)) + if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_LinkIsIncorrect)) data->state = 4; break; case 8: @@ -451,19 +451,19 @@ static void Task_EReaderComm(u8 taskId) data->state = 26; break; case 23: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_CardReadingHasBeenHalted)) + if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_CardReadingHasBeenHalted)) data->state = 26; break; case 20: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_ConnectionErrorCheckLink)) + if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_ConnectionErrorCheckLink)) data->state = 0; break; case 21: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_ConnectionErrorTryAgain)) + if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_ConnectionErrorTryAgain)) data->state = 0; break; case 22: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textOrReceiveState, gJPText_WriteErrorUnableToSaveData)) + if (PrintMysteryGiftMenuMessage(&data->textOrReceiveState, gJPText_WriteErrorUnableToSaveData)) data->state = 0; break; case 26: @@ -943,12 +943,12 @@ u16 MEvent_GetBattleCardCount(u32 command) return 0; } -void ResetReceivedWonderCardFlag(void) +void MysteryGift_DisableStats(void) { sReceivedWonderCardIsValid = FALSE; } -bool32 MEventHandleReceivedWonderCard(u16 flagId) +bool32 MysteryGift_TryEnableStatsByFlagId(u16 flagId) { sReceivedWonderCardIsValid = FALSE; if (flagId == 0) diff --git a/src/mystery_gift_menu.c b/src/mystery_gift_menu.c index 380e0b264..b07a57ee0 100644 --- a/src/mystery_gift_menu.c +++ b/src/mystery_gift_menu.c @@ -540,7 +540,7 @@ void ClearTextWindow(void) CopyWindowToVram(1, COPYWIN_MAP); } -bool32 MG_PrintTextOnWindow1AndWaitButton(u8 *textState, const u8 *str) +bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str) { switch (*textState) { @@ -650,7 +650,7 @@ u32 MysteryGift_HandleThreeOptionMenu(u8 * unused0, u16 * unused1, u8 whichMenu) return response; } -s8 mevent_message_print_and_prompt_yes_no(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str) +s8 DoMysteryGiftYesNo(u8 * textState, u16 * windowId, bool8 yesNoBoxPlacement, const u8 * str) { struct WindowTemplate windowTemplate; s8 input; @@ -878,25 +878,17 @@ bool32 TearDownCardOrNews_ReturnToTopMenu(bool32 cardOrNews, bool32 arg1) s32 mevent_message_prompt_discard(u8 * textState, u16 * windowId, bool32 cardOrNews) { if (cardOrNews == 0) - { - return mevent_message_print_and_prompt_yes_no(textState, windowId, TRUE, gText_IfThrowAwayCardEventWontHappen); - } + return DoMysteryGiftYesNo(textState, windowId, TRUE, gText_IfThrowAwayCardEventWontHappen); else - { - return mevent_message_print_and_prompt_yes_no(textState, windowId, TRUE, gText_OkayToDiscardNews); - } + return DoMysteryGiftYesNo(textState, windowId, TRUE, gText_OkayToDiscardNews); } bool32 mevent_message_was_thrown_away(u8 * textState, bool32 cardOrNews) { if (cardOrNews == 0) - { - return MG_PrintTextOnWindow1AndWaitButton(textState, gText_WonderCardThrownAway); - } + return PrintMysteryGiftMenuMessage(textState, gText_WonderCardThrownAway); else - { - return MG_PrintTextOnWindow1AndWaitButton(textState, gText_WonderNewsThrownAway); - } + return PrintMysteryGiftMenuMessage(textState, gText_WonderNewsThrownAway); } bool32 mevent_save_game(u8 * state) @@ -1098,7 +1090,7 @@ static bool32 PrintMGSendStatus(u8 * state, u16 * arg1, u8 arg2, u32 msgId) } else { - return MG_PrintTextOnWindow1AndWaitButton(state, str); + return PrintMysteryGiftMenuMessage(state, str); } } @@ -1165,7 +1157,7 @@ void task00_mystery_gift(u8 taskId) { if (data->IsCardOrNews == 0) { - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_DontHaveCardNewOneInput)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveCardNewOneInput)) { data->state = 3; PrintMysteryGiftOrEReaderTopMenu(0, 1); @@ -1173,7 +1165,7 @@ void task00_mystery_gift(u8 taskId) } else { - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_DontHaveNewsNewOneInput)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveNewsNewOneInput)) { data->state = 3; PrintMysteryGiftOrEReaderTopMenu(0, 1); @@ -1228,23 +1220,15 @@ void task00_mystery_gift(u8 taskId) { case 0: if (data->source == 1) - { - MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WCARD2); - } + CreateTask_LinkMysteryGiftWithFriend(ACTIVITY_WONDER_CARD); else if (data->source == 0) - { - MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WCARD2); - } + CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_CARD); break; case 1: if (data->source == 1) - { - MEvent_CreateTask_CardOrNewsWithFriend(ACTIVITY_WNEWS2); - } + CreateTask_LinkMysteryGiftWithFriend(ACTIVITY_WONDER_NEWS); else if (data->source == 0) - { - MEvent_CreateTask_CardOrNewsOverWireless(ACTIVITY_WNEWS2); - } + CreateTask_LinkMysteryGiftOverWireless(ACTIVITY_WONDER_NEWS); break; } data->state = 6; @@ -1291,7 +1275,7 @@ void task00_mystery_gift(u8 taskId) } break; case 9: - flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, mevent_client_get_buffer()); + flag = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, mevent_client_get_buffer()); switch (flag) { case 0: @@ -1312,14 +1296,14 @@ void task00_mystery_gift(u8 taskId) } break; case 10: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, mevent_client_get_buffer())) + if (PrintMysteryGiftMenuMessage(&data->textState, mevent_client_get_buffer())) { mevent_client_inc_flag(); data->state = 7; } break; case 11: - flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, gText_ThrowAwayWonderCard); + flag = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, gText_ThrowAwayWonderCard); switch (flag) { case 0: @@ -1347,7 +1331,7 @@ void task00_mystery_gift(u8 taskId) } break; case 12: - flag = mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, FALSE, gText_HaventReceivedCardsGift); + flag = DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, FALSE, gText_HaventReceivedCardsGift); switch (flag) { case 0: @@ -1387,17 +1371,12 @@ void task00_mystery_gift(u8 taskId) case 15: r1 = mevent_message(&sp0, data->IsCardOrNews, data->source, data->prevPromptWindowId); if (r1 == NULL) - { r1 = data->buffer; - } if (sp0) - { flag = PrintMGSuccessMessage(&data->textState, r1, &data->curPromptWindowId); - } else - { - flag = MG_PrintTextOnWindow1AndWaitButton(&data->textState, r1); - } + flag = PrintMysteryGiftMenuMessage(&data->textState, r1); + if (flag) { if (data->prevPromptWindowId == 3) @@ -1423,7 +1402,7 @@ void task00_mystery_gift(u8 taskId) } break; case 16: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_CommunicationError)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_CommunicationError)) { data->state = 0; PrintMysteryGiftOrEReaderTopMenu(0, 0); @@ -1536,7 +1515,7 @@ void task00_mystery_gift(u8 taskId) } break; case 23: - switch ((u32)mevent_message_print_and_prompt_yes_no(&data->textState, &data->curPromptWindowId, TRUE, gText_HaventReceivedGiftOkayToDiscard)) + switch ((u32)DoMysteryGiftYesNo(&data->textState, &data->curPromptWindowId, TRUE, gText_HaventReceivedGiftOkayToDiscard)) { case 0: data->state = 24; @@ -1587,10 +1566,10 @@ void task00_mystery_gift(u8 taskId) switch (data->IsCardOrNews) { case 0: - MEvent_CreateTask_Leader(ACTIVITY_WCARD2); + CreateTask_SendMysteryGift(ACTIVITY_WONDER_CARD); break; case 1: - MEvent_CreateTask_Leader(ACTIVITY_WNEWS2); + CreateTask_SendMysteryGift(ACTIVITY_WONDER_NEWS); break; } data->source = 1; @@ -1660,7 +1639,7 @@ void task00_mystery_gift(u8 taskId) } break; case 36: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_CommunicationError)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_CommunicationError)) { data->state = 0; PrintMysteryGiftOrEReaderTopMenu(0, 0); diff --git a/src/party_menu.c b/src/party_menu.c index 84b9b5807..74a76adc8 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -3877,7 +3877,7 @@ static void CursorCB_Trade1(u8 taskId) u16 species2 = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES2); u16 species = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_SPECIES); u8 isEventLegal = GetMonData(&gPlayerParty[gPartyMenu.slotId], MON_DATA_EVENT_LEGAL); - u32 stringId = GetUnionRoomTradeMessageId(*(struct RfuGameCompatibilityData *)GetHostRfuGameData(), gPartnerTgtGnameSub, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal); + u32 stringId = GetUnionRoomTradeMessageId(*(struct RfuGameCompatibilityData *)GetHostRfuGameData(), gRfuPartnerCompatibilityData, species2, gUnionRoomOfferedSpecies, gUnionRoomRequestedMonType, species, isEventLegal); if (stringId != UR_TRADE_MSG_NONE) { diff --git a/src/rfu_union_tool.c b/src/rfu_union_tool.c index 51b6106d5..d6e77519d 100644 --- a/src/rfu_union_tool.c +++ b/src/rfu_union_tool.c @@ -10,7 +10,7 @@ #include "constants/union_room.h" #include "constants/event_objects.h" -static EWRAM_DATA struct UnionObj * UnionObjWork = NULL; +static EWRAM_DATA struct UnionRoomObject * UnionObjWork = NULL; static EWRAM_DATA u32 sUnionObjRefreshTimer = 0; static u8 StartUnionObjAnimTask(void); @@ -212,7 +212,7 @@ static bool32 TryReleaseUnionRoomPlayerObjectEvent(u32 playerIdx) return TRUE; } -u8 ZeroUnionObjWork(struct UnionObj * ptr) +u8 ZeroUnionObjWork(struct UnionRoomObject * ptr) { s32 i; @@ -234,7 +234,7 @@ static const u8 sMovement_UnionPlayerExit[2] = { MOVEMENT_ACTION_STEP_END }; -static bool32 AnimateUnionRoomPlayerDespawn(s8 * a0, u32 playerIdx, struct UnionObj * ptr) +static bool32 AnimateUnionRoomPlayerDespawn(s8 * a0, u32 playerIdx, struct UnionRoomObject * ptr) { switch (*a0) { @@ -263,7 +263,7 @@ static const u8 sMovement_UnionPlayerEnter[2] = { MOVEMENT_ACTION_STEP_END }; -static bool32 AnimateUnionRoomPlayerSpawn(s8 * state_p, u32 playerIdx, struct UnionObj * ptr) +static bool32 AnimateUnionRoomPlayerSpawn(s8 * state_p, u32 playerIdx, struct UnionRoomObject * ptr) { s16 x, y; @@ -308,7 +308,7 @@ static bool32 AnimateUnionRoomPlayerSpawn(s8 * state_p, u32 playerIdx, struct Un static bool32 SpawnGroupLeader(u32 playerIdx, u32 gender, u32 idMod256) { - struct UnionObj * ptr = &UnionObjWork[playerIdx]; + struct UnionRoomObject * ptr = &UnionObjWork[playerIdx]; AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 561) ptr->schedAnim = UNION_ROOM_SPAWN_IN; ptr->gfxId = GetUnionRoomPlayerGraphicsId(gender, idMod256); @@ -324,7 +324,7 @@ static bool32 SpawnGroupLeader(u32 playerIdx, u32 gender, u32 idMod256) static bool32 DespawnGroupLeader(u32 playerIdx) { - struct UnionObj * ptr = &UnionObjWork[playerIdx]; + struct UnionRoomObject * ptr = &UnionObjWork[playerIdx]; AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 577) ptr->schedAnim = UNION_ROOM_SPAWN_OUT; if (ptr->state == 1) @@ -337,7 +337,7 @@ static bool32 DespawnGroupLeader(u32 playerIdx) } } -static void AnimateUnionObj(u32 playerIdx, struct UnionObj * ptr) +static void AnimateUnionObj(u32 playerIdx, struct UnionRoomObject * ptr) { switch (ptr->state) { @@ -418,7 +418,7 @@ static void DestroyAnimateUnionObjsTask(void) } } -void DeleteUnionObjWorkAndStopTask(void) +void DestroyUnionRoomPlayerObjects(void) { s32 i; for (i = 0; i < 8; i++) @@ -577,30 +577,30 @@ static void DespawnGroupLeaderAndMembers(u32 group, struct RfuGameData * gname) } } -static void UpdateUnionRoomPlayerSprites(struct UnkStruct_URoom * groups) +static void UpdateUnionRoomPlayerSprites(struct WirelessLink_URoom * groups) { s32 i; - struct UnkStruct_x20 * x20_p; + struct RfuPlayer * x20_p; sUnionObjRefreshTimer = 0; - for (i = 0, x20_p = groups->field_0->arr; i < 8; i++) + for (i = 0, x20_p = groups->playerList->players; i < 8; i++) { if (x20_p[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - SpawnGroupLeaderAndMembers(i, &x20_p[i].gname_uname.gname); + SpawnGroupLeaderAndMembers(i, &x20_p[i].rfu.data); } else if (x20_p[i].groupScheduledAnim == UNION_ROOM_SPAWN_OUT) { - DespawnGroupLeaderAndMembers(i, &x20_p[i].gname_uname.gname); + DespawnGroupLeaderAndMembers(i, &x20_p[i].rfu.data); } } } -void ScheduleUnionRoomPlayerRefresh(struct UnkStruct_URoom *uroom_p) +void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p) { sUnionObjRefreshTimer = 300; } -void HandleUnionRoomPlayerRefresh(struct UnkStruct_URoom *uroom_p) +void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p) { if (++sUnionObjRefreshTimer > 300) { @@ -608,17 +608,17 @@ void HandleUnionRoomPlayerRefresh(struct UnkStruct_URoom *uroom_p) } } -bool32 RfuUnionTool_GetGroupAndMemberInFrontOfPlayer(struct UnkStruct_Main0 *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds) +bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds) { s16 x, y; s32 i, j; - struct UnkStruct_x20 * x20_p; + struct RfuPlayer * x20_p; if (!is_walking_or_running()) { return FALSE; } GetXYCoordsOneStepInFrontOfPlayer(&x, &y); - for (i = 0, x20_p = main0_p->arr; i < 8; i++) + for (i = 0, x20_p = main0_p->players; i < 8; i++) { for (j = 0; j < 5; j++) { @@ -657,7 +657,7 @@ static void UnionPartnerObjectSetFacing(s32 member, s32 group, u8 direction) TurnVirtualObject(5 * group - 0x38 + member, direction); } -void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct UnkStruct_Main0 *main0_p) +void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct RfuPlayerList *main0_p) { - return UnionPartnerObjectSetFacing(member, group, UnionPartnerObjectGetFacing(member, group, &main0_p->arr[group].gname_uname.gname)); + return UnionPartnerObjectSetFacing(member, group, UnionPartnerObjectGetFacing(member, group, &main0_p->players[group].rfu.data)); } diff --git a/src/start_menu.c b/src/start_menu.c index ec2616338..76f6cade2 100644 --- a/src/start_menu.c +++ b/src/start_menu.c @@ -374,7 +374,7 @@ void Task_StartMenuHandleInput(u8 taskId) { case 0: if (InUnionRoom() == TRUE) - var_800D_set_xB(); + SetUsingUnionRoomStartMenu(); sStartMenuCallback = StartCB_HandleInput; data[0]++; break; diff --git a/src/trade.c b/src/trade.c index e8ada5673..c302f93b3 100644 --- a/src/trade.c +++ b/src/trade.c @@ -711,7 +711,7 @@ static void InitTradeMenuResources(void) } } -void CB2_ReturnFromLinkTrade(void) +void CB2_StartCreateTradeMenu(void) { SetMainCallback2(CB2_ReturnFromLinkTrade2); } @@ -1208,7 +1208,7 @@ static void TradeMenuCB_10(void) static void TradeMenuCB_13(void) { - gMain.savedCallback = CB2_ReturnFromLinkTrade; + gMain.savedCallback = CB2_StartCreateTradeMenu; if (gWirelessCommType != 0) { if (IsLinkRfuTaskFinished()) @@ -1218,7 +1218,7 @@ static void TradeMenuCB_13(void) Free(sTradeMenuResourcesPtr); gMain.callback1 = NULL; DestroyWirelessStatusIndicatorSprite(); - SetMainCallback2(CB2_InitTradeAnim_LinkTrade); + SetMainCallback2(CB2_LinkTrade); } } else @@ -1229,7 +1229,7 @@ static void TradeMenuCB_13(void) FreeAllWindowBuffers(); Free(sTradeMenuResourcesPtr); gMain.callback1 = NULL; - SetMainCallback2(CB2_InitTradeAnim_LinkTrade); + SetMainCallback2(CB2_LinkTrade); } } } diff --git a/src/trade_scene.c b/src/trade_scene.c index a946299b9..826c45c3b 100644 --- a/src/trade_scene.c +++ b/src/trade_scene.c @@ -773,7 +773,7 @@ static void LoadTradeMonPic(u8 whichParty, u8 action) } } -void CB2_InitTradeAnim_LinkTrade(void) +void CB2_LinkTrade(void) { switch (gMain.state) { @@ -2668,7 +2668,7 @@ static void CB2_HandleTradeEnded(void) case 8: if (IsBGMStopped() == TRUE) { - if (gWirelessCommType && gMain.savedCallback == CB2_ReturnFromLinkTrade) + if (gWirelessCommType && gMain.savedCallback == CB2_StartCreateTradeMenu) { SetLinkStandbyCallback(); } @@ -2680,7 +2680,7 @@ static void CB2_HandleTradeEnded(void) } break; case 9: - if (gWirelessCommType && gMain.savedCallback == CB2_ReturnFromLinkTrade) + if (gWirelessCommType && gMain.savedCallback == CB2_StartCreateTradeMenu) { if (IsLinkRfuTaskFinished()) { diff --git a/src/union_room.c b/src/union_room.c index 186d09707..2458e44ef 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -10,6 +10,7 @@ #include "easy_chat.h" #include "event_data.h" #include "event_object_lock.h" +#include "fieldmap.h" #include "field_control_avatar.h" #include "field_fadetransition.h" #include "field_player_avatar.h" @@ -48,641 +49,274 @@ #include "constants/trainer_card.h" #include "constants/union_room.h" +// States for Task_RunUnionRoom +enum { + UR_STATE_INIT, + UR_STATE_INIT_OBJECTS, + UR_STATE_INIT_LINK, + UR_STATE_CHECK_SELECTING_MON, + UR_STATE_MAIN, + UR_STATE_DO_SOMETHING_PROMPT, + UR_STATE_HANDLE_DO_SOMETHING_PROMPT_INPUT, + UR_STATE_DO_SOMETHING_PROMPT_2, + UR_STATE_PRINT_MSG, + UR_STATE_HANDLE_ACTIVITY_REQUEST, + UR_STATE_DECLINE_ACTIVITY_REQUEST, + UR_STATE_PLAYER_CONTACTED_YOU, + UR_STATE_RECV_CONTACT_DATA, + UR_STATE_PRINT_START_ACTIVITY_MSG, + UR_STATE_START_ACTIVITY_LINK, + UR_STATE_START_ACTIVITY_WAIT_FOR_LINK, + UR_STATE_START_ACTIVITY_FREE_UROOM, + UR_STATE_START_ACTIVITY_FADE, + UR_STATE_START_ACTIVITY, + UR_STATE_RECV_JOIN_CHAT_REQUEST, + UR_STATE_TRY_ACCEPT_CHAT_REQUEST_DELAY, + UR_STATE_TRY_ACCEPT_CHAT_REQUEST, + UR_STATE_ACCEPT_CHAT_REQUEST, + UR_STATE_WAIT_FOR_START_MENU, + UR_STATE_INTERACT_WITH_PLAYER, + UR_STATE_TRY_COMMUNICATING, + UR_STATE_PRINT_AND_EXIT, + UR_STATE_SEND_ACTIVITY_REQUEST, + UR_STATE_TRAINER_APPEARS_BUSY, + UR_STATE_WAIT_FOR_RESPONSE_TO_REQUEST, + UR_STATE_CANCEL_ACTIVITY_LINK_ERROR, + UR_STATE_SEND_TRADE_REQUST, + UR_STATE_REQUEST_DECLINED, + UR_STATE_PRINT_CONTACT_MSG, + UR_STATE_HANDLE_CONTACT_DATA, + UR_STATE_RECV_ACTIVITY_REQUEST, + UR_STATE_CANCEL_REQUEST_PRINT_MSG, + UR_STATE_CANCEL_REQUEST_RESTART_LINK, + UR_STATE_COMMUNICATING_WAIT_FOR_DATA, + UR_STATE_WAIT_FOR_CONTACT_DATA, + UR_STATE_PRINT_CARD_INFO, + UR_STATE_WAIT_FINISH_READING_CARD, + UR_STATE_INTERACT_WITH_ATTENDANT, + UR_STATE_REGISTER_PROMPT, + UR_STATE_CANCEL_REGISTRATION_PROMPT, + UR_STATE_CHECK_TRADING_BOARD, + UR_STATE_TRADING_BOARD_LOAD, + UR_STATE_REGISTER_PROMPT_HANDLE_INPUT, + UR_STATE_TRADING_BOARD_HANDLE_INPUT, + UR_STATE_TRADE_PROMPT, + UR_STATE_TRADE_SELECT_MON, + UR_STATE_TRADE_OFFER_MON, + UR_STATE_REGISTER_REQUEST_TYPE, + UR_STATE_REGISTER_SELECT_MON_FADE, + UR_STATE_REGISTER_SELECT_MON, + UR_STATE_REGISTER_COMPLETE, + UR_STATE_CANCEL_REGISTRATION, +}; + +// States for sUnionRoomTrade.state +enum { + URTRADE_STATE_NONE, + URTRADE_STATE_REGISTERING, + URTRADE_STATE_OFFERING, +}; + +// States for Task_TryBecomeLinkLeader +enum { + LL_STATE_INIT, + LL_STATE_INIT2 = 3, + LL_STATE_GET_AWAITING_PLAYERS_TEXT, + LL_STATE_PRINT_AWAITING_PLAYERS, + LL_STATE_AWAIT_PLAYERS, + LL_STATE_ACCEPT_NEW_MEMBER_PROMPT, + LL_STATE_WAIT_DISCONNECT_CHILD = 9, + LL_STATE_MEMBER_LEFT, + LL_STATE_ACCEPT_NEW_MEMBER_PROMPT_HANDLE_INPUT, + LL_STATE_UPDATE_AFTER_JOIN_REQUEST, + LL_STATE_ACCEPTED_FINAL_MEMBER, + LL_STATE_WAIT_AND_CONFIRM_MEMBERS, + LL_STATE_MEMBERS_OK_PROMPT, + LL_STATE_MEMBERS_OK_PROMPT_HANDLE_INPUT, + LL_STATE_CONFIRMED_MEMBERS, + LL_STATE_FINAL_MEMBER_CHECK, + LL_STATE_CANCEL_PROMPT, + LL_STATE_CANCEL_PROMPT_HANDLE_INPUT, + LL_STATE_SHUTDOWN_AND_RETRY, + LL_STATE_RETRY, + LL_STATE_SHUTDOWN_AND_FAIL, + LL_STATE_FAILED, + LL_STATE_TRY_START_ACTIVITY = 26, + LL_STATE_MEMBER_DISCONNECTED = 29, + LL_STATE_CANCEL_WITH_MSG +}; + +// States for Task_TryJoinLinkGroup +enum { + LG_STATE_INIT, + LG_STATE_CHOOSE_LEADER_MSG, + LG_STATE_INIT_WINDOWS, + LG_STATE_CHOOSE_LEADER_HANDLE_INPUT, + LG_STATE_ASK_JOIN_GROUP = 5, + LG_STATE_MAIN, + LG_STATE_ASK_LEAVE_GROUP, + LG_STATE_ASK_LEAVE_GROUP_HANDLE_INPUT, + LG_STATE_WAIT_LEAVE_GROUP, + LG_STATE_CANCEL_CHOOSE_LEADER, + LG_STATE_CANCELED, + LG_STATE_RFU_ERROR, + LG_STATE_RFU_ERROR_SHUTDOWN, + LG_STATE_DISCONNECTED, + LG_STATE_RETRY_CONNECTION, + LG_STATE_TRADE_NOT_READY = 18, + LG_STATE_TRADE_NOT_READY_RETRY, + LG_STATE_READY_START_ACTIVITY, + LG_STATE_START_ACTIVITY, + LG_STATE_SHUTDOWN = 23, +}; + +// Color types for PrintUnionRoomText +enum { + UR_COLOR_DEFAULT, + UR_COLOR_RED, + UR_COLOR_GREEN, + UR_COLOR_WHITE, + UR_COLOR_CANCEL, + UR_COLOR_TRADE_BOARD_SELF, + UR_COLOR_TRADE_BOARD_OTHER, +}; + +// Return values for HandlePlayerListUpdate +enum { + PLIST_NONE, + PLIST_NEW_PLAYER, + PLIST_RECENT_UPDATE, + PLIST_UNUSED, + PLIST_CONTACTED, +}; + static EWRAM_DATA u8 sUnionRoomPlayerName[12] = {}; static EWRAM_DATA u8 sPlayerCurrActivity = 0; static EWRAM_DATA u8 sPlayerActivityGroupSize = 0; -static EWRAM_DATA union UnkUnion_Main sUnionRoomMain = {}; -static EWRAM_DATA u32 sUnref_203B060 = 0; -EWRAM_DATA struct RfuGameCompatibilityData gPartnerTgtGnameSub = {}; +static EWRAM_DATA union +{ + struct WirelessLink_Leader *leader; + struct WirelessLink_Group *group; + struct WirelessLink_URoom *uRoom; +} sWirelessLinkMain = {}; +static EWRAM_DATA u32 sUnused = 0; +EWRAM_DATA struct RfuGameCompatibilityData gRfuPartnerCompatibilityData = {}; EWRAM_DATA u16 gUnionRoomOfferedSpecies = SPECIES_NONE; EWRAM_DATA u8 gUnionRoomRequestedMonType = TYPE_NORMAL; static EWRAM_DATA struct UnionRoomTrade sUnionRoomTrade = {}; -static struct UnkStruct_Leader * sLeader; -static struct UnkStruct_Group * sGroup; -static struct UnkStruct_URoom * sURoom; +static struct WirelessLink_Leader * sLeader; +static struct WirelessLink_Group * sGroup; +static struct WirelessLink_URoom * sURoom; -static void Task_TryBecomeLinkLeader(u8 taskId); -static void Leader_DestroyResources(struct UnkStruct_Leader * leader); -static bool8 Leader_SetStateIfMemberListChanged(struct UnkStruct_Leader * leader, u32 state1, u32 state2); -static void ItemPrintFunc_PossibleGroupMembers(u8 windowId, u32 itemId, u8 y); -static u8 LeaderUpdateGroupMembership(struct UnkStruct_Main0 * main0); -static u8 UnionRoomLeaderField0CompactionAndCount(struct UnkStruct_Main0 * main0); -static void Task_TryJoinLinkGroup(u8 taskId); -static u32 IsTryingToTradeWithHoennTooSoon(struct UnkStruct_Group * group, s32 id); -static void AskToJoinRfuGroup(struct UnkStruct_Group * group, s32 id); -static void Task_ListenToWireless(u8 taskId); -static void ListMenuItemPrintFunc_UnionRoomGroups(u8 windowId, u32 itemId, u8 y); +static void Task_TryBecomeLinkLeader(u8); +static void Leader_DestroyResources(struct WirelessLink_Leader *); +static bool8 Leader_SetStateIfMemberListChanged(struct WirelessLink_Leader *, u32, u32); +static void ItemPrintFunc_PossibleGroupMembers(u8, u32, u8); +static u8 LeaderUpdateGroupMembership(struct RfuPlayerList *); +static u8 LeaderPrunePlayerList(struct RfuPlayerList *); +static void Task_TryJoinLinkGroup(u8); +static u32 IsTryingToTradeAcrossVersionTooSoon(struct WirelessLink_Group *, s32); +static void AskToJoinRfuGroup(struct WirelessLink_Group *, s32); +static void Task_ListenToWireless(u8); +static void ListMenuItemPrintFunc_UnionRoomGroups(u8, u32, u8); static u8 GetNewLeaderCandidate(void); static void CreateTask_RunScriptAndFadeToActivity(void); static void CreateTask_StartActivity(void); -static void Task_MEvent_Leader(u8 taskId); -static void Task_CardOrNewsWithFriend(u8 taskId); -static void Task_CardOrNewsOverWireless(u8 taskId); -static void Task_RunUnionRoom(u8 taskId); -static u16 ReadAsU16(const u8 *data); -static void ReceiveUnionRoomActivityPacket(struct UnkStruct_URoom * uRoom); -static bool32 UnionRoom_HandleContactFromOtherPlayer(struct UnkStruct_URoom * uRoom); -static void Task_InitUnionRoom(u8 taskId); +static void Task_SendMysteryGift(u8); +static void Task_CardOrNewsWithFriend(u8); +static void Task_CardOrNewsOverWireless(u8); +static void Task_RunUnionRoom(u8); +static u16 ReadAsU16(const u8 *); +static void ReceiveUnionRoomActivityPacket(struct WirelessLink_URoom *); +static bool32 HandleContactFromOtherPlayer(struct WirelessLink_URoom *); +static void Task_InitUnionRoom(u8); static u8 HandlePlayerListUpdate(void); -static u8 CreateTask_SearchForChildOrParent(struct UnkStruct_Main4 * main4, struct UnkStruct_Main4 * arg1, u32 arg2); -static bool32 GetGnameWonderFlagByLinkGroup(struct RfuGameData * gname, s16 linkGroup); -static u8 CreateTask_ListenForPartnersWithCompatibleSerialNos(struct UnkStruct_Main4 * main4, u32 linkGroup); -static u8 CreateTask_ListenForPartnersWithSerial7F7D(struct UnkStruct_Main4 * main4, u32 linkGroup); -static bool32 UR_PrintFieldMessage(const u8 * str); -static bool32 UR_RunTextPrinters_CheckPrinter0Active(void); -static bool8 PrintOnTextbox(u8 *textState, const u8 *str); -static s8 UnionRoomHandleYesNo(u8 *state_p, bool32 no_draw); -static s32 ListMenuHandler_AllItemsAvailable(u8 *state_p, u8 *win_id_p, u8 *list_menu_id_p, const struct WindowTemplate * winTemplate, const struct ListMenuTemplate * menuTemplate); -static s32 TradeBoardMenuHandler(u8 *state_p, u8 *win_id_p, u8 *list_menu_id_p, u8 *trade_board_win_id_p, const struct WindowTemplate * winTemplate, const struct ListMenuTemplate * menuTemplate, struct UnkStruct_Main0 * traders); -static void UR_BlankBg0(void); -static void JoinGroup_BlankBg0AndEnableScriptContexts(void); -static void UR_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 colorIdx); -static void BlankUnkStruct_x20Array(struct UnkStruct_x20 * x20, u8 count); -static void BlankUnkStruct_x1CArray(struct UnkStruct_x1C * x1C, u8 count); -static bool8 AreGnameUnameDifferent(struct UnionGnameUnamePair * arg0, const struct UnionGnameUnamePair * arg1); -static bool32 AreUnionRoomPlayerGnamesDifferent(struct UnionGnameUnamePair * arg0, struct UnionGnameUnamePair * arg1); -static u32 Findx20Inx1CArray(struct UnkStruct_x20 * x20, struct UnkStruct_x1C * x1Carr); -static u8 Appendx1Ctox20(struct UnkStruct_x20 * x20arr, struct UnkStruct_x1C * x1C, u8 count); -static void PrintUnionRoomGroupOnWindow(u8 windowId, u8 x, u8 y, struct UnkStruct_x20 * group, u8 colorIdx, u8 id); -static void PrintGroupMemberCandidateOnWindowWithColor(u8 windowId, u8 x, u8 y, struct UnkStruct_x20 * group, u8 colorIdx, u8 id); -static bool32 PlayerIsTalkingToUnionRoomAide(void); -static u32 GetResponseIdx_InviteToURoomActivity(s32 activity); -static u32 ConvPartnerUnameAndGetWhetherMetAlready(struct UnkStruct_x20 * unkX20); -static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 * main0, u8 overrideGender, u8 playerIdx, u32 playerGender); -static void nullsub_92(u8 windowId, u32 itemId, u8 y); -static void TradeBoardListMenuItemPrintFunc(u8 windowId, u32 itemId, u8 y); -static s32 GetIndexOfNthTradeBoardOffer(struct UnkStruct_x20 * x20, s32 n); -static s32 GetUnionRoomPlayerGender(s32 playerIdx, struct UnkStruct_Main0 * main0); -static s32 IsRequestedTypeAndSpeciesInPlayerParty(u32 type, u32 species); -static void GetURoomActivityRejectMsg(u8 *dst, s32 activity, u32 playerGender); -static void GetURoomActivityStartMsg(u8 *dst, u8 activity); -static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activity_p, struct UnkStruct_URoom * uroom); -static bool32 PollPartnerYesNoResponse(struct UnkStruct_URoom * uroom); +static u8 CreateTask_SearchForChildOrParent(struct RfuIncomingPlayerList *, struct RfuIncomingPlayerList *, u32); +static bool32 HasWonderCardOrNewsByLinkGroup(struct RfuGameData *, s16); +static u8 CreateTask_ListenForCompatiblePartners(struct RfuIncomingPlayerList *, u32); +static u8 CreateTask_ListenForWonderDistributor(struct RfuIncomingPlayerList *, u32); +static bool32 UR_PrintFieldMessage(const u8 *); +static bool32 UR_RunTextPrinters(void); +static bool8 PrintOnTextbox(u8 *, const u8 *); +static s8 UnionRoomHandleYesNo(u8 *, bool32); +static s32 ListMenuHandler_AllItemsAvailable(u8 *, u8 *, u8 *, const struct WindowTemplate *, const struct ListMenuTemplate *); +static s32 TradeBoardMenuHandler(u8 *, u8 *, u8 *, u8 *, const struct WindowTemplate *, const struct ListMenuTemplate *, struct RfuPlayerList *); +static void UR_ClearBg0(void); +static void JoinGroup_EnableScriptContexts(void); +static void PrintUnionRoomText(u8, u8, const u8 *, u8, u8, u8); +static void ClearRfuPlayerList(struct RfuPlayer *, u8); +static void ClearIncomingPlayerList(struct RfuIncomingPlayer *, u8); +static bool8 ArePlayersDifferent(struct RfuPlayerData *, const struct RfuPlayerData *); +static bool32 ArePlayerDataDifferent(struct RfuPlayerData *, struct RfuPlayerData *); +static u32 GetNewIncomingPlayerId(struct RfuPlayer *, struct RfuIncomingPlayer *); +static u8 TryAddIncomingPlayerToList(struct RfuPlayer *, struct RfuIncomingPlayer *, u8); +static void PrintGroupMemberOnWindow(u8, u8, u8, struct RfuPlayer *, u8, u8); +static void PrintGroupCandidateOnWindow(u8, u8, u8, struct RfuPlayer *, u8, u8); +static bool32 IsPlayerFacingTradingBoard(void); +static u32 GetResponseIdx_InviteToURoomActivity(s32); +static u32 ConvPartnerUnameAndGetWhetherMetAlready(struct RfuPlayer *); +static s32 UnionRoomGetPlayerInteractionResponse(struct RfuPlayerList *, u8, u8, u32); +static void ItemPrintFunc_Unused(u8, u32, u8); +static void TradeBoardListMenuItemPrintFunc(u8, u32, u8); +static s32 GetIndexOfNthTradeBoardOffer(struct RfuPlayer *, s32); +static s32 GetUnionRoomPlayerGender(s32, struct RfuPlayerList *); +static s32 IsRequestedTradeInPlayerParty(u32, u32); +static void GetURoomActivityRejectMsg(u8 *, s32, u32); +static void GetURoomActivityStartMsg(u8 *, u8); +static s32 GetChatLeaderActionRequestMessage(u8 *, u32, u16 *, struct WirelessLink_URoom *); +static bool32 PollPartnerYesNoResponse(struct WirelessLink_URoom *); static bool32 HasAtLeastTwoMonsOfLevel30OrLower(void); -static void ResetUnionRoomTrade(struct UnionRoomTrade * trade); -static bool32 RegisterTradeMonAndGetIsEgg(u32 monId, struct UnionRoomTrade * trade); -static void RegisterTradeMon(u32 monId, struct UnionRoomTrade * trade); -static u32 GetPartyPositionOfRegisteredMon(struct UnionRoomTrade * trade, u8 mpId); -static void HandleCancelTrade(bool32 unlockObjs); -static void UR_EnableScriptContext2AndFreezeObjectEvents(void); -static u8 GetSinglePartnerSpriteGenderParam(s32 linkPlayer); -static u8 GetActivePartnerSpriteGenderParam(struct UnkStruct_URoom * uroom); -static void ViewURoomPartnerTrainerCard(u8 *dest, struct UnkStruct_URoom * uRoom, bool8 parent_child); +static void ResetUnionRoomTrade(struct UnionRoomTrade *); +static bool32 RegisterTradeMonAndGetIsEgg(u32, struct UnionRoomTrade *); +static void RegisterTradeMon(u32, struct UnionRoomTrade *); +static u32 GetPartyPositionOfRegisteredMon(struct UnionRoomTrade *, u8); +static void HandleCancelActivity(bool32); +static void StartScriptInteraction(void); +static u8 GetLinkPlayerInfoFlags(s32); +static u8 GetActivePartnersInfo(struct WirelessLink_URoom *); +static void ViewURoomPartnerTrainerCard(u8 *, struct WirelessLink_URoom *, bool8); -#define _8456CD8(a, b) ((a) | ((b) << 8)) - -static const u8 *const sUnionRoomActivityStringPtrs[] = { - gText_UR_EmptyString, - gText_UR_SingleBattle, - gText_UR_DoubleBattle, - gText_UR_MultiBattle, - gText_UR_PokemonTrades, - gText_UR_Chat, - gText_UR_WonderCards, - gText_UR_WonderNews, - gText_UR_Cards, - gText_UR_PokemonJump, - gText_UR_BerryCrush, - gText_UR_BerryPicking, - gText_UR_Search, - gText_UR_SpinTrade, - gText_UR_ItemTrade, - gText_UR_EmptyString, - gText_UR_EmptyString, - gText_UR_EmptyString, - gText_UR_EmptyString, - gText_UR_EmptyString, - gText_UR_EmptyString, - gText_UR_WonderCards, - gText_UR_WonderNews -}; - -static const struct WindowTemplate sWindowTemplate_BButtonCancel = { - .bg = 0, - .tilemapLeft = 0, - .tilemapTop = 0, - .width = 30, - .height = 2, - .paletteNum = 0xF, - .baseBlock = 0x008 -}; - -static const u32 sLinkGroupToActivityAndCapacity[] = { - [LINK_GROUP_SINGLE_BATTLE] = _8456CD8(ACTIVITY_BATTLE, 2), - [LINK_GROUP_DOUBLE_BATTLE] = _8456CD8(ACTIVITY_DBLBATTLE, 2), - [LINK_GROUP_MULTI_BATTLE] = _8456CD8(ACTIVITY_MLTBATTLE, 4), - [LINK_GROUP_TRADE] = _8456CD8(ACTIVITY_TRADE, 2), - [LINK_GROUP_POKEMON_JUMP] = _8456CD8(ACTIVITY_PJUMP, 5 | 0x20), - [LINK_GROUP_BERRY_CRUSH] = _8456CD8(ACTIVITY_BCRUSH, 5 | 0x20), - [LINK_GROUP_BERRY_PICKING] = _8456CD8(ACTIVITY_BPICK, 5 | 0x30), - [LINK_GROUP_WONDER_CARD] = _8456CD8(ACTIVITY_SPINTRADE, 5 | 0x30), - [LINK_GROUP_WONDER_NEWS] = _8456CD8(ACTIVITY_ITEMTRADE, 5 | 0x30) -}; - -static const struct WindowTemplate sWindowTemplate_List_PossibleGroupMembers = { - .bg = 0, - .tilemapLeft = 1, - .tilemapTop = 3, - .width = 13, - .height = 10, - .paletteNum = 15, - .baseBlock = 0x044 -}; - -static const struct WindowTemplate sWindowTemplate_NumPlayerMode = { - .bg = 0, - .tilemapLeft = 16, - .tilemapTop = 3, - .width = 7, - .height = 4, - .paletteNum = 15, - .baseBlock = 0x0C6 -}; - -const struct ListMenuItem sListMenuItems_PossibleGroupMembers[] = { - {gText_UR_EmptyString, 0}, - {gText_UR_EmptyString, 1}, - {gText_UR_EmptyString, 2}, - {gText_UR_EmptyString, 3}, - {gText_UR_EmptyString, 4} -}; - -static const struct ListMenuTemplate sListMenuTemplate_PossibleGroupMembers = { - .items = sListMenuItems_PossibleGroupMembers, - .moveCursorFunc = NULL, - .itemPrintFunc = ItemPrintFunc_PossibleGroupMembers, - .totalItems = 5, - .maxShowed = 5, - .windowId = 0, - .header_X = 0, - .item_X = 1, - .cursor_X = 0, - .upText_Y = 0, - .cursorPal = 2, - .fillValue = 1, - .cursorShadowPal = 3, - .lettersSpacing = 0, - .itemVerticalPadding = 2, - .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, - .fontId = FONT_2, - .cursorKind = 1 -}; - -static const struct WindowTemplate sWindowTemplate_MysteryGiftList = { - .bg = 0, - .tilemapLeft = 1, - .tilemapTop = 3, - .width = 17, - .height = 10, - .paletteNum = 15, - .baseBlock = 0x044 -}; - -static const struct WindowTemplate sWindowTemplate_MysteryGiftPlayerNameAndId = { - .bg = 0, - .tilemapLeft = 20, - .tilemapTop = 3, - .width = 7, - .height = 4, - .paletteNum = 15, - .baseBlock = 0x0EE -}; - -static const struct ListMenuItem sListMenuItems_UnionRoomGroups[] = { - {gText_UR_EmptyString, 0}, - {gText_UR_EmptyString, 1}, - {gText_UR_EmptyString, 2}, - {gText_UR_EmptyString, 3}, - {gText_UR_EmptyString, 4}, - {gText_UR_EmptyString, 5}, - {gText_UR_EmptyString, 6}, - {gText_UR_EmptyString, 7}, - {gText_UR_EmptyString, 8}, - {gText_UR_EmptyString, 9}, - {gText_UR_EmptyString, 10}, - {gText_UR_EmptyString, 11}, - {gText_UR_EmptyString, 12}, - {gText_UR_EmptyString, 13}, - {gText_UR_EmptyString, 14}, - {gText_UR_EmptyString, 15} -}; - -static const struct ListMenuTemplate sListMenuTemplate_UnionRoomGroups = { - .items = sListMenuItems_UnionRoomGroups, - .moveCursorFunc = ListMenuDefaultCursorMoveFunc, - .itemPrintFunc = ListMenuItemPrintFunc_UnionRoomGroups, - .totalItems = 16, - .maxShowed = 5, - .windowId = 0, - .header_X = 0, - .item_X = 8, - .cursor_X = 0, - .upText_Y = 0, - .cursorPal = 2, - .fillValue = 1, - .cursorShadowPal = 3, - .lettersSpacing = 0, - .itemVerticalPadding = 2, - .scrollMultiple = LIST_MULTIPLE_SCROLL_DPAD, - .fontId = FONT_2, - .cursorKind = 0 -}; - -static const struct WindowTemplate sWindowTemplate_InviteToActivity = { - .bg = 0, - .tilemapLeft = 20, - .tilemapTop = 6, - .width = 8, - .height = 7, - .paletteNum = 15, - .baseBlock = 0x001 -}; - -static const struct ListMenuItem sListMenuItems_InviteToActivity[] = { - {gText_UR_Greetings, _8456CD8( ACTIVITY_CARD, 2)}, - {gText_UR_Battle, _8456CD8(ACTIVITY_BATTLE | IN_UNION_ROOM, 2)}, - {gText_UR_Chat2, _8456CD8(ACTIVITY_CHAT | IN_UNION_ROOM, 2)}, - {gText_UR_Exit, _8456CD8(ACTIVITY_NONE | IN_UNION_ROOM, 0)} -}; - -static const struct ListMenuTemplate sListMenuTemplate_InviteToActivity = { - .items = sListMenuItems_InviteToActivity, - .moveCursorFunc = ListMenuDefaultCursorMoveFunc, - .itemPrintFunc = NULL, - .totalItems = 4, - .maxShowed = 4, - .windowId = 0, - .header_X = 0, - .item_X = 8, - .cursor_X = 0, - .upText_Y = 0, - .cursorPal = 2, - .fillValue = 1, - .cursorShadowPal = 3, - .lettersSpacing = 1, - .itemVerticalPadding = 0, - .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, - .fontId = FONT_2, - .cursorKind = 0 -}; - -static const struct WindowTemplate sWindowTemplate_TradeBoardRegisterInfoExit = { - .bg = 0, - .tilemapLeft = 18, - .tilemapTop = 8, - .width = 11, - .height = 5, - .paletteNum = 15, - .baseBlock = 0x001 -}; - -static const struct ListMenuItem gUnknown_8456E3C[] = { - {gText_Register, 1}, - {gText_UR_Info, 2}, - {gText_UR_Exit, 3} -}; - -static const struct ListMenuTemplate sListMenuTemplate_TradeBoardRegisterInfoExit = { - .items = gUnknown_8456E3C, - .moveCursorFunc = ListMenuDefaultCursorMoveFunc, - .itemPrintFunc = NULL, - .totalItems = 3, - .maxShowed = 3, - .windowId = 0, - .header_X = 0, - .item_X = 8, - .cursor_X = 0, - .upText_Y = 0, - .cursorPal = 2, - .fillValue = 1, - .cursorShadowPal = 3, - .lettersSpacing = 1, - .itemVerticalPadding = 0, - .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, - .fontId = FONT_2, - .cursorKind = 0 -}; - -static const struct WindowTemplate sWindowTemplate_TypeNames = { - .bg = 0, - .tilemapLeft = 20, - .tilemapTop = 2, - .width = 9, - .height = 11, - .paletteNum = 15, - .baseBlock = 0x001 -}; - -static const struct ListMenuItem sListMenuItems_TypeNames[] = { - {gTypeNames[TYPE_NORMAL], TYPE_NORMAL}, - {gTypeNames[TYPE_FIRE], TYPE_FIRE}, - {gTypeNames[TYPE_WATER], TYPE_WATER}, - {gTypeNames[TYPE_ELECTRIC], TYPE_ELECTRIC}, - {gTypeNames[TYPE_GRASS], TYPE_GRASS}, - {gTypeNames[TYPE_ICE], TYPE_ICE}, - {gTypeNames[TYPE_GROUND], TYPE_GROUND}, - {gTypeNames[TYPE_ROCK], TYPE_ROCK}, - {gTypeNames[TYPE_FLYING], TYPE_FLYING}, - {gTypeNames[TYPE_PSYCHIC], TYPE_PSYCHIC}, - {gTypeNames[TYPE_FIGHTING], TYPE_FIGHTING}, - {gTypeNames[TYPE_POISON], TYPE_POISON}, - {gTypeNames[TYPE_BUG], TYPE_BUG}, - {gTypeNames[TYPE_GHOST], TYPE_GHOST}, - {gTypeNames[TYPE_DRAGON], TYPE_DRAGON}, - {gTypeNames[TYPE_STEEL], TYPE_STEEL}, - {gTypeNames[TYPE_DARK], TYPE_DARK}, - {gText_UR_Exit, NUMBER_OF_MON_TYPES} -}; - -static const struct ListMenuTemplate sListMenuTemplate_TypeNames = { - .items = sListMenuItems_TypeNames, - .moveCursorFunc = ListMenuDefaultCursorMoveFunc, - .itemPrintFunc = NULL, - .totalItems = NUMBER_OF_MON_TYPES, - .maxShowed = 6, - .windowId = 0, - .header_X = 0, - .item_X = 8, - .cursor_X = 0, - .upText_Y = 2, - .cursorPal = 2, - .fillValue = 1, - .cursorShadowPal = 3, - .lettersSpacing = 1, - .itemVerticalPadding = 0, - .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, - .fontId = FONT_2, - .cursorKind = 0 -}; - -static const struct WindowTemplate sTradeBoardWindowTemplate = { - .bg = 0, - .tilemapLeft = 1, - .tilemapTop = 1, - .width = 28, - .height = 2, - .paletteNum = 13, - .baseBlock = 0x001 -}; - -static const struct WindowTemplate gUnknown_8456F24 = { - .bg = 0, - .tilemapLeft = 1, - .tilemapTop = 5, - .width = 28, - .height = 10, - .paletteNum = 13, - .baseBlock = 0x039 -}; - -static const struct ListMenuItem sTradeBoardListMenuItems[] = { - {gText_UR_EmptyString, -3}, - {gText_UR_EmptyString, 0}, - {gText_UR_EmptyString, 1}, - {gText_UR_EmptyString, 2}, - {gText_UR_EmptyString, 3}, - {gText_UR_EmptyString, 4}, - {gText_UR_EmptyString, 5}, - {gText_UR_EmptyString, 6}, - {gText_UR_EmptyString, 7}, - {gText_UR_Exit2, 8} -}; - -static const struct ListMenuTemplate sTradeBoardListMenuTemplate = { - .items = sTradeBoardListMenuItems, - .moveCursorFunc = ListMenuDefaultCursorMoveFunc, - .itemPrintFunc = TradeBoardListMenuItemPrintFunc, - .totalItems = 10, - .maxShowed = 5, - .windowId = 0, - .header_X = 0, - .item_X = 12, - .cursor_X = 0, - .upText_Y = 2, - .cursorPal = 14, - .fillValue = 15, - .cursorShadowPal = 13, - .lettersSpacing = 1, - .itemVerticalPadding = 1, - .scrollMultiple = LIST_NO_MULTIPLE_SCROLL, - .fontId = FONT_2, - .cursorKind = 0 -}; - -static const struct WindowTemplate gUnknown_8456F94 = { - .bg = 0, - .tilemapLeft = 1, - .tilemapTop = 5, - .width = 28, - .height = 10, - .paletteNum = 13, - .baseBlock = 0x039 -}; - -static const struct ListMenuItem gUnknown_8456F9C[] = { - {gText_UR_EmptyString, 0}, - {gText_UR_EmptyString, 1}, - {gText_UR_EmptyString, 2}, - {gText_UR_EmptyString, 3}, - {gText_UR_EmptyString, 4}, - {gText_UR_EmptyString, 5}, - {gText_UR_EmptyString, 6}, - {gText_UR_EmptyString, 7}, - {gText_UR_EmptyString, 8}, - {gText_UR_EmptyString, 9}, - {gText_UR_EmptyString, 10}, - {gText_UR_EmptyString, 11}, - {gText_UR_EmptyString, 12}, - {gText_UR_EmptyString, 13}, - {gText_UR_EmptyString, 14}, - {gText_UR_EmptyString, 15} -}; - -static const struct ListMenuTemplate gUnknown_845701C = { - .items = gUnknown_8456F9C, - .moveCursorFunc = ListMenuDefaultCursorMoveFunc, - .itemPrintFunc = nullsub_92, - .totalItems = 16, - .maxShowed = 4, - .windowId = 0, - .header_X = 0, - .item_X = 8, - .cursor_X = 1, - .upText_Y = 0, - .cursorPal = 2, - .fillValue = 1, - .cursorShadowPal = 3, - .lettersSpacing = 1, - .itemVerticalPadding = 0, - .scrollMultiple = LIST_MULTIPLE_SCROLL_DPAD, - .fontId = FONT_2, - .cursorKind = 0 -}; - -static const struct UnionGnameUnamePair sUnionGnameUnamePair_Dummy = {}; - -// starts at gUnknown_082F0474 in pokeemerald, union link groups - -ALIGNED(4) static const u8 gUnknown_845704C[] = { - ACTIVITY_BATTLE, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457050[] = { - ACTIVITY_DBLBATTLE, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457054[] = { - ACTIVITY_MLTBATTLE, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457058[] = { - ACTIVITY_TRADE, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_845705C[] = { - ACTIVITY_PJUMP, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457060[] = { - ACTIVITY_BCRUSH, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457064[] = { - ACTIVITY_BPICK, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457068[] = { - ACTIVITY_WCARD2, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_845706C[] = { - ACTIVITY_WNEWS2, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457070[] = { - ACTIVITY_NONE | IN_UNION_ROOM, - ACTIVITY_BATTLE | IN_UNION_ROOM, - ACTIVITY_TRADE | IN_UNION_ROOM, - ACTIVITY_CHAT | IN_UNION_ROOM, - ACTIVITY_CARD | IN_UNION_ROOM, - ACTIVITY_ACCEPT | IN_UNION_ROOM, - ACTIVITY_DECLINE | IN_UNION_ROOM, - ACTIVITY_NPCTALK | IN_UNION_ROOM, - ACTIVITY_PLYRTALK | IN_UNION_ROOM, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_845707C[] = { - ACTIVITY_SEARCH, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_8457080[] = { - ACTIVITY_BATTLE, - ACTIVITY_DBLBATTLE, - ACTIVITY_MLTBATTLE, - ACTIVITY_TRADE, - ACTIVITY_PJUMP, - ACTIVITY_BCRUSH, - ACTIVITY_BPICK, - ACTIVITY_WCARD2, - ACTIVITY_WNEWS2, - ACTIVITY_SPINTRADE, - 0xFF -}; - -ALIGNED(4) static const u8 gUnknown_845708C[] = { - ACTIVITY_BATTLE, - ACTIVITY_DBLBATTLE, - ACTIVITY_MLTBATTLE, - ACTIVITY_TRADE, - ACTIVITY_BCRUSH, - 0xFF -}; - -static const u8 *const sAcceptedActivityIds[] = { - [LINK_GROUP_SINGLE_BATTLE] = gUnknown_845704C, - [LINK_GROUP_DOUBLE_BATTLE] = gUnknown_8457050, - [LINK_GROUP_MULTI_BATTLE] = gUnknown_8457054, - [LINK_GROUP_TRADE] = gUnknown_8457058, - [LINK_GROUP_POKEMON_JUMP] = gUnknown_845705C, - [LINK_GROUP_BERRY_CRUSH] = gUnknown_8457060, - [LINK_GROUP_BERRY_PICKING] = gUnknown_8457064, - [LINK_GROUP_WONDER_CARD] = gUnknown_8457068, - [LINK_GROUP_WONDER_NEWS] = gUnknown_845706C, - [9] = gUnknown_8457070, - [10] = gUnknown_845707C, - [11] = gUnknown_8457080, - [12] = gUnknown_845708C -}; - -static const u8 sLinkGroupToURoomActivity[] = { - [LINK_GROUP_SINGLE_BATTLE] = ACTIVITY_BATTLE, - [LINK_GROUP_DOUBLE_BATTLE] = ACTIVITY_DBLBATTLE, - [LINK_GROUP_MULTI_BATTLE] = ACTIVITY_MLTBATTLE, - [LINK_GROUP_TRADE] = ACTIVITY_TRADE, - [LINK_GROUP_POKEMON_JUMP] = ACTIVITY_PJUMP, - [LINK_GROUP_BERRY_CRUSH] = ACTIVITY_BCRUSH, - [LINK_GROUP_BERRY_PICKING] = ACTIVITY_BPICK, - [LINK_GROUP_WONDER_CARD] = ACTIVITY_WCARD2, - [LINK_GROUP_WONDER_NEWS] = ACTIVITY_WNEWS2 -}; - -static const u8 sUnref_84570D1[] = _("{DYNAMIC 00}·{DYNAMIC 01}"); - -#undef _8456CD8 +#include "data/union_room.h" // These are functions in Emerald but inlined in FireRed -#define IntlConvPartnerUname7(dest, arg1) ({ \ - StringCopy_PlayerName(dest, (arg1).gname_uname.uname); \ - ConvertInternationalString(dest, (arg1).gname_uname.gname.compatibility.language); \ +#define CopyAndTranslatePlayerName(dest, player) ({ \ + StringCopy_PlayerName(dest, (player).rfu.name); \ + ConvertInternationalString(dest, (player).rfu.data.compatibility.language); \ }) -#define IntlConvPartnerUname(dest, arg1) ({ \ - StringCopy(dest, (arg1).gname_uname.uname); \ - ConvertInternationalString(dest, (arg1).gname_uname.gname.compatibility.language); \ +#define CopyAndTranslatePlayerName2(dest, player) ({ \ + StringCopy(dest, (player).rfu.name); \ + ConvertInternationalString(dest, (player).rfu.data.compatibility.language); \ }) #define CopyTrainerCardData(dest, src, _version) ({ \ - (dest) = *((struct TrainerCard * )(src)); \ - (dest).version = _version; \ + (dest) = *((struct TrainerCard * )(src)); \ + (dest).version = _version; \ }) #define GetStringRightAlignXOffset(_fontId, _string, _maxWidth) ({ \ - u16 strWidth = GetStringWidth(_fontId, _string, 0); \ - _maxWidth - strWidth; \ + u16 strWidth = GetStringWidth(_fontId, _string, 0); \ + _maxWidth - strWidth; \ }) -// capacityCode is a 2-nybble code -// Bits 0-3: Capacity -// Bits 4-7: Min required (if 0, must have exactly Capacity players -static void PrintNumPlayersWaitingForMsg(u8 windowId, u8 capacityCode, u8 count) +static void PrintNumPlayersWaitingForMsg(u8 windowId, u8 capacityCode, u8 stringId) { FillWindowPixelBuffer(windowId, PIXEL_FILL(1)); switch (capacityCode << 8) { - case 0x200: - UR_AddTextPrinterParameterized(windowId, 2, gTexts_UR_PlayersNeededOrMode[0][count - 1], 0, 2, UR_COLOR_DKE_WHT_LTE); + case LINK_GROUP_CAPACITY(0, 2): + PrintUnionRoomText(windowId, FONT_2, gTexts_UR_PlayersNeededOrMode[0][stringId - 1], 0, 2, UR_COLOR_DEFAULT); break; - case 0x400: - UR_AddTextPrinterParameterized(windowId, 2, gTexts_UR_PlayersNeededOrMode[1][count - 1], 0, 2, UR_COLOR_DKE_WHT_LTE); + case LINK_GROUP_CAPACITY(0, 4): + PrintUnionRoomText(windowId, FONT_2, gTexts_UR_PlayersNeededOrMode[1][stringId - 1], 0, 2, UR_COLOR_DEFAULT); break; - case 0x2500: - UR_AddTextPrinterParameterized(windowId, 2, gTexts_UR_PlayersNeededOrMode[2][count - 1], 0, 2, UR_COLOR_DKE_WHT_LTE); + case LINK_GROUP_CAPACITY(2, 5): + PrintUnionRoomText(windowId, FONT_2, gTexts_UR_PlayersNeededOrMode[2][stringId - 1], 0, 2, UR_COLOR_DEFAULT); break; - case 0x3500: - UR_AddTextPrinterParameterized(windowId, 2, gTexts_UR_PlayersNeededOrMode[3][count - 1], 0, 2, UR_COLOR_DKE_WHT_LTE); + case LINK_GROUP_CAPACITY(3, 5): + PrintUnionRoomText(windowId, FONT_2, gTexts_UR_PlayersNeededOrMode[3][stringId - 1], 0, 2, UR_COLOR_DEFAULT); break; } @@ -694,28 +328,33 @@ static void PrintPlayerNameAndIdOnWindow(u8 windowId) u8 text[12]; u8 text2[12]; - UR_AddTextPrinterParameterized(windowId, 2, gSaveBlock2Ptr->playerName, 0, 2, UR_COLOR_DKE_WHT_LTE); + PrintUnionRoomText(windowId, FONT_2, gSaveBlock2Ptr->playerName, 0, 2, UR_COLOR_DEFAULT); StringCopy(text2, gText_UR_ID); ConvertIntToDecimalStringN(text, ReadAsU16(gSaveBlock2Ptr->playerTrainerId), STR_CONV_MODE_LEADING_ZEROS, 5); StringAppend(text2, text); - UR_AddTextPrinterParameterized(windowId, 0, text2, 0, 0x10, UR_COLOR_DKE_WHT_LTE); + PrintUnionRoomText(windowId, FONT_0, text2, 0, 16, UR_COLOR_DEFAULT); } -static void StringExpandPlaceholders_AwaitingCommFromAnother(u8 *dst, u8 caseId) +static void GetAwaitingCommunicationText(u8 *dst, u8 caseId) { switch (caseId) { - case ACTIVITY_BATTLE: - case ACTIVITY_DBLBATTLE: - case ACTIVITY_MLTBATTLE: + case ACTIVITY_BATTLE_SINGLE: + case ACTIVITY_BATTLE_DOUBLE: + case ACTIVITY_BATTLE_MULTI: case ACTIVITY_TRADE: - case ACTIVITY_PJUMP: - case ACTIVITY_BCRUSH: - case ACTIVITY_BPICK: - case ACTIVITY_WCARD2: - case ACTIVITY_WNEWS2: - // UB: argument *dst isn't used, instead it always prints to gStringVar4 + case ACTIVITY_POKEMON_JUMP: + case ACTIVITY_BERRY_CRUSH: + case ACTIVITY_BERRY_PICK: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: + // BUG: argument *dst isn't used, instead it always prints to gStringVar4 + // not an issue in practice since Gamefreak never used any other arguments here besides gStringVar4 + #ifndef BUGFIX StringExpandPlaceholders(gStringVar4, gText_UR_AwaitingCommunication); + #else + StringExpandPlaceholders(dst, gText_UR_AwaitingCommunication); + #endif break; } } @@ -723,51 +362,51 @@ static void StringExpandPlaceholders_AwaitingCommFromAnother(u8 *dst, u8 caseId) void TryBecomeLinkLeader(void) { u8 taskId; - struct UnkStruct_Leader * dataPtr; + struct WirelessLink_Leader * data; taskId = CreateTask(Task_TryBecomeLinkLeader, 0); - sUnionRoomMain.leader = dataPtr = (void *)(gTasks[taskId].data); - sLeader = dataPtr; + sWirelessLinkMain.leader = data = (void *)(gTasks[taskId].data); + sLeader = data; - dataPtr->state = 0; - dataPtr->textState = 0; - gSpecialVar_Result = 0; + data->state = LL_STATE_INIT; + data->textState = 0; + gSpecialVar_Result = LINKUP_ONGOING; } static void Task_TryBecomeLinkLeader(u8 taskId) { u32 id, val; - struct UnkStruct_Leader * data = sUnionRoomMain.leader; + struct WirelessLink_Leader * data = sWirelessLinkMain.leader; switch (data->state) { - case 0: + case LL_STATE_INIT: sPlayerCurrActivity = sLinkGroupToActivityAndCapacity[gSpecialVar_0x8004]; sPlayerActivityGroupSize = sLinkGroupToActivityAndCapacity[gSpecialVar_0x8004] >> 8; SetHostRfuGameData(sPlayerCurrActivity, 0, 0); SetWirelessCommType1(); OpenLink(); - InitializeRfuLinkManager_LinkLeader(sPlayerActivityGroupSize & 0xF); - data->state = 3; + InitializeRfuLinkManager_LinkLeader(GROUP_MAX(sPlayerActivityGroupSize)); + data->state = LL_STATE_INIT2; break; - case 3: - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(UROOM_MAX_PARTY_SIZE * sizeof(struct UnkStruct_x20)); - data->field_8 = AllocZeroed(UROOM_MAX_PARTY_SIZE * sizeof(struct UnkStruct_x20)); - BlankUnkStruct_x1CArray(data->field_4->arr, 4); - BlankUnkStruct_x20Array(data->field_0->arr, UROOM_MAX_PARTY_SIZE); - CopyHostRfuGameDataAndUsername(&data->field_0->arr[0].gname_uname.gname, data->field_0->arr[0].gname_uname.uname); - data->field_0->arr[0].field_18 = 0; - data->field_0->arr[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - data->field_0->arr[0].field_1A_1 = 0; - data->field_0->arr[0].field_1B = 0; - data->listenTaskId = CreateTask_ListenForPartnersWithCompatibleSerialNos(data->field_4, 0xFF); + case LL_STATE_INIT2: + data->incomingPlayerList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + data->playerList = AllocZeroed(MAX_RFU_PLAYERS * sizeof(struct RfuPlayer)); + data->playerListBackup = AllocZeroed(MAX_RFU_PLAYERS * sizeof(struct RfuPlayer)); + ClearIncomingPlayerList(data->incomingPlayerList->players, RFU_CHILD_MAX); + ClearRfuPlayerList(data->playerList->players, MAX_RFU_PLAYERS); + CopyHostRfuGameDataAndUsername(&data->playerList->players[0].rfu.data, data->playerList->players[0].rfu.name); + data->playerList->players[0].timeoutCounter = 0; + data->playerList->players[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; + data->playerList->players[0].useRedText = FALSE; + data->playerList->players[0].newPlayerCountdown = 0; + data->listenTaskId = CreateTask_ListenForCompatiblePartners(data->incomingPlayerList, 0xFF); data->bButtonCancelWindowId = AddWindow(&sWindowTemplate_BButtonCancel); data->listWindowId = AddWindow(&sWindowTemplate_List_PossibleGroupMembers); data->nPlayerModeWindowId = AddWindow(&sWindowTemplate_NumPlayerMode); FillWindowPixelBuffer(data->bButtonCancelWindowId, PIXEL_FILL(2)); - UR_AddTextPrinterParameterized(data->bButtonCancelWindowId, 0, gText_UR_BButtonCancel, 8, 2, UR_COLOR_WHT_DKE_LTE); + PrintUnionRoomText(data->bButtonCancelWindowId, FONT_0, gText_UR_BButtonCancel, 8, 2, UR_COLOR_CANCEL); PutWindowTilemap(data->bButtonCancelWindowId); CopyWindowToVram(data->bButtonCancelWindowId, COPYWIN_GFX); @@ -782,129 +421,125 @@ static void Task_TryBecomeLinkLeader(u8 taskId) CopyBgTilemapBufferToVram(0); data->playerCount = 1; - data->state = 4; + data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT; break; - case 4: - StringCopy(gStringVar1, sUnionRoomActivityStringPtrs[sPlayerCurrActivity]); - if ((sPlayerActivityGroupSize >> 4) != 0) + case LL_STATE_GET_AWAITING_PLAYERS_TEXT: + StringCopy(gStringVar1, sLinkGroupActivityNameTexts[sPlayerCurrActivity]); + if (GROUP_MIN(sPlayerActivityGroupSize) != 0) { - if (data->playerCount > (sPlayerActivityGroupSize >> 4) - 1 && (sPlayerActivityGroupSize & 0xF) != 0) + if (data->playerCount > GROUP_MIN(sPlayerActivityGroupSize) - 1 && GROUP_MAX(sPlayerActivityGroupSize) != 0) StringExpandPlaceholders(gStringVar4, gText_UR_AwaitingLinkPressStart); else StringExpandPlaceholders(gStringVar4, gText_UR_AwaitingCommunication); } else { - StringExpandPlaceholders_AwaitingCommFromAnother(gStringVar4, sPlayerCurrActivity); + GetAwaitingCommunicationText(gStringVar4, sPlayerCurrActivity); } PrintNumPlayersWaitingForMsg(data->nPlayerModeWindowId, sPlayerActivityGroupSize, data->playerCount); - data->state = 5; + data->state = LL_STATE_PRINT_AWAITING_PLAYERS; break; - case 5: + case LL_STATE_PRINT_AWAITING_PLAYERS: if (PrintOnTextbox(&data->textState, gStringVar4)) - data->state = 6; + data->state = LL_STATE_AWAIT_PLAYERS; break; - case 6: - Leader_SetStateIfMemberListChanged(data, 7, 10); + case LL_STATE_AWAIT_PLAYERS: + Leader_SetStateIfMemberListChanged(data, LL_STATE_ACCEPT_NEW_MEMBER_PROMPT, LL_STATE_MEMBER_LEFT); if (JOY_NEW(B_BUTTON)) { if (data->playerCount == 1) - data->state = 23; - else if ((sPlayerActivityGroupSize & 0xF0) != 0) - data->state = 30; + data->state = LL_STATE_SHUTDOWN_AND_FAIL; + else if (GROUP_MIN2(sPlayerActivityGroupSize) != 0) + data->state = LL_STATE_CANCEL_WITH_MSG; else - data->state = 19; + data->state = LL_STATE_CANCEL_PROMPT; } - if ((sPlayerActivityGroupSize >> 4) != 0 - && data->playerCount > (sPlayerActivityGroupSize >> 4) - 1 - && (sPlayerActivityGroupSize & 0xF) != 0 + if (GROUP_MIN(sPlayerActivityGroupSize) != 0 + && data->playerCount > GROUP_MIN(sPlayerActivityGroupSize) - 1 + && GROUP_MAX(sPlayerActivityGroupSize) != 0 && IsRfuCommunicatingWithAllChildren() && JOY_NEW(START_BUTTON)) { - data->state = 15; + data->state = LL_STATE_MEMBERS_OK_PROMPT; LinkRfu_StopManagerAndFinalizeSlots(); } - if (data->state == 6 && RfuTryDisconnectLeavingChildren()) + if (data->state == LL_STATE_AWAIT_PLAYERS && RfuTryDisconnectLeavingChildren()) { - data->state = 9; + // At least 1 group member has left or is trying to leave + data->state = LL_STATE_WAIT_DISCONNECT_CHILD; } break; - case 9: + case LL_STATE_WAIT_DISCONNECT_CHILD: + // Resume after ensuring all members trying to leave have left if (!RfuTryDisconnectLeavingChildren()) { - data->state = 6; - data->playerCount = UnionRoomLeaderField0CompactionAndCount(data->field_0); + data->state = LL_STATE_AWAIT_PLAYERS; + data->playerCount = LeaderPrunePlayerList(data->playerList); } break; - case 10: - id = ((sPlayerCurrActivity & 0xF) == 2) ? 1 : 0; + case LL_STATE_MEMBER_LEFT: + id = (GROUP_MAX(sPlayerCurrActivity) == 2) ? 1 : 0; if (PrintOnTextbox(&data->textState, gTexts_UR_PlayerUnavailable[id])) { - data->playerCount = UnionRoomLeaderField0CompactionAndCount(data->field_0); + data->playerCount = LeaderPrunePlayerList(data->playerList); RedrawListMenu(data->listTaskId); - data->state = 4; + data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT; } break; - case 29: - // Other player cancelled. - id = ((sPlayerActivityGroupSize & 0xF) == 2) ? 0 : 1; + case LL_STATE_MEMBER_DISCONNECTED: + id = (GROUP_MAX(sPlayerActivityGroupSize) == 2) ? 0 : 1; if (PrintOnTextbox(&data->textState, gTexts_UR_PlayerUnavailable[id])) - { - data->state = 21; - } + data->state = LL_STATE_SHUTDOWN_AND_RETRY; break; - case 7: + case LL_STATE_ACCEPT_NEW_MEMBER_PROMPT: if (PrintOnTextbox(&data->textState, gStringVar4)) - { - data->state = 11; - } + data->state = LL_STATE_ACCEPT_NEW_MEMBER_PROMPT_HANDLE_INPUT; break; - case 11: + case LL_STATE_ACCEPT_NEW_MEMBER_PROMPT_HANDLE_INPUT: switch (UnionRoomHandleYesNo(&data->textState, HasTrainerLeftPartnersList( - ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), - data->field_0->arr[data->playerCount].gname_uname.uname))) + ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), + data->playerList->players[data->playerCount].rfu.name))) { - case 0: + case 0: // YES LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); - data->field_19 = 5; - SendRfuStatusToPartner(5, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); - data->state = 12; + data->joinRequestAnswer = RFU_STATUS_JOIN_GROUP_OK; + SendRfuStatusToPartner(data->joinRequestAnswer, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name); + data->state = LL_STATE_UPDATE_AFTER_JOIN_REQUEST; break; - case 1: - case -1: - data->field_19 = 6; - SendRfuStatusToPartner(6, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); - data->state = 12; + case 1: // NO + case MENU_B_PRESSED: + data->joinRequestAnswer = RFU_STATUS_JOIN_GROUP_NO; + SendRfuStatusToPartner(data->joinRequestAnswer, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name); + data->state = LL_STATE_UPDATE_AFTER_JOIN_REQUEST; break; case -3: - data->state = 9; + data->state = LL_STATE_WAIT_DISCONNECT_CHILD; break; } break; - case 12: - val = WaitSendRfuStatusToPartner(ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); - if (val == 1) + case LL_STATE_UPDATE_AFTER_JOIN_REQUEST: + val = WaitSendRfuStatusToPartner(ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name); + if (val == 1) // Send complete { - // Xfer complete - if (data->field_19 == 5) + if (data->joinRequestAnswer == RFU_STATUS_JOIN_GROUP_OK) { // Sent "OK" - data->field_0->arr[data->playerCount].field_1B = 0; + data->playerList->players[data->playerCount].newPlayerCountdown = 0; RedrawListMenu(data->listTaskId); data->playerCount++; - if (data->playerCount == (sPlayerActivityGroupSize & 0xF)) + if (data->playerCount == GROUP_MAX(sPlayerActivityGroupSize)) { - if ((sPlayerActivityGroupSize & 0xF0) != 0 || data->playerCount == 4) + if (GROUP_MIN2(sPlayerActivityGroupSize) != 0 || data->playerCount == RFU_CHILD_MAX) { - data->state = 15; + data->state = LL_STATE_MEMBERS_OK_PROMPT; } else { - IntlConvPartnerUname7(gStringVar1, data->field_0->arr[data->playerCount - 1]); + CopyAndTranslatePlayerName(gStringVar1, data->playerList->players[data->playerCount - 1]); StringExpandPlaceholders(gStringVar4, gText_UR_AnOKWasSentToPlayer); - data->state = 13; + data->state = LL_STATE_ACCEPTED_FINAL_MEMBER; } LinkRfu_StopManagerAndFinalizeSlots(); @@ -912,124 +547,119 @@ static void Task_TryBecomeLinkLeader(u8 taskId) } else { - data->state = 4; + data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT; } } - else + else // Member disconnected { - // Sent "no" - RequestDisconnectSlotByTrainerNameAndId(data->field_0->arr[data->playerCount].gname_uname.uname, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId)); - data->field_0->arr[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; - UnionRoomLeaderField0CompactionAndCount(data->field_0); + RequestDisconnectSlotByTrainerNameAndId(data->playerList->players[data->playerCount].rfu.name, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId)); + data->playerList->players[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; + LeaderPrunePlayerList(data->playerList); RedrawListMenu(data->listTaskId); - data->state = 4; + data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT; } - data->field_19 = 0; + data->joinRequestAnswer = 0; } else if (val == 2) { // Disconnect RfuSetStatus(RFU_STATUS_OK, 0); - data->state = 4; + data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT; } break; - case 13: + case LL_STATE_ACCEPTED_FINAL_MEMBER: if (PrintOnTextbox(&data->textState, gStringVar4)) - data->state = 14; + data->state = LL_STATE_WAIT_AND_CONFIRM_MEMBERS; break; - case 14: + case LL_STATE_WAIT_AND_CONFIRM_MEMBERS: if (++data->delayTimerAfterOk > 120) - data->state = 17; + data->state = LL_STATE_CONFIRMED_MEMBERS; break; - case 15: + case LL_STATE_MEMBERS_OK_PROMPT: if (PrintOnTextbox(&data->textState, gText_UR_AreTheseMembersOK)) - data->state = 16; + data->state = LL_STATE_MEMBERS_OK_PROMPT_HANDLE_INPUT; break; - case 16: + case LL_STATE_MEMBERS_OK_PROMPT_HANDLE_INPUT: switch (UnionRoomHandleYesNo(&data->textState, FALSE)) { - case 0: - // Yes - data->state = 17; + case 0: // YES + data->state = LL_STATE_CONFIRMED_MEMBERS; break; - case 1: - case -1: - // No - if ((sPlayerActivityGroupSize & 0xF0) != 0) - data->state = 30; + case 1: // NO + case MENU_B_PRESSED: + if (GROUP_MIN2(sPlayerActivityGroupSize) != 0) + data->state = LL_STATE_CANCEL_WITH_MSG; else - data->state = 19; + data->state = LL_STATE_CANCEL_PROMPT; break; } break; - case 19: + case LL_STATE_CANCEL_PROMPT: if (PrintOnTextbox(&data->textState, gText_UR_CancelModeWithTheseMembers)) - data->state = 20; + data->state = LL_STATE_CANCEL_PROMPT_HANDLE_INPUT; break; - case 20: + case LL_STATE_CANCEL_PROMPT_HANDLE_INPUT: switch (UnionRoomHandleYesNo(&data->textState, FALSE)) { - case 0: - data->state = 23; + case 0: // YES + data->state = LL_STATE_SHUTDOWN_AND_FAIL; break; - case 1: - case -1: - if ((sPlayerActivityGroupSize & 0xF0) != 0) - data->state = 15; - else if (data->playerCount == (sPlayerActivityGroupSize & 0xF)) - data->state = 15; + case 1: // NO + case MENU_B_PRESSED: + if (GROUP_MIN2(sPlayerActivityGroupSize) != 0) + data->state = LL_STATE_MEMBERS_OK_PROMPT; + else if (data->playerCount == GROUP_MAX(sPlayerActivityGroupSize)) + data->state = LL_STATE_MEMBERS_OK_PROMPT; else - data->state = 4; + data->state = LL_STATE_GET_AWAITING_PLAYERS_TEXT; break; } break; - case 17: - // Go to start - // Final membership check - if (!Leader_SetStateIfMemberListChanged(data, 7, 23)) - data->state = 18; + case LL_STATE_CONFIRMED_MEMBERS: + if (!Leader_SetStateIfMemberListChanged(data, LL_STATE_ACCEPT_NEW_MEMBER_PROMPT, LL_STATE_SHUTDOWN_AND_FAIL)) + data->state = LL_STATE_FINAL_MEMBER_CHECK; break; - case 18: + case LL_STATE_FINAL_MEMBER_CHECK: if (LmanAcceptSlotFlagIsNotZero()) { if (WaitRfuState(FALSE)) { - data->state = 26; + data->state = LL_STATE_TRY_START_ACTIVITY; } } else { - data->state = 29; + data->state = LL_STATE_MEMBER_DISCONNECTED; data->textState = 0; } break; - case 30: + case LL_STATE_CANCEL_WITH_MSG: if (PrintOnTextbox(&data->textState, gText_UR_ModeWithTheseMembersWillBeCanceled)) - data->state = 23; + data->state = LL_STATE_SHUTDOWN_AND_FAIL; break; - case 21: - case 23: + case LL_STATE_SHUTDOWN_AND_RETRY: + case LL_STATE_SHUTDOWN_AND_FAIL: // An error occurred. Please start over from the beginning. DestroyWirelessStatusIndicatorSprite(); LinkRfu_Shutdown(); Leader_DestroyResources(data); - data->state++; + data->state++; // LL_STATE_RETRY or LL_STATE_FAILED break; - case 24: + case LL_STATE_FAILED: ScriptContext_Enable(); DestroyTask(taskId); - gSpecialVar_Result = 5; + gSpecialVar_Result = LINKUP_FAILED; break; - case 22: + case LL_STATE_RETRY: ScriptContext_Enable(); DestroyTask(taskId); - gSpecialVar_Result = 8; + gSpecialVar_Result = LINKUP_RETRY_ROLE_ASSIGN; break; - case 26: + case LL_STATE_TRY_START_ACTIVITY: if (RfuHasErrored()) { - data->state = 29; + data->state = LL_STATE_MEMBER_DISCONNECTED; } else { @@ -1045,7 +675,7 @@ static void Task_TryBecomeLinkLeader(u8 taskId) } } -static void Leader_DestroyResources(struct UnkStruct_Leader * data) +static void Leader_DestroyResources(struct WirelessLink_Leader * data) { ClearWindowTilemap(data->nPlayerModeWindowId); ClearStdWindowAndFrame(data->nPlayerModeWindowId, FALSE); @@ -1058,28 +688,28 @@ static void Leader_DestroyResources(struct UnkStruct_Leader * data) RemoveWindow(data->bButtonCancelWindowId); DestroyTask(data->listenTaskId); - Free(data->field_8); - Free(data->field_0); - Free(data->field_4); + Free(data->playerListBackup); + Free(data->playerList); + Free(data->incomingPlayerList); } static void Leader_GetAcceptNewMemberPrompt(u8 *dst, u8 activity) { switch (activity) { - case ACTIVITY_BATTLE: - case ACTIVITY_DBLBATTLE: + case ACTIVITY_BATTLE_SINGLE: + case ACTIVITY_BATTLE_DOUBLE: case ACTIVITY_TRADE: StringExpandPlaceholders(dst, gText_UR_PlayerContactedYouForXAccept); break; - case ACTIVITY_WCARD2: - case ACTIVITY_WNEWS2: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: StringExpandPlaceholders(dst, gText_UR_PlayerContactedYouShareX); break; - case ACTIVITY_MLTBATTLE: - case ACTIVITY_PJUMP: - case ACTIVITY_BCRUSH: - case ACTIVITY_BPICK: + case ACTIVITY_BATTLE_MULTI: + case ACTIVITY_POKEMON_JUMP: + case ACTIVITY_BERRY_CRUSH: + case ACTIVITY_BERRY_PICK: StringExpandPlaceholders(dst, gText_UR_PlayerContactedYouAddToMembers); break; } @@ -1089,7 +719,7 @@ static void GetYouDeclinedTheOfferMessage(u8 *dst, u8 activity) { switch (activity) { - case ACTIVITY_BATTLE | IN_UNION_ROOM: + case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM: case ACTIVITY_TRADE | IN_UNION_ROOM: StringExpandPlaceholders(dst, gText_UR_OfferDeclined1); break; @@ -1104,17 +734,17 @@ static void GetYouAskedToJoinGroupPleaseWaitMessage(u8 *dst, u8 activity) { switch (activity) { - case ACTIVITY_BATTLE: - case ACTIVITY_DBLBATTLE: + case ACTIVITY_BATTLE_SINGLE: + case ACTIVITY_BATTLE_DOUBLE: case ACTIVITY_TRADE: - case ACTIVITY_WCARD2: - case ACTIVITY_WNEWS2: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: StringExpandPlaceholders(dst, gText_UR_AwaitingPlayersResponse); break; - case ACTIVITY_MLTBATTLE: - case ACTIVITY_PJUMP: - case ACTIVITY_BCRUSH: - case ACTIVITY_BPICK: + case ACTIVITY_BATTLE_MULTI: + case ACTIVITY_POKEMON_JUMP: + case ACTIVITY_BERRY_CRUSH: + case ACTIVITY_BERRY_PICK: StringExpandPlaceholders(dst, gText_UR_PlayerHasBeenAskedToRegisterYouPleaseWait); break; } @@ -1124,96 +754,98 @@ static void GetGroupLeaderSentAnOKMessage(u8 *dst, u8 caseId) { switch (caseId) { - case ACTIVITY_BATTLE: - case ACTIVITY_DBLBATTLE: + case ACTIVITY_BATTLE_SINGLE: + case ACTIVITY_BATTLE_DOUBLE: case ACTIVITY_TRADE: - case ACTIVITY_WCARD2: - case ACTIVITY_WNEWS2: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: StringExpandPlaceholders(dst, gText_UR_PlayerSentBackOK); break; - case ACTIVITY_MLTBATTLE: - case ACTIVITY_PJUMP: - case ACTIVITY_BCRUSH: - case ACTIVITY_BPICK: + case ACTIVITY_BATTLE_MULTI: + case ACTIVITY_POKEMON_JUMP: + case ACTIVITY_BERRY_CRUSH: + case ACTIVITY_BERRY_PICK: StringExpandPlaceholders(dst, gText_UR_PlayerOKdRegistration); break; } } -static bool8 Leader_SetStateIfMemberListChanged(struct UnkStruct_Leader * data, u32 state1, u32 state2) +static bool8 Leader_SetStateIfMemberListChanged(struct WirelessLink_Leader * data, u32 joinedState, u32 droppedState) { - switch (LeaderUpdateGroupMembership(data->field_0)) + switch (LeaderUpdateGroupMembership(data->playerList)) { case UNION_ROOM_SPAWN_IN: PlaySE(SE_PC_LOGIN); RedrawListMenu(data->listTaskId); - IntlConvPartnerUname7(gStringVar2, data->field_0->arr[data->playerCount]); + CopyAndTranslatePlayerName(gStringVar2, data->playerList->players[data->playerCount]); Leader_GetAcceptNewMemberPrompt(gStringVar4, sPlayerCurrActivity); - data->state = state1; + data->state = joinedState; break; case UNION_ROOM_SPAWN_OUT: RfuSetStatus(RFU_STATUS_OK, 0); RedrawListMenu(data->listTaskId); - data->state = state2; + data->state = droppedState; return TRUE; } return FALSE; } -static void ItemPrintFunc_PossibleGroupMembers(u8 windowId, u32 itemId, u8 y) +static void ItemPrintFunc_PossibleGroupMembers(u8 windowId, u32 id, u8 y) { - struct UnkStruct_Leader * data = sUnionRoomMain.leader; - u8 var = 0; + struct WirelessLink_Leader * data = sWirelessLinkMain.leader; + u8 colorIdx = UR_COLOR_DEFAULT; - switch (data->field_0->arr[itemId].groupScheduledAnim) + switch (data->playerList->players[id].groupScheduledAnim) { case UNION_ROOM_SPAWN_IN: - if (data->field_0->arr[itemId].field_1B != 0) - var = UR_COLOR_GRN_WHT_LTG; + if (data->playerList->players[id].newPlayerCountdown != 0) + colorIdx = UR_COLOR_GREEN; break; case UNION_ROOM_SPAWN_OUT: - var = UR_COLOR_RED_WHT_LTR; + colorIdx = UR_COLOR_RED; break; } - PrintGroupMemberCandidateOnWindowWithColor(windowId, 0, y, &data->field_0->arr[itemId], var, itemId); + PrintGroupCandidateOnWindow(windowId, 0, y, &data->playerList->players[id], colorIdx, id); } -static u8 LeaderUpdateGroupMembership(struct UnkStruct_Main0 * arg0) +static u8 LeaderUpdateGroupMembership(struct RfuPlayerList * list) { - struct UnkStruct_Leader * data = sUnionRoomMain.leader; + struct WirelessLink_Leader * data = sWirelessLinkMain.leader; u8 ret = UNION_ROOM_SPAWN_NONE; u8 i; s32 id; - for (i = 1; i < UROOM_MAX_PARTY_SIZE; i++) + for (i = 1; i < MAX_RFU_PLAYERS; i++) { - u16 var = data->field_0->arr[i].groupScheduledAnim; + u16 var = data->playerList->players[i].groupScheduledAnim; if (var == UNION_ROOM_SPAWN_IN) { - id = Findx20Inx1CArray(&data->field_0->arr[i], data->field_4->arr); + id = GetNewIncomingPlayerId(&data->playerList->players[i], data->incomingPlayerList->players); if (id != 0xFF) { - data->field_0->arr[i].gname_uname = data->field_4->arr[id].gname_uname; - data->field_0->arr[i].field_18 = 1; + // New incoming player + data->playerList->players[i].rfu = data->incomingPlayerList->players[id].rfu; + data->playerList->players[i].timeoutCounter = 1; } else { - data->field_0->arr[i].groupScheduledAnim = UNION_ROOM_SPAWN_OUT; + // No new incoming player + data->playerList->players[i].groupScheduledAnim = UNION_ROOM_SPAWN_OUT; ret = UNION_ROOM_SPAWN_OUT; } } } for (id = 0; id < RFU_CHILD_MAX; id++) - Appendx1Ctox20(data->field_0->arr, &data->field_4->arr[id], UROOM_MAX_PARTY_SIZE); + TryAddIncomingPlayerToList(data->playerList->players, &data->incomingPlayerList->players[id], MAX_RFU_PLAYERS); if (ret != UNION_ROOM_SPAWN_OUT) { - for (id = 0; id < UROOM_MAX_PARTY_SIZE; id++) + for (id = 0; id < MAX_RFU_PLAYERS; id++) { - if (data->field_0->arr[id].field_1B != 0) + if (data->playerList->players[id].newPlayerCountdown != 0) ret = UNION_ROOM_SPAWN_IN; } } @@ -1221,95 +853,95 @@ static u8 LeaderUpdateGroupMembership(struct UnkStruct_Main0 * arg0) return ret; } -static u8 UnionRoomLeaderField0CompactionAndCount(struct UnkStruct_Main0 * arg0) +static u8 LeaderPrunePlayerList(struct RfuPlayerList * list) { - struct UnkStruct_Leader * data = sUnionRoomMain.leader; + struct WirelessLink_Leader * data = sWirelessLinkMain.leader; u8 copiedCount; s32 i; - u8 ret; + u8 playerCount; - for (i = 0; i < UROOM_MAX_PARTY_SIZE; i++) - data->field_8->arr[i] = data->field_0->arr[i]; + for (i = 0; i < MAX_RFU_PLAYERS; i++) + data->playerListBackup->players[i] = data->playerList->players[i]; copiedCount = 0; - for (i = 0; i < UROOM_MAX_PARTY_SIZE; i++) + for (i = 0; i < MAX_RFU_PLAYERS; i++) { - if (data->field_8->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (data->playerListBackup->players[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - data->field_0->arr[copiedCount] = data->field_8->arr[i]; + data->playerList->players[copiedCount] = data->playerListBackup->players[i]; copiedCount++; } } - ret = copiedCount; - for (; copiedCount < UROOM_MAX_PARTY_SIZE; copiedCount++) + playerCount = copiedCount; + for (; copiedCount < MAX_RFU_PLAYERS; copiedCount++) { - data->field_0->arr[copiedCount].gname_uname = sUnionGnameUnamePair_Dummy; - data->field_0->arr[copiedCount].field_18 = 0; - data->field_0->arr[copiedCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; - data->field_0->arr[copiedCount].field_1A_1 = FALSE; - data->field_0->arr[copiedCount].field_1B = 0; + data->playerList->players[copiedCount].rfu = sRfuPlayerData_Dummy; + data->playerList->players[copiedCount].timeoutCounter = 0; + data->playerList->players[copiedCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; + data->playerList->players[copiedCount].useRedText = FALSE; + data->playerList->players[copiedCount].newPlayerCountdown = 0; } - for (i = 0; i < UROOM_MAX_PARTY_SIZE; i++) + for (i = 0; i < MAX_RFU_PLAYERS; i++) { - if (data->field_0->arr[i].groupScheduledAnim != UNION_ROOM_SPAWN_IN) + if (data->playerList->players[i].groupScheduledAnim != UNION_ROOM_SPAWN_IN) continue; - if (data->field_0->arr[i].field_1B != 0x40) + if (data->playerList->players[i].newPlayerCountdown != 64) continue; - ret = i; + playerCount = i; break; } - return ret; + return playerCount; } void TryJoinLinkGroup(void) { u8 taskId; - struct UnkStruct_Group * dataPtr; + struct WirelessLink_Group * data; taskId = CreateTask(Task_TryJoinLinkGroup, 0); - sUnionRoomMain.group = dataPtr = (void *)(gTasks[taskId].data); - sGroup = dataPtr; + sWirelessLinkMain.group = data = (void *)(gTasks[taskId].data); + sGroup = data; - dataPtr->state = 0; - dataPtr->textState = 0; - gSpecialVar_Result = 0; + data->state = LG_STATE_INIT; + data->textState = 0; + gSpecialVar_Result = LINKUP_ONGOING; } static void Task_TryJoinLinkGroup(u8 taskId) { s32 id; - struct UnkStruct_Group * data = sUnionRoomMain.group; + struct WirelessLink_Group * data = sWirelessLinkMain.group; switch (data->state) { - case 0: + case LG_STATE_INIT: SetHostRfuGameData(sLinkGroupToURoomActivity[gSpecialVar_0x8004], 0, 0); sPlayerCurrActivity = sLinkGroupToURoomActivity[gSpecialVar_0x8004]; SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(16 * sizeof(struct UnkStruct_x20)); - data->state = 1; + data->incomingPlayerList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + data->playerList = AllocZeroed(MAX_RFU_PLAYER_LIST_SIZE * sizeof(struct RfuPlayer)); + data->state = LG_STATE_CHOOSE_LEADER_MSG; break; - case 1: + case LG_STATE_CHOOSE_LEADER_MSG: if (PrintOnTextbox(&data->textState, gTexts_UR_ChooseTrainer[gSpecialVar_0x8004])) - data->state = 2; + data->state = LG_STATE_INIT_WINDOWS; break; - case 2: - BlankUnkStruct_x1CArray(data->field_4->arr, 4); - BlankUnkStruct_x20Array(data->field_0->arr, 16); - data->listenTaskId = CreateTask_ListenForPartnersWithCompatibleSerialNos(data->field_4, gSpecialVar_0x8004); + case LG_STATE_INIT_WINDOWS: + ClearIncomingPlayerList(data->incomingPlayerList->players, RFU_CHILD_MAX); + ClearRfuPlayerList(data->playerList->players, MAX_RFU_PLAYER_LIST_SIZE); + data->listenTaskId = CreateTask_ListenForCompatiblePartners(data->incomingPlayerList, gSpecialVar_0x8004); data->bButtonCancelWindowId = AddWindow(&sWindowTemplate_BButtonCancel); - data->listWindowId = AddWindow(&sWindowTemplate_MysteryGiftList); - data->playerNameAndIdWindowId = AddWindow(&sWindowTemplate_MysteryGiftPlayerNameAndId); + data->listWindowId = AddWindow(&sWindowTemplate_GroupList); + data->playerNameAndIdWindowId = AddWindow(&sWindowTemplate_PlayerNameAndId); FillWindowPixelBuffer(data->bButtonCancelWindowId, PIXEL_FILL(2)); - UR_AddTextPrinterParameterized(data->bButtonCancelWindowId, 0, gText_UR_ChooseJoinCancel, 8, 2, UR_COLOR_WHT_DKE_LTE); + PrintUnionRoomText(data->bButtonCancelWindowId, FONT_0, gText_UR_ChooseJoinCancel, 8, 2, UR_COLOR_CANCEL); PutWindowTilemap(data->bButtonCancelWindowId); CopyWindowToVram(data->bButtonCancelWindowId, COPYWIN_GFX); @@ -1325,9 +957,9 @@ static void Task_TryJoinLinkGroup(u8 taskId) CopyBgTilemapBufferToVram(0); data->leaderId = 0; - data->state = 3; + data->state = LG_STATE_CHOOSE_LEADER_HANDLE_INPUT; break; - case 3: + case LG_STATE_CHOOSE_LEADER_HANDLE_INPUT: id = GetNewLeaderCandidate(); switch (id) { @@ -1337,26 +969,26 @@ static void Task_TryJoinLinkGroup(u8 taskId) break; case 0: id = ListMenu_ProcessInput(data->listTaskId); - if (JOY_NEW(A_BUTTON) && id != -1) + if (JOY_NEW(A_BUTTON) && id != LIST_NOTHING_CHOSEN) { // this unused variable along with the assignment is needed to match - u32 unusedVar; - unusedVar = data->field_0->arr[id].gname_uname.gname.activity; + u32 activity = data->playerList->players[id].rfu.data.activity; - if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[id].gname_uname.gname.startedActivity) + if (data->playerList->players[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->playerList->players[id].rfu.data.startedActivity) { - u32 var = IsTryingToTradeWithHoennTooSoon(data, id); - if (var == 0) + u32 readyStatus = IsTryingToTradeAcrossVersionTooSoon(data, id); + if (readyStatus == UR_TRADE_READY) { + // Trading is allowed, or not trading at all AskToJoinRfuGroup(data, id); - data->state = 5; + data->state = LG_STATE_ASK_JOIN_GROUP; PlaySE(SE_POKENAV_ON); } else { // Postgame flags not both set - StringCopy(gStringVar4, gTexts_UR_CantTransmitToTrainer[var - 1]); - data->state = 18; + StringCopy(gStringVar4, gTexts_UR_CantTransmitToTrainer[readyStatus - 1]); + data->state = LG_STATE_TRADE_NOT_READY; PlaySE(SE_POKENAV_ON); } } @@ -1367,7 +999,7 @@ static void Task_TryJoinLinkGroup(u8 taskId) } else if (JOY_NEW(B_BUTTON)) { - data->state = 10; + data->state = LG_STATE_CANCEL_CHOOSE_LEADER; } break; default: @@ -1375,59 +1007,58 @@ static void Task_TryJoinLinkGroup(u8 taskId) break; } break; - case 5: + case LG_STATE_ASK_JOIN_GROUP: GetYouAskedToJoinGroupPleaseWaitMessage(gStringVar4, sPlayerCurrActivity); if (PrintOnTextbox(&data->textState, gStringVar4)) { - IntlConvPartnerUname7(gStringVar1, data->field_0->arr[data->leaderId]); - data->state = 6; + CopyAndTranslatePlayerName(gStringVar1, data->playerList->players[data->leaderId]); + data->state = LG_STATE_MAIN; } break; - case 6: + case LG_STATE_MAIN: if (gReceivedRemoteLinkPlayers) { - sPlayerCurrActivity = data->field_0->arr[data->leaderId].gname_uname.gname.activity; + sPlayerCurrActivity = data->playerList->players[data->leaderId].rfu.data.activity; RfuSetStatus(RFU_STATUS_OK, 0); switch (sPlayerCurrActivity) { - case ACTIVITY_BATTLE: - case ACTIVITY_DBLBATTLE: - case ACTIVITY_MLTBATTLE: + case ACTIVITY_BATTLE_SINGLE: + case ACTIVITY_BATTLE_DOUBLE: + case ACTIVITY_BATTLE_MULTI: case ACTIVITY_TRADE: case ACTIVITY_CHAT: - case ACTIVITY_PJUMP: - case ACTIVITY_BCRUSH: - case ACTIVITY_BPICK: - case ACTIVITY_SPINTRADE: - case ACTIVITY_ITEMTRADE: - case ACTIVITY_WCARD2: - case ACTIVITY_WNEWS2: - data->state = 20; + case ACTIVITY_POKEMON_JUMP: + case ACTIVITY_BERRY_CRUSH: + case ACTIVITY_BERRY_PICK: + case ACTIVITY_SPIN_TRADE: + case ACTIVITY_ITEM_TRADE: + case ACTIVITY_WONDER_CARD: + case ACTIVITY_WONDER_NEWS: + data->state = LG_STATE_READY_START_ACTIVITY; break; } } switch (RfuGetStatus()) { - case 1: - data->state = 12; + case RFU_STATUS_FATAL_ERROR: + data->state = LG_STATE_RFU_ERROR; break; - case 2: - case 6: - case 9: - data->state = 14; + case RFU_STATUS_CONNECTION_ERROR: + case RFU_STATUS_JOIN_GROUP_NO: + case RFU_STATUS_LEAVE_GROUP: + data->state = LG_STATE_DISCONNECTED; break; - case 5: + case RFU_STATUS_JOIN_GROUP_OK: GetGroupLeaderSentAnOKMessage(gStringVar4, sPlayerCurrActivity); if (PrintOnTextbox(&data->textState, gStringVar4)) { RfuSetStatus(RFU_STATUS_WAIT_ACK_JOIN_GROUP, 0); - StringCopy(gStringVar1, sUnionRoomActivityStringPtrs[sPlayerCurrActivity]); + StringCopy(gStringVar1, sLinkGroupActivityNameTexts[sPlayerCurrActivity]); StringExpandPlaceholders(gStringVar4, gText_UR_AwaitingOtherMembers); } break; - case 7: - // Wait 4 seconds + case RFU_STATUS_WAIT_ACK_JOIN_GROUP: if (data->delayBeforePrint > 240) { if (PrintOnTextbox(&data->textState, gStringVar4)) @@ -1443,41 +1074,41 @@ static void Task_TryJoinLinkGroup(u8 taskId) break; } - if (!RfuGetStatus() && JOY_NEW(B_BUTTON)) - data->state = 7; + if (RfuGetStatus() == RFU_STATUS_OK && JOY_NEW(B_BUTTON)) + data->state = LG_STATE_ASK_LEAVE_GROUP; break; - case 7: + case LG_STATE_ASK_LEAVE_GROUP: if (PrintOnTextbox(&data->textState, gText_UR_QuitBeingMember)) - data->state = 8; + data->state = LG_STATE_ASK_LEAVE_GROUP_HANDLE_INPUT; break; - case 8: + case LG_STATE_ASK_LEAVE_GROUP_HANDLE_INPUT: switch (UnionRoomHandleYesNo(&data->textState, RfuGetStatus())) { - case 0: + case 0: // YES SendLeaveGroupNotice(); - data->state = 9; + data->state = LG_STATE_WAIT_LEAVE_GROUP; RedrawListMenu(data->listTaskId); break; - case 1: - case -1: - data->state = 5; + case 1: // NO + case MENU_B_PRESSED: + data->state = LG_STATE_ASK_JOIN_GROUP; RedrawListMenu(data->listTaskId); break; case -3: - data->state = 6; + data->state = LG_STATE_MAIN; RedrawListMenu(data->listTaskId); break; } break; - case 9: + case LG_STATE_WAIT_LEAVE_GROUP: if (RfuGetStatus()) - data->state = 6; + data->state = LG_STATE_MAIN; break; - case 10: - case 12: - case 14: - case 18: - case 20: + case LG_STATE_CANCEL_CHOOSE_LEADER: // next: LG_STATE_CANCELED + case LG_STATE_RFU_ERROR: // next: LG_STATE_RFU_ERROR_SHUTDOWN + case LG_STATE_DISCONNECTED: // next: LG_STATE_RETRY_CONNECTION + case LG_STATE_TRADE_NOT_READY: // next: LG_STATE_TRADE_NOT_READY_RETRY + case LG_STATE_READY_START_ACTIVITY: // next: LG_STATE_START_ACTIVITY ClearWindowTilemap(data->playerNameAndIdWindowId); ClearStdWindowAndFrame(data->playerNameAndIdWindowId, FALSE); DestroyListMenuTask(data->listTaskId, 0, 0); @@ -1488,116 +1119,121 @@ static void Task_TryJoinLinkGroup(u8 taskId) RemoveWindow(data->listWindowId); RemoveWindow(data->bButtonCancelWindowId); DestroyTask(data->listenTaskId); - Free(data->field_0); - Free(data->field_4); + Free(data->playerList); + Free(data->incomingPlayerList); data->state++; break; - case 13: + case LG_STATE_RFU_ERROR_SHUTDOWN: DestroyWirelessStatusIndicatorSprite(); if (PrintOnTextbox(&data->textState, gTexts_UR_PlayerDisconnected[RfuGetStatus()])) { - gSpecialVar_Result = 6; - data->state = 23; + gSpecialVar_Result = LINKUP_CONNECTION_ERROR; + data->state = LG_STATE_SHUTDOWN; } break; - case 11: + case LG_STATE_CANCELED: DestroyWirelessStatusIndicatorSprite(); - gSpecialVar_Result = 5; - data->state = 23; + gSpecialVar_Result = LINKUP_FAILED; + data->state = LG_STATE_SHUTDOWN; break; - case 15: + case LG_STATE_RETRY_CONNECTION: + // Failure from disconnection + // Happens if player or required member(s) leave group + // or if player is rejected from joining group DestroyWirelessStatusIndicatorSprite(); if (PrintOnTextbox(&data->textState, gTexts_UR_PlayerDisconnected[RfuGetStatus()])) { - gSpecialVar_Result = 8; - data->state = 23; + gSpecialVar_Result = LINKUP_RETRY_ROLE_ASSIGN; + data->state = LG_STATE_SHUTDOWN; } break; - case 19: + case LG_STATE_TRADE_NOT_READY_RETRY: if (PrintOnTextbox(&data->textState, gStringVar4)) { - gSpecialVar_Result = 8; - data->state = 23; + gSpecialVar_Result = LINKUP_RETRY_ROLE_ASSIGN; + data->state = LG_STATE_SHUTDOWN; } break; - case 23: + case LG_STATE_SHUTDOWN: DestroyTask(taskId); - JoinGroup_BlankBg0AndEnableScriptContexts(); + JoinGroup_EnableScriptContexts(); LinkRfu_Shutdown(); break; - case 21: + case LG_STATE_START_ACTIVITY: CreateTask_RunScriptAndFadeToActivity(); DestroyTask(taskId); break; } } -static u32 IsTryingToTradeWithHoennTooSoon(struct UnkStruct_Group * arg0, s32 id) +static u32 IsTryingToTradeAcrossVersionTooSoon(struct WirelessLink_Group * data, s32 id) { - struct UnkStruct_x20 * structPtr = &arg0->field_0->arr[id]; + struct RfuPlayer * partner = &data->playerList->players[id]; - if (sPlayerCurrActivity == ACTIVITY_TRADE && structPtr->gname_uname.gname.compatibility.version != VERSION_FIRE_RED && structPtr->gname_uname.gname.compatibility.version != VERSION_LEAF_GREEN) + if (sPlayerCurrActivity == ACTIVITY_TRADE + && partner->rfu.data.compatibility.version != VERSION_FIRE_RED + && partner->rfu.data.compatibility.version != VERSION_LEAF_GREEN) { if (!(gSaveBlock2Ptr->specialSaveWarpFlags & CHAMPION_SAVEWARP)) - return 1; - else if (structPtr->gname_uname.gname.compatibility.isChampion) - return 0; + return UR_TRADE_PLAYER_NOT_READY; + else if (partner->rfu.data.compatibility.isChampion) + return UR_TRADE_READY; } else { - return 0; + return UR_TRADE_READY; } - return 2; + return UR_TRADE_PARTNER_NOT_READY; } -static void AskToJoinRfuGroup(struct UnkStruct_Group * data, s32 id) +static void AskToJoinRfuGroup(struct WirelessLink_Group * data, s32 id) { data->leaderId = id; LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); RedrawListMenu(data->listTaskId); - IntlConvPartnerUname7(gStringVar1, data->field_0->arr[data->leaderId]); + CopyAndTranslatePlayerName(gStringVar1, data->playerList->players[data->leaderId]); UpdateGameData_SetActivity(sLinkGroupToURoomActivity[gSpecialVar_0x8004], 0, TRUE); - CreateTask_RfuReconnectWithParent(data->field_0->arr[data->leaderId].gname_uname.uname, ReadAsU16(data->field_0->arr[data->leaderId].gname_uname.gname.compatibility.playerTrainerId)); + CreateTask_RfuReconnectWithParent(data->playerList->players[data->leaderId].rfu.name, ReadAsU16(data->playerList->players[data->leaderId].rfu.data.compatibility.playerTrainerId)); } u8 CreateTask_ListenToWireless(void) { u8 taskId; - struct UnkStruct_Group * dataPtr; + struct WirelessLink_Group * data; taskId = CreateTask(Task_ListenToWireless, 0); - sUnionRoomMain.group = dataPtr = (void *)(gTasks[taskId].data); + sWirelessLinkMain.group = data = (void *)(gTasks[taskId].data); - dataPtr->state = 0; - dataPtr->textState = 0; + data->state = 0; + data->textState = 0; - sGroup = dataPtr; + sGroup = data; return taskId; } static void Task_ListenToWireless(u8 taskId) { - struct UnkStruct_Group * data = sUnionRoomMain.group; + struct WirelessLink_Group * data = sWirelessLinkMain.group; switch (data->state) { case 0: - SetHostRfuGameData(0, 0, 0); + SetHostRfuGameData(ACTIVITY_NONE, 0, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); RfuSetIgnoreError(TRUE); - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(16 * sizeof(struct UnkStruct_x20)); + data->incomingPlayerList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + data->playerList = AllocZeroed(MAX_RFU_PLAYER_LIST_SIZE * sizeof(struct RfuPlayer)); data->state = 2; break; case 2: - BlankUnkStruct_x1CArray(data->field_4->arr, 4); - BlankUnkStruct_x20Array(data->field_0->arr, 16); - data->listenTaskId = CreateTask_ListenForPartnersWithCompatibleSerialNos(data->field_4, 0xFF); + ClearIncomingPlayerList(data->incomingPlayerList->players, RFU_CHILD_MAX); + ClearRfuPlayerList(data->playerList->players, MAX_RFU_PLAYER_LIST_SIZE); + data->listenTaskId = CreateTask_ListenForCompatiblePartners(data->incomingPlayerList, 0xFF); data->leaderId = 0; data->state = 3; break; @@ -1609,8 +1245,8 @@ static void Task_ListenToWireless(u8 taskId) break; case 10: DestroyTask(data->listenTaskId); - Free(data->field_0); - Free(data->field_4); + Free(data->playerList); + Free(data->incomingPlayerList); LinkRfu_Shutdown(); data->state++; break; @@ -1626,11 +1262,11 @@ static bool32 IsPartnerActivityAcceptable(u32 activity, u32 group) if (group == 0xFF) return TRUE; - #ifndef UBFIX - if (group <= NELEMS(sAcceptedActivityIds)) // UB: <= may access data outside the array - #else - if (group < NELEMS(sAcceptedActivityIds)) - #endif +#ifdef UBFIX + if (group < ARRAY_COUNT(sAcceptedActivityIds)) +#else + if (group <= ARRAY_COUNT(sAcceptedActivityIds)) // UB: <= may access data outside the array +#endif { const u8 *bytes = sAcceptedActivityIds[group]; @@ -1645,78 +1281,78 @@ static bool32 IsPartnerActivityAcceptable(u32 activity, u32 group) return FALSE; } -static u8 URoomGroupListGetTextColor(struct UnkStruct_Group * data, u32 id) +static u8 GetGroupListTextColor(struct WirelessLink_Group * data, u32 id) { - if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (data->playerList->players[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - if (data->field_0->arr[id].gname_uname.gname.startedActivity) - return UR_COLOR_WHT_WHT_LTE; - else if (data->field_0->arr[id].field_1A_1) - return UR_COLOR_RED_WHT_LTR; - else if (data->field_0->arr[id].field_1B != 0) - return UR_COLOR_GRN_WHT_LTG; + if (data->playerList->players[id].rfu.data.startedActivity) + return UR_COLOR_WHITE; + else if (data->playerList->players[id].useRedText) + return UR_COLOR_RED; + else if (data->playerList->players[id].newPlayerCountdown != 0) + return UR_COLOR_GREEN; } - return UR_COLOR_DKE_WHT_LTE; + return UR_COLOR_DEFAULT; } -static void ListMenuItemPrintFunc_UnionRoomGroups(u8 windowId, u32 itemId, u8 y) +static void ListMenuItemPrintFunc_UnionRoomGroups(u8 windowId, u32 id, u8 y) { - struct UnkStruct_Group * data = sUnionRoomMain.group; - u8 color_idx = URoomGroupListGetTextColor(data, itemId); + struct WirelessLink_Group * data = sWirelessLinkMain.group; + u8 colorId = GetGroupListTextColor(data, id); - PrintUnionRoomGroupOnWindow(windowId, 8, y, &data->field_0->arr[itemId], color_idx, itemId); + PrintGroupMemberOnWindow(windowId, 8, y, &data->playerList->players[id], colorId, id); } static u8 GetNewLeaderCandidate(void) { - struct UnkStruct_Group * data = sUnionRoomMain.group; + struct WirelessLink_Group * data = sWirelessLinkMain.group; u8 ret = 0; u8 i; s32 id; - for (i = 0; i < 16; i++) + for (i = 0; i < MAX_RFU_PLAYER_LIST_SIZE; i++) { - if (data->field_0->arr[i].groupScheduledAnim != UNION_ROOM_SPAWN_NONE) + if (data->playerList->players[i].groupScheduledAnim != UNION_ROOM_SPAWN_NONE) { - id = Findx20Inx1CArray(&data->field_0->arr[i], data->field_4->arr); + id = GetNewIncomingPlayerId(&data->playerList->players[i], data->incomingPlayerList->players); if (id != 0xFF) { - if (data->field_0->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (data->playerList->players[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - if (AreUnionRoomPlayerGnamesDifferent(&data->field_0->arr[i].gname_uname, &data->field_4->arr[id].gname_uname)) + if (ArePlayerDataDifferent(&data->playerList->players[i].rfu, &data->incomingPlayerList->players[id].rfu)) { - data->field_0->arr[i].gname_uname = data->field_4->arr[id].gname_uname; - data->field_0->arr[i].field_1B = 64; + data->playerList->players[i].rfu = data->incomingPlayerList->players[id].rfu; + data->playerList->players[i].newPlayerCountdown = 64; ret = 1; } else { - if (data->field_0->arr[i].field_1B != 0) + if (data->playerList->players[i].newPlayerCountdown != 0) { - data->field_0->arr[i].field_1B--; - if (data->field_0->arr[i].field_1B == 0) + data->playerList->players[i].newPlayerCountdown--; + if (data->playerList->players[i].newPlayerCountdown == 0) ret = 2; } } } else { - data->field_0->arr[i].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - data->field_0->arr[i].field_1B = 64; + data->playerList->players[i].groupScheduledAnim = UNION_ROOM_SPAWN_IN; + data->playerList->players[i].newPlayerCountdown = 64; ret = 1; } - data->field_0->arr[i].field_18 = 0; + data->playerList->players[i].timeoutCounter = 0; } else { - if (data->field_0->arr[i].groupScheduledAnim != UNION_ROOM_SPAWN_OUT) + if (data->playerList->players[i].groupScheduledAnim != UNION_ROOM_SPAWN_OUT) { - data->field_0->arr[i].field_18++; - if (data->field_0->arr[i].field_18 >= 300) + data->playerList->players[i].timeoutCounter++; + if (data->playerList->players[i].timeoutCounter >= 300) { - data->field_0->arr[i].groupScheduledAnim = UNION_ROOM_SPAWN_OUT; + data->playerList->players[i].groupScheduledAnim = UNION_ROOM_SPAWN_OUT; ret = 2; } } @@ -1726,24 +1362,22 @@ static u8 GetNewLeaderCandidate(void) for (id = 0; id < RFU_CHILD_MAX; id++) { - if (Appendx1Ctox20(data->field_0->arr, &data->field_4->arr[id], 16) != 0xFF) + if (TryAddIncomingPlayerToList(data->playerList->players, &data->incomingPlayerList->players[id], MAX_RFU_PLAYER_LIST_SIZE) != 0xFF) ret = 1; } return ret; } -static void Task_CallCB2ReturnFromLinkTrade(u8 taskId) +static void Task_CreateTradeMenu(u8 taskId) { - CB2_ReturnFromLinkTrade(); + CB2_StartCreateTradeMenu(); DestroyTask(taskId); } -u8 UnionRoom_CreateTask_CallCB2ReturnFromLinkTrade(void) +u8 CreateTask_CreateTradeMenu(void) { - u8 taskId = CreateTask(Task_CallCB2ReturnFromLinkTrade, 0); - - return taskId; + return CreateTask(Task_CreateTradeMenu, 0); } static void Task_StartUnionRoomTrade(u8 taskId) @@ -1778,7 +1412,7 @@ static void Task_StartUnionRoomTrade(u8 taskId) gSelectedTradeMonPositions[TRADE_PLAYER] = monId; gSelectedTradeMonPositions[TRADE_PARTNER] = PARTY_SIZE; gMain.savedCallback = CB2_ReturnToField; - SetMainCallback2(CB2_InitTradeAnim_LinkTrade); + SetMainCallback2(CB2_LinkTrade); ResetUnionRoomTrade(&sUnionRoomTrade); DestroyTask(taskId); } @@ -1804,17 +1438,17 @@ static void Task_ExchangeCards(u8 taskId) for (i = 0; i < GetLinkPlayerCount(); i++) { recvBuff = gBlockRecvBuffer[i]; - CopyTrainerCardData(gTrainerCards[i], recvBuff, gLinkPlayers[i].version); + CopyTrainerCardData(gTrainerCards[i], (struct TrainerCard *)recvBuff, gLinkPlayers[i].version); } if (GetLinkPlayerCount() == 2) { recvBuff = gBlockRecvBuffer[GetMultiplayerId() ^ 1]; - MEventHandleReceivedWonderCard(recvBuff[sizeof(struct TrainerCard) / 2]); + MysteryGift_TryEnableStatsByFlagId(recvBuff[sizeof(struct TrainerCard) / 2]); } else { - ResetReceivedWonderCardFlag(); + MysteryGift_DisableStats(); } ResetBlockReceivedFlags(); @@ -1857,22 +1491,22 @@ void StartUnionRoomBattle(u16 battleFlags) PlayBattleBGM(); } -static void SetCableClubStateAndWarpCurrentMap(u16 linkService, u16 x, u16 y) +static void WarpForWirelessMinigame(u16 linkService, u16 x, u16 y) { VarSet(VAR_CABLE_CLUB_STATE, linkService); - SetWarpDestination(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1, x, y); - SetDynamicWarpWithCoords(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, -1, x, y); + SetWarpDestination(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, WARP_ID_NONE, x, y); + SetDynamicWarpWithCoords(0, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, WARP_ID_NONE, x, y); WarpIntoMap(); } -static void SetCableClubStateAndWarpToNewMap(s8 mapGroup, s8 mapNum, s32 x, s32 y, u16 linkService) +static void WarpForCableClubActivity(s8 mapGroup, s8 mapNum, s32 x, s32 y, u16 linkService) { gSpecialVar_0x8004 = linkService; VarSet(VAR_CABLE_CLUB_STATE, linkService); gFieldLinkPlayerCount = GetLinkPlayerCount(); gLocalLinkPlayerId = GetMultiplayerId(); SetCableClubWarp(); - SetWarpDestination(mapGroup, mapNum, -1, x, y); + SetWarpDestination(mapGroup, mapNum, WARP_ID_NONE, x, y); WarpIntoMap(); } @@ -1907,61 +1541,61 @@ static void CreateTrainerCardInBuffer(void *dest, bool32 setWonderCard) static void Task_StartActivity(u8 taskId) { - ResetReceivedWonderCardFlag(); + MysteryGift_DisableStats(); switch (sPlayerCurrActivity) { - case ACTIVITY_BATTLE: - case ACTIVITY_DBLBATTLE: - case ACTIVITY_MLTBATTLE: + case ACTIVITY_BATTLE_SINGLE: + case ACTIVITY_BATTLE_DOUBLE: + case ACTIVITY_BATTLE_MULTI: case ACTIVITY_TRADE: - case ACTIVITY_PJUMP: - case ACTIVITY_BCRUSH: - case ACTIVITY_BPICK: - case ACTIVITY_SPINTRADE: - case ACTIVITY_ITEMTRADE: + case ACTIVITY_POKEMON_JUMP: + case ACTIVITY_BERRY_CRUSH: + case ACTIVITY_BERRY_PICK: + case ACTIVITY_SPIN_TRADE: + case ACTIVITY_ITEM_TRADE: SaveLinkTrainerNames(); break; } switch (sPlayerCurrActivity) { - case ACTIVITY_BATTLE | IN_UNION_ROOM: + case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM: case ACTIVITY_ACCEPT | IN_UNION_ROOM: CleanupOverworldWindowsAndTilemaps(); gMain.savedCallback = CB2_UnionRoomBattle; InitChooseMonsForBattle(CHOOSE_MONS_FOR_UNION_ROOM_BATTLE); break; - case ACTIVITY_BATTLE: + case ACTIVITY_BATTLE_SINGLE: CleanupOverworldWindowsAndTilemaps(); CreateTrainerCardInBuffer(gBlockSendBuffer, TRUE); HealPlayerParty(); SavePlayerParty(); LoadPlayerBag(); - SetCableClubStateAndWarpToNewMap(MAP_GROUP(BATTLE_COLOSSEUM_2P), MAP_NUM(BATTLE_COLOSSEUM_2P), 6, 8, USING_SINGLE_BATTLE); + WarpForCableClubActivity(MAP_GROUP(BATTLE_COLOSSEUM_2P), MAP_NUM(BATTLE_COLOSSEUM_2P), 6, 8, USING_SINGLE_BATTLE); SetMainCallback2(CB2_TransitionToCableClub); break; - case ACTIVITY_DBLBATTLE: + case ACTIVITY_BATTLE_DOUBLE: CleanupOverworldWindowsAndTilemaps(); HealPlayerParty(); SavePlayerParty(); LoadPlayerBag(); CreateTrainerCardInBuffer(gBlockSendBuffer, TRUE); - SetCableClubStateAndWarpToNewMap(MAP_GROUP(BATTLE_COLOSSEUM_2P), MAP_NUM(BATTLE_COLOSSEUM_2P), 6, 8, USING_DOUBLE_BATTLE); + WarpForCableClubActivity(MAP_GROUP(BATTLE_COLOSSEUM_2P), MAP_NUM(BATTLE_COLOSSEUM_2P), 6, 8, USING_DOUBLE_BATTLE); SetMainCallback2(CB2_TransitionToCableClub); break; - case ACTIVITY_MLTBATTLE: + case ACTIVITY_BATTLE_MULTI: CleanupOverworldWindowsAndTilemaps(); HealPlayerParty(); SavePlayerParty(); LoadPlayerBag(); CreateTrainerCardInBuffer(gBlockSendBuffer, TRUE); - SetCableClubStateAndWarpToNewMap(MAP_GROUP(BATTLE_COLOSSEUM_4P), MAP_NUM(BATTLE_COLOSSEUM_4P), 5, 8, USING_MULTI_BATTLE); + WarpForCableClubActivity(MAP_GROUP(BATTLE_COLOSSEUM_4P), MAP_NUM(BATTLE_COLOSSEUM_4P), 5, 8, USING_MULTI_BATTLE); SetMainCallback2(CB2_TransitionToCableClub); break; case ACTIVITY_TRADE: CreateTrainerCardInBuffer(gBlockSendBuffer, TRUE); CleanupOverworldWindowsAndTilemaps(); - SetCableClubStateAndWarpToNewMap(MAP_GROUP(TRADE_CENTER), MAP_NUM(TRADE_CENTER), 5, 8, USING_TRADE_CENTER); + WarpForCableClubActivity(MAP_GROUP(TRADE_CENTER), MAP_NUM(TRADE_CENTER), 5, 8, USING_TRADE_CENTER); SetMainCallback2(CB2_TransitionToCableClub); break; case ACTIVITY_TRADE | IN_UNION_ROOM: @@ -1976,7 +1610,7 @@ static void Task_StartActivity(u8 taskId) else { LinkRfu_StopManagerBeforeEnteringChat(); - SetHostRfuGameData(ACTIVITY_CHAT | IN_UNION_ROOM, 0, 1); + SetHostRfuGameData(ACTIVITY_CHAT | IN_UNION_ROOM, 0, TRUE); } EnterUnionRoomChat(); break; @@ -1985,22 +1619,22 @@ static void Task_StartActivity(u8 taskId) CreateTrainerCardInBuffer(gBlockSendBuffer, FALSE); SetMainCallback2(CB2_ShowCard); break; - case ACTIVITY_PJUMP: - SetCableClubStateAndWarpCurrentMap(USING_MINIGAME, 5, 1); + case ACTIVITY_POKEMON_JUMP: + WarpForWirelessMinigame(USING_MINIGAME, 5, 1); StartPokemonJump(GetCursorSelectionMonId(), CB2_LoadMap); break; - case ACTIVITY_BCRUSH: - SetCableClubStateAndWarpCurrentMap(USING_BERRY_CRUSH, 9, 1); + case ACTIVITY_BERRY_CRUSH: + WarpForWirelessMinigame(USING_BERRY_CRUSH, 9, 1); StartBerryCrush(CB2_LoadMap); break; - case ACTIVITY_BPICK: - SetCableClubStateAndWarpCurrentMap(USING_MINIGAME, 5, 1); + case ACTIVITY_BERRY_PICK: + WarpForWirelessMinigame(USING_MINIGAME, 5, 1); StartDodrioBerryPicking(GetCursorSelectionMonId(), CB2_LoadMap); break; } DestroyTask(taskId); - gSpecialVar_Result = 1; + gSpecialVar_Result = LINKUP_SUCCESS; UnlockPlayerFieldControls(); } @@ -2012,7 +1646,7 @@ static void Task_RunScriptAndFadeToActivity(u8 taskId) switch (data[0]) { case 0: - gSpecialVar_Result = 1; + gSpecialVar_Result = LINKUP_SUCCESS; ScriptContext_Enable(); data[0]++; break; @@ -2051,23 +1685,24 @@ static void CreateTask_StartActivity(void) gTasks[taskId].data[0] = 0; } -void MEvent_CreateTask_Leader(u32 activity) +// Sending Wonder Card/News +void CreateTask_SendMysteryGift(u32 activity) { u8 taskId; - struct UnkStruct_Leader * dataPtr; + struct WirelessLink_Leader * data; - taskId = CreateTask(Task_MEvent_Leader, 0); - sUnionRoomMain.leader = dataPtr = (void *)(gTasks[taskId].data); + taskId = CreateTask(Task_SendMysteryGift, 0); + sWirelessLinkMain.leader = data = (void *)(gTasks[taskId].data); - dataPtr->state = 0; - dataPtr->textState = 0; - dataPtr->activity = activity; - gSpecialVar_Result = 0; + data->state = 0; + data->textState = 0; + data->activity = activity; + gSpecialVar_Result = LINKUP_ONGOING; } -static void Task_MEvent_Leader(u8 taskId) +static void Task_SendMysteryGift(u8 taskId) { - struct UnkStruct_Leader * data = sUnionRoomMain.leader; + struct WirelessLink_Leader * data = sWirelessLinkMain.leader; struct WindowTemplate winTemplate; s32 val; @@ -2076,7 +1711,7 @@ static void Task_MEvent_Leader(u8 taskId) case 0: sPlayerCurrActivity = data->activity; sPlayerActivityGroupSize = 2; - SetHostRfuGameData(data->activity, 0, 0); + SetHostRfuGameData(data->activity, 0, FALSE); SetHostRfuWonderFlags(FALSE, FALSE); SetWirelessCommType1(); OpenLink(); @@ -2084,17 +1719,17 @@ static void Task_MEvent_Leader(u8 taskId) data->state = 1; break; case 1: - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(UROOM_MAX_PARTY_SIZE * sizeof(struct UnkStruct_x20)); - data->field_8 = AllocZeroed(UROOM_MAX_PARTY_SIZE * sizeof(struct UnkStruct_x20)); - BlankUnkStruct_x1CArray(data->field_4->arr, 4); - BlankUnkStruct_x20Array(data->field_0->arr, UROOM_MAX_PARTY_SIZE); - CopyHostRfuGameDataAndUsername(&data->field_0->arr[0].gname_uname.gname, data->field_0->arr[0].gname_uname.uname); - data->field_0->arr[0].field_18 = 0; - data->field_0->arr[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - data->field_0->arr[0].field_1A_1 = FALSE; - data->field_0->arr[0].field_1B = 0; - data->listenTaskId = CreateTask_ListenForPartnersWithCompatibleSerialNos(data->field_4, 0xFF); + data->incomingPlayerList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + data->playerList = AllocZeroed(MAX_RFU_PLAYERS * sizeof(struct RfuPlayer)); + data->playerListBackup = AllocZeroed(MAX_RFU_PLAYERS * sizeof(struct RfuPlayer)); + ClearIncomingPlayerList(data->incomingPlayerList->players, RFU_CHILD_MAX); + ClearRfuPlayerList(data->playerList->players, MAX_RFU_PLAYERS); + CopyHostRfuGameDataAndUsername(&data->playerList->players[0].rfu.data, data->playerList->players[0].rfu.name); + data->playerList->players[0].timeoutCounter = 0; + data->playerList->players[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; + data->playerList->players[0].useRedText = FALSE; + data->playerList->players[0].newPlayerCountdown = 0; + data->listenTaskId = CreateTask_ListenForCompatiblePartners(data->incomingPlayerList, 0xFF); winTemplate = sWindowTemplate_List_PossibleGroupMembers; winTemplate.baseBlock = GetMysteryGiftBaseBlock(); @@ -2109,8 +1744,8 @@ static void Task_MEvent_Leader(u8 taskId) data->state = 2; break; case 2: - StringCopy(gStringVar1, sUnionRoomActivityStringPtrs[sPlayerCurrActivity]); - StringExpandPlaceholders_AwaitingCommFromAnother(gStringVar4, sPlayerCurrActivity); + StringCopy(gStringVar1, sLinkGroupActivityNameTexts[sPlayerCurrActivity]); + GetAwaitingCommunicationText(gStringVar4, sPlayerCurrActivity); data->state = 3; break; case 3: @@ -2126,9 +1761,9 @@ static void Task_MEvent_Leader(u8 taskId) } break; case 6: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_UR_LinkWithFriendDropped)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_UR_LinkWithFriendDropped)) { - data->playerCount = UnionRoomLeaderField0CompactionAndCount(data->field_0); + data->playerCount = LeaderPrunePlayerList(data->playerList); RedrawListMenu(data->listTaskId); data->state = 2; } @@ -2137,51 +1772,51 @@ static void Task_MEvent_Leader(u8 taskId) data->state = 7; break; case 7: - switch (mevent_message_print_and_prompt_yes_no(&data->textState, (u16 *)&data->messageWindowId, FALSE, gStringVar4)) + switch (DoMysteryGiftYesNo(&data->textState, &data->yesNoWindowId, FALSE, gStringVar4)) { case 0: LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); - data->field_0->arr[data->playerCount].field_1B = 0; + data->playerList->players[data->playerCount].newPlayerCountdown = 0; RedrawListMenu(data->listTaskId); - data->field_19 = 5; - SendRfuStatusToPartner(5, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + data->joinRequestAnswer = RFU_STATUS_JOIN_GROUP_OK; + SendRfuStatusToPartner(data->joinRequestAnswer, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name); data->state = 8; break; case 1: - case -1: - data->field_19 = 6; - SendRfuStatusToPartner(6, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); + case MENU_B_PRESSED: + data->joinRequestAnswer = RFU_STATUS_JOIN_GROUP_NO; + SendRfuStatusToPartner(data->joinRequestAnswer, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name); data->state = 8; break; } break; case 8: - val = WaitSendRfuStatusToPartner(ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId), data->field_0->arr[data->playerCount].gname_uname.uname); - if (val == 1) + val = WaitSendRfuStatusToPartner(ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId), data->playerList->players[data->playerCount].rfu.name); + if (val == 1) // Send complete { - if (data->field_19 == 5) + if (data->joinRequestAnswer == RFU_STATUS_JOIN_GROUP_OK) { - data->field_0->arr[data->playerCount].field_1B = 0; + data->playerList->players[data->playerCount].newPlayerCountdown = 0; RedrawListMenu(data->listTaskId); data->playerCount++; - IntlConvPartnerUname7(gStringVar1, data->field_0->arr[data->playerCount - 1]); + CopyAndTranslatePlayerName(gStringVar1, data->playerList->players[data->playerCount - 1]); StringExpandPlaceholders(gStringVar4, gText_UR_AnOKWasSentToPlayer); data->state = 9; LinkRfu_StopManagerAndFinalizeSlots(); } else { - RequestDisconnectSlotByTrainerNameAndId(data->field_0->arr[data->playerCount].gname_uname.uname, ReadAsU16(data->field_0->arr[data->playerCount].gname_uname.gname.compatibility.playerTrainerId)); - data->field_0->arr[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; - UnionRoomLeaderField0CompactionAndCount(data->field_0); + RequestDisconnectSlotByTrainerNameAndId(data->playerList->players[data->playerCount].rfu.name, ReadAsU16(data->playerList->players[data->playerCount].rfu.data.compatibility.playerTrainerId)); + data->playerList->players[data->playerCount].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; + LeaderPrunePlayerList(data->playerList); RedrawListMenu(data->listTaskId); data->state = 2; } - data->field_19 = 0; + data->joinRequestAnswer = 0; } - else if (val == 2) + else if (val == 2) // Member disconnected { RfuSetStatus(RFU_STATUS_OK, 0); data->state = 2; @@ -2217,21 +1852,21 @@ static void Task_MEvent_Leader(u8 taskId) CopyBgTilemapBufferToVram(0); RemoveWindow(data->listWindowId); DestroyTask(data->listenTaskId); - Free(data->field_8); - Free(data->field_0); - Free(data->field_4); + Free(data->playerListBackup); + Free(data->playerList); + Free(data->incomingPlayerList); data->state++; break; case 14: // Please start over from the beginning. - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_UR_PleaseStartOver)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_UR_PleaseStartOver)) { DestroyTask(taskId); - gSpecialVar_Result = 5; + gSpecialVar_Result = LINKUP_FAILED; } break; case 15: - if (RfuGetStatus() == 1 || RfuGetStatus() == 2) + if (RfuGetStatus() == RFU_STATUS_FATAL_ERROR || RfuGetStatus() == RFU_STATUS_CONNECTION_ERROR) { data->state = 13; } @@ -2246,9 +1881,9 @@ static void Task_MEvent_Leader(u8 taskId) CopyBgTilemapBufferToVram(0); RemoveWindow(data->listWindowId); DestroyTask(data->listenTaskId); - Free(data->field_8); - Free(data->field_0); - Free(data->field_4); + Free(data->playerListBackup); + Free(data->playerList); + Free(data->incomingPlayerList); SetLinkStandbyCallback(); data->state++; break; @@ -2259,36 +1894,36 @@ static void Task_MEvent_Leader(u8 taskId) } } -void MEvent_CreateTask_CardOrNewsWithFriend(u32 activity) +void CreateTask_LinkMysteryGiftWithFriend(u32 activity) { u8 taskId; - struct UnkStruct_Group * dataPtr; + struct WirelessLink_Group * data; taskId = CreateTask(Task_CardOrNewsWithFriend, 0); - sUnionRoomMain.group = dataPtr = (void *)(gTasks[taskId].data); - sGroup = dataPtr; + sWirelessLinkMain.group = data = (void *)(gTasks[taskId].data); + sGroup = data; - dataPtr->state = 0; - dataPtr->textState = 0; - dataPtr->cardOrNews = activity - ACTIVITY_WCARD2; // 0: Card; 1: News - gSpecialVar_Result = 0; + data->state = 0; + data->textState = 0; + data->isWonderNews = activity - ACTIVITY_WONDER_CARD; // 0: Card; 1: News + gSpecialVar_Result = LINKUP_ONGOING; } static void Task_CardOrNewsWithFriend(u8 taskId) { s32 id; - struct WindowTemplate winTemplate1, winTemplate2; - struct UnkStruct_Group * data = sUnionRoomMain.group; + struct WindowTemplate listWinTemplate; + struct WirelessLink_Group * data = sWirelessLinkMain.group; switch (data->state) { case 0: - SetHostRfuGameData(data->cardOrNews + ACTIVITY_WCARD2, 0, 0); + SetHostRfuGameData(data->isWonderNews + ACTIVITY_WONDER_CARD, 0, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(16 * sizeof(struct UnkStruct_x20)); + data->incomingPlayerList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + data->playerList = AllocZeroed(MAX_RFU_PLAYER_LIST_SIZE * sizeof(struct RfuPlayer)); data->state = 1; break; case 1: @@ -2296,15 +1931,15 @@ static void Task_CardOrNewsWithFriend(u8 taskId) data->state = 2; break; case 2: - BlankUnkStruct_x1CArray(data->field_4->arr, 4); - BlankUnkStruct_x20Array(data->field_0->arr, 16); - data->listenTaskId = CreateTask_ListenForPartnersWithCompatibleSerialNos(data->field_4, data->cardOrNews + LINK_GROUP_WONDER_CARD); + ClearIncomingPlayerList(data->incomingPlayerList->players, RFU_CHILD_MAX); + ClearRfuPlayerList(data->playerList->players, MAX_RFU_PLAYER_LIST_SIZE); + data->listenTaskId = CreateTask_ListenForCompatiblePartners(data->incomingPlayerList, data->isWonderNews + LINK_GROUP_WONDER_CARD); - winTemplate1 = sWindowTemplate_MysteryGiftList; - winTemplate1.baseBlock = GetMysteryGiftBaseBlock(); - data->listWindowId = AddWindow(&winTemplate1); + listWinTemplate = sWindowTemplate_GroupList; + listWinTemplate.baseBlock = GetMysteryGiftBaseBlock(); + data->listWindowId = AddWindow(&listWinTemplate); - data->playerNameAndIdWindowId = AddWindow(&sWindowTemplate_MysteryGiftPlayerNameAndId); + data->playerNameAndIdWindowId = AddWindow(&sWindowTemplate_PlayerNameAndId); MG_DrawTextBorder(data->listWindowId); gMultiuseListMenuTemplate = sListMenuTemplate_UnionRoomGroups; @@ -2332,20 +1967,19 @@ static void Task_CardOrNewsWithFriend(u8 taskId) break; case 0: id = ListMenu_ProcessInput(data->listTaskId); - if (JOY_NEW(A_BUTTON) && id != -1) + if (JOY_NEW(A_BUTTON) && id != LIST_NOTHING_CHOSEN) { // this unused variable along with the assignment is needed to match - u32 unusedVar; - unusedVar = data->field_0->arr[id].gname_uname.gname.activity; + u32 activity = data->playerList->players[id].rfu.data.activity; - if (data->field_0->arr[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[id].gname_uname.gname.startedActivity) + if (data->playerList->players[id].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->playerList->players[id].rfu.data.startedActivity) { data->leaderId = id; LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); RedrawListMenu(data->listTaskId); - IntlConvPartnerUname(gStringVar1, data->field_0->arr[data->leaderId]); - CreateTask_RfuReconnectWithParent(data->field_0->arr[data->leaderId].gname_uname.uname, ReadAsU16(data->field_0->arr[data->leaderId].gname_uname.gname.compatibility.playerTrainerId)); + CopyAndTranslatePlayerName2(gStringVar1, data->playerList->players[data->leaderId]); + CreateTask_RfuReconnectWithParent(data->playerList->players[data->leaderId].rfu.name, ReadAsU16(data->playerList->players[data->leaderId].rfu.data.compatibility.playerTrainerId)); PlaySE(SE_POKENAV_ON); data->state = 4; } @@ -2363,24 +1997,24 @@ static void Task_CardOrNewsWithFriend(u8 taskId) break; case 4: AddTextPrinterToWindow1(gText_UR_AwaitingPlayersResponse); - IntlConvPartnerUname(gStringVar1, data->field_0->arr[data->leaderId]); + CopyAndTranslatePlayerName2(gStringVar1, data->playerList->players[data->leaderId]); data->state = 5; break; case 5: if (gReceivedRemoteLinkPlayers) { - sPlayerCurrActivity = data->field_0->arr[data->leaderId].gname_uname.gname.activity; + sPlayerCurrActivity = data->playerList->players[data->leaderId].rfu.data.activity; data->state = 10; } switch (RfuGetStatus()) { - case 1: - case 2: - case 6: + case RFU_STATUS_FATAL_ERROR: + case RFU_STATUS_CONNECTION_ERROR: + case RFU_STATUS_JOIN_GROUP_NO: data->state = 8; break; - case 5: + case RFU_STATUS_JOIN_GROUP_OK: AddTextPrinterToWindow1(gText_UR_PlayerSentBackOK); RfuSetStatus(RFU_STATUS_OK, 0); break; @@ -2394,17 +2028,17 @@ static void Task_CardOrNewsWithFriend(u8 taskId) RemoveWindow(data->playerNameAndIdWindowId); RemoveWindow(data->listWindowId); DestroyTask(data->listenTaskId); - Free(data->field_0); - Free(data->field_4); + Free(data->playerList); + Free(data->incomingPlayerList); data->state++; break; case 9: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gTexts_UR_LinkDropped[RfuGetStatus()])) + if (PrintMysteryGiftMenuMessage(&data->textState, gTexts_UR_LinkDropped[RfuGetStatus()])) { DestroyWirelessStatusIndicatorSprite(); DestroyTask(taskId); LinkRfu_Shutdown(); - gSpecialVar_Result = 5; + gSpecialVar_Result = LINKUP_FAILED; } break; case 7: @@ -2412,7 +2046,7 @@ static void Task_CardOrNewsWithFriend(u8 taskId) AddTextPrinterToWindow1(gText_UR_PleaseStartOver); DestroyTask(taskId); LinkRfu_Shutdown(); - gSpecialVar_Result = 5; + gSpecialVar_Result = LINKUP_FAILED; break; case 11: data->state++; @@ -2425,36 +2059,36 @@ static void Task_CardOrNewsWithFriend(u8 taskId) } } -void MEvent_CreateTask_CardOrNewsOverWireless(u32 activity) +void CreateTask_LinkMysteryGiftOverWireless(u32 activity) { u8 taskId; - struct UnkStruct_Group * dataPtr; + struct WirelessLink_Group * data; taskId = CreateTask(Task_CardOrNewsOverWireless, 0); - sUnionRoomMain.group = dataPtr = (void *)(gTasks[taskId].data); - sGroup = dataPtr; + sWirelessLinkMain.group = data = (void *)(gTasks[taskId].data); + sGroup = data; - dataPtr->state = 0; - dataPtr->textState = 0; - dataPtr->cardOrNews = activity - ACTIVITY_WCARD2; // 0: Card; 1: News - gSpecialVar_Result = 0; + data->state = 0; + data->textState = 0; + data->isWonderNews = activity - ACTIVITY_WONDER_CARD; // 0: Card; 1: News + gSpecialVar_Result = LINKUP_ONGOING; } static void Task_CardOrNewsOverWireless(u8 taskId) { s32 id; struct WindowTemplate winTemplate; - struct UnkStruct_Group * data = sUnionRoomMain.group; + struct WirelessLink_Group * data = sWirelessLinkMain.group; switch (data->state) { case 0: - SetHostRfuGameData(0, 0, 0); + SetHostRfuGameData(ACTIVITY_NONE, 0, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_JoinGroup(); - data->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(16 * sizeof(struct UnkStruct_x20)); + data->incomingPlayerList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + data->playerList = AllocZeroed(MAX_RFU_PLAYER_LIST_SIZE * sizeof(struct RfuPlayer)); data->state = 1; break; case 1: @@ -2462,13 +2096,13 @@ static void Task_CardOrNewsOverWireless(u8 taskId) data->state = 2; break; case 2: - BlankUnkStruct_x1CArray(data->field_4->arr, 4); - BlankUnkStruct_x20Array(data->field_0->arr, 16); - data->listenTaskId = CreateTask_ListenForPartnersWithSerial7F7D(data->field_4, data->cardOrNews + LINK_GROUP_WONDER_CARD); + ClearIncomingPlayerList(data->incomingPlayerList->players, RFU_CHILD_MAX); + ClearRfuPlayerList(data->playerList->players, MAX_RFU_PLAYER_LIST_SIZE); + data->listenTaskId = CreateTask_ListenForWonderDistributor(data->incomingPlayerList, data->isWonderNews + LINK_GROUP_WONDER_CARD); - if (data->field_13 != 0) + if (data->showListMenu) { - winTemplate = sWindowTemplate_MysteryGiftList; + winTemplate = sWindowTemplate_GroupList; winTemplate.baseBlock = GetMysteryGiftBaseBlock(); data->listWindowId = AddWindow(&winTemplate); @@ -2490,23 +2124,23 @@ static void Task_CardOrNewsOverWireless(u8 taskId) case 1: PlaySE(SE_PC_LOGIN); default: - if (data->field_13 != 0) + if (data->showListMenu) RedrawListMenu(data->listTaskId); break; case 0: - if (data->field_13 != 0) + if (data->showListMenu) id = ListMenu_ProcessInput(data->listTaskId); if (data->refreshTimer > 120) { - if (data->field_0->arr[0].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->field_0->arr[0].gname_uname.gname.startedActivity) + if (data->playerList->players[0].groupScheduledAnim == UNION_ROOM_SPAWN_IN && !data->playerList->players[0].rfu.data.startedActivity) { - if (GetGnameWonderFlagByLinkGroup(&data->field_0->arr[0].gname_uname.gname, data->cardOrNews + LINK_GROUP_WONDER_CARD)) + if (HasWonderCardOrNewsByLinkGroup(&data->playerList->players[0].rfu.data, data->isWonderNews + LINK_GROUP_WONDER_CARD)) { data->leaderId = 0; data->refreshTimer = 0; LoadWirelessStatusIndicatorSpriteGfx(); CreateWirelessStatusIndicatorSprite(0, 0); - CreateTask_RfuReconnectWithParent(data->field_0->arr[0].gname_uname.uname, ReadAsU16(data->field_0->arr[0].gname_uname.gname.compatibility.playerTrainerId)); + CreateTask_RfuReconnectWithParent(data->playerList->players[0].rfu.name, ReadAsU16(data->playerList->players[0].rfu.data.compatibility.playerTrainerId)); PlaySE(SE_POKENAV_ON); data->state = 4; } @@ -2528,24 +2162,24 @@ static void Task_CardOrNewsOverWireless(u8 taskId) break; case 4: AddTextPrinterToWindow1(gText_UR_AwaitingResponseFromWirelessSystem); - IntlConvPartnerUname(gStringVar1, data->field_0->arr[data->leaderId]); + CopyAndTranslatePlayerName2(gStringVar1, data->playerList->players[data->leaderId]); data->state = 5; break; case 5: if (gReceivedRemoteLinkPlayers) { - sPlayerCurrActivity = data->field_0->arr[data->leaderId].gname_uname.gname.activity; + sPlayerCurrActivity = data->playerList->players[data->leaderId].rfu.data.activity; data->state = 12; } switch (RfuGetStatus()) { - case 1: - case 2: - case 6: + case RFU_STATUS_FATAL_ERROR: + case RFU_STATUS_CONNECTION_ERROR: + case RFU_STATUS_JOIN_GROUP_NO: data->state = 8; break; - case 5: + case RFU_STATUS_JOIN_GROUP_OK: AddTextPrinterToWindow1(gText_UR_WirelessLinkEstablished); RfuSetStatus(RFU_STATUS_OK, 0); break; @@ -2555,37 +2189,37 @@ static void Task_CardOrNewsOverWireless(u8 taskId) case 8: case 10: case 12: - if (data->field_13 != 0) + if (data->showListMenu) { DestroyListMenuTask(data->listTaskId, 0, 0); CopyBgTilemapBufferToVram(0); RemoveWindow(data->listWindowId); } DestroyTask(data->listenTaskId); - Free(data->field_0); - Free(data->field_4); + Free(data->playerList); + Free(data->incomingPlayerList); data->state++; break; case 9: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_UR_WirelessLinkDropped)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_UR_WirelessLinkDropped)) { DestroyWirelessStatusIndicatorSprite(); DestroyTask(taskId); LinkRfu_Shutdown(); - gSpecialVar_Result = 5; + gSpecialVar_Result = LINKUP_FAILED; } break; case 7: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gText_UR_WirelessSearchCanceled)) + if (PrintMysteryGiftMenuMessage(&data->textState, gText_UR_WirelessSearchCanceled)) { DestroyWirelessStatusIndicatorSprite(); DestroyTask(taskId); LinkRfu_Shutdown(); - gSpecialVar_Result = 5; + gSpecialVar_Result = LINKUP_FAILED; } break; case 11: - if (MG_PrintTextOnWindow1AndWaitButton(&data->textState, gTexts_UR_NoWonderShared[data->cardOrNews])) + if (PrintMysteryGiftMenuMessage(&data->textState, gTexts_UR_NoWonderShared[data->isWonderNews])) { DestroyWirelessStatusIndicatorSprite(); DestroyTask(taskId); @@ -2604,24 +2238,24 @@ static void Task_CardOrNewsOverWireless(u8 taskId) } } -void UnionRoomSpecial(void) +void RunUnionRoom(void) { - struct UnkStruct_URoom * dataPtr; + struct WirelessLink_URoom * uroom; ResetHostRfuGameData(); CreateTask(Task_RunUnionRoom, 10); // dumb line needed to match - sUnionRoomMain.uRoom = sUnionRoomMain.uRoom; + sWirelessLinkMain.uRoom = sWirelessLinkMain.uRoom; - dataPtr = AllocZeroed(sizeof(*sUnionRoomMain.uRoom)); - sUnionRoomMain.uRoom = dataPtr; - sURoom = dataPtr; + uroom = AllocZeroed(sizeof(*sWirelessLinkMain.uRoom)); + sWirelessLinkMain.uRoom = uroom; + sURoom = uroom; - dataPtr->state = 0; - dataPtr->textState = 0; - dataPtr->field_10 = 0; - dataPtr->field_12 = 0; + uroom->state = UR_STATE_INIT; + uroom->textState = 0; + uroom->unknown = 0; + uroom->unreadPlayerId = 0; gSpecialVar_Result = 0; ListMenuLoadStdPalAt(0xD0, 1); @@ -2632,144 +2266,148 @@ static u16 ReadAsU16(const u8 *ptr) return (ptr[1] << 8) | (ptr[0]); } -static void UnionRoom_ScheduleFieldMessageWithFollowupState(u32 nextState, const u8 *src) +static void ScheduleFieldMessageWithFollowupState(u32 nextState, const u8 *src) { - struct UnkStruct_URoom * data = sUnionRoomMain.uRoom; + struct WirelessLink_URoom * uroom = sWirelessLinkMain.uRoom; - data->state = 8; - data->stateAfterPrint = nextState; + uroom->state = UR_STATE_PRINT_MSG; + uroom->stateAfterPrint = nextState; if (src != gStringVar4) StringExpandPlaceholders(gStringVar4, src); } -static void UnionRoom_ScheduleFieldMessageAndExit(const u8 *src) +static void ScheduleFieldMessageAndExit(const u8 *src) { - struct UnkStruct_URoom * data = sUnionRoomMain.uRoom; + struct WirelessLink_URoom * uroom = sWirelessLinkMain.uRoom; - data->state = 26; + uroom->state = UR_STATE_PRINT_AND_EXIT; if (src != gStringVar4) StringExpandPlaceholders(gStringVar4, src); } -static void BackUpURoomField0ToDecompressionBuffer(struct UnkStruct_URoom * data) +static void CopyPlayerListToBuffer(struct WirelessLink_URoom * uroom) { - memcpy(&gDecompressionBuffer[0x3F00], data->field_0, UROOM_MAX_GROUP_COUNT * sizeof(struct UnkStruct_x20)); + memcpy(&gDecompressionBuffer[sizeof(gDecompressionBuffer) - (MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer))], + uroom->playerList, + MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer)); } -static void RestoreURoomField0FromDecompressionBuffer(struct UnkStruct_URoom * data) +static void CopyPlayerListFromBuffer(struct WirelessLink_URoom * uroom) { - memcpy(data->field_0, &gDecompressionBuffer[0x3F00], UROOM_MAX_GROUP_COUNT * sizeof(struct UnkStruct_x20)); + memcpy(uroom->playerList, + &gDecompressionBuffer[sizeof(gDecompressionBuffer) - (MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer))], + MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer)); } static void Task_RunUnionRoom(u8 taskId) { u32 id = 0; - s32 var5 = 0; + s32 input = 0; s32 playerGender = MALE; - struct UnkStruct_URoom * data = sUnionRoomMain.uRoom; + struct WirelessLink_URoom * uroom = sWirelessLinkMain.uRoom; s16 *taskData = gTasks[taskId].data; - switch (data->state) + switch (uroom->state) { - case 0: - data->field_4 = AllocZeroed(RFU_CHILD_MAX * sizeof(struct UnkStruct_x1C)); - data->field_C = AllocZeroed(RFU_CHILD_MAX * sizeof(struct UnkStruct_x1C)); - data->field_0 = AllocZeroed(UROOM_MAX_GROUP_COUNT * sizeof(struct UnkStruct_x20)); - data->field_8 = AllocZeroed(sizeof(struct UnkStruct_x20)); - BlankUnkStruct_x20Array(data->field_0->arr, UROOM_MAX_GROUP_COUNT); + case UR_STATE_INIT: + uroom->incomingChildList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + uroom->incomingParentList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + uroom->playerList = AllocZeroed(MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer)); + uroom->spawnPlayer = AllocZeroed(sizeof(struct RfuPlayer)); + ClearRfuPlayerList(uroom->playerList->players, MAX_UNION_ROOM_LEADERS); sPlayerCurrActivity = IN_UNION_ROOM; - data->field_20 = CreateTask_SearchForChildOrParent(data->field_C, data->field_4, LINK_GROUP_UNION_ROOM_RESUME); - ZeroUnionObjWork(data->unionObjs); + uroom->searchTaskId = CreateTask_SearchForChildOrParent(uroom->incomingParentList, uroom->incomingChildList, LINK_GROUP_UNION_ROOM_RESUME); + ZeroUnionObjWork(uroom->objects); MakeGroupAssemblyAreasPassable(); - data->state = 1; + uroom->state = UR_STATE_INIT_OBJECTS; break; - case 1: - CreateGroupMemberObjectsInvisible(data->spriteIds, taskData[0]); + case UR_STATE_INIT_OBJECTS: + CreateGroupMemberObjectsInvisible(uroom->spriteIds, taskData[0]); if (++taskData[0] == 8) - data->state = 2; + uroom->state = UR_STATE_INIT_LINK; break; - case 2: - SetHostRfuGameData(IN_UNION_ROOM, 0, 0); + case UR_STATE_INIT_LINK: + SetHostRfuGameData(IN_UNION_ROOM, 0, FALSE); SetTradeBoardRegisteredMonInfo(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_EnterUnionRoom(); - BlankUnkStruct_x20Array(&data->field_8->arr[0], 1); - BlankUnkStruct_x1CArray(data->field_4->arr, 4); - BlankUnkStruct_x1CArray(data->field_C->arr, 4); + ClearRfuPlayerList(&uroom->spawnPlayer->players[0], 1); + ClearIncomingPlayerList(uroom->incomingChildList->players, RFU_CHILD_MAX); + ClearIncomingPlayerList(uroom->incomingParentList->players, RFU_CHILD_MAX); gSpecialVar_Result = 0; - data->state = 3; + uroom->state = UR_STATE_CHECK_SELECTING_MON; break; - case 3: + case UR_STATE_CHECK_SELECTING_MON: if ((GetPartyMenuType() == PARTY_MENU_TYPE_UNION_ROOM_REGISTER || GetPartyMenuType() == PARTY_MENU_TYPE_UNION_ROOM_TRADE) - && sUnionRoomTrade.field_0 != 0) + && sUnionRoomTrade.state != URTRADE_STATE_NONE) { id = GetCursorSelectionMonId(); - switch (sUnionRoomTrade.field_0) + switch (sUnionRoomTrade.state) { - case 1: + case URTRADE_STATE_REGISTERING: UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); if (id >= PARTY_SIZE) { ResetUnionRoomTrade(&sUnionRoomTrade); - SetTradeBoardRegisteredMonInfo(0, 0, 0); - UnionRoom_ScheduleFieldMessageAndExit(gText_UR_RegistrationCanceled); + SetTradeBoardRegisteredMonInfo(TYPE_NORMAL, SPECIES_NONE, 0); + ScheduleFieldMessageAndExit(gText_UR_RegistrationCanceled); } else if (!RegisterTradeMonAndGetIsEgg(GetCursorSelectionMonId(), &sUnionRoomTrade)) { - UnionRoom_ScheduleFieldMessageWithFollowupState(52, gText_UR_ChooseRequestedMonType); + ScheduleFieldMessageWithFollowupState(UR_STATE_REGISTER_REQUEST_TYPE, gText_UR_ChooseRequestedMonType); } else { - data->state = 55; + uroom->state = UR_STATE_REGISTER_COMPLETE; } break; - case 2: - RestoreURoomField0FromDecompressionBuffer(data); - taskData[1] = sUnionRoomTrade.field_8; + case URTRADE_STATE_OFFERING: + CopyPlayerListFromBuffer(uroom); + taskData[1] = sUnionRoomTrade.offerPlayerId; if (id >= PARTY_SIZE) { - UnionRoom_ScheduleFieldMessageAndExit(gText_UR_TradeCanceled); + ScheduleFieldMessageAndExit(gText_UR_TradeCanceled); } else { UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); sPlayerCurrActivity = ACTIVITY_TRADE | IN_UNION_ROOM; RegisterTradeMon(GetCursorSelectionMonId(), &sUnionRoomTrade); - data->state = 51; + uroom->state = UR_STATE_TRADE_OFFER_MON; } break; } - sUnionRoomTrade.field_0 = 0; + sUnionRoomTrade.state = URTRADE_STATE_NONE; } else { - data->state = 4; + uroom->state = UR_STATE_MAIN; } break; - case 4: + case UR_STATE_MAIN: if (gSpecialVar_Result != 0) { - if (gSpecialVar_Result == 9) + if (gSpecialVar_Result == UR_INTERACT_ATTENDANT) { UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); PlaySE(SE_PC_LOGIN); StringCopy(gStringVar1, gSaveBlock2Ptr->playerName); - data->state = 42; + uroom->state = UR_STATE_INTERACT_WITH_ATTENDANT; gSpecialVar_Result = 0; } - else if (gSpecialVar_Result == 11) + else if (gSpecialVar_Result == UR_INTERACT_START_MENU) { UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); - data->state = 23; + uroom->state = UR_STATE_WAIT_FOR_START_MENU; gSpecialVar_Result = 0; } - else + else // UR_INTERACT_PLAYER_# (1-8) { taskData[0] = 0; taskData[1] = gSpecialVar_Result - 1; - data->state = 24; + uroom->state = UR_STATE_INTERACT_WITH_PLAYER; gSpecialVar_Result = 0; } } @@ -2777,81 +2415,81 @@ static void Task_RunUnionRoom(u8 taskId) { if (JOY_NEW(A_BUTTON)) { - if (RfuUnionTool_GetGroupAndMemberInFrontOfPlayer(data->field_0, &taskData[0], &taskData[1], data->spriteIds)) + if (TryInteractWithUnionRoomMember(uroom->playerList, &taskData[0], &taskData[1], uroom->spriteIds)) { PlaySE(SE_SELECT); - UR_EnableScriptContext2AndFreezeObjectEvents(); - data->state = 24; + StartScriptInteraction(); + uroom->state = UR_STATE_INTERACT_WITH_PLAYER; break; } - else if (PlayerIsTalkingToUnionRoomAide()) + else if (IsPlayerFacingTradingBoard()) { UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); PlaySE(SE_PC_LOGIN); - UR_EnableScriptContext2AndFreezeObjectEvents(); + StartScriptInteraction(); StringCopy(gStringVar1, gSaveBlock2Ptr->playerName); - data->state = 45; + uroom->state = UR_STATE_CHECK_TRADING_BOARD; break; } } switch (HandlePlayerListUpdate()) { - case 1: + case PLIST_NEW_PLAYER: PlaySE(SE_NOTE_C); - case 2: - ScheduleUnionRoomPlayerRefresh(data); + case PLIST_RECENT_UPDATE: + ScheduleUnionRoomPlayerRefresh(uroom); break; - case 4: - data->state = 11; - UR_EnableScriptContext2AndFreezeObjectEvents(); - SetTradeBoardRegisteredMonInfo(0, 0, 0); - UpdateGameData_SetActivity(ACTIVITY_NPCTALK | IN_UNION_ROOM, GetActivePartnerSpriteGenderParam(data), FALSE); + case PLIST_CONTACTED: + uroom->state = UR_STATE_PLAYER_CONTACTED_YOU; + StartScriptInteraction(); + SetTradeBoardRegisteredMonInfo(TYPE_NORMAL, SPECIES_NONE, 0); + UpdateGameData_SetActivity(ACTIVITY_NPCTALK | IN_UNION_ROOM, GetActivePartnersInfo(uroom), FALSE); break; } - HandleUnionRoomPlayerRefresh(data); + HandleUnionRoomPlayerRefresh(uroom); } break; - case 23: + case UR_STATE_WAIT_FOR_START_MENU: if (!FuncIsActiveTask(Task_StartMenuHandleInput)) { - UpdateGameData_SetActivity(IN_UNION_ROOM, 0, FALSE); - data->state = 4; + UpdateGameData_SetActivity(ACTIVITY_NONE | IN_UNION_ROOM, 0, FALSE); + uroom->state = UR_STATE_MAIN; } break; - case 24: - UR_RunTextPrinters_CheckPrinter0Active(); - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); + case UR_STATE_INTERACT_WITH_PLAYER: + UR_RunTextPrinters(); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); - switch (UnionRoomGetPlayerInteractionResponse(data->field_0, taskData[0], taskData[1], playerGender)) + switch (UnionRoomGetPlayerInteractionResponse(uroom->playerList, taskData[0], taskData[1], playerGender)) { - case 0: - data->state = 26; + case 0: // Player is or was just doing an activity + uroom->state = UR_STATE_PRINT_AND_EXIT; break; - case 1: - TryConnectToUnionRoomParent(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, sPlayerCurrActivity); - data->field_12 = id; // Should be just 0, but won't match any other way. - data->state = 25; + case 1: // Link communicating + TryConnectToUnionRoomParent(uroom->playerList->players[taskData[1]].rfu.name, &uroom->playerList->players[taskData[1]].rfu.data, sPlayerCurrActivity); + uroom->unreadPlayerId = id; // Should be just 0, but won't match any other way. + uroom->state = UR_STATE_TRY_COMMUNICATING; break; - case 2: - UnionRoom_ScheduleFieldMessageWithFollowupState(19, gStringVar4); + case 2: // Ask to join chat + ScheduleFieldMessageWithFollowupState(UR_STATE_RECV_JOIN_CHAT_REQUEST, gStringVar4); break; } break; - case 25: - UR_RunTextPrinters_CheckPrinter0Active(); + case UR_STATE_TRY_COMMUNICATING: + UR_RunTextPrinters(); switch (RfuGetStatus()) { - case 4: - HandleCancelTrade(TRUE); - data->state = 4; + case RFU_STATUS_NEW_CHILD_DETECTED: + HandleCancelActivity(TRUE); + uroom->state = UR_STATE_MAIN; break; - case 1: - case 2: + case RFU_STATUS_FATAL_ERROR: + case RFU_STATUS_CONNECTION_ERROR: if (IsUnionRoomListenTaskActive() == TRUE) - UnionRoom_ScheduleFieldMessageAndExit(gText_UR_TrainerAppearsBusy); + ScheduleFieldMessageAndExit(gText_UR_TrainerAppearsBusy); else - UnionRoom_ScheduleFieldMessageWithFollowupState(30, gText_UR_TrainerAppearsBusy); + ScheduleFieldMessageWithFollowupState(UR_STATE_CANCEL_ACTIVITY_LINK_ERROR, gText_UR_TrainerAppearsBusy); sPlayerCurrActivity = IN_UNION_ROOM; break; @@ -2861,138 +2499,141 @@ static void Task_RunUnionRoom(u8 taskId) { CreateTrainerCardInBuffer(gBlockSendBuffer, TRUE); CreateTask(Task_ExchangeCards, 5); - data->state = 38; + uroom->state = UR_STATE_COMMUNICATING_WAIT_FOR_DATA; } break; - case 38: + case UR_STATE_COMMUNICATING_WAIT_FOR_DATA: if (!FuncIsActiveTask(Task_ExchangeCards)) { if (sPlayerCurrActivity == (ACTIVITY_TRADE | IN_UNION_ROOM)) - UnionRoom_ScheduleFieldMessageWithFollowupState(31, gText_UR_AwaitingPlayersResponseAboutTrade); + ScheduleFieldMessageWithFollowupState(UR_STATE_SEND_TRADE_REQUST, gText_UR_AwaitingPlayersResponseAboutTrade); else - data->state = 5; + uroom->state = UR_STATE_DO_SOMETHING_PROMPT; } break; - case 30: + case UR_STATE_CANCEL_ACTIVITY_LINK_ERROR: if (!gReceivedRemoteLinkPlayers) { - HandleCancelTrade(FALSE); - UpdateUnionGroupMemberFacing(taskData[0], taskData[1], data->field_0); - data->state = 2; + HandleCancelActivity(FALSE); + UpdateUnionGroupMemberFacing(taskData[0], taskData[1], uroom->playerList); + uroom->state = UR_STATE_INIT_LINK; } break; - case 5: - id = ConvPartnerUnameAndGetWhetherMetAlready(&data->field_0->arr[taskData[1]]); - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - UnionRoom_ScheduleFieldMessageWithFollowupState(6, gTexts_UR_HiDoSomething[id][playerGender]); + case UR_STATE_DO_SOMETHING_PROMPT: + id = ConvPartnerUnameAndGetWhetherMetAlready(&uroom->playerList->players[taskData[1]]); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); + ScheduleFieldMessageWithFollowupState(UR_STATE_HANDLE_DO_SOMETHING_PROMPT_INPUT, gTexts_UR_HiDoSomething[id][playerGender]); break; - case 6: - var5 = ListMenuHandler_AllItemsAvailable(&data->textState, &data->topListMenuWindowId, &data->topListMenuListMenuId, &sWindowTemplate_InviteToActivity, &sListMenuTemplate_InviteToActivity); - if (var5 != -1) + case UR_STATE_HANDLE_DO_SOMETHING_PROMPT_INPUT: + input = ListMenuHandler_AllItemsAvailable(&uroom->textState, + &uroom->topListMenuWindowId, + &uroom->topListMenuId, + &sWindowTemplate_InviteToActivity, + &sListMenuTemplate_InviteToActivity); + if (input != LIST_NOTHING_CHOSEN) { if (!gReceivedRemoteLinkPlayers) { - data->state = 28; + uroom->state = UR_STATE_TRAINER_APPEARS_BUSY; } else { - data->partnerYesNoResponse = 0; - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - if (var5 == -2 || var5 == IN_UNION_ROOM) + uroom->partnerYesNoResponse = 0; + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); + if (input == LIST_CANCEL || input == IN_UNION_ROOM) { - data->playerSendBuffer[0] = IN_UNION_ROOM; - Rfu_SendPacket(data->playerSendBuffer); + uroom->playerSendBuffer[0] = IN_UNION_ROOM; + Rfu_SendPacket(uroom->playerSendBuffer); StringCopy(gStringVar4, gTexts_UR_IfYouWantToDoSomething[gLinkPlayers[0].gender]); - data->state = 32; + uroom->state = UR_STATE_REQUEST_DECLINED; } else { - sPlayerCurrActivity = var5; - sPlayerActivityGroupSize = (u32)(var5) >> 8; - if (sPlayerCurrActivity == (ACTIVITY_BATTLE | IN_UNION_ROOM) && !HasAtLeastTwoMonsOfLevel30OrLower()) + sPlayerCurrActivity = input; + sPlayerActivityGroupSize = (u32)(input) >> 8; // Extract capacity from sInviteToActivityMenuItems + if (sPlayerCurrActivity == (ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM) && !HasAtLeastTwoMonsOfLevel30OrLower()) { - UnionRoom_ScheduleFieldMessageWithFollowupState(5, gText_UR_NeedTwoMonsOfLevel30OrLower1); + ScheduleFieldMessageWithFollowupState(UR_STATE_DO_SOMETHING_PROMPT, gText_UR_NeedTwoMonsOfLevel30OrLower1); } else { - data->playerSendBuffer[0] = sPlayerCurrActivity | IN_UNION_ROOM; - Rfu_SendPacket(data->playerSendBuffer); - data->state = 27; + uroom->playerSendBuffer[0] = sPlayerCurrActivity | IN_UNION_ROOM; + Rfu_SendPacket(uroom->playerSendBuffer); + uroom->state = UR_STATE_SEND_ACTIVITY_REQUEST; } } } } break; - case 28: + case UR_STATE_TRAINER_APPEARS_BUSY: StringCopy(gStringVar4, gText_UR_TrainerBattleBusy); - data->state = 36; + uroom->state = UR_STATE_CANCEL_REQUEST_PRINT_MSG; break; - case 27: - PollPartnerYesNoResponse(data); - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - id = GetResponseIdx_InviteToURoomActivity(data->playerSendBuffer[0] & 0x3F); - if (PrintOnTextbox(&data->textState, gTexts_UR_WaitOrShowCard[playerGender][id])) + case UR_STATE_SEND_ACTIVITY_REQUEST: + PollPartnerYesNoResponse(uroom); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); + id = GetResponseIdx_InviteToURoomActivity(uroom->playerSendBuffer[0] & 0x3F); + if (PrintOnTextbox(&uroom->textState, gTexts_UR_WaitOrShowCard[playerGender][id])) { taskData[3] = 0; - data->state = 29; + uroom->state = UR_STATE_WAIT_FOR_RESPONSE_TO_REQUEST; } break; - case 32: + case UR_STATE_REQUEST_DECLINED: SetCloseLinkCallback(); - data->state = 36; + uroom->state = UR_STATE_CANCEL_REQUEST_PRINT_MSG; break; - case 31: - data->playerSendBuffer[0] = ACTIVITY_TRADE | IN_UNION_ROOM; - data->playerSendBuffer[1] = sUnionRoomTrade.species; - data->playerSendBuffer[2] = sUnionRoomTrade.level; - Rfu_SendPacket(data->playerSendBuffer); - data->state = 29; + case UR_STATE_SEND_TRADE_REQUST: + uroom->playerSendBuffer[0] = ACTIVITY_TRADE | IN_UNION_ROOM; + uroom->playerSendBuffer[1] = sUnionRoomTrade.species; + uroom->playerSendBuffer[2] = sUnionRoomTrade.level; + Rfu_SendPacket(uroom->playerSendBuffer); + uroom->state = UR_STATE_WAIT_FOR_RESPONSE_TO_REQUEST; break; - case 29: + case UR_STATE_WAIT_FOR_RESPONSE_TO_REQUEST: if (!gReceivedRemoteLinkPlayers) { StringCopy(gStringVar4, gText_UR_TrainerBattleBusy); - data->state = 28; + uroom->state = UR_STATE_TRAINER_APPEARS_BUSY; } else { - PollPartnerYesNoResponse(data); - if (data->partnerYesNoResponse == (ACTIVITY_ACCEPT | IN_UNION_ROOM)) + PollPartnerYesNoResponse(uroom); + if (uroom->partnerYesNoResponse == (ACTIVITY_ACCEPT | IN_UNION_ROOM)) { if (sPlayerCurrActivity == ACTIVITY_CARD) { - ViewURoomPartnerTrainerCard(gStringVar4, data, MODE_CHILD); - data->state = 40; + ViewURoomPartnerTrainerCard(gStringVar4, uroom, MODE_CHILD); + uroom->state = UR_STATE_PRINT_CARD_INFO; } else { - data->state = 13; + uroom->state = UR_STATE_PRINT_START_ACTIVITY_MSG; } } - else if (data->partnerYesNoResponse == (ACTIVITY_DECLINE | IN_UNION_ROOM)) + else if (uroom->partnerYesNoResponse == (ACTIVITY_DECLINE | IN_UNION_ROOM)) { - data->state = 32; + uroom->state = UR_STATE_REQUEST_DECLINED; GetURoomActivityRejectMsg(gStringVar4, sPlayerCurrActivity | IN_UNION_ROOM, gLinkPlayers[0].gender); - sPlayerCurrActivity = 0; + sPlayerCurrActivity = ACTIVITY_NONE; } } break; - - case 7: - id = ConvPartnerUnameAndGetWhetherMetAlready(&data->field_0->arr[taskData[1]]); - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - UnionRoom_ScheduleFieldMessageWithFollowupState(6, gTexts_UR_HiDoSomething[id][playerGender]); + case UR_STATE_DO_SOMETHING_PROMPT_2: + id = ConvPartnerUnameAndGetWhetherMetAlready(&uroom->playerList->players[taskData[1]]); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); + ScheduleFieldMessageWithFollowupState(UR_STATE_HANDLE_DO_SOMETHING_PROMPT_INPUT, gTexts_UR_HiDoSomething[id][playerGender]); break; - case 40: - if (PrintOnTextbox(&data->textState, gStringVar4)) + case UR_STATE_PRINT_CARD_INFO: + if (PrintOnTextbox(&uroom->textState, gStringVar4)) { - data->state = 41; + uroom->state = UR_STATE_WAIT_FINISH_READING_CARD; SetLinkStandbyCallback(); - data->partnerYesNoResponse = 0; - data->recvActivityRequest[0] = 0; + uroom->partnerYesNoResponse = 0; + uroom->recvActivityRequest[0] = 0; } break; - case 41: + case UR_STATE_WAIT_FINISH_READING_CARD: if (IsLinkTaskFinished()) { if (GetMultiplayerId() == 0) @@ -3000,227 +2641,225 @@ static void Task_RunUnionRoom(u8 taskId) StringCopy(gStringVar1, gLinkPlayers[GetMultiplayerId() ^ 1].name); id = PlayerHasMetTrainerBefore(gLinkPlayers[1].trainerId, gLinkPlayers[1].name); StringExpandPlaceholders(gStringVar4, gTexts_UR_AwaitingResponse[id]); - data->state = 33; + uroom->state = UR_STATE_PRINT_CONTACT_MSG; } else { - data->state = 7; + uroom->state = UR_STATE_DO_SOMETHING_PROMPT_2; } } break; - case 19: - switch (UnionRoomHandleYesNo(&data->textState, FALSE)) + case UR_STATE_RECV_JOIN_CHAT_REQUEST: + switch (UnionRoomHandleYesNo(&uroom->textState, FALSE)) { - case 0: + case 0: // YES CopyBgTilemapBufferToVram(0); sPlayerCurrActivity = ACTIVITY_CHAT | IN_UNION_ROOM; UpdateGameData_SetActivity(ACTIVITY_CHAT | IN_UNION_ROOM, 0, TRUE); - TryConnectToUnionRoomParent(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, sPlayerCurrActivity); - data->field_12 = taskData[1]; - data->state = 20; + TryConnectToUnionRoomParent(uroom->playerList->players[taskData[1]].rfu.name, &uroom->playerList->players[taskData[1]].rfu.data, sPlayerCurrActivity); + uroom->unreadPlayerId = taskData[1]; + uroom->state = UR_STATE_TRY_ACCEPT_CHAT_REQUEST_DELAY; taskData[3] = 0; break; - case 1: - case -1: - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); - UnionRoom_ScheduleFieldMessageAndExit(gTexts_UR_DeclineChat[playerGender]); + case 1: // NO + case MENU_B_PRESSED: + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); + ScheduleFieldMessageAndExit(gTexts_UR_DeclineChat[playerGender]); break; } break; - case 20: + case UR_STATE_TRY_ACCEPT_CHAT_REQUEST_DELAY: if (++taskData[2] > 60) { - data->state = 21; + uroom->state = UR_STATE_TRY_ACCEPT_CHAT_REQUEST; taskData[2] = 0; } break; - case 21: + case UR_STATE_TRY_ACCEPT_CHAT_REQUEST: switch (RfuGetStatus()) { - case 4: - HandleCancelTrade(TRUE); - data->state = 4; + case RFU_STATUS_NEW_CHILD_DETECTED: + HandleCancelActivity(TRUE); + uroom->state = UR_STATE_MAIN; break; - case 1: - case 2: - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); + case RFU_STATUS_FATAL_ERROR: + case RFU_STATUS_CONNECTION_ERROR: + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); if (IsUnionRoomListenTaskActive() == TRUE) - UnionRoom_ScheduleFieldMessageAndExit(gTexts_UR_ChatDeclined[playerGender]); + ScheduleFieldMessageAndExit(gTexts_UR_ChatDeclined[playerGender]); else - UnionRoom_ScheduleFieldMessageWithFollowupState(30, gTexts_UR_ChatDeclined[playerGender]); + ScheduleFieldMessageWithFollowupState(UR_STATE_CANCEL_ACTIVITY_LINK_ERROR, gTexts_UR_ChatDeclined[playerGender]); break; - case 3: - data->state = 22; + case RFU_STATUS_CHILD_SEND_COMPLETE: + uroom->state = UR_STATE_ACCEPT_CHAT_REQUEST; break; } taskData[3]++; break; - case 22: + case UR_STATE_ACCEPT_CHAT_REQUEST: if (RfuHasErrored()) { - playerGender = GetUnionRoomPlayerGender(taskData[1], data->field_0); + playerGender = GetUnionRoomPlayerGender(taskData[1], uroom->playerList); UpdateGameData_SetActivity(ACTIVITY_PLYRTALK | IN_UNION_ROOM, 0, TRUE); if (IsUnionRoomListenTaskActive() == TRUE) - UnionRoom_ScheduleFieldMessageAndExit(gTexts_UR_ChatDeclined[playerGender]); + ScheduleFieldMessageAndExit(gTexts_UR_ChatDeclined[playerGender]); else - UnionRoom_ScheduleFieldMessageWithFollowupState(30, gTexts_UR_ChatDeclined[playerGender]); + ScheduleFieldMessageWithFollowupState(UR_STATE_CANCEL_ACTIVITY_LINK_ERROR, gTexts_UR_ChatDeclined[playerGender]); } if (gReceivedRemoteLinkPlayers) - data->state = 16; + uroom->state = UR_STATE_START_ACTIVITY_FREE_UROOM; break; - case 11: + case UR_STATE_PLAYER_CONTACTED_YOU: PlaySE(SE_DING_DONG); StopUnionRoomLinkManager(); - data->state = 12; - data->recvActivityRequest[0] = 0; + uroom->state = UR_STATE_RECV_CONTACT_DATA; + uroom->recvActivityRequest[0] = 0; break; - case 12: + case UR_STATE_RECV_CONTACT_DATA: if (RfuHasErrored()) { - HandleCancelTrade(FALSE); - data->state = 2; + HandleCancelActivity(FALSE); + uroom->state = UR_STATE_INIT_LINK; } else if (gReceivedRemoteLinkPlayers) { CreateTrainerCardInBuffer(gBlockSendBuffer, TRUE); CreateTask(Task_ExchangeCards, 5); - data->state = 39; + uroom->state = UR_STATE_WAIT_FOR_CONTACT_DATA; } break; - case 39: - ReceiveUnionRoomActivityPacket(data); + case UR_STATE_WAIT_FOR_CONTACT_DATA: + ReceiveUnionRoomActivityPacket(uroom); if (!FuncIsActiveTask(Task_ExchangeCards)) { - data->state = 33; + uroom->state = UR_STATE_PRINT_CONTACT_MSG; StringCopy(gStringVar1, gLinkPlayers[1].name); id = PlayerHasMetTrainerBefore(gLinkPlayers[1].trainerId, gLinkPlayers[1].name); StringExpandPlaceholders(gStringVar4, gTexts_UR_PlayerContactedYou[id]); } break; - case 33: - ReceiveUnionRoomActivityPacket(data); - if (PrintOnTextbox(&data->textState, gStringVar4)) - data->state = 34; + case UR_STATE_PRINT_CONTACT_MSG: + ReceiveUnionRoomActivityPacket(uroom); + if (PrintOnTextbox(&uroom->textState, gStringVar4)) + uroom->state = UR_STATE_HANDLE_CONTACT_DATA; break; - case 34: - ReceiveUnionRoomActivityPacket(data); - if (UnionRoom_HandleContactFromOtherPlayer(data) && JOY_NEW(B_BUTTON)) + case UR_STATE_HANDLE_CONTACT_DATA: + ReceiveUnionRoomActivityPacket(uroom); + if (HandleContactFromOtherPlayer(uroom) && JOY_NEW(B_BUTTON)) { Rfu_DisconnectPlayerById(1); StringCopy(gStringVar4, gText_UR_ChatEnded); - data->state = 36; + uroom->state = UR_STATE_CANCEL_REQUEST_PRINT_MSG; } break; - case 35: - // You said yes - UnionRoom_ScheduleFieldMessageWithFollowupState(9, gStringVar4); + case UR_STATE_RECV_ACTIVITY_REQUEST: + ScheduleFieldMessageWithFollowupState(UR_STATE_HANDLE_ACTIVITY_REQUEST, gStringVar4); break; - case 9: - switch (UnionRoomHandleYesNo(&data->textState, FALSE)) + case UR_STATE_HANDLE_ACTIVITY_REQUEST: + switch (UnionRoomHandleYesNo(&uroom->textState, FALSE)) { - case 0: - data->playerSendBuffer[0] = ACTIVITY_ACCEPT | IN_UNION_ROOM; + case 0: // ACCEPT + uroom->playerSendBuffer[0] = ACTIVITY_ACCEPT | IN_UNION_ROOM; if (sPlayerCurrActivity == (ACTIVITY_CHAT | IN_UNION_ROOM)) - UpdateGameData_SetActivity(sPlayerCurrActivity | IN_UNION_ROOM, GetSinglePartnerSpriteGenderParam(1), FALSE); + UpdateGameData_SetActivity(sPlayerCurrActivity | IN_UNION_ROOM, GetLinkPlayerInfoFlags(1), FALSE); else - UpdateGameData_SetActivity(sPlayerCurrActivity | IN_UNION_ROOM, GetSinglePartnerSpriteGenderParam(1), TRUE); + UpdateGameData_SetActivity(sPlayerCurrActivity | IN_UNION_ROOM, GetLinkPlayerInfoFlags(1), TRUE); - data->field_8->arr[0].field_1B = 0; + uroom->spawnPlayer->players[0].newPlayerCountdown = 0; taskData[3] = 0; - if (sPlayerCurrActivity == (ACTIVITY_BATTLE | IN_UNION_ROOM)) + if (sPlayerCurrActivity == (ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM)) { if (!HasAtLeastTwoMonsOfLevel30OrLower()) { - data->playerSendBuffer[0] = ACTIVITY_DECLINE | IN_UNION_ROOM; - Rfu_SendPacket(data->playerSendBuffer); - data->state = 10; + uroom->playerSendBuffer[0] = ACTIVITY_DECLINE | IN_UNION_ROOM; + Rfu_SendPacket(uroom->playerSendBuffer); + uroom->state = UR_STATE_DECLINE_ACTIVITY_REQUEST; StringCopy(gStringVar4, gText_UR_NeedTwoMonsOfLevel30OrLower2); } else { - Rfu_SendPacket(data->playerSendBuffer); - data->state = 13; + Rfu_SendPacket(uroom->playerSendBuffer); + uroom->state = UR_STATE_PRINT_START_ACTIVITY_MSG; } } else if (sPlayerCurrActivity == (ACTIVITY_CARD | IN_UNION_ROOM)) { - Rfu_SendPacket(data->playerSendBuffer); - ViewURoomPartnerTrainerCard(gStringVar4, data, MODE_PARENT); - data->state = 40; + Rfu_SendPacket(uroom->playerSendBuffer); + ViewURoomPartnerTrainerCard(gStringVar4, uroom, MODE_PARENT); + uroom->state = UR_STATE_PRINT_CARD_INFO; } else { - Rfu_SendPacket(data->playerSendBuffer); - data->state = 13; + Rfu_SendPacket(uroom->playerSendBuffer); + uroom->state = UR_STATE_PRINT_START_ACTIVITY_MSG; } break; - case 1: - case -1: - data->playerSendBuffer[0] = ACTIVITY_DECLINE | IN_UNION_ROOM; - Rfu_SendPacket(data->playerSendBuffer); - data->state = 10; + case 1: // DECLINE + case MENU_B_PRESSED: + uroom->playerSendBuffer[0] = ACTIVITY_DECLINE | IN_UNION_ROOM; + Rfu_SendPacket(uroom->playerSendBuffer); + uroom->state = UR_STATE_DECLINE_ACTIVITY_REQUEST; GetYouDeclinedTheOfferMessage(gStringVar4, sPlayerCurrActivity); break; } break; - case 10: + case UR_STATE_DECLINE_ACTIVITY_REQUEST: SetCloseLinkCallback(); - data->state = 36; + uroom->state = UR_STATE_CANCEL_REQUEST_PRINT_MSG; break; - case 36: - // You said no + case UR_STATE_CANCEL_REQUEST_PRINT_MSG: if (!gReceivedRemoteLinkPlayers) { sPlayerCurrActivity = IN_UNION_ROOM; - UnionRoom_ScheduleFieldMessageWithFollowupState(37, gStringVar4); - memset(data->playerSendBuffer, 0, sizeof(data->playerSendBuffer)); - data->recvActivityRequest[0] = 0; - data->partnerYesNoResponse = 0; + ScheduleFieldMessageWithFollowupState(UR_STATE_CANCEL_REQUEST_RESTART_LINK, gStringVar4); + memset(uroom->playerSendBuffer, 0, sizeof(uroom->playerSendBuffer)); + uroom->recvActivityRequest[0] = 0; + uroom->partnerYesNoResponse = 0; } break; - case 37: - data->state = 2; - HandleCancelTrade(FALSE); + case UR_STATE_CANCEL_REQUEST_RESTART_LINK: + uroom->state = UR_STATE_INIT_LINK; + HandleCancelActivity(FALSE); break; - case 13: + case UR_STATE_PRINT_START_ACTIVITY_MSG: GetURoomActivityStartMsg(gStringVar4, sPlayerCurrActivity | IN_UNION_ROOM); - UnionRoom_ScheduleFieldMessageWithFollowupState(14, gStringVar4); + ScheduleFieldMessageWithFollowupState(UR_STATE_START_ACTIVITY_LINK, gStringVar4); break; - case 14: + case UR_STATE_START_ACTIVITY_LINK: SetLinkStandbyCallback(); - data->state = 15; + uroom->state = UR_STATE_START_ACTIVITY_WAIT_FOR_LINK; break; - case 15: + case UR_STATE_START_ACTIVITY_WAIT_FOR_LINK: if (IsLinkTaskFinished()) - data->state = 16; + uroom->state = UR_STATE_START_ACTIVITY_FREE_UROOM; break; - case 16: - Free(data->field_8); - Free(data->field_0); - Free(data->field_C); - Free(data->field_4); - DestroyTask(data->field_20); - DestroyGroupMemberObjects(data->spriteIds); - data->state = 17; + case UR_STATE_START_ACTIVITY_FREE_UROOM: + Free(uroom->spawnPlayer); + Free(uroom->playerList); + Free(uroom->incomingParentList); + Free(uroom->incomingChildList); + DestroyTask(uroom->searchTaskId); + DestroyGroupMemberObjects(uroom->spriteIds); + uroom->state = UR_STATE_START_ACTIVITY_FADE; break; - case 17: - BeginNormalPaletteFade(-1, 0, 0, 0x10, RGB_BLACK); - data->state = 18; + case UR_STATE_START_ACTIVITY_FADE: + BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); + uroom->state = UR_STATE_START_ACTIVITY; break; - case 18: + case UR_STATE_START_ACTIVITY: if (!UpdatePaletteFade()) { - DeleteUnionObjWorkAndStopTask(); + DestroyUnionRoomPlayerObjects(); DestroyTask(taskId); - Free(sUnionRoomMain.uRoom); + Free(sWirelessLinkMain.uRoom); CreateTask_StartActivity(); } break; - case 42: + case UR_STATE_INTERACT_WITH_ATTENDANT: if (GetHostRfuGameData()->tradeSpecies == SPECIES_NONE) { - data->state = 43; + uroom->state = UR_STATE_REGISTER_PROMPT; } else { @@ -3234,194 +2873,204 @@ static void Task_RunUnionRoom(u8 taskId) ConvertIntToDecimalStringN(gStringVar2, GetHostRfuGameData()->tradeLevel, STR_CONV_MODE_LEFT_ALIGN, 3); StringExpandPlaceholders(gStringVar4, gText_UR_CancelRegistrationOfMon); } - UnionRoom_ScheduleFieldMessageWithFollowupState(44, gStringVar4); + ScheduleFieldMessageWithFollowupState(UR_STATE_CANCEL_REGISTRATION_PROMPT, gStringVar4); } break; - case 43: - if (PrintOnTextbox(&data->textState, gText_UR_RegisterMonAtTradingBoard)) - data->state = 47; + case UR_STATE_REGISTER_PROMPT: + if (PrintOnTextbox(&uroom->textState, gText_UR_RegisterMonAtTradingBoard)) + uroom->state = UR_STATE_REGISTER_PROMPT_HANDLE_INPUT; break; - case 47: - var5 = ListMenuHandler_AllItemsAvailable(&data->textState, &data->tradeBoardSelectWindowId, &data->tradeBoardDetailsWindowId, &sWindowTemplate_TradeBoardRegisterInfoExit, &sListMenuTemplate_TradeBoardRegisterInfoExit); - if (var5 != -1) + case UR_STATE_REGISTER_PROMPT_HANDLE_INPUT: + input = ListMenuHandler_AllItemsAvailable(&uroom->textState, + &uroom->tradeBoardMainWindowId, + &uroom->tradeBoardHeaderWindowId, + &sWindowTemplate_RegisterForTrade, + &sListMenuTemplate_RegisterForTrade); + if (input != LIST_NOTHING_CHOSEN) { - if (var5 == -2 || var5 == 3) + if (input == LIST_CANCEL || input == 3) // Exit { - data->state = 4; - HandleCancelTrade(TRUE); + uroom->state = UR_STATE_MAIN; + HandleCancelActivity(TRUE); } else { - switch (var5) + switch (input) { case 1: // REGISTER - UnionRoom_ScheduleFieldMessageWithFollowupState(53, gText_UR_WhichMonWillYouOffer); + ScheduleFieldMessageWithFollowupState(UR_STATE_REGISTER_SELECT_MON_FADE, gText_UR_WhichMonWillYouOffer); break; case 2: // INFO - UnionRoom_ScheduleFieldMessageWithFollowupState(47, gText_UR_TradingBoardInfo); + ScheduleFieldMessageWithFollowupState(UR_STATE_REGISTER_PROMPT_HANDLE_INPUT, gText_UR_TradingBoardInfo); break; } } DestroyHelpMessageWindow_(); } break; - case 53: - BeginNormalPaletteFade(-1, 0, 0, 0x10, RGB_BLACK); - data->state = 54; + case UR_STATE_REGISTER_SELECT_MON_FADE: + BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); + uroom->state = UR_STATE_REGISTER_SELECT_MON; break; - case 54: + case UR_STATE_REGISTER_SELECT_MON: if (!gPaletteFade.active) { - sUnionRoomTrade.field_0 = 1; + sUnionRoomTrade.state = URTRADE_STATE_REGISTERING; gFieldCallback = FieldCB_ContinueScriptUnionRoom; ChooseMonForTradingBoard(PARTY_MENU_TYPE_UNION_ROOM_REGISTER, CB2_ReturnToField); } break; - case 52: - var5 = ListMenuHandler_AllItemsAvailable(&data->textState, &data->tradeBoardSelectWindowId, &data->tradeBoardDetailsWindowId, &sWindowTemplate_TypeNames, &sListMenuTemplate_TypeNames); - if (var5 != -1) + case UR_STATE_REGISTER_REQUEST_TYPE: + input = ListMenuHandler_AllItemsAvailable(&uroom->textState, &uroom->tradeBoardMainWindowId, &uroom->tradeBoardHeaderWindowId, &sWindowTemplate_TypeNames, &sListMenuTemplate_TypeNames); + if (input != LIST_NOTHING_CHOSEN) { - switch (var5) + switch (input) { - case -2: - case 18: + case LIST_CANCEL: + case NUMBER_OF_MON_TYPES: // Exit ResetUnionRoomTrade(&sUnionRoomTrade); - SetTradeBoardRegisteredMonInfo(0, 0, 0); - UnionRoom_ScheduleFieldMessageAndExit(gText_UR_RegistrationCanceled); + SetTradeBoardRegisteredMonInfo(TYPE_NORMAL, SPECIES_NONE, 0); + ScheduleFieldMessageAndExit(gText_UR_RegistrationCanceled); break; default: - sUnionRoomTrade.type = var5; - data->state = 55; + sUnionRoomTrade.type = input; + uroom->state = UR_STATE_REGISTER_COMPLETE; break; } } break; - case 55: + case UR_STATE_REGISTER_COMPLETE: SetTradeBoardRegisteredMonInfo(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); - UnionRoom_ScheduleFieldMessageAndExit(gText_UR_RegistraionCompleted); + ScheduleFieldMessageAndExit(gText_UR_RegistraionCompleted); break; - case 44: - switch (UnionRoomHandleYesNo(&data->textState, FALSE)) + case UR_STATE_CANCEL_REGISTRATION_PROMPT: + switch (UnionRoomHandleYesNo(&uroom->textState, FALSE)) { - case 0: - data->state = 56; + case 0: // YES + uroom->state = UR_STATE_CANCEL_REGISTRATION; break; - case 1: - case -1: - HandleCancelTrade(TRUE); - data->state = 4; + case 1: // NO + case MENU_B_PRESSED: + HandleCancelActivity(TRUE); + uroom->state = UR_STATE_MAIN; break; } break; - case 56: - if (PrintOnTextbox(&data->textState, gText_UR_RegistrationCanceled2)) + case UR_STATE_CANCEL_REGISTRATION: + if (PrintOnTextbox(&uroom->textState, gText_UR_RegistrationCanceled2)) { - SetTradeBoardRegisteredMonInfo(0, 0, 0); + SetTradeBoardRegisteredMonInfo(TYPE_NORMAL, SPECIES_NONE, 0); ResetUnionRoomTrade(&sUnionRoomTrade); - HandleCancelTrade(TRUE); - data->state = 4; + HandleCancelActivity(TRUE); + uroom->state = UR_STATE_MAIN; } break; - case 45: - if (PrintOnTextbox(&data->textState, gText_UR_XCheckedTradingBoard)) - data->state = 46; + case UR_STATE_CHECK_TRADING_BOARD: + if (PrintOnTextbox(&uroom->textState, gText_UR_XCheckedTradingBoard)) + uroom->state = UR_STATE_TRADING_BOARD_LOAD; break; - case 46: - UR_BlankBg0(); - data->state = 48; + case UR_STATE_TRADING_BOARD_LOAD: + UR_ClearBg0(); + uroom->state = UR_STATE_TRADING_BOARD_HANDLE_INPUT; break; - case 48: - var5 = TradeBoardMenuHandler(&data->textState, &data->tradeBoardSelectWindowId, &data->tradeBoardListMenuId, &data->tradeBoardDetailsWindowId, &gUnknown_8456F24, &sTradeBoardListMenuTemplate, data->field_0); - if (var5 != -1) + case UR_STATE_TRADING_BOARD_HANDLE_INPUT: + input = TradeBoardMenuHandler(&uroom->textState, + &uroom->tradeBoardMainWindowId, + &uroom->tradeBoardListMenuId, + &uroom->tradeBoardHeaderWindowId, + &sWindowTemplate_TradingBoardMain, + &sListMenuTemplate_TradeBoard, + uroom->playerList); + if (input != LIST_NOTHING_CHOSEN) { - switch (var5) + switch (input) { - case -2: - case 8: - HandleCancelTrade(TRUE); + case LIST_CANCEL: + case 8: // EXIT + HandleCancelActivity(TRUE); DestroyHelpMessageWindow_(); - data->state = 4; + uroom->state = UR_STATE_MAIN; break; default: - switch (IsRequestedTypeAndSpeciesInPlayerParty(data->field_0->arr[var5].gname_uname.gname.tradeType, data->field_0->arr[var5].gname_uname.gname.tradeSpecies)) + switch (IsRequestedTradeInPlayerParty(uroom->playerList->players[input].rfu.data.tradeType, uroom->playerList->players[input].rfu.data.tradeSpecies)) { case UR_TRADE_MATCH: - IntlConvPartnerUname(gStringVar1, data->field_0->arr[var5]); - UnionRoom_ScheduleFieldMessageWithFollowupState(49, gText_UR_AskTrainerToMakeTrade); - taskData[1] = var5; + CopyAndTranslatePlayerName2(gStringVar1, uroom->playerList->players[input]); + ScheduleFieldMessageWithFollowupState(UR_STATE_TRADE_PROMPT, gText_UR_AskTrainerToMakeTrade); + taskData[1] = input; break; case UR_TRADE_NOTYPE: - IntlConvPartnerUname(gStringVar1, data->field_0->arr[var5]); - StringCopy(gStringVar2, gTypeNames[data->field_0->arr[var5].gname_uname.gname.tradeType]); - UnionRoom_ScheduleFieldMessageWithFollowupState(46, gText_UR_DontHaveTypeTrainerWants); + CopyAndTranslatePlayerName2(gStringVar1, uroom->playerList->players[input]); + StringCopy(gStringVar2, gTypeNames[uroom->playerList->players[input].rfu.data.tradeType]); + ScheduleFieldMessageWithFollowupState(UR_STATE_TRADING_BOARD_LOAD, gText_UR_DontHaveTypeTrainerWants); break; case UR_TRADE_NOEGG: - IntlConvPartnerUname(gStringVar1, data->field_0->arr[var5]); - StringCopy(gStringVar2, gTypeNames[data->field_0->arr[var5].gname_uname.gname.tradeType]); - UnionRoom_ScheduleFieldMessageWithFollowupState(46, gText_UR_DontHaveEggTrainerWants); + CopyAndTranslatePlayerName2(gStringVar1, uroom->playerList->players[input]); + StringCopy(gStringVar2, gTypeNames[uroom->playerList->players[input].rfu.data.tradeType]); + ScheduleFieldMessageWithFollowupState(UR_STATE_TRADING_BOARD_LOAD, gText_UR_DontHaveEggTrainerWants); break; } break; } } break; - case 49: - switch (UnionRoomHandleYesNo(&data->textState, FALSE)) + case UR_STATE_TRADE_PROMPT: + switch (UnionRoomHandleYesNo(&uroom->textState, FALSE)) { - case 0: - data->state = 50; + case 0: // YES + uroom->state = UR_STATE_TRADE_SELECT_MON; break; - case -1: - case 1: - HandleCancelTrade(TRUE); - data->state = 4; + case MENU_B_PRESSED: + case 1: // NO + HandleCancelActivity(TRUE); + uroom->state = UR_STATE_MAIN; break; } break; - case 50: - if (PrintOnTextbox(&data->textState, gText_UR_WhichMonWillYouOffer)) + case UR_STATE_TRADE_SELECT_MON: + if (PrintOnTextbox(&uroom->textState, gText_UR_WhichMonWillYouOffer)) { - sUnionRoomTrade.field_0 = 2; - memcpy(&gPartnerTgtGnameSub, &data->field_0->arr[taskData[1]].gname_uname.gname.compatibility, sizeof(gPartnerTgtGnameSub)); - gUnionRoomRequestedMonType = data->field_0->arr[taskData[1]].gname_uname.gname.tradeType; - gUnionRoomOfferedSpecies = data->field_0->arr[taskData[1]].gname_uname.gname.tradeSpecies; + sUnionRoomTrade.state = URTRADE_STATE_OFFERING; + memcpy(&gRfuPartnerCompatibilityData, &uroom->playerList->players[taskData[1]].rfu.data.compatibility, sizeof(gRfuPartnerCompatibilityData)); + gUnionRoomRequestedMonType = uroom->playerList->players[taskData[1]].rfu.data.tradeType; + gUnionRoomOfferedSpecies = uroom->playerList->players[taskData[1]].rfu.data.tradeSpecies; gFieldCallback = FieldCB_ContinueScriptUnionRoom; ChooseMonForTradingBoard(PARTY_MENU_TYPE_UNION_ROOM_TRADE, CB2_ReturnToField); - BackUpURoomField0ToDecompressionBuffer(data); - sUnionRoomTrade.field_8 = taskData[1]; + CopyPlayerListToBuffer(uroom); + sUnionRoomTrade.offerPlayerId = taskData[1]; } break; - case 51: + case UR_STATE_TRADE_OFFER_MON: sPlayerCurrActivity = ACTIVITY_TRADE | IN_UNION_ROOM; - TryConnectToUnionRoomParent(data->field_0->arr[taskData[1]].gname_uname.uname, &data->field_0->arr[taskData[1]].gname_uname.gname, ACTIVITY_TRADE | IN_UNION_ROOM); - IntlConvPartnerUname(gStringVar1, data->field_0->arr[taskData[1]]); + TryConnectToUnionRoomParent(uroom->playerList->players[taskData[1]].rfu.name, &uroom->playerList->players[taskData[1]].rfu.data, ACTIVITY_TRADE | IN_UNION_ROOM); + CopyAndTranslatePlayerName2(gStringVar1, uroom->playerList->players[taskData[1]]); UR_PrintFieldMessage(gTexts_UR_CommunicatingWait[2]); - data->state = 25; + uroom->state = UR_STATE_TRY_COMMUNICATING; break; - case 26: - if (PrintOnTextbox(&data->textState, gStringVar4)) + case UR_STATE_PRINT_AND_EXIT: + if (PrintOnTextbox(&uroom->textState, gStringVar4)) { - HandleCancelTrade(TRUE); - UpdateUnionGroupMemberFacing(taskData[0], taskData[1], data->field_0); - data->state = 4; + HandleCancelActivity(TRUE); + UpdateUnionGroupMemberFacing(taskData[0], taskData[1], uroom->playerList); + uroom->state = UR_STATE_MAIN; } break; - case 8: - if (PrintOnTextbox(&data->textState, gStringVar4)) - data->state = data->stateAfterPrint; + case UR_STATE_PRINT_MSG: + if (PrintOnTextbox(&uroom->textState, gStringVar4)) + uroom->state = uroom->stateAfterPrint; break; } } -void var_800D_set_xB(void) +void SetUsingUnionRoomStartMenu(void) { if (InUnionRoom() == TRUE) - gSpecialVar_Result = 11; + gSpecialVar_Result = UR_INTERACT_START_MENU; } -static void ReceiveUnionRoomActivityPacket(struct UnkStruct_URoom * uroom) +static void ReceiveUnionRoomActivityPacket(struct WirelessLink_URoom * uroom) { - if (gRecvCmds[1][1] != 0 && (gRecvCmds[1][0] & 0xFF00) == RFUCMD_SEND_PACKET) + if (gRecvCmds[1][1] != 0 && (gRecvCmds[1][0] & RFUCMD_MASK) == RFUCMD_SEND_PACKET) { uroom->recvActivityRequest[0] = gRecvCmds[1][1]; if (gRecvCmds[1][1] == (ACTIVITY_TRADE | IN_UNION_ROOM)) @@ -3432,24 +3081,24 @@ static void ReceiveUnionRoomActivityPacket(struct UnkStruct_URoom * uroom) } } -static bool32 UnionRoom_HandleContactFromOtherPlayer(struct UnkStruct_URoom * uroom) +static bool32 HandleContactFromOtherPlayer(struct WirelessLink_URoom * uroom) { if (uroom->recvActivityRequest[0] != 0) { - s32 var = GetChatLeaderActionRequestMessage(gStringVar4, gLinkPlayers[1].gender, &uroom->recvActivityRequest[0], uroom); - if (var == 0) + s32 id = GetChatLeaderActionRequestMessage(gStringVar4, gLinkPlayers[1].gender, &uroom->recvActivityRequest[0], uroom); + if (id == 0) // Error { return TRUE; } - else if (var == 1) + else if (id == 1) // Recieve activity request { - uroom->state = 35; + uroom->state = UR_STATE_RECV_ACTIVITY_REQUEST; sPlayerCurrActivity = uroom->recvActivityRequest[0]; return FALSE; } - else if (var == 2) + else if (id == 2) // No activity { - uroom->state = 36; + uroom->state = UR_STATE_CANCEL_REQUEST_PRINT_MSG; SetCloseLinkCallback(); return FALSE; } @@ -3460,19 +3109,19 @@ static bool32 UnionRoom_HandleContactFromOtherPlayer(struct UnkStruct_URoom * ur void InitUnionRoom(void) { - struct UnkStruct_URoom * ptr; + struct WirelessLink_URoom * data; sUnionRoomPlayerName[0] = EOS; if (QL_IS_PLAYBACK_STATE) return; CreateTask(Task_InitUnionRoom, 0); - sUnionRoomMain.uRoom = sUnionRoomMain.uRoom; // Needed to match. - sUnionRoomMain.uRoom = ptr = AllocZeroed(sizeof(struct UnkStruct_URoom)); - sURoom = sUnionRoomMain.uRoom; - ptr->state = 0; - ptr->textState = 0; - ptr->field_10 = 0; - ptr->field_12 = 0; + sWirelessLinkMain.uRoom = sWirelessLinkMain.uRoom; // Needed to match. + sWirelessLinkMain.uRoom = data = AllocZeroed(sizeof(struct WirelessLink_URoom)); + sURoom = sWirelessLinkMain.uRoom; + data->state = 0; + data->textState = 0; + data->unknown = 0; + data->unreadPlayerId = 0; sUnionRoomPlayerName[0] = EOS; } @@ -3480,46 +3129,46 @@ static void Task_InitUnionRoom(u8 taskId) { s32 i; u8 text[32]; - struct UnkStruct_URoom * structPtr = sUnionRoomMain.uRoom; + struct WirelessLink_URoom * data = sWirelessLinkMain.uRoom; - switch (structPtr->state) + switch (data->state) { case 0: - structPtr->state = 1; + data->state = 1; break; case 1: - SetHostRfuGameData(ACTIVITY_SEARCH, 0, 0); + SetHostRfuGameData(ACTIVITY_SEARCH, 0, FALSE); SetWirelessCommType1(); OpenLink(); InitializeRfuLinkManager_EnterUnionRoom(); RfuSetIgnoreError(TRUE); - structPtr->state = 2; + data->state = 2; break; case 2: - structPtr->field_4 = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - BlankUnkStruct_x1CArray(structPtr->field_4->arr, 4); - structPtr->field_C = AllocZeroed(4 * sizeof(struct UnkStruct_x1C)); - BlankUnkStruct_x1CArray(structPtr->field_C->arr, 4); - structPtr->field_0 = AllocZeroed(UROOM_MAX_GROUP_COUNT * sizeof(struct UnkStruct_x20)); - BlankUnkStruct_x20Array(structPtr->field_0->arr, UROOM_MAX_GROUP_COUNT); - structPtr->field_8 = AllocZeroed(sizeof(struct UnkStruct_x20)); - BlankUnkStruct_x20Array(&structPtr->field_8->arr[0], 1); - structPtr->field_20 = CreateTask_SearchForChildOrParent(structPtr->field_C, structPtr->field_4, LINK_GROUP_UNION_ROOM_INIT); - structPtr->state = 3; + data->incomingChildList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + ClearIncomingPlayerList(data->incomingChildList->players, RFU_CHILD_MAX); + data->incomingParentList = AllocZeroed(RFU_CHILD_MAX * sizeof(struct RfuIncomingPlayer)); + ClearIncomingPlayerList(data->incomingParentList->players, RFU_CHILD_MAX); + data->playerList = AllocZeroed(MAX_UNION_ROOM_LEADERS * sizeof(struct RfuPlayer)); + ClearRfuPlayerList(data->playerList->players, MAX_UNION_ROOM_LEADERS); + data->spawnPlayer = AllocZeroed(sizeof(struct RfuPlayer)); + ClearRfuPlayerList(&data->spawnPlayer->players[0], 1); + data->searchTaskId = CreateTask_SearchForChildOrParent(data->incomingParentList, data->incomingChildList, LINK_GROUP_UNION_ROOM_INIT); + data->state = 3; break; case 3: switch (HandlePlayerListUpdate()) { - case 1: - case 2: + case PLIST_NEW_PLAYER: + case PLIST_RECENT_UPDATE: if (sUnionRoomPlayerName[0] == EOS) { for (i = 0; i < PLAYER_NAME_LENGTH + 1; i++) { - if (structPtr->field_0->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (data->playerList->players[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - IntlConvPartnerUname(text, structPtr->field_0->arr[i]); - if (PlayerHasMetTrainerBefore(ReadAsU16(structPtr->field_0->arr[i].gname_uname.gname.compatibility.playerTrainerId), text)) + CopyAndTranslatePlayerName2(text, data->playerList->players[i]); + if (PlayerHasMetTrainerBefore(ReadAsU16(data->playerList->players[i].rfu.data.compatibility.playerTrainerId), text)) { StringCopy(sUnionRoomPlayerName, text); break; @@ -3528,17 +3177,17 @@ static void Task_InitUnionRoom(u8 taskId) } } break; - case 3: + case PLIST_UNUSED: break; } break; case 4: - Free(structPtr->field_8); - Free(structPtr->field_0); - Free(structPtr->field_C); - Free(structPtr->field_4); - DestroyTask(structPtr->field_20); - Free(sUnionRoomMain.uRoom); + Free(data->spawnPlayer); + Free(data->playerList); + Free(data->incomingParentList); + Free(data->incomingChildList); + DestroyTask(data->searchTaskId); + Free(sWirelessLinkMain.uRoom); LinkRfu_Shutdown(); DestroyTask(taskId); break; @@ -3563,73 +3212,73 @@ static u8 HandlePlayerListUpdate(void) { s32 i; u8 j; - struct UnkStruct_URoom * structPtr = sUnionRoomMain.uRoom; - s32 r7 = 0; + struct WirelessLink_URoom * data = sWirelessLinkMain.uRoom; + s32 retVal = PLIST_NONE; - // If someone new joined, register them in field_8 + // If someone new joined, register them in spawnPlayer for (i = 0; i < RFU_CHILD_MAX; i++) { - if (AreGnameUnameDifferent(&structPtr->field_C->arr[i].gname_uname, &sUnionGnameUnamePair_Dummy) == TRUE) + if (ArePlayersDifferent(&data->incomingParentList->players[i].rfu, &sRfuPlayerData_Dummy) == TRUE) { - structPtr->field_8->arr[0].gname_uname = structPtr->field_C->arr[i].gname_uname; - structPtr->field_8->arr[0].field_18 = 0; - structPtr->field_8->arr[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - structPtr->field_8->arr[0].field_1B = 1; - return 4; + data->spawnPlayer->players[0].rfu = data->incomingParentList->players[i].rfu; + data->spawnPlayer->players[0].timeoutCounter = 0; + data->spawnPlayer->players[0].groupScheduledAnim = UNION_ROOM_SPAWN_IN; + data->spawnPlayer->players[0].newPlayerCountdown = 1; + return PLIST_CONTACTED; } } // Handle changes to existing player statuses - for (j = 0; j < UROOM_MAX_GROUP_COUNT; j++) + for (j = 0; j < MAX_UNION_ROOM_LEADERS; j++) { - if (structPtr->field_0->arr[j].groupScheduledAnim != UNION_ROOM_SPAWN_NONE) + if (data->playerList->players[j].groupScheduledAnim != UNION_ROOM_SPAWN_NONE) { - i = Findx20Inx1CArray(&structPtr->field_0->arr[j], &structPtr->field_4->arr[0]); + i = GetNewIncomingPlayerId(&data->playerList->players[j], &data->incomingChildList->players[0]); if (i != 0xFF) { - if (structPtr->field_0->arr[j].groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (data->playerList->players[j].groupScheduledAnim == UNION_ROOM_SPAWN_IN) { // New join in queue - if (AreUnionRoomPlayerGnamesDifferent(&structPtr->field_0->arr[j].gname_uname, &structPtr->field_4->arr[i].gname_uname)) + if (ArePlayerDataDifferent(&data->playerList->players[j].rfu, &data->incomingChildList->players[i].rfu)) { // Just joined, copy their names - structPtr->field_0->arr[j].gname_uname = structPtr->field_4->arr[i].gname_uname; - structPtr->field_0->arr[j].field_1B = 0x40; - r7 = 1; + data->playerList->players[j].rfu = data->incomingChildList->players[i].rfu; + data->playerList->players[j].newPlayerCountdown = 64; + retVal = PLIST_NEW_PLAYER; } - else if (structPtr->field_0->arr[j].field_1B != 0) + else if (data->playerList->players[j].newPlayerCountdown != 0) { - structPtr->field_0->arr[j].field_1B--; - if (structPtr->field_0->arr[j].field_1B == 0) - r7 = 2; + data->playerList->players[j].newPlayerCountdown--; + if (data->playerList->players[j].newPlayerCountdown == 0) + retVal = PLIST_RECENT_UPDATE; } } else { // New join, queue them - structPtr->field_0->arr[j].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - structPtr->field_0->arr[j].field_1B = 0; - r7 = 2; + data->playerList->players[j].groupScheduledAnim = UNION_ROOM_SPAWN_IN; + data->playerList->players[j].newPlayerCountdown = 0; + retVal = 2; } - structPtr->field_0->arr[j].field_18 = 0; + data->playerList->players[j].timeoutCounter = 0; } - else if (structPtr->field_0->arr[j].groupScheduledAnim != UNION_ROOM_SPAWN_OUT) + else if (data->playerList->players[j].groupScheduledAnim != UNION_ROOM_SPAWN_OUT) { // Person may have disconnected. Give them 10 seconds. - structPtr->field_0->arr[j].field_18++; - if (structPtr->field_0->arr[j].field_18 >= 600) + data->playerList->players[j].timeoutCounter++; + if (data->playerList->players[j].timeoutCounter >= 600) { - structPtr->field_0->arr[j].groupScheduledAnim = UNION_ROOM_SPAWN_OUT; - r7 = 2; + data->playerList->players[j].groupScheduledAnim = UNION_ROOM_SPAWN_OUT; + retVal = PLIST_RECENT_UPDATE; } } - else if (structPtr->field_0->arr[j].groupScheduledAnim == UNION_ROOM_SPAWN_OUT) + else if (data->playerList->players[j].groupScheduledAnim == UNION_ROOM_SPAWN_OUT) { // Person dropped. Wait 15 seconds, then remove them. - structPtr->field_0->arr[j].field_18++; - if (structPtr->field_0->arr[j].field_18 >= 900) + data->playerList->players[j].timeoutCounter++; + if (data->playerList->players[j].timeoutCounter >= 900) { - BlankUnkStruct_x20Array(&structPtr->field_0->arr[j], 1); + ClearRfuPlayerList(&data->playerList->players[j], 1); } } } @@ -3638,107 +3287,91 @@ static u8 HandlePlayerListUpdate(void) // Update the players list for (i = 0; i < RFU_CHILD_MAX; i++) { - if (Appendx1Ctox20(&structPtr->field_0->arr[0], &structPtr->field_4->arr[i], UROOM_MAX_GROUP_COUNT) != 0xFF) - r7 = 1; + if (TryAddIncomingPlayerToList(&data->playerList->players[0], &data->incomingChildList->players[i], MAX_UNION_ROOM_LEADERS) != 0xFF) + retVal = PLIST_NEW_PLAYER; } - return r7; + return retVal; } static void Task_SearchForChildOrParent(u8 taskId) { s32 i, j; - struct UnionGnameUnamePair gname_uname; - struct UnkStruct_Main4 ** ptr = (void *) gTasks[taskId].data; - bool8 parent_child; + struct RfuPlayerData rfu; + struct RfuIncomingPlayerList ** list = (void *) gTasks[taskId].data; + bool8 isParent; for (i = 0; i < RFU_CHILD_MAX; i++) { - parent_child = Rfu_GetCompatiblePlayerData(&gname_uname.gname, gname_uname.uname, i); - if (!IsPartnerActivityAcceptable(gname_uname.gname.activity, gTasks[taskId].data[4])) - { - gname_uname = sUnionGnameUnamePair_Dummy; - } - if (gname_uname.gname.compatibility.language == LANGUAGE_JAPANESE) - { - gname_uname = sUnionGnameUnamePair_Dummy; - } - if (parent_child == MODE_CHILD) + isParent = Rfu_GetCompatiblePlayerData(&rfu.data, rfu.name, i); + if (!IsPartnerActivityAcceptable(rfu.data.activity, gTasks[taskId].data[4])) + rfu = sRfuPlayerData_Dummy; + if (rfu.data.compatibility.language == LANGUAGE_JAPANESE) + rfu = sRfuPlayerData_Dummy; + + if (!isParent) { for (j = 0; j < i; j++) { - if (!AreGnameUnameDifferent(&ptr[1]->arr[j].gname_uname, &gname_uname)) - { - gname_uname = sUnionGnameUnamePair_Dummy; - } + if (!ArePlayersDifferent(&list[1]->players[j].rfu, &rfu)) + rfu = sRfuPlayerData_Dummy; } - ptr[1]->arr[i].gname_uname = gname_uname; - ptr[1]->arr[i].active = AreGnameUnameDifferent(&ptr[1]->arr[i].gname_uname, &sUnionGnameUnamePair_Dummy); + list[1]->players[i].rfu = rfu; + list[1]->players[i].active = ArePlayersDifferent(&list[1]->players[i].rfu, &sRfuPlayerData_Dummy); } else { - ptr[0]->arr[i].gname_uname = gname_uname; - ptr[0]->arr[i].active = AreGnameUnameDifferent(&ptr[0]->arr[i].gname_uname, &sUnionGnameUnamePair_Dummy); + list[0]->players[i].rfu = rfu; + list[0]->players[i].active = ArePlayersDifferent(&list[0]->players[i].rfu, &sRfuPlayerData_Dummy); } } } -static u8 CreateTask_SearchForChildOrParent(struct UnkStruct_Main4 * main4_parent, struct UnkStruct_Main4 * main4_child, u32 linkGroup) +static u8 CreateTask_SearchForChildOrParent(struct RfuIncomingPlayerList * parentList, struct RfuIncomingPlayerList * childList, u32 linkGroup) { u8 taskId = CreateTask(Task_SearchForChildOrParent, 0); - struct UnkStruct_Main4 ** data = (void *)gTasks[taskId].data; - data[0] = main4_parent; - data[1] = main4_child; + struct RfuIncomingPlayerList ** data = (void *)gTasks[taskId].data; + data[0] = parentList; + data[1] = childList; gTasks[taskId].data[4] = linkGroup; return taskId; } -static void Task_ListenForPartnersWithCompatibleSerialNos(u8 taskId) +static void Task_ListenForCompatiblePartners(u8 taskId) { s32 i, j; - struct UnkStruct_Main4 ** ptr = (void *) gTasks[taskId].data; + struct RfuIncomingPlayerList ** list = (void *) gTasks[taskId].data; for (i = 0; i < RFU_CHILD_MAX; i++) { - Rfu_GetCompatiblePlayerData(&ptr[0]->arr[i].gname_uname.gname, ptr[0]->arr[i].gname_uname.uname, i); - if (!IsPartnerActivityAcceptable(ptr[0]->arr[i].gname_uname.gname.activity, gTasks[taskId].data[2])) - { - ptr[0]->arr[i].gname_uname = sUnionGnameUnamePair_Dummy; - } + Rfu_GetCompatiblePlayerData(&list[0]->players[i].rfu.data, list[0]->players[i].rfu.name, i); + if (!IsPartnerActivityAcceptable(list[0]->players[i].rfu.data.activity, gTasks[taskId].data[2])) + list[0]->players[i].rfu = sRfuPlayerData_Dummy; + for (j = 0; j < i; j++) { - if (!AreGnameUnameDifferent(&ptr[0]->arr[j].gname_uname, &ptr[0]->arr[i].gname_uname)) - { - ptr[0]->arr[i].gname_uname = sUnionGnameUnamePair_Dummy; - } + if (!ArePlayersDifferent(&list[0]->players[j].rfu, &list[0]->players[i].rfu)) + list[0]->players[i].rfu = sRfuPlayerData_Dummy; } - ptr[0]->arr[i].active = AreGnameUnameDifferent(&ptr[0]->arr[i].gname_uname, &sUnionGnameUnamePair_Dummy); + list[0]->players[i].active = ArePlayersDifferent(&list[0]->players[i].rfu, &sRfuPlayerData_Dummy); } } -static bool32 GetGnameWonderFlagByLinkGroup(struct RfuGameData * gname, s16 linkGroup) +static bool32 HasWonderCardOrNewsByLinkGroup(struct RfuGameData * data, s16 linkGroup) { if (linkGroup == LINK_GROUP_WONDER_CARD) { - if (!gname->compatibility.hasCard) - { + if (!data->compatibility.hasCard) return FALSE; - } else - { return TRUE; - } } else if (linkGroup == LINK_GROUP_WONDER_NEWS) { - if (!gname->compatibility.hasNews) - { + if (!data->compatibility.hasNews) return FALSE; - } else - { return TRUE; - } } else { @@ -3746,35 +3379,34 @@ static bool32 GetGnameWonderFlagByLinkGroup(struct RfuGameData * gname, s16 link } } -static void Task_ListenForPartnersWithSerial7F7D(u8 taskId) +static void Task_ListenForWonderDistributor(u8 taskId) { s32 i; - struct UnkStruct_Main4 ** ptr = (void *) gTasks[taskId].data; + struct RfuIncomingPlayerList ** list = (void *) gTasks[taskId].data; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (Rfu_GetWonderDistributorPlayerData(&ptr[0]->arr[i].gname_uname.gname, ptr[0]->arr[i].gname_uname.uname, i)) - { - GetGnameWonderFlagByLinkGroup(&ptr[0]->arr[i].gname_uname.gname, gTasks[taskId].data[2]); - } - ptr[0]->arr[i].active = AreGnameUnameDifferent(&ptr[0]->arr[i].gname_uname, &sUnionGnameUnamePair_Dummy); + if (Rfu_GetWonderDistributorPlayerData(&list[0]->players[i].rfu.data, list[0]->players[i].rfu.name, i)) + HasWonderCardOrNewsByLinkGroup(&list[0]->players[i].rfu.data, gTasks[taskId].data[2]); + + list[0]->players[i].active = ArePlayersDifferent(&list[0]->players[i].rfu, &sRfuPlayerData_Dummy); } } -static u8 CreateTask_ListenForPartnersWithCompatibleSerialNos(struct UnkStruct_Main4 * main4, u32 linkGroup) +static u8 CreateTask_ListenForCompatiblePartners(struct RfuIncomingPlayerList * main4, u32 linkGroup) { - u8 taskId = CreateTask(Task_ListenForPartnersWithCompatibleSerialNos, 0); - struct UnkStruct_Main4 ** ptr = (void *) gTasks[taskId].data; - ptr[0] = main4; + u8 taskId = CreateTask(Task_ListenForCompatiblePartners, 0); + struct RfuIncomingPlayerList ** list = (void *) gTasks[taskId].data; + list[0] = main4; gTasks[taskId].data[2] = linkGroup; return taskId; } -static u8 CreateTask_ListenForPartnersWithSerial7F7D(struct UnkStruct_Main4 * main4, u32 linkGroup) +static u8 CreateTask_ListenForWonderDistributor(struct RfuIncomingPlayerList * main4, u32 linkGroup) { - u8 taskId = CreateTask(Task_ListenForPartnersWithSerial7F7D, 0); - struct UnkStruct_Main4 ** ptr = (void *) gTasks[taskId].data; - ptr[0] = main4; + u8 taskId = CreateTask(Task_ListenForWonderDistributor, 0); + struct RfuIncomingPlayerList ** list = (void *) gTasks[taskId].data; + list[0] = main4; gTasks[taskId].data[2] = linkGroup; return taskId; } @@ -3788,16 +3420,12 @@ static bool32 UR_PrintFieldMessage(const u8 *src) return FALSE; } -static bool32 UR_RunTextPrinters_CheckPrinter0Active(void) +static bool32 UR_RunTextPrinters(void) { if (!RunTextPrinters_CheckPrinter0Active()) - { return TRUE; - } else - { return FALSE; - } } static bool8 PrintOnTextbox(u8 *textState, const u8 *str) @@ -3822,36 +3450,34 @@ static bool8 PrintOnTextbox(u8 *textState, const u8 *str) return FALSE; } -static s8 UnionRoomHandleYesNo(u8 *state_p, bool32 no_draw) +static s8 UnionRoomHandleYesNo(u8 *state, bool32 noDraw) { - s8 r1; + s8 input; - switch (*state_p) + switch (*state) { case 0: - if (no_draw) - { + if (noDraw) return -3; - } DisplayYesNoMenuDefaultYes(); - (*state_p)++; + (*state)++; break; case 1: - if (no_draw) + if (noDraw) { DestroyYesNoMenu(); - *state_p = 0; + *state = 0; return -3; } - r1 = Menu_ProcessInputNoWrapClearOnChoose(); - if (r1 == -1 || r1 == 0 || r1 == 1) + input = Menu_ProcessInputNoWrapClearOnChoose(); + if (input == MENU_B_PRESSED || input == 0 || input == 1) { - *state_p = 0; - return r1; + *state = 0; + return input; } break; } - return -2; + return MENU_NOTHING_CHOSEN; } static u8 CreateTradeBoardWindow(const struct WindowTemplate * template) @@ -3859,7 +3485,7 @@ static u8 CreateTradeBoardWindow(const struct WindowTemplate * template) u8 windowId = AddWindow(template); DrawStdWindowFrame(windowId, FALSE); FillWindowPixelBuffer(windowId, PIXEL_FILL(15)); - UR_AddTextPrinterParameterized(windowId, 0, gText_UR_NameWantedOfferLv, 8, 1, UR_COLOR_DN5_DN6_LTB); + PrintUnionRoomText(windowId, FONT_0, gText_UR_NameWantedOfferLv, 8, 1, UR_COLOR_TRADE_BOARD_OTHER); PutWindowTilemap(windowId); CopyWindowToVram(windowId, COPYWIN_GFX); return windowId; @@ -3871,86 +3497,90 @@ static void DeleteTradeBoardWindow(u8 windowId) RemoveWindow(windowId); } -static s32 ListMenuHandler_AllItemsAvailable(u8 *state_p, u8 *win_id_p, u8 *list_menu_id_p, const struct WindowTemplate * winTemplate, const struct ListMenuTemplate * menuTemplate) +static s32 ListMenuHandler_AllItemsAvailable(u8 *state, u8 *windowId, u8 *listMenuId, const struct WindowTemplate * winTemplate, const struct ListMenuTemplate * menuTemplate) { s32 input; - switch (*state_p) + switch (*state) { case 0: - *win_id_p = AddWindow(winTemplate); - DrawStdWindowFrame(*win_id_p, FALSE); + *windowId = AddWindow(winTemplate); + DrawStdWindowFrame(*windowId, FALSE); gMultiuseListMenuTemplate = *menuTemplate; - gMultiuseListMenuTemplate.windowId = *win_id_p; - *list_menu_id_p = ListMenuInit(&gMultiuseListMenuTemplate, 0, 0); - CopyWindowToVram(*win_id_p, TRUE); - (*state_p)++; + gMultiuseListMenuTemplate.windowId = *windowId; + *listMenuId = ListMenuInit(&gMultiuseListMenuTemplate, 0, 0); + CopyWindowToVram(*windowId, TRUE); + (*state)++; break; case 1: - input = ListMenu_ProcessInput(*list_menu_id_p); + input = ListMenu_ProcessInput(*listMenuId); if (JOY_NEW(A_BUTTON)) { - DestroyListMenuTask(*list_menu_id_p, NULL, NULL); - ClearStdWindowAndFrame(*win_id_p, TRUE); - RemoveWindow(*win_id_p); - *state_p = 0; + DestroyListMenuTask(*listMenuId, NULL, NULL); + ClearStdWindowAndFrame(*windowId, TRUE); + RemoveWindow(*windowId); + *state = 0; return input; } else if (JOY_NEW(B_BUTTON)) { - DestroyListMenuTask(*list_menu_id_p, NULL, NULL); - ClearStdWindowAndFrame(*win_id_p, TRUE); - RemoveWindow(*win_id_p); - *state_p = 0; - return -2; + DestroyListMenuTask(*listMenuId, NULL, NULL); + ClearStdWindowAndFrame(*windowId, TRUE); + RemoveWindow(*windowId); + *state = 0; + return LIST_CANCEL; } break; } - return -1; + return LIST_NOTHING_CHOSEN; } -static s32 TradeBoardMenuHandler(u8 *state_p, u8 *win_id_p, u8 *list_menu_id_p, u8 *trade_board_win_id_p, const struct WindowTemplate * winTemplate, const struct ListMenuTemplate * menuTemplate, struct UnkStruct_Main0 * traders) +static s32 TradeBoardMenuHandler(u8 *state, u8 *mainWindowId, u8 *listMenuId, u8 *headerWindowId, + const struct WindowTemplate * winTemplate, + const struct ListMenuTemplate * menuTemplate, + struct RfuPlayerList * list) { s32 input; - s32 r4; + s32 idx; - switch (*state_p) + switch (*state) { case 0: - *trade_board_win_id_p = CreateTradeBoardWindow(&sTradeBoardWindowTemplate); - *win_id_p = AddWindow(winTemplate); - DrawStdWindowFrame(*win_id_p, FALSE); + *headerWindowId = CreateTradeBoardWindow(&sWindowTemplate_TradingBoardHeader); + *mainWindowId = AddWindow(winTemplate); + DrawStdWindowFrame(*mainWindowId, FALSE); gMultiuseListMenuTemplate = *menuTemplate; - gMultiuseListMenuTemplate.windowId = *win_id_p; - *list_menu_id_p = ListMenuInit(&gMultiuseListMenuTemplate, 0, 1); - CopyWindowToVram(*win_id_p, TRUE); - (*state_p)++; + gMultiuseListMenuTemplate.windowId = *mainWindowId; + *listMenuId = ListMenuInit(&gMultiuseListMenuTemplate, 0, 1); + CopyWindowToVram(*mainWindowId, TRUE); + (*state)++; break; case 1: - input = ListMenu_ProcessInput(*list_menu_id_p); + input = ListMenu_ProcessInput(*listMenuId); if (JOY_NEW(A_BUTTON | B_BUTTON)) { - if (input == UROOM_MAX_GROUP_COUNT || JOY_NEW(B_BUTTON)) + // Exit or B button + if (input == 8 || JOY_NEW(B_BUTTON)) { - DestroyListMenuTask(*list_menu_id_p, NULL, NULL); - ClearStdWindowAndFrame(*win_id_p, TRUE); - RemoveWindow(*win_id_p); - DeleteTradeBoardWindow(*trade_board_win_id_p); - *state_p = 0; - return -2; + DestroyListMenuTask(*listMenuId, NULL, NULL); + ClearStdWindowAndFrame(*mainWindowId, TRUE); + RemoveWindow(*mainWindowId); + DeleteTradeBoardWindow(*headerWindowId); + *state = 0; + return LIST_CANCEL; } else { - r4 = GetIndexOfNthTradeBoardOffer(traders->arr, input); - if (r4 >= 0) + idx = GetIndexOfNthTradeBoardOffer(list->players, input); + if (idx >= 0) { - DestroyListMenuTask(*list_menu_id_p, NULL, NULL); - ClearStdWindowAndFrame(*win_id_p, TRUE); - RemoveWindow(*win_id_p); - DeleteTradeBoardWindow(*trade_board_win_id_p); - *state_p = 0; - return r4; + DestroyListMenuTask(*listMenuId, NULL, NULL); + ClearStdWindowAndFrame(*mainWindowId, TRUE); + RemoveWindow(*mainWindowId); + DeleteTradeBoardWindow(*headerWindowId); + *state = 0; + return idx; } else { @@ -3961,23 +3591,23 @@ static s32 TradeBoardMenuHandler(u8 *state_p, u8 *win_id_p, u8 *list_menu_id_p, break; } - return -1; + return LIST_NOTHING_CHOSEN; } -static void UR_BlankBg0(void) +static void UR_ClearBg0(void) { FillBgTilemapBufferRect(0, 0, 0, 0, 32, 32, 0); CopyBgTilemapBufferToVram(0); } -static void JoinGroup_BlankBg0AndEnableScriptContexts(void) +static void JoinGroup_EnableScriptContexts(void) { FillBgTilemapBufferRect(0, 0, 0, 0, 32, 32, 0); CopyBgTilemapBufferToVram(0); ScriptContext_Enable(); } -static void UR_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 colorIdx) +static void PrintUnionRoomText(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 colorIdx) { struct TextPrinterTemplate printerTemplate; @@ -3993,49 +3623,49 @@ static void UR_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str gTextFlags.useAlternateDownArrow = FALSE; switch (colorIdx) { - case UR_COLOR_DKE_WHT_LTE: + case UR_COLOR_DEFAULT: printerTemplate.letterSpacing = 0; printerTemplate.lineSpacing = 0; printerTemplate.fgColor = TEXT_COLOR_DARK_GRAY; printerTemplate.bgColor = TEXT_COLOR_WHITE; printerTemplate.shadowColor = TEXT_COLOR_LIGHT_GRAY; break; - case UR_COLOR_RED_WHT_LTR: + case UR_COLOR_RED: printerTemplate.letterSpacing = 0; printerTemplate.lineSpacing = 0; printerTemplate.fgColor = TEXT_COLOR_RED; printerTemplate.bgColor = TEXT_COLOR_WHITE; printerTemplate.shadowColor = TEXT_COLOR_LIGHT_RED; break; - case UR_COLOR_GRN_WHT_LTG: + case UR_COLOR_GREEN: printerTemplate.letterSpacing = 0; printerTemplate.lineSpacing = 0; printerTemplate.fgColor = TEXT_COLOR_GREEN; printerTemplate.bgColor = TEXT_COLOR_WHITE; printerTemplate.shadowColor = TEXT_COLOR_LIGHT_GREEN; break; - case UR_COLOR_WHT_WHT_LTE: + case UR_COLOR_WHITE: printerTemplate.letterSpacing = 0; printerTemplate.lineSpacing = 0; printerTemplate.fgColor = TEXT_COLOR_WHITE; printerTemplate.bgColor = TEXT_COLOR_WHITE; printerTemplate.shadowColor = TEXT_COLOR_LIGHT_GRAY; break; - case UR_COLOR_WHT_DKE_LTE: + case UR_COLOR_CANCEL: printerTemplate.letterSpacing = 0; printerTemplate.lineSpacing = 0; printerTemplate.fgColor = TEXT_COLOR_WHITE; printerTemplate.bgColor = TEXT_COLOR_DARK_GRAY; printerTemplate.shadowColor = TEXT_COLOR_LIGHT_GRAY; break; - case UR_COLOR_GRN_DN6_LTB: + case UR_COLOR_TRADE_BOARD_SELF: printerTemplate.letterSpacing = 0; printerTemplate.lineSpacing = 0; printerTemplate.fgColor = TEXT_COLOR_LIGHT_GREEN; printerTemplate.bgColor = TEXT_DYNAMIC_COLOR_6; printerTemplate.shadowColor = TEXT_COLOR_LIGHT_BLUE; break; - case UR_COLOR_DN5_DN6_LTB: + case UR_COLOR_TRADE_BOARD_OTHER: printerTemplate.letterSpacing = 0; printerTemplate.lineSpacing = 0; printerTemplate.fgColor = TEXT_DYNAMIC_COLOR_5; @@ -4044,114 +3674,111 @@ static void UR_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 *str break; } - AddTextPrinter(&printerTemplate, 0xFF, NULL); + AddTextPrinter(&printerTemplate, TEXT_SKIP_DRAW, NULL); } -static void BlankUnkStruct_x20Array(struct UnkStruct_x20 * x20arr, u8 count) +static void ClearRfuPlayerList(struct RfuPlayer * x20arr, u8 count) { s32 i; for (i = 0; i < count; i++) { - x20arr[i].gname_uname = sUnionGnameUnamePair_Dummy; - x20arr[i].field_18 = 0xFF; + x20arr[i].rfu = sRfuPlayerData_Dummy; + x20arr[i].timeoutCounter = 0xFF; x20arr[i].groupScheduledAnim = UNION_ROOM_SPAWN_NONE; - x20arr[i].field_1A_1 = FALSE; - x20arr[i].field_1B = 0; + x20arr[i].useRedText = FALSE; + x20arr[i].newPlayerCountdown = 0; } } -static void BlankUnkStruct_x1CArray(struct UnkStruct_x1C * x1Carr, u8 count) +static void ClearIncomingPlayerList(struct RfuIncomingPlayer * x1Carr, u8 count) { s32 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - x1Carr[i].gname_uname = sUnionGnameUnamePair_Dummy; + x1Carr[i].rfu = sRfuPlayerData_Dummy; x1Carr[i].active = FALSE; } } -static bool8 AreGnameUnameDifferent(struct UnionGnameUnamePair * left, const struct UnionGnameUnamePair * right) +// Checks player name and trainer id, returns TRUE if they are not the same +static bool8 ArePlayersDifferent(struct RfuPlayerData * player1, const struct RfuPlayerData * player2) { s32 i; for (i = 0; i < 2; i++) { - if (left->gname.compatibility.playerTrainerId[i] != right->gname.compatibility.playerTrainerId[i]) - { + if (player1->data.compatibility.playerTrainerId[i] != player2->data.compatibility.playerTrainerId[i]) return TRUE; - } } for (i = 0; i < RFU_USER_NAME_LENGTH; i++) { - if (left->uname[i] != right->uname[i]) - { + if (player1->name[i] != player2->name[i]) return TRUE; - } } return FALSE; } -static bool32 AreUnionRoomPlayerGnamesDifferent(struct UnionGnameUnamePair * left, struct UnionGnameUnamePair * right) +static bool32 ArePlayerDataDifferent(struct RfuPlayerData * player1, struct RfuPlayerData * player2) { s32 i; - if (left->gname.activity != right->gname.activity) + if (player1->data.activity != player2->data.activity) return TRUE; - if (left->gname.startedActivity != right->gname.startedActivity) + if (player1->data.startedActivity != player2->data.startedActivity) return TRUE; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (left->gname.partnerInfo[i] != right->gname.partnerInfo[i]) + if (player1->data.partnerInfo[i] != player2->data.partnerInfo[i]) return TRUE; } - if (left->gname.tradeSpecies != right->gname.tradeSpecies) + if (player1->data.tradeSpecies != player2->data.tradeSpecies) return TRUE; - if (left->gname.tradeType != right->gname.tradeType) + if (player1->data.tradeType != player2->data.tradeType) return TRUE; return FALSE; } -static u32 Findx20Inx1CArray(struct UnkStruct_x20 * x20, struct UnkStruct_x1C * x1Carr) +static u32 GetNewIncomingPlayerId(struct RfuPlayer * player, struct RfuIncomingPlayer * incomingPlayer) { u8 result = 0xFF; s32 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (x1Carr[i].active && !AreGnameUnameDifferent(&x20->gname_uname, &x1Carr[i].gname_uname)) + if (incomingPlayer[i].active && !ArePlayersDifferent(&player->rfu, &incomingPlayer[i].rfu)) { result = i; - x1Carr[i].active = FALSE; + incomingPlayer[i].active = FALSE; } } return result; } -static u8 Appendx1Ctox20(struct UnkStruct_x20 * x20arr, struct UnkStruct_x1C * x1C, u8 count) +static u8 TryAddIncomingPlayerToList(struct RfuPlayer * players, struct RfuIncomingPlayer * incomingPlayer, u8 count) { s32 i; - if (x1C->active) + if (incomingPlayer->active) { for (i = 0; i < count; i++) { - if (x20arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_NONE) + if (players[i].groupScheduledAnim == UNION_ROOM_SPAWN_NONE) { - x20arr[i].gname_uname = x1C->gname_uname; - x20arr[i].field_18 = 0; - x20arr[i].groupScheduledAnim = UNION_ROOM_SPAWN_IN; - x20arr[i].field_1B = 0x40; - x1C->active = FALSE; + players[i].rfu = incomingPlayer->rfu; + players[i].timeoutCounter = 0; + players[i].groupScheduledAnim = UNION_ROOM_SPAWN_IN; + players[i].newPlayerCountdown = 0x40; + incomingPlayer->active = FALSE; return i; } } @@ -4160,62 +3787,59 @@ static u8 Appendx1Ctox20(struct UnkStruct_x20 * x20arr, struct UnkStruct_x1C * x return 0xFF; } -static void PrintUnionRoomGroupOnWindow(u8 windowId, u8 x, u8 y, struct UnkStruct_x20 * group, u8 colorIdx, u8 id) +static void PrintGroupMemberOnWindow(u8 windowId, u8 x, u8 y, struct RfuPlayer * player, u8 colorIdx, u8 id) { u8 activity; - u8 id_str[6]; + u8 trainerId[6]; u8 uname[30]; ConvertIntToDecimalStringN(gStringVar4, id + 1, STR_CONV_MODE_LEADING_ZEROS, 2); StringAppend(gStringVar4, gText_UR_Colon); - UR_AddTextPrinterParameterized(windowId, 0, gStringVar4, x, y, UR_COLOR_DKE_WHT_LTE); + PrintUnionRoomText(windowId, FONT_0, gStringVar4, x, y, UR_COLOR_DEFAULT); x += 18; - activity = group->gname_uname.gname.activity; - if (group->groupScheduledAnim == UNION_ROOM_SPAWN_IN && !(activity & IN_UNION_ROOM)) + activity = player->rfu.data.activity; + if (player->groupScheduledAnim == UNION_ROOM_SPAWN_IN && !(activity & IN_UNION_ROOM)) { - IntlConvPartnerUname(uname, *group); - UR_AddTextPrinterParameterized(windowId, 2, uname, x, y, colorIdx); - ConvertIntToDecimalStringN(id_str, group->gname_uname.gname.compatibility.playerTrainerId[0] | (group->gname_uname.gname.compatibility.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); + CopyAndTranslatePlayerName2(uname, *player); + PrintUnionRoomText(windowId, FONT_2, uname, x, y, colorIdx); + ConvertIntToDecimalStringN(trainerId, player->rfu.data.compatibility.playerTrainerId[0] | (player->rfu.data.compatibility.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); StringCopy(gStringVar4, gText_UR_ID); - StringAppend(gStringVar4, id_str); + StringAppend(gStringVar4, trainerId); x += 77; - UR_AddTextPrinterParameterized(windowId, 0, gStringVar4, x, y, colorIdx); + PrintUnionRoomText(windowId, FONT_0, gStringVar4, x, y, colorIdx); } } -static void PrintGroupMemberCandidateOnWindowWithColor(u8 windowId, u8 x, u8 y, struct UnkStruct_x20 * group, u8 colorIdx, u8 id) +static void PrintGroupCandidateOnWindow(u8 windowId, u8 x, u8 y, struct RfuPlayer * player, u8 colorIdx, u8 id) { u8 id_str[6]; u8 uname[30]; - if (group->groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (player->groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - IntlConvPartnerUname(uname, *group); - UR_AddTextPrinterParameterized(windowId, 2, uname, x, y, colorIdx); - ConvertIntToDecimalStringN(id_str, group->gname_uname.gname.compatibility.playerTrainerId[0] | (group->gname_uname.gname.compatibility.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); + CopyAndTranslatePlayerName2(uname, *player); + PrintUnionRoomText(windowId, FONT_2, uname, x, y, colorIdx); + ConvertIntToDecimalStringN(id_str, player->rfu.data.compatibility.playerTrainerId[0] | (player->rfu.data.compatibility.playerTrainerId[1] << 8), STR_CONV_MODE_LEADING_ZEROS, 5); StringCopy(gStringVar4, gText_UR_ID); StringAppend(gStringVar4, id_str); x += 71; - UR_AddTextPrinterParameterized(windowId, 0, gStringVar4, x, y, colorIdx); + PrintUnionRoomText(windowId, FONT_0, gStringVar4, x, y, colorIdx); } } -static bool32 PlayerIsTalkingToUnionRoomAide(void) +static bool32 IsPlayerFacingTradingBoard(void) { s16 x, y; GetXYCoordsOneStepInFrontOfPlayer(&x, &y); - if (x != 9) - { + + if (x != 2 + MAP_OFFSET) return FALSE; - } - if (y != 8) - { + + if (y != 1 + MAP_OFFSET) return FALSE; - } - if (gPlayerAvatar.tileTransitionState == 2 || gPlayerAvatar.tileTransitionState == 0) - { + + if (gPlayerAvatar.tileTransitionState == T_TILE_CENTER || gPlayerAvatar.tileTransitionState == T_NOT_MOVING) return TRUE; - } return FALSE; } @@ -4230,30 +3854,30 @@ static u32 GetResponseIdx_InviteToURoomActivity(s32 activity) return 2; case ACTIVITY_CARD: return 3; - case ACTIVITY_MLTBATTLE: + case ACTIVITY_BATTLE_MULTI: default: return 0; } } -static u32 ConvPartnerUnameAndGetWhetherMetAlready(struct UnkStruct_x20 * x20) +static u32 ConvPartnerUnameAndGetWhetherMetAlready(struct RfuPlayer * player) { - u8 sp0[30]; - IntlConvPartnerUname(sp0, *x20); - return PlayerHasMetTrainerBefore(ReadAsU16(x20->gname_uname.gname.compatibility.playerTrainerId), sp0); + u8 name[30]; + CopyAndTranslatePlayerName2(name, *player); + return PlayerHasMetTrainerBefore(ReadAsU16(player->rfu.data.compatibility.playerTrainerId), name); } -static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 * main0, u8 overrideGender, u8 playerIdx, u32 playerGender) +static s32 UnionRoomGetPlayerInteractionResponse(struct RfuPlayerList * list, bool8 overrideGender, u8 playerIdx, u32 playerGender) { bool32 metBefore; - struct UnkStruct_x20 * x20 = &main0->arr[playerIdx]; + struct RfuPlayer * player = &list->players[playerIdx]; - if (!x20->gname_uname.gname.startedActivity && overrideGender == 0) + if (!player->rfu.data.startedActivity && !overrideGender) { - IntlConvPartnerUname(gStringVar1, *x20); - metBefore = PlayerHasMetTrainerBefore(ReadAsU16(x20->gname_uname.gname.compatibility.playerTrainerId), gStringVar1); - if (x20->gname_uname.gname.activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) + CopyAndTranslatePlayerName2(gStringVar1, *player); + metBefore = PlayerHasMetTrainerBefore(ReadAsU16(player->rfu.data.compatibility.playerTrainerId), gStringVar1); + if (player->rfu.data.activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) { StringExpandPlaceholders(gStringVar4, gTexts_UR_JoinChat[metBefore][playerGender]); return 2; @@ -4266,14 +3890,13 @@ static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 * main0, } else { - IntlConvPartnerUname(gStringVar1, *x20); - if (overrideGender != 0) + CopyAndTranslatePlayerName2(gStringVar1, *player); + if (overrideGender) + playerGender = (player->rfu.data.compatibility.playerTrainerId[overrideGender + 1] >> 3) & 1; + + switch (player->rfu.data.activity & 0x3F) { - playerGender = (x20->gname_uname.gname.compatibility.playerTrainerId[overrideGender + 1] >> 3) & 1; - } - switch (x20->gname_uname.gname.activity & 0x3F) - { - case ACTIVITY_BATTLE: + case ACTIVITY_BATTLE_SINGLE: StringExpandPlaceholders(gStringVar4, gTexts_UR_BattleReaction[playerGender][Random() % 4]); break; case ACTIVITY_TRADE: @@ -4293,91 +3916,85 @@ static s32 UnionRoomGetPlayerInteractionResponse(struct UnkStruct_Main0 * main0, } } -static void nullsub_92(u8 windowId, u32 itemId, u8 y) +static void ItemPrintFunc_Unused(u8 windowId, u32 itemId, u8 y) { } -static void TradeBoardPrintItemInfo(u8 windowId, u8 y, struct RfuGameData * gname, const u8 * uname, u8 colorIdx) +static void TradeBoardPrintItemInfo(u8 windowId, u8 y, struct RfuGameData * data, const u8 * playerName, u8 colorIdx) { - u8 level_t[4]; - u16 species = gname->tradeSpecies; - u8 type = gname->tradeType; - u8 level = gname->tradeLevel; + u8 levelStr[4]; + u16 species = data->tradeSpecies; + u8 type = data->tradeType; + u8 level = data->tradeLevel; - UR_AddTextPrinterParameterized(windowId, 2, uname, 8, y, colorIdx); + PrintUnionRoomText(windowId, FONT_2, playerName, 8, y, colorIdx); if (species == SPECIES_EGG) { - UR_AddTextPrinterParameterized(windowId, 2, gText_UR_EggTrade, 0x44, y, colorIdx); + PrintUnionRoomText(windowId, FONT_2, gText_UR_EggTrade, 68, y, colorIdx); } else { - BlitMoveInfoIcon(windowId, type + 1, 0x44, y); - UR_AddTextPrinterParameterized(windowId, 2, gSpeciesNames[species], 0x76, y, colorIdx); - ConvertIntToDecimalStringN(level_t, level, STR_CONV_MODE_LEFT_ALIGN, 3); - UR_AddTextPrinterParameterized(windowId, 2, level_t, GetStringRightAlignXOffset(2, level_t, 218), y, colorIdx); + BlitMoveInfoIcon(windowId, type + 1, 68, y); + PrintUnionRoomText(windowId, FONT_2, gSpeciesNames[species], 118, y, colorIdx); + ConvertIntToDecimalStringN(levelStr, level, STR_CONV_MODE_LEFT_ALIGN, 3); + PrintUnionRoomText(windowId, FONT_2, levelStr, GetStringRightAlignXOffset(2, levelStr, 218), y, colorIdx); } } static void TradeBoardListMenuItemPrintFunc(u8 windowId, u32 itemId, u8 y) { - struct UnkStruct_Leader * leader = sUnionRoomMain.leader; - struct RfuGameData * rfu; + struct WirelessLink_Leader * leader = sWirelessLinkMain.leader; + struct RfuGameData * gameData; s32 i, j; - u8 uname[RFU_USER_NAME_LENGTH]; + u8 playerName[RFU_USER_NAME_LENGTH]; - if (itemId == -3 && y == sTradeBoardListMenuTemplate.upText_Y) + if (itemId == LIST_HEADER && y == sListMenuTemplate_TradeBoard.upText_Y) { - rfu = GetHostRfuGameData(); - if (rfu->tradeSpecies != SPECIES_NONE) - { - TradeBoardPrintItemInfo(windowId, y, rfu, gSaveBlock2Ptr->playerName, 5); - } + gameData = GetHostRfuGameData(); + if (gameData->tradeSpecies != SPECIES_NONE) + TradeBoardPrintItemInfo(windowId, y, gameData, gSaveBlock2Ptr->playerName, 5); } else { j = 0; - for (i = 0; i < UROOM_MAX_GROUP_COUNT; i++) + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) { - if (leader->field_0->arr[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && leader->field_0->arr[i].gname_uname.gname.tradeSpecies != SPECIES_NONE) - { + if (leader->playerList->players[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && leader->playerList->players[i].rfu.data.tradeSpecies != SPECIES_NONE) j++; - } + if (j == itemId + 1) { - IntlConvPartnerUname(uname, leader->field_0->arr[i]); - TradeBoardPrintItemInfo(windowId, y, &leader->field_0->arr[i].gname_uname.gname, uname, 6); + CopyAndTranslatePlayerName2(playerName, leader->playerList->players[i]); + TradeBoardPrintItemInfo(windowId, y, &leader->playerList->players[i].rfu.data, playerName, UR_COLOR_TRADE_BOARD_OTHER); break; } } } } -static s32 GetIndexOfNthTradeBoardOffer(struct UnkStruct_x20 * x20, s32 n) +static s32 GetIndexOfNthTradeBoardOffer(struct RfuPlayer * players, s32 n) { s32 i; s32 j = 0; - for (i = 0; i < UROOM_MAX_GROUP_COUNT; i++) + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) { - if (x20[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && x20[i].gname_uname.gname.tradeSpecies != SPECIES_NONE) - { + if (players[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN && players[i].rfu.data.tradeSpecies != SPECIES_NONE) j++; - } + if (j == n + 1) - { return i; - } } return -1; } -static s32 GetUnionRoomPlayerGender(s32 playerIdx, struct UnkStruct_Main0 * main0) +static s32 GetUnionRoomPlayerGender(s32 playerIdx, struct RfuPlayerList * list) { - return main0->arr[playerIdx].gname_uname.gname.playerGender; + return list->players[playerIdx].rfu.data.playerGender; } -static s32 IsRequestedTypeAndSpeciesInPlayerParty(u32 type, u32 species) +static s32 IsRequestedTradeInPlayerParty(u32 type, u32 species) { s32 i; @@ -4387,9 +4004,7 @@ static s32 IsRequestedTypeAndSpeciesInPlayerParty(u32 type, u32 species) { species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); if (species == SPECIES_EGG) - { return UR_TRADE_MATCH; - } } return UR_TRADE_NOEGG; } @@ -4399,9 +4014,7 @@ static s32 IsRequestedTypeAndSpeciesInPlayerParty(u32 type, u32 species) { species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); if (gBaseStats[species].type1 == type || gBaseStats[species].type2 == type) - { return UR_TRADE_MATCH; - } } return UR_TRADE_NOTYPE; } @@ -4411,7 +4024,7 @@ static void GetURoomActivityRejectMsg(u8 *dst, s32 activity, u32 playerGender) { switch (activity) { - case ACTIVITY_BATTLE | IN_UNION_ROOM: + case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM: StringExpandPlaceholders(dst, gTexts_UR_BattleDeclined[playerGender]); break; case ACTIVITY_CHAT | IN_UNION_ROOM: @@ -4433,7 +4046,7 @@ static void GetURoomActivityStartMsg(u8 *dst, u8 activity) switch (activity) { - case ACTIVITY_BATTLE | IN_UNION_ROOM: + case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM: StringCopy(dst, gTexts_UR_StartActivity[mpId][gender][0]); break; case ACTIVITY_TRADE | IN_UNION_ROOM: @@ -4445,15 +4058,15 @@ static void GetURoomActivityStartMsg(u8 *dst, u8 activity) } } -static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activity_p, struct UnkStruct_URoom * arg3) +static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activityData, struct WirelessLink_URoom * uroom) { s32 result = 0; u16 species = SPECIES_NONE; s32 i; - switch (activity_p[0]) + switch (activityData[0]) { - case ACTIVITY_BATTLE | IN_UNION_ROOM: + case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM: StringExpandPlaceholders(dst, gText_UR_BattleChallenge); result = 1; break; @@ -4462,15 +4075,15 @@ static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activity_ result = 1; break; case ACTIVITY_TRADE | IN_UNION_ROOM: - ConvertIntToDecimalStringN(arg3->activityRequestStrbufs[0], sUnionRoomTrade.playerLevel, STR_CONV_MODE_LEFT_ALIGN, 3); - StringCopy(arg3->activityRequestStrbufs[1], gSpeciesNames[sUnionRoomTrade.playerSpecies]); + ConvertIntToDecimalStringN(uroom->activityRequestStrbufs[0], sUnionRoomTrade.playerLevel, STR_CONV_MODE_LEFT_ALIGN, 3); + StringCopy(uroom->activityRequestStrbufs[1], gSpeciesNames[sUnionRoomTrade.playerSpecies]); for (i = 0; i < RFU_CHILD_MAX; i++) { - if (gRfuLinkStatus->partner[i].serialNo == 0x0002) + if (gRfuLinkStatus->partner[i].serialNo == RFU_SERIAL_GAME) { - ConvertIntToDecimalStringN(arg3->activityRequestStrbufs[2], activity_p[2], STR_CONV_MODE_LEFT_ALIGN, 3); - StringCopy(arg3->activityRequestStrbufs[3], gSpeciesNames[activity_p[1]]); - species = activity_p[1]; + ConvertIntToDecimalStringN(uroom->activityRequestStrbufs[2], activityData[2], STR_CONV_MODE_LEFT_ALIGN, 3); + StringCopy(uroom->activityRequestStrbufs[3], gSpeciesNames[activityData[1]]); + species = activityData[1]; break; } } @@ -4481,9 +4094,7 @@ static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activity_ else { for (i = 0; i < RFU_CHILD_MAX; i++) - { - DynamicPlaceholderTextUtil_SetPlaceholderPtr(i, arg3->activityRequestStrbufs[i]); - } + DynamicPlaceholderTextUtil_SetPlaceholderPtr(i, uroom->activityRequestStrbufs[i]); DynamicPlaceholderTextUtil_ExpandPlaceholders(dst, gText_UR_OfferToTradeMon); } result = 1; @@ -4492,8 +4103,7 @@ static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activity_ StringExpandPlaceholders(dst, gText_UR_ShowTrainerCard); result = 1; break; - case IN_UNION_ROOM: - // Chat dropped + case ACTIVITY_NONE | IN_UNION_ROOM: StringExpandPlaceholders(dst, gText_UR_ChatDropped); result = 2; break; @@ -4502,7 +4112,7 @@ static s32 GetChatLeaderActionRequestMessage(u8 *dst, u32 gender, u16 *activity_ return result; } -static bool32 PollPartnerYesNoResponse(struct UnkStruct_URoom * uroom) +static bool32 PollPartnerYesNoResponse(struct WirelessLink_URoom * uroom) { if (gRecvCmds[0][1] != 0) { @@ -4534,11 +4144,9 @@ static bool32 HasAtLeastTwoMonsOfLevel30OrLower(void) for (i = 0; i < gPlayerPartyCount; i++) { - if (GetMonData(&gPlayerParty[i], MON_DATA_LEVEL) <= 30 + if (GetMonData(&gPlayerParty[i], MON_DATA_LEVEL) <= UNION_ROOM_MAX_LEVEL && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2) != SPECIES_EGG) - { count++; - } } if (count > 1) @@ -4549,12 +4157,12 @@ static bool32 HasAtLeastTwoMonsOfLevel30OrLower(void) static void ResetUnionRoomTrade(struct UnionRoomTrade * uroomTrade) { - uroomTrade->field_0 = 0; + uroomTrade->state = URTRADE_STATE_NONE; uroomTrade->type = 0; uroomTrade->playerPersonality = 0; - uroomTrade->playerSpecies = 0; + uroomTrade->playerSpecies = SPECIES_NONE; uroomTrade->playerLevel = 0; - uroomTrade->species = 0; + uroomTrade->species = SPECIES_NONE; uroomTrade->level = 0; uroomTrade->personality = 0; } @@ -4608,14 +4216,10 @@ static u32 GetPartyPositionOfRegisteredMon(struct UnionRoomTrade * trade, u8 mul { cur_personality = GetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY); if (cur_personality != personality) - { continue; - } cur_species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2); if (cur_species != species) - { continue; - } response = i; break; } @@ -4623,26 +4227,26 @@ static u32 GetPartyPositionOfRegisteredMon(struct UnionRoomTrade * trade, u8 mul return response; } -static void HandleCancelTrade(bool32 unlockObjs) +static void HandleCancelActivity(bool32 setData) { - UR_BlankBg0(); + UR_ClearBg0(); UnlockPlayerFieldControls(); UnionRoom_UnlockPlayerAndChatPartner(); sPlayerCurrActivity = 0; - if (unlockObjs) + if (setData) { SetTradeBoardRegisteredMonInfo(sUnionRoomTrade.type, sUnionRoomTrade.playerSpecies, sUnionRoomTrade.playerLevel); UpdateGameData_SetActivity(IN_UNION_ROOM, 0, FALSE); } } -static void UR_EnableScriptContext2AndFreezeObjectEvents(void) +static void StartScriptInteraction(void) { LockPlayerFieldControls(); FreezeObjects_WaitForPlayer(); } -static u8 GetSinglePartnerSpriteGenderParam(s32 linkPlayer) +static u8 GetLinkPlayerInfoFlags(s32 linkPlayer) { u8 retval = 0x80; retval |= gLinkPlayers[linkPlayer].gender << 3; @@ -4650,17 +4254,17 @@ static u8 GetSinglePartnerSpriteGenderParam(s32 linkPlayer) return retval; } -static u8 GetActivePartnerSpriteGenderParam(struct UnkStruct_URoom * uroom) +static u8 GetActivePartnersInfo(struct WirelessLink_URoom * uroom) { - u8 retVal = 0x80; + u8 retVal = PINFO_ACTIVE_FLAG; u8 i; for (i = 0; i < RFU_CHILD_MAX; i++) { - if (uroom->field_C->arr[i].active) + if (uroom->incomingParentList->players[i].active) { - retVal |= uroom->field_C->arr[i].gname_uname.gname.playerGender << 3; - retVal |= uroom->field_C->arr[i].gname_uname.gname.compatibility.playerTrainerId[0] & 7; + retVal |= uroom->incomingParentList->players[i].rfu.data.playerGender << PINFO_GENDER_SHIFT; + retVal |= uroom->incomingParentList->players[i].rfu.data.compatibility.playerTrainerId[0] & PINFO_TID_MASK; break; } } @@ -4668,7 +4272,7 @@ static u8 GetActivePartnerSpriteGenderParam(struct UnkStruct_URoom * uroom) return retVal; } -static void ViewURoomPartnerTrainerCard(u8 *unused, struct UnkStruct_URoom * uroom, bool8 parent_child) +static void ViewURoomPartnerTrainerCard(u8 *unused, struct WirelessLink_URoom * uroom, bool8 isParent) { struct TrainerCard * trainerCard = &gTrainerCards[GetMultiplayerId() ^ 1]; s32 i; @@ -4676,61 +4280,57 @@ static void ViewURoomPartnerTrainerCard(u8 *unused, struct UnkStruct_URoom * uro DynamicPlaceholderTextUtil_Reset(); - StringCopy(uroom->trainerCardStrbufs[0], gTrainerClassNames[GetUnionRoomTrainerClass()]); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, uroom->trainerCardStrbufs[0]); + StringCopy(uroom->trainerCardStrBuffer[0], gTrainerClassNames[GetUnionRoomTrainerClass()]); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, uroom->trainerCardStrBuffer[0]); DynamicPlaceholderTextUtil_SetPlaceholderPtr(1, trainerCard->rse.playerName); - StringCopy(uroom->field_174, gTexts_UR_CardColor[trainerCard->rse.stars]); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, uroom->field_174); + StringCopy(uroom->trainerCardColorStrBuffer, gTexts_UR_CardColor[trainerCard->rse.stars]); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, uroom->trainerCardColorStrBuffer); - ConvertIntToDecimalStringN(uroom->trainerCardStrbufs[2], trainerCard->rse.caughtMonsCount, STR_CONV_MODE_LEFT_ALIGN, 3); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(3, uroom->trainerCardStrbufs[2]); + ConvertIntToDecimalStringN(uroom->trainerCardStrBuffer[2], trainerCard->rse.caughtMonsCount, STR_CONV_MODE_LEFT_ALIGN, 3); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(3, uroom->trainerCardStrBuffer[2]); - ConvertIntToDecimalStringN(uroom->trainerCardStrbufs[3], trainerCard->rse.playTimeHours, STR_CONV_MODE_LEFT_ALIGN, 3); - ConvertIntToDecimalStringN(uroom->trainerCardStrbufs[4], trainerCard->rse.playTimeMinutes, STR_CONV_MODE_LEADING_ZEROS, 2); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(4, uroom->trainerCardStrbufs[3]); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(5, uroom->trainerCardStrbufs[4]); + ConvertIntToDecimalStringN(uroom->trainerCardStrBuffer[3], trainerCard->rse.playTimeHours, STR_CONV_MODE_LEFT_ALIGN, 3); + ConvertIntToDecimalStringN(uroom->trainerCardStrBuffer[4], trainerCard->rse.playTimeMinutes, STR_CONV_MODE_LEADING_ZEROS, 2); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(4, uroom->trainerCardStrBuffer[3]); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(5, uroom->trainerCardStrBuffer[4]); - DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->field_1A4, gText_UR_TrainerCardInfoPage1); - StringCopy(gStringVar4, uroom->field_1A4); + DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->trainerCardMsgStrBuffer, gText_UR_TrainerCardInfoPage1); + StringCopy(gStringVar4, uroom->trainerCardMsgStrBuffer); n = trainerCard->rse.linkBattleWins; if (n > 9999) - { n = 9999; - } - ConvertIntToDecimalStringN(uroom->trainerCardStrbufs[0], n, STR_CONV_MODE_LEFT_ALIGN, 4); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, uroom->trainerCardStrbufs[0]); + ConvertIntToDecimalStringN(uroom->trainerCardStrBuffer[0], n, STR_CONV_MODE_LEFT_ALIGN, 4); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(0, uroom->trainerCardStrBuffer[0]); n = trainerCard->rse.linkBattleLosses; if (n > 9999) - { n = 9999; - } - ConvertIntToDecimalStringN(uroom->trainerCardStrbufs[1], n, STR_CONV_MODE_LEFT_ALIGN, 4); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, uroom->trainerCardStrbufs[1]); + ConvertIntToDecimalStringN(uroom->trainerCardStrBuffer[1], n, STR_CONV_MODE_LEFT_ALIGN, 4); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(2, uroom->trainerCardStrBuffer[1]); - ConvertIntToDecimalStringN(uroom->trainerCardStrbufs[2], trainerCard->rse.pokemonTrades, STR_CONV_MODE_LEFT_ALIGN, 5); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(3, uroom->trainerCardStrbufs[2]); + ConvertIntToDecimalStringN(uroom->trainerCardStrBuffer[2], trainerCard->rse.pokemonTrades, STR_CONV_MODE_LEFT_ALIGN, 5); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(3, uroom->trainerCardStrBuffer[2]); for (i = 0; i < TRAINER_CARD_PROFILE_LENGTH; i++) { - CopyEasyChatWord(uroom->trainerCardStrbufs[i + 3], trainerCard->rse.easyChatProfile[i]); - DynamicPlaceholderTextUtil_SetPlaceholderPtr(i + 4, uroom->trainerCardStrbufs[i + 3]); + CopyEasyChatWord(uroom->trainerCardStrBuffer[i + 3], trainerCard->rse.easyChatProfile[i]); + DynamicPlaceholderTextUtil_SetPlaceholderPtr(i + 4, uroom->trainerCardStrBuffer[i + 3]); } - DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->field_1A4, gText_UR_TrainerCardInfoPage2); - StringAppend(gStringVar4, uroom->field_1A4); + DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->trainerCardMsgStrBuffer, gText_UR_TrainerCardInfoPage2); + StringAppend(gStringVar4, uroom->trainerCardMsgStrBuffer); - if (parent_child == MODE_PARENT) + if (isParent == TRUE) { - DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->field_1A4, gText_UR_FinishedCheckingPlayersTrainerCard); - StringAppend(gStringVar4, uroom->field_1A4); + DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->trainerCardMsgStrBuffer, gText_UR_FinishedCheckingPlayersTrainerCard); + StringAppend(gStringVar4, uroom->trainerCardMsgStrBuffer); } - else if (parent_child == MODE_CHILD) + else if (isParent == FALSE) { - DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->field_1A4, gTexts_UR_GladToMeetYou[trainerCard->rse.gender]); - StringAppend(gStringVar4, uroom->field_1A4); + DynamicPlaceholderTextUtil_ExpandPlaceholders(uroom->trainerCardMsgStrBuffer, gTexts_UR_GladToMeetYou[trainerCard->rse.gender]); + StringAppend(gStringVar4, uroom->trainerCardMsgStrBuffer); } } diff --git a/src/wireless_communication_status_screen.c b/src/wireless_communication_status_screen.c index 97131a768..b6f018a9a 100644 --- a/src/wireless_communication_status_screen.c +++ b/src/wireless_communication_status_screen.c @@ -121,29 +121,29 @@ static const u8 sCountParams[][3] = { // activity, count idx, by // by=0 means count all // UB: no check for count idx == -1 - {ACTIVITY_BATTLE, 1, 2}, - {ACTIVITY_DBLBATTLE, 1, 2}, - {ACTIVITY_MLTBATTLE, 1, 4}, - {ACTIVITY_TRADE, 0, 2}, - {ACTIVITY_WCARD2, 3, 2}, - {ACTIVITY_WNEWS2, 3, 2}, - {ACTIVITY_PJUMP, 4, 0}, - {ACTIVITY_BCRUSH, 4, 0}, - {ACTIVITY_BPICK, 4, 0}, - {ACTIVITY_SEARCH, -1, 0}, - {ACTIVITY_SPINTRADE, 0, 0}, - {ACTIVITY_ITEMTRADE, -1, 0}, - {0x0f, 4, 0}, - {0x10, -1, 0}, - {0x40, 2, 1}, - {ACTIVITY_BATTLE | 0x40, 2, 2}, - {ACTIVITY_TRADE | 0x40, 2, 2}, - {ACTIVITY_CHAT | 0x40, 2, 0}, - {ACTIVITY_CARD | 0x40, 2, 2}, - {20 | 0x40, 2, 1}, - {19 | 0x40, 2, 2}, - {ACTIVITY_ACCEPT | 0x40, 2, 1}, - {ACTIVITY_DECLINE | 0x40, 2, 1} + {ACTIVITY_BATTLE_SINGLE, 1, 2}, + {ACTIVITY_BATTLE_DOUBLE, 1, 2}, + {ACTIVITY_BATTLE_MULTI, 1, 4}, + {ACTIVITY_TRADE, 0, 2}, + {ACTIVITY_WONDER_CARD, 3, 2}, + {ACTIVITY_WONDER_NEWS, 3, 2}, + {ACTIVITY_POKEMON_JUMP, 4, 0}, + {ACTIVITY_BERRY_CRUSH, 4, 0}, + {ACTIVITY_BERRY_PICK, 4, 0}, + {ACTIVITY_SEARCH, -1, 0}, + {ACTIVITY_SPIN_TRADE, 0, 0}, + {ACTIVITY_ITEM_TRADE, -1, 0}, + {ACTIVITY_RECORD_CORNER, 4, 0}, + {ACTIVITY_BERRY_BLENDER, -1, 0}, + {ACTIVITY_NONE | IN_UNION_ROOM, 2, 1}, + {ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM, 2, 2}, + {ACTIVITY_TRADE | IN_UNION_ROOM, 2, 2}, + {ACTIVITY_CHAT | IN_UNION_ROOM, 2, 0}, + {ACTIVITY_CARD | IN_UNION_ROOM, 2, 2}, + {ACTIVITY_PLYRTALK | IN_UNION_ROOM, 2, 1}, + {ACTIVITY_NPCTALK | IN_UNION_ROOM, 2, 2}, + {ACTIVITY_ACCEPT | IN_UNION_ROOM, 2, 1}, + {ACTIVITY_DECLINE | IN_UNION_ROOM, 2, 1} }; static void CB2_RunWirelessCommunicationScreen(void) @@ -352,9 +352,9 @@ static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 * AddTextPrinterParameterized4(windowId, fontId, x, y, fontId == FONT_0 ? 0 : 1, 0, textColor, -1, str); } -static u32 CountMembersInGroup(struct UnkStruct_x20 * unk20, u32 * counts) +static u32 CountMembersInGroup(struct RfuPlayer * unk20, u32 * counts) { - u32 activity = unk20->gname_uname.gname.activity; + u32 activity = unk20->rfu.data.activity; s32 i, j, k; for (i = 0; i < NELEMS(sCountParams); i++) @@ -366,7 +366,7 @@ static u32 CountMembersInGroup(struct UnkStruct_x20 * unk20, u32 * counts) k = 0; for (j = 0; j < RFU_CHILD_MAX; j++) { - if (unk20->gname_uname.gname.partnerInfo[j] != 0) k++; + if (unk20->rfu.data.partnerInfo[j] != 0) k++; } k++; counts[sCountParams[i][1]] += k; @@ -398,12 +398,12 @@ static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * ac { bool32 activitiesUpdated = FALSE; u32 buffer[4] = {0, 0, 0, 0}; - struct UnkStruct_Group * group = (void *)gTasks[taskId].data; + struct WirelessLink_Group * group = (void *)gTasks[taskId].data; s32 i; for (i = 0; i < 16; i++) { - u32 activity = CountMembersInGroup(&group->field_0->arr[i], buffer); + u32 activity = CountMembersInGroup(&group->playerList->players[i], buffer); if (activity != activities[i]) { activities[i] = activity; From 5ce573fca1ce2fa80baff3a6e441716723afe9b4 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Tue, 8 Nov 2022 02:05:33 -0500 Subject: [PATCH 07/12] Sync wireless_communication_status_screen --- graphics/misc/unk_846f4f0.pal | 19 - .../anim_00.pal} | 0 .../anim_01.pal} | 0 .../anim_02.pal} | 0 .../anim_03.pal} | 0 .../anim_04.pal} | 0 .../anim_05.pal} | 0 .../anim_06.pal} | 0 .../anim_07.pal} | 0 .../anim_08.pal} | 0 .../anim_09.pal} | 0 .../anim_10.pal} | 0 .../anim_11.pal} | 0 .../anim_12.pal} | 0 .../anim_13.pal} | 0 .../bg.bin} | Bin .../bg.png} | Bin .../default.pal} | 0 src/wireless_communication_status_screen.c | 357 ++++++++++-------- 19 files changed, 194 insertions(+), 182 deletions(-) delete mode 100644 graphics/misc/unk_846f4f0.pal rename graphics/{misc/unk_846f510.pal => wireless_status_screen/anim_00.pal} (100%) rename graphics/{misc/unk_846f530.pal => wireless_status_screen/anim_01.pal} (100%) rename graphics/{misc/unk_846f550.pal => wireless_status_screen/anim_02.pal} (100%) rename graphics/{misc/unk_846f570.pal => wireless_status_screen/anim_03.pal} (100%) rename graphics/{misc/unk_846f590.pal => wireless_status_screen/anim_04.pal} (100%) rename graphics/{misc/unk_846f5b0.pal => wireless_status_screen/anim_05.pal} (100%) rename graphics/{misc/unk_846f5d0.pal => wireless_status_screen/anim_06.pal} (100%) rename graphics/{misc/unk_846f5f0.pal => wireless_status_screen/anim_07.pal} (100%) rename graphics/{misc/unk_846f610.pal => wireless_status_screen/anim_08.pal} (100%) rename graphics/{misc/unk_846f630.pal => wireless_status_screen/anim_09.pal} (100%) rename graphics/{misc/unk_846f650.pal => wireless_status_screen/anim_10.pal} (100%) rename graphics/{misc/unk_846f670.pal => wireless_status_screen/anim_11.pal} (100%) rename graphics/{misc/unk_846f690.pal => wireless_status_screen/anim_12.pal} (100%) rename graphics/{misc/unk_846f4d0.pal => wireless_status_screen/anim_13.pal} (100%) rename graphics/{misc/unk_846f8e0.bin => wireless_status_screen/bg.bin} (100%) rename graphics/{misc/unk_846f6d0.png => wireless_status_screen/bg.png} (100%) rename graphics/{misc/unk_846f6b0.pal => wireless_status_screen/default.pal} (100%) diff --git a/graphics/misc/unk_846f4f0.pal b/graphics/misc/unk_846f4f0.pal deleted file mode 100644 index 4b0812f09..000000000 --- a/graphics/misc/unk_846f4f0.pal +++ /dev/null @@ -1,19 +0,0 @@ -JASC-PAL -0100 -16 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 diff --git a/graphics/misc/unk_846f510.pal b/graphics/wireless_status_screen/anim_00.pal similarity index 100% rename from graphics/misc/unk_846f510.pal rename to graphics/wireless_status_screen/anim_00.pal diff --git a/graphics/misc/unk_846f530.pal b/graphics/wireless_status_screen/anim_01.pal similarity index 100% rename from graphics/misc/unk_846f530.pal rename to graphics/wireless_status_screen/anim_01.pal diff --git a/graphics/misc/unk_846f550.pal b/graphics/wireless_status_screen/anim_02.pal similarity index 100% rename from graphics/misc/unk_846f550.pal rename to graphics/wireless_status_screen/anim_02.pal diff --git a/graphics/misc/unk_846f570.pal b/graphics/wireless_status_screen/anim_03.pal similarity index 100% rename from graphics/misc/unk_846f570.pal rename to graphics/wireless_status_screen/anim_03.pal diff --git a/graphics/misc/unk_846f590.pal b/graphics/wireless_status_screen/anim_04.pal similarity index 100% rename from graphics/misc/unk_846f590.pal rename to graphics/wireless_status_screen/anim_04.pal diff --git a/graphics/misc/unk_846f5b0.pal b/graphics/wireless_status_screen/anim_05.pal similarity index 100% rename from graphics/misc/unk_846f5b0.pal rename to graphics/wireless_status_screen/anim_05.pal diff --git a/graphics/misc/unk_846f5d0.pal b/graphics/wireless_status_screen/anim_06.pal similarity index 100% rename from graphics/misc/unk_846f5d0.pal rename to graphics/wireless_status_screen/anim_06.pal diff --git a/graphics/misc/unk_846f5f0.pal b/graphics/wireless_status_screen/anim_07.pal similarity index 100% rename from graphics/misc/unk_846f5f0.pal rename to graphics/wireless_status_screen/anim_07.pal diff --git a/graphics/misc/unk_846f610.pal b/graphics/wireless_status_screen/anim_08.pal similarity index 100% rename from graphics/misc/unk_846f610.pal rename to graphics/wireless_status_screen/anim_08.pal diff --git a/graphics/misc/unk_846f630.pal b/graphics/wireless_status_screen/anim_09.pal similarity index 100% rename from graphics/misc/unk_846f630.pal rename to graphics/wireless_status_screen/anim_09.pal diff --git a/graphics/misc/unk_846f650.pal b/graphics/wireless_status_screen/anim_10.pal similarity index 100% rename from graphics/misc/unk_846f650.pal rename to graphics/wireless_status_screen/anim_10.pal diff --git a/graphics/misc/unk_846f670.pal b/graphics/wireless_status_screen/anim_11.pal similarity index 100% rename from graphics/misc/unk_846f670.pal rename to graphics/wireless_status_screen/anim_11.pal diff --git a/graphics/misc/unk_846f690.pal b/graphics/wireless_status_screen/anim_12.pal similarity index 100% rename from graphics/misc/unk_846f690.pal rename to graphics/wireless_status_screen/anim_12.pal diff --git a/graphics/misc/unk_846f4d0.pal b/graphics/wireless_status_screen/anim_13.pal similarity index 100% rename from graphics/misc/unk_846f4d0.pal rename to graphics/wireless_status_screen/anim_13.pal diff --git a/graphics/misc/unk_846f8e0.bin b/graphics/wireless_status_screen/bg.bin similarity index 100% rename from graphics/misc/unk_846f8e0.bin rename to graphics/wireless_status_screen/bg.bin diff --git a/graphics/misc/unk_846f6d0.png b/graphics/wireless_status_screen/bg.png similarity index 100% rename from graphics/misc/unk_846f6d0.png rename to graphics/wireless_status_screen/bg.png diff --git a/graphics/misc/unk_846f6b0.pal b/graphics/wireless_status_screen/default.pal similarity index 100% rename from graphics/misc/unk_846f6b0.pal rename to graphics/wireless_status_screen/default.pal diff --git a/src/wireless_communication_status_screen.c b/src/wireless_communication_status_screen.c index b6f018a9a..971db680f 100644 --- a/src/wireless_communication_status_screen.c +++ b/src/wireless_communication_status_screen.c @@ -14,46 +14,60 @@ #include "constants/songs.h" #include "constants/union_room.h" -struct WirelessCommunicationStatusScreenStruct -{ - u32 counts[4]; - u32 lastCounts[4]; - u32 activities[16]; - u8 taskId; - u8 rfuTaskId; - u8 filler_62[0xA]; +enum { + COLOR_NONE, + COLOR_NORMAL, + COLOR_TOTAL, + COLOR_TITLE, + COLOR_UNUSED, }; -static struct WirelessCommunicationStatusScreenStruct * sWCSS; +enum { + GROUPTYPE_NONE = -1, + GROUPTYPE_TRADE, + GROUPTYPE_BATTLE, + GROUPTYPE_UNION, + GROUPTYPE_TOTAL, + NUM_GROUPTYPES +}; + +static struct +{ + u32 groupCounts[NUM_GROUPTYPES]; + u32 prevGroupCounts[NUM_GROUPTYPES]; + u32 activities[NUM_TASK_DATA]; + u8 taskId; + u8 rfuTaskId; + u8 filler[10]; +} * sStatusScreen; static void CB2_InitWirelessCommunicationScreen(void); static void Task_WirelessCommunicationScreen(u8 taskId); static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 palIdx); static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * activities, u8 taskId); -static const u16 sWCSS_Palettes[][16] = { - INCBIN_U16("graphics/misc/unk_846f4d0.gbapal"), - INCBIN_U16("graphics/misc/unk_846f4f0.gbapal"), - INCBIN_U16("graphics/misc/unk_846f510.gbapal"), - INCBIN_U16("graphics/misc/unk_846f530.gbapal"), - INCBIN_U16("graphics/misc/unk_846f550.gbapal"), - INCBIN_U16("graphics/misc/unk_846f570.gbapal"), - INCBIN_U16("graphics/misc/unk_846f590.gbapal"), - INCBIN_U16("graphics/misc/unk_846f5b0.gbapal"), - INCBIN_U16("graphics/misc/unk_846f5d0.gbapal"), - INCBIN_U16("graphics/misc/unk_846f5f0.gbapal"), - INCBIN_U16("graphics/misc/unk_846f610.gbapal"), - INCBIN_U16("graphics/misc/unk_846f630.gbapal"), - INCBIN_U16("graphics/misc/unk_846f650.gbapal"), - INCBIN_U16("graphics/misc/unk_846f670.gbapal"), - INCBIN_U16("graphics/misc/unk_846f690.gbapal"), - INCBIN_U16("graphics/misc/unk_846f6b0.gbapal") +static const u16 sPalettes[][16] = { + INCBIN_U16("graphics/wireless_status_screen/default.gbapal"), + {}, // All black. Never read + INCBIN_U16("graphics/wireless_status_screen/anim_00.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_01.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_02.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_03.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_04.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_05.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_06.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_07.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_08.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_09.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_10.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_11.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_12.gbapal"), + INCBIN_U16("graphics/wireless_status_screen/anim_13.gbapal") }; +static const u32 sBgTiles_Gfx[] = INCBIN_U32("graphics/wireless_status_screen/bg.4bpp.lz"); +static const u16 sBgTiles_Tilemap[] = INCBIN_U16("graphics/wireless_status_screen/bg.bin"); -static const u32 sBgTilesGfx[] = INCBIN_U32("graphics/misc/unk_846f6d0.4bpp.lz"); -static const u16 sBgTilemap[] = INCBIN_U16("graphics/misc/unk_846f8e0.bin"); - -static const struct BgTemplate sBGTemplates[] = { +static const struct BgTemplate sBgTemplates[] = { { .bg = 0, .charBaseIndex = 2, @@ -75,29 +89,29 @@ static const struct BgTemplate sBGTemplates[] = { static const struct WindowTemplate sWindowTemplates[] = { { - .bg = 0x00, - .tilemapLeft = 0x03, - .tilemapTop = 0x00, - .width = 0x18, - .height = 0x03, - .paletteNum = 0x0f, - .baseBlock = 0x0001 + .bg = 0, + .tilemapLeft = 3, + .tilemapTop = 0, + .width = 24, + .height = 3, + .paletteNum = 15, + .baseBlock = 0x001 }, { - .bg = 0x00, - .tilemapLeft = 0x03, - .tilemapTop = 0x04, - .width = 0x16, - .height = 0x0f, - .paletteNum = 0x0f, - .baseBlock = 0x0049 + .bg = 0, + .tilemapLeft = 3, + .tilemapTop = 4, + .width = 22, + .height = 15, + .paletteNum = 15, + .baseBlock = 0x049 }, { - .bg = 0x00, - .tilemapLeft = 0x19, - .tilemapTop = 0x04, - .width = 0x02, - .height = 0x0f, - .paletteNum = 0x0f, - .baseBlock = 0x0193 + .bg = 0, + .tilemapLeft = 25, + .tilemapTop = 4, + .width = 2, + .height = 15, + .paletteNum = 15, + .baseBlock = 0x193 }, DUMMY_WIN_TEMPLATE }; @@ -109,41 +123,43 @@ static const u8 *const sPlayersTextPtrs[] = { gText_Dynamic3Players }; -static const u8 *const sHeaderTextPtrs[] = { - gText_WirelessCommunicationStatus, - gText_PeopleTrading, - gText_PeopleBattling, - gText_PeopleInUnionRoom, - gText_PeopleCommunicating +static const u8 *const sHeaderTexts[NUM_GROUPTYPES + 1] = { + [0] = gText_WirelessCommunicationStatus, + [GROUPTYPE_TRADE + 1] = gText_PeopleTrading, + [GROUPTYPE_BATTLE + 1] = gText_PeopleBattling, + [GROUPTYPE_UNION + 1] = gText_PeopleInUnionRoom, + [GROUPTYPE_TOTAL + 1] = gText_PeopleCommunicating }; -static const u8 sCountParams[][3] = { - // activity, count idx, by - // by=0 means count all - // UB: no check for count idx == -1 - {ACTIVITY_BATTLE_SINGLE, 1, 2}, - {ACTIVITY_BATTLE_DOUBLE, 1, 2}, - {ACTIVITY_BATTLE_MULTI, 1, 4}, - {ACTIVITY_TRADE, 0, 2}, - {ACTIVITY_WONDER_CARD, 3, 2}, - {ACTIVITY_WONDER_NEWS, 3, 2}, - {ACTIVITY_POKEMON_JUMP, 4, 0}, - {ACTIVITY_BERRY_CRUSH, 4, 0}, - {ACTIVITY_BERRY_PICK, 4, 0}, - {ACTIVITY_SEARCH, -1, 0}, - {ACTIVITY_SPIN_TRADE, 0, 0}, - {ACTIVITY_ITEM_TRADE, -1, 0}, - {ACTIVITY_RECORD_CORNER, 4, 0}, - {ACTIVITY_BERRY_BLENDER, -1, 0}, - {ACTIVITY_NONE | IN_UNION_ROOM, 2, 1}, - {ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM, 2, 2}, - {ACTIVITY_TRADE | IN_UNION_ROOM, 2, 2}, - {ACTIVITY_CHAT | IN_UNION_ROOM, 2, 0}, - {ACTIVITY_CARD | IN_UNION_ROOM, 2, 2}, - {ACTIVITY_PLYRTALK | IN_UNION_ROOM, 2, 1}, - {ACTIVITY_NPCTALK | IN_UNION_ROOM, 2, 2}, - {ACTIVITY_ACCEPT | IN_UNION_ROOM, 2, 1}, - {ACTIVITY_DECLINE | IN_UNION_ROOM, 2, 1} +// Activity, group type, number of players +// 0 players means the number of players can change and should be counted dynamically +// GROUPTYPE_TOTAL have no unique group and are simply counted in the total of "people communicating". +// A handful use NUM_GROUPTYPES, which is invalid, and are changed to GROUPTYPE_TOTAL in Emerald. +// UB: GROUPTYPE_NONE (-1) can potentially be used as an index into a u8[4] in CountPlayersInGroupAndGetActivity. +static const u8 sActivityGroupInfo[][3] = { + {ACTIVITY_BATTLE_SINGLE, GROUPTYPE_BATTLE, 2}, + {ACTIVITY_BATTLE_DOUBLE, GROUPTYPE_BATTLE, 2}, + {ACTIVITY_BATTLE_MULTI, GROUPTYPE_BATTLE, 4}, + {ACTIVITY_TRADE, GROUPTYPE_TRADE, 2}, + {ACTIVITY_WONDER_CARD, GROUPTYPE_TOTAL, 2}, + {ACTIVITY_WONDER_NEWS, GROUPTYPE_TOTAL, 2}, + {ACTIVITY_POKEMON_JUMP, NUM_GROUPTYPES, 0}, + {ACTIVITY_BERRY_CRUSH, NUM_GROUPTYPES, 0}, + {ACTIVITY_BERRY_PICK, NUM_GROUPTYPES, 0}, + {ACTIVITY_SEARCH, GROUPTYPE_NONE, 0}, + {ACTIVITY_SPIN_TRADE, GROUPTYPE_TRADE, 0}, + {ACTIVITY_ITEM_TRADE, GROUPTYPE_NONE, 0}, + {ACTIVITY_RECORD_CORNER, NUM_GROUPTYPES, 0}, + {ACTIVITY_BERRY_BLENDER, GROUPTYPE_NONE, 0}, + {ACTIVITY_NONE | IN_UNION_ROOM, GROUPTYPE_UNION, 1}, + {ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM, GROUPTYPE_UNION, 2}, + {ACTIVITY_TRADE | IN_UNION_ROOM, GROUPTYPE_UNION, 2}, + {ACTIVITY_CHAT | IN_UNION_ROOM, GROUPTYPE_UNION, 0}, + {ACTIVITY_CARD | IN_UNION_ROOM, GROUPTYPE_UNION, 2}, + {ACTIVITY_PLYRTALK | IN_UNION_ROOM, GROUPTYPE_UNION, 1}, + {ACTIVITY_NPCTALK | IN_UNION_ROOM, GROUPTYPE_UNION, 2}, + {ACTIVITY_ACCEPT | IN_UNION_ROOM, GROUPTYPE_UNION, 1}, + {ACTIVITY_DECLINE | IN_UNION_ROOM, GROUPTYPE_UNION, 1} }; static void CB2_RunWirelessCommunicationScreen(void) @@ -173,14 +189,14 @@ void ShowWirelessCommunicationScreen(void) static void CB2_InitWirelessCommunicationScreen(void) { SetGpuReg(REG_OFFSET_DISPCNT, 0); - sWCSS = AllocZeroed(sizeof(*sWCSS)); + sStatusScreen = AllocZeroed(sizeof(*sStatusScreen)); SetVBlankCallback(NULL); ResetBgsAndClearDma3BusyFlags(FALSE); - InitBgsFromTemplates(0, sBGTemplates, NELEMS(sBGTemplates)); - SetBgTilemapBuffer(1, Alloc(0x800)); - SetBgTilemapBuffer(0, Alloc(0x800)); - DecompressAndLoadBgGfxUsingHeap(1, sBgTilesGfx, 0, 0, 0); - CopyToBgTilemapBuffer(1, sBgTilemap, 0, 0); + InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates)); + SetBgTilemapBuffer(1, Alloc(BG_SCREEN_SIZE)); + SetBgTilemapBuffer(0, Alloc(BG_SCREEN_SIZE)); + DecompressAndLoadBgGfxUsingHeap(1, sBgTiles_Gfx, 0, 0, 0); + CopyToBgTilemapBuffer(1, sBgTiles_Tilemap, 0, 0); InitWindows(sWindowTemplates); DeactivateAllTextPrinters(); ResetPaletteFade(); @@ -189,14 +205,14 @@ static void CB2_InitWirelessCommunicationScreen(void) ScanlineEffect_Stop(); m4aSoundVSyncOn(); SetVBlankCallback(VBlankCB_WirelessCommunicationScreen); - sWCSS->taskId = CreateTask(Task_WirelessCommunicationScreen, 0); - sWCSS->rfuTaskId = CreateTask_ListenToWireless(); - sWCSS->lastCounts[3] = 1; - ChangeBgX(0, 0, 0); - ChangeBgY(0, 0, 0); - ChangeBgX(1, 0, 0); - ChangeBgY(1, 0, 0); - LoadPalette(sWCSS_Palettes, 0, 0x20); + sStatusScreen->taskId = CreateTask(Task_WirelessCommunicationScreen, 0); + sStatusScreen->rfuTaskId = CreateTask_ListenToWireless(); + sStatusScreen->prevGroupCounts[3] = 1; + ChangeBgX(0, 0, BG_COORD_SET); + ChangeBgY(0, 0, BG_COORD_SET); + ChangeBgX(1, 0, BG_COORD_SET); + ChangeBgY(1, 0, BG_COORD_SET); + LoadPalette(sPalettes, 0, 0x20); Menu_LoadStdPalAt(0xf0); DynamicPlaceholderTextUtil_Reset(); FillBgTilemapBufferRect(0, 0x000, 0, 0, 32, 32, 0xF); @@ -214,29 +230,24 @@ static void ExitWirelessCommunicationStatusScreen(void) s32 i; FreeAllWindowBuffers(); - for (i = 0; i < 2; i++) - { + for (i = 0; i < (int)ARRAY_COUNT(sBgTemplates); i++) Free(GetBgTilemapBuffer(i)); - } - Free(sWCSS); + Free(sStatusScreen); SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); } -static void WCSS_CyclePalette(s16 * frameCtr_p, s16 * palIdx_p) +// Cycle through palettes that relocate various shades of blue to create the wave effect at the bottom of the screen. +static void CyclePalette(s16 * counter, s16 * palIdx) { s32 idx; - (*frameCtr_p)++; - if (*frameCtr_p > 5) + if (++(*counter) > 5) { - (*palIdx_p)++; - if (*palIdx_p == 14) - { - *palIdx_p = 0; - } - *frameCtr_p = 0; + if (++(*palIdx) == (int)ARRAY_COUNT(sPalettes) - 2) + *palIdx = 0; + *counter = 0; } - idx = *palIdx_p + 2; - LoadPalette(sWCSS_Palettes[idx], 0, 16); + idx = *palIdx + 2; // +2 skips over default.pal and the empty black palette after it + LoadPalette(sPalettes[idx], 0, 16); } static void PrintHeaderTexts(void) @@ -247,50 +258,57 @@ static void PrintHeaderTexts(void) FillWindowPixelBuffer(0, PIXEL_FILL(0)); FillWindowPixelBuffer(1, PIXEL_FILL(0)); FillWindowPixelBuffer(2, PIXEL_FILL(0)); - width = 0xC0 - GetStringWidth(FONT_3, sHeaderTextPtrs[0], 0); - WCSS_AddTextPrinterParameterized(0, FONT_3, sHeaderTextPtrs[0], width / 2, 6, 3); - for (i = 0; i < 3; i++) - { - WCSS_AddTextPrinterParameterized(1, FONT_3, sHeaderTextPtrs[i + 1], 0, 30 * i + 10, 1); - } - WCSS_AddTextPrinterParameterized(1, FONT_3, sHeaderTextPtrs[i + 1], 0, 30 * i + 10, 2); + + // Print title + width = 192 - GetStringWidth(FONT_3, sHeaderTexts[0], 0); + WCSS_AddTextPrinterParameterized(0, FONT_3, sHeaderTexts[0], width / 2, 6, COLOR_TITLE); + + // Print label for each group (excluding total) + for (i = 0; i < NUM_GROUPTYPES - 1; i++) + WCSS_AddTextPrinterParameterized(1, FONT_3, sHeaderTexts[i + 1], 0, 30 * i + 10, COLOR_NORMAL); + + // Print label for total + WCSS_AddTextPrinterParameterized(1, FONT_3, sHeaderTexts[i + 1], 0, 30 * i + 10, COLOR_TOTAL); + PutWindowTilemap(0); CopyWindowToVram(0, COPYWIN_GFX); PutWindowTilemap(1); CopyWindowToVram(1, COPYWIN_GFX); } +#define tState data[0] + static void Task_WirelessCommunicationScreen(u8 taskId) { s32 i; - switch (gTasks[taskId].data[0]) + switch (gTasks[taskId].tState) { case 0: PrintHeaderTexts(); - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 1: BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK); ShowBg(1); CopyBgTilemapBufferToVram(0); ShowBg(0); - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 2: if (!gPaletteFade.active) - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 3: - if (UpdateCommunicationCounts(sWCSS->counts, sWCSS->lastCounts, sWCSS->activities, sWCSS->rfuTaskId)) + if (UpdateCommunicationCounts(sStatusScreen->groupCounts, sStatusScreen->prevGroupCounts, sStatusScreen->activities, sStatusScreen->rfuTaskId)) { FillWindowPixelBuffer(2, PIXEL_FILL(0)); - for (i = 0; i < 4; i++) + for (i = 0; i < NUM_GROUPTYPES; i++) { - ConvertIntToDecimalStringN(gStringVar4, sWCSS->counts[i], STR_CONV_MODE_RIGHT_ALIGN, 2); - if (i != 3) - WCSS_AddTextPrinterParameterized(2, FONT_3, gStringVar4, 4, 30 * i + 10, 1); + ConvertIntToDecimalStringN(gStringVar4, sStatusScreen->groupCounts[i], STR_CONV_MODE_RIGHT_ALIGN, 2); + if (i != GROUPTYPE_TOTAL) + WCSS_AddTextPrinterParameterized(2, FONT_3, gStringVar4, 4, 30 * i + 10, COLOR_NORMAL); else - WCSS_AddTextPrinterParameterized(2, FONT_3, gStringVar4, 4, 100, 2); + WCSS_AddTextPrinterParameterized(2, FONT_3, gStringVar4, 4, 100, COLOR_TOTAL); } PutWindowTilemap(2); CopyWindowToVram(2, COPYWIN_FULL); @@ -298,14 +316,14 @@ static void Task_WirelessCommunicationScreen(u8 taskId) if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON)) { PlaySE(SE_SELECT); - gTasks[sWCSS->rfuTaskId].data[15] = 0xFF; - gTasks[taskId].data[0]++; + gTasks[sStatusScreen->rfuTaskId].data[15] = 0xFF; + gTasks[taskId].tState++; } - WCSS_CyclePalette(&gTasks[taskId].data[7], &gTasks[taskId].data[8]); + CyclePalette(&gTasks[taskId].data[7], &gTasks[taskId].data[8]); break; case 4: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - gTasks[taskId].data[0]++; + gTasks[taskId].tState++; break; case 5: if (!gPaletteFade.active) @@ -317,93 +335,99 @@ static void Task_WirelessCommunicationScreen(u8 taskId) } } -static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 palIdx) +static void WCSS_AddTextPrinterParameterized(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 mode) { u8 textColor[3]; - switch (palIdx) + switch (mode) { - case 0: + case COLOR_NONE: // Unused. Default to usual text colors textColor[0] = TEXT_COLOR_TRANSPARENT; textColor[1] = TEXT_COLOR_DARK_GRAY; textColor[2] = TEXT_COLOR_LIGHT_GRAY; break; - case 1: + case COLOR_NORMAL: textColor[0] = TEXT_COLOR_TRANSPARENT; textColor[1] = TEXT_COLOR_WHITE; textColor[2] = TEXT_COLOR_LIGHT_GRAY; break; - case 2: + case COLOR_TOTAL: textColor[0] = TEXT_COLOR_TRANSPARENT; textColor[1] = TEXT_COLOR_RED; textColor[2] = TEXT_COLOR_LIGHT_RED; break; - case 3: + case COLOR_TITLE: textColor[0] = TEXT_COLOR_TRANSPARENT; textColor[1] = TEXT_COLOR_LIGHT_GREEN; textColor[2] = TEXT_COLOR_GREEN; break; - case 4: + case COLOR_UNUSED: textColor[0] = TEXT_COLOR_TRANSPARENT; textColor[1] = TEXT_COLOR_WHITE; textColor[2] = TEXT_COLOR_DARK_GRAY; break; // default: UB } - AddTextPrinterParameterized4(windowId, fontId, x, y, fontId == FONT_0 ? 0 : 1, 0, textColor, -1, str); + AddTextPrinterParameterized4(windowId, fontId, x, y, fontId == FONT_0 ? 0 : 1, 0, textColor, TEXT_SKIP_DRAW, str); } -static u32 CountMembersInGroup(struct RfuPlayer * unk20, u32 * counts) +static u32 CountPlayersInGroupAndGetActivity(struct RfuPlayer * player, u32 * groupCounts) { - u32 activity = unk20->rfu.data.activity; + u32 activity = player->rfu.data.activity; s32 i, j, k; - for (i = 0; i < NELEMS(sCountParams); i++) + #define group_activity(i) (sActivityGroupInfo[(i)][0]) + #define group_type(i) (sActivityGroupInfo[(i)][1]) + #define group_players(i) (sActivityGroupInfo[(i)][2]) + + for (i = 0; i < ARRAY_COUNT(sActivityGroupInfo); i++) { - if (activity == sCountParams[i][0] && unk20->groupScheduledAnim == UNION_ROOM_SPAWN_IN) + if (activity == group_activity(i) && player->groupScheduledAnim == UNION_ROOM_SPAWN_IN) { - if (sCountParams[i][2] == 0) + if (group_players(i) == 0) { k = 0; for (j = 0; j < RFU_CHILD_MAX; j++) - { - if (unk20->rfu.data.partnerInfo[j] != 0) k++; - } + if (player->rfu.data.partnerInfo[j] != 0) k++; k++; - counts[sCountParams[i][1]] += k; + groupCounts[group_type(i)] += k; } else { - counts[sCountParams[i][1]] += sCountParams[i][2]; + groupCounts[group_type(i)] += group_players(i); } } } return activity; + + #undef group_activity + #undef group_type + #undef group_players } -static bool32 HaveCountsChanged(const u32 * newCounts, const u32 * prevCounts) +static bool32 HaveCountsChanged(const u32 * curCounts, const u32 * prevCounts) { s32 i; - for (i = 0; i < 4; i++) + for (i = 0; i < NUM_GROUPTYPES; i++) { - if (newCounts[i] != prevCounts[i]) + if (curCounts[i] != prevCounts[i]) return TRUE; } return FALSE; } -static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * activities, u8 taskId) +static bool32 UpdateCommunicationCounts(u32 * groupCounts, u32 * prevGroupCounts, u32 * activities, u8 taskId) { bool32 activitiesUpdated = FALSE; - u32 buffer[4] = {0, 0, 0, 0}; + u32 groupCountBuffer[NUM_GROUPTYPES] = {0, 0, 0, 0}; struct WirelessLink_Group * group = (void *)gTasks[taskId].data; s32 i; - for (i = 0; i < 16; i++) + for (i = 0; i < NUM_TASK_DATA; i++) { - u32 activity = CountMembersInGroup(&group->playerList->players[i], buffer); + u32 activity = CountPlayersInGroupAndGetActivity(&group->playerList->players[i], groupCountBuffer); if (activity != activities[i]) { activities[i] = activity; @@ -411,7 +435,7 @@ static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * ac } } - if (HaveCountsChanged(buffer, lastCounts) == FALSE) + if (!HaveCountsChanged(groupCountBuffer, prevGroupCounts)) { if (activitiesUpdated == TRUE) return TRUE; @@ -419,8 +443,15 @@ static bool32 UpdateCommunicationCounts(u32 * counts, u32 * lastCounts, u32 * ac return FALSE; } - memcpy(counts, buffer, sizeof(buffer)); - memcpy(lastCounts, buffer, sizeof(buffer)); - counts[3] = counts[0] + counts[1] + counts[2]; + memcpy(groupCounts, groupCountBuffer, sizeof(groupCountBuffer)); + memcpy(prevGroupCounts, groupCountBuffer, sizeof(groupCountBuffer)); + + groupCounts[GROUPTYPE_TOTAL] = groupCounts[GROUPTYPE_TRADE] + + groupCounts[GROUPTYPE_BATTLE] + + groupCounts[GROUPTYPE_UNION] + #ifdef BUGFIX + + groupCounts[GROUPTYPE_TOTAL] // Missing count for activities not in above groups + #endif + ; return TRUE; } From a7609df31b8a5756a4d6308fcce89e4886766f2e Mon Sep 17 00:00:00 2001 From: GriffinR Date: Tue, 8 Nov 2022 13:00:51 -0500 Subject: [PATCH 08/12] Sync union_room_player_avatar --- data/maps/UnionRoom/scripts.inc | 9 - include/constants/event_objects.h | 17 +- include/rfu_union_tool.h | 16 - include/union_room_player_avatar.h | 16 + ld_script.txt | 4 +- src/pokemon.c | 17 +- src/rfu_union_tool.c | 663 ----------------------------- src/union_room.c | 14 +- src/union_room_player_avatar.c | 615 ++++++++++++++++++++++++++ sym_ewram.txt | 2 +- 10 files changed, 665 insertions(+), 708 deletions(-) delete mode 100644 include/rfu_union_tool.h create mode 100644 include/union_room_player_avatar.h delete mode 100644 src/rfu_union_tool.c create mode 100644 src/union_room_player_avatar.c diff --git a/data/maps/UnionRoom/scripts.inc b/data/maps/UnionRoom/scripts.inc index c214b06d3..38b5c3dda 100644 --- a/data/maps/UnionRoom/scripts.inc +++ b/data/maps/UnionRoom/scripts.inc @@ -1,12 +1,3 @@ -.set LOCALID_UNION_ROOM_PLAYER_4, 2 -.set LOCALID_UNION_ROOM_PLAYER_8, 3 -.set LOCALID_UNION_ROOM_PLAYER_7, 4 -.set LOCALID_UNION_ROOM_PLAYER_6, 5 -.set LOCALID_UNION_ROOM_PLAYER_5, 6 -.set LOCALID_UNION_ROOM_PLAYER_3, 7 -.set LOCALID_UNION_ROOM_PLAYER_2, 8 -.set LOCALID_UNION_ROOM_PLAYER_1, 9 - UnionRoom_MapScripts:: map_script MAP_SCRIPT_ON_RESUME, UnionRoom_OnResume map_script MAP_SCRIPT_ON_TRANSITION, UnionRoom_OnTransition diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index 99d3e4209..0eac72a29 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -189,10 +189,21 @@ #define TRACKS_FOOT 1 #define TRACKS_BIKE_TIRE 2 -#define OBJ_EVENT_ID_PLAYER 0xFF -#define OBJ_EVENT_ID_CAMERA 0x7F - #define OBJ_KIND_NORMAL 0 #define OBJ_KIND_CLONE 255 +// Special object event local ids +#define OBJ_EVENT_ID_PLAYER 0xFF +#define OBJ_EVENT_ID_CAMERA 0x7F + +// Object event local ids referenced in C files +#define LOCALID_UNION_ROOM_PLAYER_4 2 +#define LOCALID_UNION_ROOM_PLAYER_8 3 +#define LOCALID_UNION_ROOM_PLAYER_7 4 +#define LOCALID_UNION_ROOM_PLAYER_6 5 +#define LOCALID_UNION_ROOM_PLAYER_5 6 +#define LOCALID_UNION_ROOM_PLAYER_3 7 +#define LOCALID_UNION_ROOM_PLAYER_2 8 +#define LOCALID_UNION_ROOM_PLAYER_1 9 + #endif // GUARD_CONSTANTS_EVENT_OBJECTS_H diff --git a/include/rfu_union_tool.h b/include/rfu_union_tool.h deleted file mode 100644 index ffecc3f8d..000000000 --- a/include/rfu_union_tool.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef GUARD_UNION_ROOM_PLAYER_AVATAR_H -#define GUARD_UNION_ROOM_PLAYER_AVATAR_H - -#include "union_room.h" - -u8 ZeroUnionObjWork(struct UnionRoomObject * ptr); -void DestroyUnionRoomPlayerObjects(void); -void CreateGroupMemberObjectsInvisible(u8 *spriteIds, s32 group); -void DestroyGroupMemberObjects(u8 *spriteIds); -void MakeGroupAssemblyAreasPassable(void); -void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p); -void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p); -bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds); -void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct RfuPlayerList *main0_p); - -#endif //GUARD_UNION_ROOM_PLAYER_AVATAR_H diff --git a/include/union_room_player_avatar.h b/include/union_room_player_avatar.h new file mode 100644 index 000000000..17ace17de --- /dev/null +++ b/include/union_room_player_avatar.h @@ -0,0 +1,16 @@ +#ifndef GUARD_UNION_ROOM_PLAYER_AVATAR_H +#define GUARD_UNION_ROOM_PLAYER_AVATAR_H + +#include "union_room.h" + +u8 InitUnionRoomPlayerObjects(struct UnionRoomObject * players); +void DestroyUnionRoomPlayerObjects(void); +void CreateUnionRoomPlayerSprites(u8 *spriteIds, s32 leaderId); +void DestroyUnionRoomPlayerSprites(u8 *spriteIds); +void MakeGroupAssemblyAreasPassable(void); +void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom); +void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom); +bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *list, s16 *memberIdPtr, s16 *leaderIdPtr, u8 *spriteIds); +void UpdateUnionRoomMemberFacing(u32 memberId, u32 leaderId, struct RfuPlayerList *list); + +#endif //GUARD_UNION_ROOM_PLAYER_AVATAR_H diff --git a/ld_script.txt b/ld_script.txt index 546f6b5fe..5c7a3751d 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -249,7 +249,7 @@ SECTIONS { src/trainer_fan_club.o(.text); src/quest_log_events.o(.text); src/union_room.o(.text); - src/rfu_union_tool.o(.text); + src/union_room_player_avatar.o(.text); src/union_room_battle.o(.text); src/pokemon_special_anim.o(.text); src/pokemon_special_anim_scene.o(.text); @@ -542,7 +542,7 @@ SECTIONS { src/trainer_fan_club.o(.rodata); src/quest_log_events.o(.rodata); src/union_room.o(.rodata); - src/rfu_union_tool.o(.rodata); + src/union_room_player_avatar.o(.rodata); src/union_room_battle.o(.rodata); src/union_room_message.o(.rodata); src/pokemon_special_anim.o(.rodata); diff --git a/src/pokemon.c b/src/pokemon.c index 6a164028e..e3cae699c 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -34,6 +34,7 @@ #include "constants/trainers.h" #include "constants/hold_effects.h" #include "constants/battle_move_effects.h" +#include "constants/union_room.h" #define SPECIES_TO_HOENN(name) [SPECIES_##name - 1] = HOENN_DEX_##name #define SPECIES_TO_NATIONAL(name) [SPECIES_##name - 1] = NATIONAL_DEX_##name @@ -1643,7 +1644,9 @@ static const u16 sDeoxysBaseStats[] = }; #endif -const u16 gLinkPlayerFacilityClasses[] = +// The classes used by other players in the Union Room. +// These should correspond with the overworld graphics in sUnionRoomObjGfxIds +const u16 gUnionRoomFacilityClasses[NUM_UNION_ROOM_CLASSES * GENDER_COUNT] = { // Male FACILITY_CLASS_COOLTRAINER_M, @@ -6031,19 +6034,19 @@ void SetDeoxysStats(void) u16 GetUnionRoomTrainerPic(void) { u8 linkId = GetMultiplayerId() ^ 1; - u32 arrId = gLinkPlayers[linkId].trainerId & 7; - arrId |= gLinkPlayers[linkId].gender << 3; - return FacilityClassToPicIndex(gLinkPlayerFacilityClasses[arrId]); + u32 arrId = gLinkPlayers[linkId].trainerId % NUM_UNION_ROOM_CLASSES; + arrId |= gLinkPlayers[linkId].gender * NUM_UNION_ROOM_CLASSES; + return FacilityClassToPicIndex(gUnionRoomFacilityClasses[arrId]); } u16 GetUnionRoomTrainerClass(void) { u8 linkId = GetMultiplayerId() ^ 1; - u32 arrId = gLinkPlayers[linkId].trainerId & 7; - arrId |= gLinkPlayers[linkId].gender << 3; - return gFacilityClassToTrainerClass[gLinkPlayerFacilityClasses[arrId]]; + u32 arrId = gLinkPlayers[linkId].trainerId % NUM_UNION_ROOM_CLASSES; + arrId |= gLinkPlayers[linkId].gender * NUM_UNION_ROOM_CLASSES; + return gFacilityClassToTrainerClass[gUnionRoomFacilityClasses[arrId]]; } void CreateEventLegalEnemyMon(void) diff --git a/src/rfu_union_tool.c b/src/rfu_union_tool.c deleted file mode 100644 index d6e77519d..000000000 --- a/src/rfu_union_tool.c +++ /dev/null @@ -1,663 +0,0 @@ -#include "global.h" -#include "event_data.h" -#include "event_object_movement.h" -#include "field_player_avatar.h" -#include "fieldmap.h" -#include "rfu_union_tool.h" -#include "script.h" -#include "task.h" -#include "constants/event_object_movement.h" -#include "constants/union_room.h" -#include "constants/event_objects.h" - -static EWRAM_DATA struct UnionRoomObject * UnionObjWork = NULL; -static EWRAM_DATA u32 sUnionObjRefreshTimer = 0; - -static u8 StartUnionObjAnimTask(void); -static u32 RfuUnionGroupMemberIsInvisible(u32 group, u32 member); -static void UnionPartnerObjectSetFacing(s32 member, s32 group, u8 direction); - -static const u8 sUnionObjectEventGfxIds[][10] = { - [MALE] = { - OBJ_EVENT_GFX_COOLTRAINER_M, - OBJ_EVENT_GFX_BLACKBELT, - OBJ_EVENT_GFX_CAMPER, - OBJ_EVENT_GFX_YOUNGSTER, - OBJ_EVENT_GFX_BOY, - OBJ_EVENT_GFX_BUG_CATCHER, - OBJ_EVENT_GFX_MAN, - OBJ_EVENT_GFX_ROCKER - }, - [FEMALE] = { - OBJ_EVENT_GFX_COOLTRAINER_F, - OBJ_EVENT_GFX_CHANNELER, - OBJ_EVENT_GFX_PICNICKER, - OBJ_EVENT_GFX_LASS, - OBJ_EVENT_GFX_WOMAN_1, - OBJ_EVENT_GFX_BATTLE_GIRL, - OBJ_EVENT_GFX_WOMAN_2, - OBJ_EVENT_GFX_BEAUTY - } -}; - -static const s16 sUnionPartnerCoords[][2] = { - { 4, 6}, - {13, 8}, - {10, 6}, - { 1, 8}, - {13, 4}, - { 7, 4}, - { 1, 4}, - { 7, 8} -}; - -static const s8 sFacingDirectionOffsets[][2] = { - [DIR_NONE] = { 0, 0}, - [DIR_SOUTH] = { 1, 0}, - [DIR_NORTH] = { 0, -1}, - [DIR_WEST] = {-1, 0}, - [DIR_EAST] = { 0, 1} -}; - -static const u8 sOppositeFacingDirection[] = { - [DIR_NONE] = DIR_NONE, - [DIR_SOUTH] = DIR_NORTH, - [DIR_NORTH] = DIR_SOUTH, - [DIR_WEST] = DIR_EAST, - [DIR_EAST] = DIR_WEST -}; - -static const u8 sUnionGroupMemberFacings[] = { - DIR_SOUTH, - DIR_WEST, - DIR_SOUTH, - DIR_EAST, - DIR_NORTH -}; - -static const u8 sUnionRoomLocalIds[] = { - 9, - 8, - 7, - 2, - 6, - 5, - 4, - 3 -}; - -// Unused -static const u16 sHidePlayerFlags[] = { - FLAG_HIDE_UNION_ROOM_PLAYER_1, - FLAG_HIDE_UNION_ROOM_PLAYER_2, - FLAG_HIDE_UNION_ROOM_PLAYER_3, - FLAG_HIDE_UNION_ROOM_PLAYER_4, - FLAG_HIDE_UNION_ROOM_PLAYER_5, - FLAG_HIDE_UNION_ROOM_PLAYER_6, - FLAG_HIDE_UNION_ROOM_PLAYER_7, - FLAG_HIDE_UNION_ROOM_PLAYER_8 -}; - -static bool32 is_walking_or_running(void) -{ - if (gPlayerAvatar.tileTransitionState == 2 || gPlayerAvatar.tileTransitionState == 0) - { - return TRUE; - } - else - { - return FALSE; - } -} - -static u8 GetUnionRoomPlayerGraphicsId(u32 gender, u32 id) -{ - return sUnionObjectEventGfxIds[gender][id % 8]; -} - -static void GetUnionRoomPlayerFacingCoords(u32 group, u32 member, s32 * xp, s32 * yp) -{ - *xp = sUnionPartnerCoords[group][0] + sFacingDirectionOffsets[member][0] + 7; - *yp = sUnionPartnerCoords[group][1] + sFacingDirectionOffsets[member][1] + 7; -} - -static bool32 IsUnionRoomPlayerFacingTileAt(u32 group, u32 member, s32 x, s32 y) -{ - if (sUnionPartnerCoords[group][0] + sFacingDirectionOffsets[member][0] + 7 != x) - { - return FALSE; - } - else if (sUnionPartnerCoords[group][1] + sFacingDirectionOffsets[member][1] + 7 != y) - { - return FALSE; - } - else - { - return TRUE; - } -} - -static bool32 IsUnionRoomPlayerHidden(u32 player_idx) -{ - return FlagGet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + player_idx); -} - -static void HideUnionRoomPlayer(u32 player_idx) -{ - FlagSet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + player_idx); -} - -static void ShowUnionRoomPlayer(u32 player_idx) -{ - FlagClear(FLAG_HIDE_UNION_ROOM_PLAYER_1 + player_idx); -} - -static void SetUnionRoomPlayerGfx(u32 playerIdx, u32 gfxId) -{ - VarSet(VAR_OBJ_GFX_ID_0 + playerIdx, gfxId); -} - -static void CreateUnionRoomPlayerObjectEvent(u32 playerIdx) -{ - TrySpawnObjectEvent(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); -} - -static void RemoveUnionRoomPlayerObjectEvent(u32 playerIdx) -{ - RemoveObjectEventByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); -} - -static bool32 SetUnionRoomPlayerEnterExitMovement(u32 playerIdx, const u8 * movement) -{ - u8 objectId; - struct ObjectEvent * object; - if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId)) - { - return FALSE; - } - object = &gObjectEvents[objectId]; - if (ObjectEventIsMovementOverridden(object)) - { - return FALSE; - } - if (ObjectEventSetHeldMovement(object, *movement)) - { - AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 387); - return FALSE; - } - return TRUE; -} - -static bool32 TryReleaseUnionRoomPlayerObjectEvent(u32 playerIdx) -{ - u8 objectId; - struct ObjectEvent * object; - if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[playerIdx], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId)) - { - return TRUE; - } - object = &gObjectEvents[objectId]; - if (!ObjectEventClearHeldMovementIfFinished(object)) - { - return FALSE; - } - if (!ArePlayerFieldControlsLocked()) - { - UnfreezeObjectEvent(object); - } - else - { - FreezeObjectEvent(object); - } - return TRUE; -} - -u8 ZeroUnionObjWork(struct UnionRoomObject * ptr) -{ - s32 i; - - sUnionObjRefreshTimer = 0; - UnionObjWork = ptr; - AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 442) - for (i = 0; i < 8; i++) - { - ptr[i].state = 0; - ptr[i].gfxId = 0; - ptr[i].animState = 0; - ptr[i].schedAnim = 0; - } - return StartUnionObjAnimTask(); -} - -static const u8 sMovement_UnionPlayerExit[2] = { - MOVEMENT_ACTION_FLY_UP, - MOVEMENT_ACTION_STEP_END -}; - -static bool32 AnimateUnionRoomPlayerDespawn(s8 * a0, u32 playerIdx, struct UnionRoomObject * ptr) -{ - switch (*a0) - { - case 0: - if (SetUnionRoomPlayerEnterExitMovement(playerIdx, sMovement_UnionPlayerExit) == TRUE) - { - HideUnionRoomPlayer(playerIdx); - (*a0)++; - } - break; - case 1: - if (TryReleaseUnionRoomPlayerObjectEvent(playerIdx)) - { - RemoveUnionRoomPlayerObjectEvent(playerIdx); - HideUnionRoomPlayer(playerIdx); - *a0 = 0; - return TRUE; - } - break; - } - return FALSE; -} - -static const u8 sMovement_UnionPlayerEnter[2] = { - MOVEMENT_ACTION_FLY_DOWN, - MOVEMENT_ACTION_STEP_END -}; - -static bool32 AnimateUnionRoomPlayerSpawn(s8 * state_p, u32 playerIdx, struct UnionRoomObject * ptr) -{ - s16 x, y; - - switch (*state_p) - { - case 0: - if (!is_walking_or_running()) - { - break; - } - PlayerGetDestCoords(&x, &y); - if (IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x, y) == TRUE) - { - break; - } - player_get_pos_including_state_based_drift(&x, &y); - if (IsUnionRoomPlayerFacingTileAt(playerIdx, 0, x, y) == TRUE) - { - break; - } - SetUnionRoomPlayerGfx(playerIdx, ptr->gfxId); - CreateUnionRoomPlayerObjectEvent(playerIdx); - ShowUnionRoomPlayer(playerIdx); - (*state_p)++; - // fallthrough - case 3: // incorrect? - if (SetUnionRoomPlayerEnterExitMovement(playerIdx, sMovement_UnionPlayerEnter) == 1) - { - (*state_p)++; - } - break; - case 2: - if (TryReleaseUnionRoomPlayerObjectEvent(playerIdx)) - { - *state_p = 0; - return TRUE; - } - break; - } - return FALSE; -} - -static bool32 SpawnGroupLeader(u32 playerIdx, u32 gender, u32 idMod256) -{ - struct UnionRoomObject * ptr = &UnionObjWork[playerIdx]; - AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 561) - ptr->schedAnim = UNION_ROOM_SPAWN_IN; - ptr->gfxId = GetUnionRoomPlayerGraphicsId(gender, idMod256); - if (ptr->state == 0) - { - return TRUE; - } - else - { - return FALSE; - } -} - -static bool32 DespawnGroupLeader(u32 playerIdx) -{ - struct UnionRoomObject * ptr = &UnionObjWork[playerIdx]; - AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 577) - ptr->schedAnim = UNION_ROOM_SPAWN_OUT; - if (ptr->state == 1) - { - return TRUE; - } - else - { - return FALSE; - } -} - -static void AnimateUnionObj(u32 playerIdx, struct UnionRoomObject * ptr) -{ - switch (ptr->state) - { - case 0: - if (ptr->schedAnim == UNION_ROOM_SPAWN_IN) - { - ptr->state = 2; - ptr->animState = 0; - } - else - { - break; - } - // fallthrough - case 2: - if (!RfuUnionGroupMemberIsInvisible(playerIdx, 0) && ptr->schedAnim == 2) - { - ptr->state = 0; - ptr->animState = 0; - RemoveUnionRoomPlayerObjectEvent(playerIdx); - HideUnionRoomPlayer(playerIdx); - } - else if (AnimateUnionRoomPlayerSpawn(&ptr->animState, playerIdx, ptr) == TRUE) - { - ptr->state = 1; - } - break; - case 1: - if (ptr->schedAnim == UNION_ROOM_SPAWN_OUT) - { - ptr->state = 3; - ptr->animState = 0; - } - else - { - break; - } - // fallthrough - case 3: - if (AnimateUnionRoomPlayerDespawn(&ptr->animState, playerIdx, ptr) == TRUE) - { - ptr->state = 0; - } - break; - } - ptr->schedAnim = UNION_ROOM_SPAWN_NONE; -} - -static void Task_AnimateUnionObjs(u8 taskId) -{ - s32 i; - AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 643) - for (i = 0; i < 8; i++) - { - AnimateUnionObj(i, &UnionObjWork[i]); - } -} - -static u8 StartUnionObjAnimTask(void) -{ - if (FuncIsActiveTask(Task_AnimateUnionObjs) == TRUE) - { - AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 655) - return NUM_TASKS; - } - else - { - return CreateTask(Task_AnimateUnionObjs, 5); - } -} - -static void DestroyAnimateUnionObjsTask(void) -{ - u8 taskId = FindTaskIdByFunc(Task_AnimateUnionObjs); - if (taskId < NUM_TASKS) - { - DestroyTask(taskId); - } -} - -void DestroyUnionRoomPlayerObjects(void) -{ - s32 i; - for (i = 0; i < 8; i++) - { - if (!IsUnionRoomPlayerHidden(i)) - { - RemoveUnionRoomPlayerObjectEvent(i); - HideUnionRoomPlayer(i); - } - } - UnionObjWork = NULL; - DestroyAnimateUnionObjsTask(); -} - -void CreateGroupMemberObjectsInvisible(u8 * sprite_ids, s32 group) -{ - s32 i; - - for (i = 0; i < 5; i++) - { - s32 obj_id = 5 * group + i; - sprite_ids[obj_id] = CreateVirtualObject(OBJ_EVENT_GFX_MAN, obj_id - 0x38, sUnionPartnerCoords[group][0] + sFacingDirectionOffsets[i][0], sUnionPartnerCoords[group][1] + sFacingDirectionOffsets[i][1], 3, 1); - SetVirtualObjectInvisibility(obj_id - 0x38, TRUE); - } -} - -void DestroyGroupMemberObjects(u8 *spriteIds) -{ - s32 i; - for (i = 0; i < 40; i++) - { - DestroySprite(&gSprites[spriteIds[i]]); - } -} - -void MakeGroupAssemblyAreasPassable(void) -{ - s32 i, j, x, y; - for (i = 0; i < 8; i++) - { - for (j = 0; j < 5; j++) - { - GetUnionRoomPlayerFacingCoords(i, j, &x, &y); - MapGridSetMetatileImpassabilityAt(x, y, FALSE); - } - } -} - -static u8 UnionPartnerObjectGetFacing(u32 member, u32 group, struct RfuGameData * gname) -{ - if (member != 0) - { - return sUnionGroupMemberFacings[member]; - } - else if (gname->activity == 0x45) - { - return DIR_SOUTH; - } - else - { - return DIR_EAST; - } -} - -static u32 RfuUnionGroupMemberIsInvisible(u32 group, u32 member) -{ - return IsVirtualObjectInvisible(5 * group + member - 0x38); -} - -static void SpawnGroupMember(u32 groupNo, u32 memberNo, u8 direction, struct RfuGameData * gname) -{ - s32 x, y; - s32 objId = 5 * groupNo + memberNo; - if (RfuUnionGroupMemberIsInvisible(groupNo, memberNo) == TRUE) - { - SetVirtualObjectInvisibility(objId - 0x38, FALSE); - SetVirtualObjectSpriteAnim(objId - 0x38, UNION_ROOM_SPAWN_IN); - } - SetVirtualObjectGraphics(objId - 0x38, direction); - UnionPartnerObjectSetFacing(memberNo, groupNo, UnionPartnerObjectGetFacing(memberNo, groupNo, gname)); - GetUnionRoomPlayerFacingCoords(groupNo, memberNo, &x, &y); - MapGridSetMetatileImpassabilityAt(x, y, TRUE); -} - -static void DespawnGroupMember(u32 group, u32 member) -{ - s32 x, y; - SetVirtualObjectSpriteAnim(5 * group + member - 0x38, UNION_ROOM_SPAWN_OUT); - GetUnionRoomPlayerFacingCoords(group, member, &x, &y); - MapGridSetMetatileImpassabilityAt(x, y, FALSE); -} - -static void AssembleGroup(u32 group, struct RfuGameData * gname) -{ - s16 x, y, x2, y2; - s32 i; - - PlayerGetDestCoords(&x, &y); - player_get_pos_including_state_based_drift(&x2, &y2); - if (IsVirtualObjectInvisible(5 * group - 0x38) == TRUE) - { - if (IsUnionRoomPlayerFacingTileAt(group, 0, x, y) == TRUE || IsUnionRoomPlayerFacingTileAt(group, 0, x2, y2) == TRUE) - { - return; - } - SpawnGroupMember(group, 0, GetUnionRoomPlayerGraphicsId(gname->playerGender, gname->compatibility.playerTrainerId[0]), gname); - } - for (i = 1; i < 5; i++) - { - if (gname->partnerInfo[i - 1] == 0) - { - DespawnGroupMember(group, i); - } - else if (IsUnionRoomPlayerFacingTileAt(group, i, x, y) == FALSE && IsUnionRoomPlayerFacingTileAt(group, i, x2, y2) == FALSE) - { - SpawnGroupMember(group, i, GetUnionRoomPlayerGraphicsId((gname->partnerInfo[i - 1] >> 3) & 1, gname->partnerInfo[i - 1] & 7), gname); - } - } -} - -static void SpawnGroupLeaderAndMembers(u32 group, struct RfuGameData * gname) -{ - u32 i; - switch (gname->activity) - { - case 0x40: - case 0x54: - SpawnGroupLeader(group, gname->playerGender, gname->compatibility.playerTrainerId[0]); - for (i = 0; i < 5; i++) - { - DespawnGroupMember(group, i); - } - break; - case 0x41: - case 0x44: - case 0x45: - case 0x48: - case 0x51: - case 0x52: - case 0x53: - DespawnGroupLeader(group); - AssembleGroup(group, gname); - break; - default: - AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 979) - } -} - -static void DespawnGroupLeaderAndMembers(u32 group, struct RfuGameData * gname) -{ - s32 i; - DespawnGroupLeader(group); - for (i = 0; i < 5; i++) - { - DespawnGroupMember(group, i); - } -} - -static void UpdateUnionRoomPlayerSprites(struct WirelessLink_URoom * groups) -{ - s32 i; - struct RfuPlayer * x20_p; - sUnionObjRefreshTimer = 0; - for (i = 0, x20_p = groups->playerList->players; i < 8; i++) - { - if (x20_p[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) - { - SpawnGroupLeaderAndMembers(i, &x20_p[i].rfu.data); - } - else if (x20_p[i].groupScheduledAnim == UNION_ROOM_SPAWN_OUT) - { - DespawnGroupLeaderAndMembers(i, &x20_p[i].rfu.data); - } - } -} - -void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p) -{ - sUnionObjRefreshTimer = 300; -} - -void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom_p) -{ - if (++sUnionObjRefreshTimer > 300) - { - UpdateUnionRoomPlayerSprites(uroom_p); - } -} - -bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *main0_p, s16 *member_p, s16 *group_p, u8 *spriteIds) -{ - s16 x, y; - s32 i, j; - struct RfuPlayer * x20_p; - if (!is_walking_or_running()) - { - return FALSE; - } - GetXYCoordsOneStepInFrontOfPlayer(&x, &y); - for (i = 0, x20_p = main0_p->players; i < 8; i++) - { - for (j = 0; j < 5; j++) - { - s32 objId = 5 * i + j; - if (x != sUnionPartnerCoords[i][0] + sFacingDirectionOffsets[j][0] + 7) - { - continue; - } - if (y != sUnionPartnerCoords[i][1] + sFacingDirectionOffsets[j][1] + 7) - { - continue; - } - if (IsVirtualObjectInvisible(objId - 0x38) != FALSE) - { - continue; - } - if (IsVirtualObjectAnimating(objId - 0x38) != FALSE) - { - continue; - } - if (x20_p[i].groupScheduledAnim != UNION_ROOM_SPAWN_IN) - { - continue; - } - UnionPartnerObjectSetFacing(j, i, sOppositeFacingDirection[GetPlayerFacingDirection()]); - *member_p = j; - *group_p = i; - return TRUE; - } - } - return FALSE; -} - -static void UnionPartnerObjectSetFacing(s32 member, s32 group, u8 direction) -{ - TurnVirtualObject(5 * group - 0x38 + member, direction); -} - -void UpdateUnionGroupMemberFacing(u32 member, u32 group, struct RfuPlayerList *main0_p) -{ - return UnionPartnerObjectSetFacing(member, group, UnionPartnerObjectGetFacing(member, group, &main0_p->players[group].rfu.data)); -} diff --git a/src/union_room.c b/src/union_room.c index 2458e44ef..8b8410e3d 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -40,7 +40,7 @@ #include "union_room.h" #include "union_room_battle.h" #include "union_room_chat.h" -#include "rfu_union_tool.h" +#include "union_room_player_avatar.h" #include "union_room_message.h" #include "constants/songs.h" #include "constants/maps.h" @@ -2317,13 +2317,13 @@ static void Task_RunUnionRoom(u8 taskId) ClearRfuPlayerList(uroom->playerList->players, MAX_UNION_ROOM_LEADERS); sPlayerCurrActivity = IN_UNION_ROOM; uroom->searchTaskId = CreateTask_SearchForChildOrParent(uroom->incomingParentList, uroom->incomingChildList, LINK_GROUP_UNION_ROOM_RESUME); - ZeroUnionObjWork(uroom->objects); + InitUnionRoomPlayerObjects(uroom->objects); MakeGroupAssemblyAreasPassable(); uroom->state = UR_STATE_INIT_OBJECTS; break; case UR_STATE_INIT_OBJECTS: - CreateGroupMemberObjectsInvisible(uroom->spriteIds, taskData[0]); - if (++taskData[0] == 8) + CreateUnionRoomPlayerSprites(uroom->spriteIds, taskData[0]); + if (++taskData[0] == MAX_UNION_ROOM_LEADERS) uroom->state = UR_STATE_INIT_LINK; break; case UR_STATE_INIT_LINK: @@ -2515,7 +2515,7 @@ static void Task_RunUnionRoom(u8 taskId) if (!gReceivedRemoteLinkPlayers) { HandleCancelActivity(FALSE); - UpdateUnionGroupMemberFacing(taskData[0], taskData[1], uroom->playerList); + UpdateUnionRoomMemberFacing(taskData[0], taskData[1], uroom->playerList); uroom->state = UR_STATE_INIT_LINK; } break; @@ -2840,7 +2840,7 @@ static void Task_RunUnionRoom(u8 taskId) Free(uroom->incomingParentList); Free(uroom->incomingChildList); DestroyTask(uroom->searchTaskId); - DestroyGroupMemberObjects(uroom->spriteIds); + DestroyUnionRoomPlayerSprites(uroom->spriteIds); uroom->state = UR_STATE_START_ACTIVITY_FADE; break; case UR_STATE_START_ACTIVITY_FADE: @@ -3051,7 +3051,7 @@ static void Task_RunUnionRoom(u8 taskId) if (PrintOnTextbox(&uroom->textState, gStringVar4)) { HandleCancelActivity(TRUE); - UpdateUnionGroupMemberFacing(taskData[0], taskData[1], uroom->playerList); + UpdateUnionRoomMemberFacing(taskData[0], taskData[1], uroom->playerList); uroom->state = UR_STATE_MAIN; } break; diff --git a/src/union_room_player_avatar.c b/src/union_room_player_avatar.c new file mode 100644 index 000000000..2cfa38167 --- /dev/null +++ b/src/union_room_player_avatar.c @@ -0,0 +1,615 @@ +#include "global.h" +#include "event_data.h" +#include "event_object_movement.h" +#include "field_player_avatar.h" +#include "fieldmap.h" +#include "union_room_player_avatar.h" +#include "script.h" +#include "task.h" +#include "constants/event_object_movement.h" +#include "constants/union_room.h" +#include "constants/event_objects.h" + +#define UR_SPRITE_START_ID (MAX_SPRITES - MAX_UNION_ROOM_LEADERS) + +// Each parent player can lead a group of up to MAX_RFU_PLAYERS (including themselves). +// Multiply the leader's id by MAX_RFU_PLAYERS and add the member's id (0 if the leader) to +// get the sprite index of that player. +#define UR_PLAYER_SPRITE_ID(leaderId, memberId)(MAX_RFU_PLAYERS * leaderId + memberId) + +// Original symbol name from ASSERT statements +#define UnionObjWork sUnionObjWork + +static EWRAM_DATA struct UnionRoomObject * sUnionObjWork = NULL; +static EWRAM_DATA u32 sUnionObjRefreshTimer = 0; + +static u8 CreateTask_AnimateUnionRoomPlayers(void); +static u32 IsUnionRoomPlayerInvisible(u32 leaderId, u32 member); +static void SetUnionRoomObjectFacingDirection(s32 member, s32 leaderId, u8 direction); + +// + 2 is just to match, those elements are empty and never read +// Graphics ids should correspond with the classes in gUnionRoomFacilityClasses +static const u8 sUnionRoomObjGfxIds[GENDER_COUNT][NUM_UNION_ROOM_CLASSES + 2] = { + [MALE] = { + OBJ_EVENT_GFX_COOLTRAINER_M, + OBJ_EVENT_GFX_BLACKBELT, + OBJ_EVENT_GFX_CAMPER, + OBJ_EVENT_GFX_YOUNGSTER, + OBJ_EVENT_GFX_BOY, + OBJ_EVENT_GFX_BUG_CATCHER, + OBJ_EVENT_GFX_MAN, + OBJ_EVENT_GFX_ROCKER + }, + [FEMALE] = { + OBJ_EVENT_GFX_COOLTRAINER_F, + OBJ_EVENT_GFX_CHANNELER, + OBJ_EVENT_GFX_PICNICKER, + OBJ_EVENT_GFX_LASS, + OBJ_EVENT_GFX_WOMAN_1, + OBJ_EVENT_GFX_BATTLE_GIRL, + OBJ_EVENT_GFX_WOMAN_2, + OBJ_EVENT_GFX_BEAUTY + } +}; + +static const s16 sUnionRoomPlayerCoords[MAX_UNION_ROOM_LEADERS][2] = { + { 4, 6}, + {13, 8}, + {10, 6}, + { 1, 8}, + {13, 4}, + { 7, 4}, + { 1, 4}, + { 7, 8} +}; + +// If there's a group of players interacting in the Union Room, the group +// leader will be at one of the positions above and each member in the group +// will be at one of the offsets from that position below. The leader will +// be at the first offset (0,0), as they're at the center. +static const s8 sUnionRoomGroupOffsets[][2] = { + { 0, 0}, // Center + { 1, 0}, // Left + { 0, -1}, // Top + {-1, 0}, // Right + { 0, 1} // Bottom +}; + +static const u8 sOppositeFacingDirection[] = { + [DIR_NONE] = DIR_NONE, + [DIR_SOUTH] = DIR_NORTH, + [DIR_NORTH] = DIR_SOUTH, + [DIR_WEST] = DIR_EAST, + [DIR_EAST] = DIR_WEST +}; + +// Compare to sUnionRoomGroupOffsets, the direction each group member +// needs to be facing in order to face the group leader in the center. +static const u8 sMemberFacingDirections[] = { + DIR_SOUTH, // Leader, but never read + DIR_WEST, + DIR_SOUTH, + DIR_EAST, + DIR_NORTH +}; + +static const u8 sUnionRoomLocalIds[] = { + LOCALID_UNION_ROOM_PLAYER_1, + LOCALID_UNION_ROOM_PLAYER_2, + LOCALID_UNION_ROOM_PLAYER_3, + LOCALID_UNION_ROOM_PLAYER_4, + LOCALID_UNION_ROOM_PLAYER_5, + LOCALID_UNION_ROOM_PLAYER_6, + LOCALID_UNION_ROOM_PLAYER_7, + LOCALID_UNION_ROOM_PLAYER_8 +}; + +// Unused +static const u16 sHidePlayerFlags[] = { + FLAG_HIDE_UNION_ROOM_PLAYER_1, + FLAG_HIDE_UNION_ROOM_PLAYER_2, + FLAG_HIDE_UNION_ROOM_PLAYER_3, + FLAG_HIDE_UNION_ROOM_PLAYER_4, + FLAG_HIDE_UNION_ROOM_PLAYER_5, + FLAG_HIDE_UNION_ROOM_PLAYER_6, + FLAG_HIDE_UNION_ROOM_PLAYER_7, + FLAG_HIDE_UNION_ROOM_PLAYER_8 +}; + +static bool32 IsPlayerStandingStill(void) +{ + if (gPlayerAvatar.tileTransitionState == T_TILE_CENTER || gPlayerAvatar.tileTransitionState == T_NOT_MOVING) + return TRUE; + else + return FALSE; +} + +// Gender and trainer id are used to determine which sprite a player appears as +static u8 GetUnionRoomPlayerGraphicsId(u32 gender, u32 id) +{ + return sUnionRoomObjGfxIds[gender][id % NUM_UNION_ROOM_CLASSES]; +} + +static void GetUnionRoomPlayerCoords(u32 leaderId, u32 memberId, s32 * x, s32 * y) +{ + *x = sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + 7; + *y = sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + 7; +} + +static bool32 IsUnionRoomPlayerAt(u32 leaderId, u32 memberId, s32 x, s32 y) +{ + if ((sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + MAP_OFFSET == x) + && (sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + MAP_OFFSET == y)) + return TRUE; + else + return FALSE; +} + +static bool32 IsUnionRoomPlayerHidden(u32 leaderId) +{ + return FlagGet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + leaderId); +} + +static void HideUnionRoomPlayer(u32 leaderId) +{ + FlagSet(FLAG_HIDE_UNION_ROOM_PLAYER_1 + leaderId); +} + +static void ShowUnionRoomPlayer(u32 leaderId) +{ + FlagClear(FLAG_HIDE_UNION_ROOM_PLAYER_1 + leaderId); +} + +static void SetUnionRoomPlayerGfx(u32 leaderId, u32 gfxId) +{ + VarSet(VAR_OBJ_GFX_ID_0 + leaderId, gfxId); +} + +static void CreateUnionRoomPlayerObjectEvent(u32 leaderId) +{ + TrySpawnObjectEvent(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); +} + +static void RemoveUnionRoomPlayerObjectEvent(u32 leaderId) +{ + RemoveObjectEventByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup); +} + +static bool32 SetUnionRoomPlayerEnterExitMovement(u32 leaderId, const u8 * movement) +{ + u8 objectId; + struct ObjectEvent * object; + if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId)) + return FALSE; + object = &gObjectEvents[objectId]; + if (ObjectEventIsMovementOverridden(object)) + return FALSE; + if (ObjectEventSetHeldMovement(object, *movement)) + { + AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 387); + return FALSE; + } + return TRUE; +} + +static bool32 TryReleaseUnionRoomPlayerObjectEvent(u32 leaderId) +{ + u8 objectId; + struct ObjectEvent * object; + if (TryGetObjectEventIdByLocalIdAndMap(sUnionRoomLocalIds[leaderId], gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectId)) + return TRUE; + + object = &gObjectEvents[objectId]; + if (!ObjectEventClearHeldMovementIfFinished(object)) + return FALSE; + + if (!ArePlayerFieldControlsLocked()) + UnfreezeObjectEvent(object); + else + FreezeObjectEvent(object); + return TRUE; +} + +u8 InitUnionRoomPlayerObjects(struct UnionRoomObject * players) +{ + s32 i; + + sUnionObjRefreshTimer = 0; + sUnionObjWork = players; + AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 442) + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) + { + players[i].state = 0; + players[i].gfxId = 0; + players[i].animState = 0; + players[i].schedAnim = UNION_ROOM_SPAWN_NONE; + } + return CreateTask_AnimateUnionRoomPlayers(); +} + +static const u8 sMovement_UnionPlayerExit[2] = { + MOVEMENT_ACTION_FLY_UP, + MOVEMENT_ACTION_STEP_END +}; + +static bool32 AnimateUnionRoomPlayerDespawn(s8 * state, u32 leaderId, struct UnionRoomObject * object) +{ + switch (*state) + { + case 0: + if (SetUnionRoomPlayerEnterExitMovement(leaderId, sMovement_UnionPlayerExit) == TRUE) + { + HideUnionRoomPlayer(leaderId); + (*state)++; + } + break; + case 1: + if (TryReleaseUnionRoomPlayerObjectEvent(leaderId)) + { + RemoveUnionRoomPlayerObjectEvent(leaderId); + HideUnionRoomPlayer(leaderId); + *state = 0; + return TRUE; + } + break; + } + return FALSE; +} + +static const u8 sMovement_UnionPlayerEnter[2] = { + MOVEMENT_ACTION_FLY_DOWN, + MOVEMENT_ACTION_STEP_END +}; + +static bool32 AnimateUnionRoomPlayerSpawn(s8 * state, u32 leaderId, struct UnionRoomObject * object) +{ + s16 x, y; + + switch (*state) + { + case 0: + if (!IsPlayerStandingStill()) + break; + PlayerGetDestCoords(&x, &y); + if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE) + break; + player_get_pos_including_state_based_drift(&x, &y); + if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE) + break; + SetUnionRoomPlayerGfx(leaderId, object->gfxId); + CreateUnionRoomPlayerObjectEvent(leaderId); + ShowUnionRoomPlayer(leaderId); + (*state)++; + // fallthrough + case 3: // incorrect? + if (SetUnionRoomPlayerEnterExitMovement(leaderId, sMovement_UnionPlayerEnter) == 1) + (*state)++; + break; + case 2: + if (TryReleaseUnionRoomPlayerObjectEvent(leaderId)) + { + *state = 0; + return TRUE; + } + break; + } + return FALSE; +} + +static bool32 SpawnGroupLeader(u32 leaderId, u32 gender, u32 id) +{ + struct UnionRoomObject * object = &sUnionObjWork[leaderId]; + AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 561) + object->schedAnim = UNION_ROOM_SPAWN_IN; + object->gfxId = GetUnionRoomPlayerGraphicsId(gender, id); + + if (object->state == 0) + return TRUE; + else + return FALSE; +} + +static bool32 DespawnGroupLeader(u32 leaderId) +{ + struct UnionRoomObject * object = &sUnionObjWork[leaderId]; + AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 577) + object->schedAnim = UNION_ROOM_SPAWN_OUT; + + if (object->state == 1) + return TRUE; + else + return FALSE; +} + +static void AnimateUnionRoomPlayer(u32 leaderId, struct UnionRoomObject * object) +{ + switch (object->state) + { + case 0: + if (object->schedAnim == UNION_ROOM_SPAWN_IN) + { + object->state = 2; + object->animState = 0; + } + else + { + break; + } + // fallthrough + case 2: + if (!IsUnionRoomPlayerInvisible(leaderId, 0) && object->schedAnim == UNION_ROOM_SPAWN_OUT) + { + object->state = 0; + object->animState = 0; + RemoveUnionRoomPlayerObjectEvent(leaderId); + HideUnionRoomPlayer(leaderId); + } + else if (AnimateUnionRoomPlayerSpawn(&object->animState, leaderId, object) == TRUE) + { + object->state = 1; + } + break; + case 1: + if (object->schedAnim != UNION_ROOM_SPAWN_OUT) + break; + object->state = 3; + object->animState = 0; + // fallthrough + case 3: + if (AnimateUnionRoomPlayerDespawn(&object->animState, leaderId, object) == TRUE) + object->state = 0; + break; + } + object->schedAnim = UNION_ROOM_SPAWN_NONE; +} + +static void Task_AnimateUnionRoomPlayers(u8 taskId) +{ + s32 i; + AGB_ASSERT_EX(UnionObjWork != NULL, ABSPATH("rfu_union_tool.c"), 643) + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) + AnimateUnionRoomPlayer(i, &sUnionObjWork[i]); +} + +static u8 CreateTask_AnimateUnionRoomPlayers(void) +{ + if (FuncIsActiveTask(Task_AnimateUnionRoomPlayers) == TRUE) + { + AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 655) + return NUM_TASKS; + } + else + { + return CreateTask(Task_AnimateUnionRoomPlayers, 5); + } +} + +static void DestroyTask_AnimateUnionRoomPlayers(void) +{ + u8 taskId = FindTaskIdByFunc(Task_AnimateUnionRoomPlayers); + if (taskId < NUM_TASKS) + DestroyTask(taskId); +} + +void DestroyUnionRoomPlayerObjects(void) +{ + s32 i; + for (i = 0; i < MAX_UNION_ROOM_LEADERS; i++) + { + if (!IsUnionRoomPlayerHidden(i)) + { + RemoveUnionRoomPlayerObjectEvent(i); + HideUnionRoomPlayer(i); + } + } + sUnionObjWork = NULL; + DestroyTask_AnimateUnionRoomPlayers(); +} + +void CreateUnionRoomPlayerSprites(u8 * spriteIds, s32 leaderId) +{ + s32 memberId; + + for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++) + { + s32 id = UR_PLAYER_SPRITE_ID(leaderId, memberId); + spriteIds[id] = CreateVirtualObject(OBJ_EVENT_GFX_MAN, + id - UR_SPRITE_START_ID, + sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0], + sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1], + 3, 1); + SetVirtualObjectInvisibility(id - UR_SPRITE_START_ID, TRUE); + } +} + +void DestroyUnionRoomPlayerSprites(u8 *spriteIds) +{ + s32 i; + for (i = 0; i < NUM_UNION_ROOM_SPRITES; i++) + DestroySprite(&gSprites[spriteIds[i]]); +} + +// Clear the impassable metatiles around the group leaders that get set +// to prevent the player from walking through the group member sprites. +void MakeGroupAssemblyAreasPassable(void) +{ + s32 leaderId, memberId, x, y; + for (leaderId = 0; leaderId < MAX_UNION_ROOM_LEADERS; leaderId++) + { + for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++) + { + GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y); + MapGridSetMetatileImpassabilityAt(x, y, FALSE); + } + } +} + +static u8 GetNewFacingDirectionForUnionRoomPlayer(u32 memberId, u32 leaderId, struct RfuGameData * gameData) +{ + if (memberId != 0) // If not leader + return sMemberFacingDirections[memberId]; + else if (gameData->activity == (ACTIVITY_CHAT | IN_UNION_ROOM)) + return DIR_SOUTH; + else + return DIR_EAST; +} + +static u32 IsUnionRoomPlayerInvisible(u32 leaderId, u32 memberId) +{ + return IsVirtualObjectInvisible(UR_PLAYER_SPRITE_ID(leaderId, memberId) - UR_SPRITE_START_ID); +} + +static void SpawnGroupMember(u32 leaderId, u32 memberId, u8 graphicsId, struct RfuGameData * gameData) +{ + s32 x, y; + s32 id = UR_PLAYER_SPRITE_ID(leaderId, memberId); + if (IsUnionRoomPlayerInvisible(leaderId, memberId) == TRUE) + { + SetVirtualObjectInvisibility(id - UR_SPRITE_START_ID, FALSE); + SetVirtualObjectSpriteAnim(id - UR_SPRITE_START_ID, UNION_ROOM_SPAWN_IN); + } + SetVirtualObjectGraphics(id - UR_SPRITE_START_ID, graphicsId); + SetUnionRoomObjectFacingDirection(memberId, leaderId, GetNewFacingDirectionForUnionRoomPlayer(memberId, leaderId, gameData)); + GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y); + MapGridSetMetatileImpassabilityAt(x, y, TRUE); +} + +static void DespawnGroupMember(u32 leaderId, u32 memberId) +{ + s32 x, y; + SetVirtualObjectSpriteAnim(UR_PLAYER_SPRITE_ID(leaderId, memberId) - UR_SPRITE_START_ID, UNION_ROOM_SPAWN_OUT); + GetUnionRoomPlayerCoords(leaderId, memberId, &x, &y); + MapGridSetMetatileImpassabilityAt(x, y, FALSE); +} + +static void AssembleGroup(u32 leaderId, struct RfuGameData * gameData) +{ + s16 x, y, x2, y2; + s32 i; + + PlayerGetDestCoords(&x, &y); + player_get_pos_including_state_based_drift(&x2, &y2); + if (IsVirtualObjectInvisible(UR_PLAYER_SPRITE_ID(leaderId, 0) - UR_SPRITE_START_ID) == TRUE) + { + if (IsUnionRoomPlayerAt(leaderId, 0, x, y) == TRUE || IsUnionRoomPlayerAt(leaderId, 0, x2, y2) == TRUE) + return; + SpawnGroupMember(leaderId, 0, GetUnionRoomPlayerGraphicsId(gameData->playerGender, gameData->compatibility.playerTrainerId[0]), gameData); + } + for (i = 1; i < MAX_RFU_PLAYERS; i++) + { + if (gameData->partnerInfo[i - 1] == 0) + DespawnGroupMember(leaderId, i); + else if (IsUnionRoomPlayerAt(leaderId, i, x, y) == FALSE && IsUnionRoomPlayerAt(leaderId, i, x2, y2) == FALSE) + SpawnGroupMember(leaderId, i, GetUnionRoomPlayerGraphicsId((gameData->partnerInfo[i - 1] >> PINFO_GENDER_SHIFT) & 1, + gameData->partnerInfo[i - 1] & PINFO_TID_MASK), + gameData); + } +} + +static void SpawnGroupLeaderAndMembers(u32 leaderId, struct RfuGameData * gameData) +{ + u32 i; + switch (gameData->activity) + { + case ACTIVITY_NONE | IN_UNION_ROOM: + case ACTIVITY_PLYRTALK | IN_UNION_ROOM: + SpawnGroupLeader(leaderId, gameData->playerGender, gameData->compatibility.playerTrainerId[0]); + for (i = 0; i < MAX_RFU_PLAYERS; i++) + DespawnGroupMember(leaderId, i); + break; + case ACTIVITY_BATTLE_SINGLE | IN_UNION_ROOM: + case ACTIVITY_TRADE | IN_UNION_ROOM: + case ACTIVITY_CHAT | IN_UNION_ROOM: + case ACTIVITY_CARD | IN_UNION_ROOM: + case ACTIVITY_ACCEPT | IN_UNION_ROOM: + case ACTIVITY_DECLINE | IN_UNION_ROOM: + case ACTIVITY_NPCTALK | IN_UNION_ROOM: + DespawnGroupLeader(leaderId); + AssembleGroup(leaderId, gameData); + break; + default: + AGB_ASSERT_EX(0, ABSPATH("rfu_union_tool.c"), 979) + } +} + +static void DespawnGroupLeaderAndMembers(u32 leaderId, struct RfuGameData * gameData) +{ + s32 i; + DespawnGroupLeader(leaderId); + for (i = 0; i < MAX_RFU_PLAYERS; i++) + DespawnGroupMember(leaderId, i); +} + +static void UpdateUnionRoomPlayerSprites(struct WirelessLink_URoom * uroom) +{ + s32 i; + struct RfuPlayer * leaders; + sUnionObjRefreshTimer = 0; + for (i = 0, leaders = uroom->playerList->players; i < MAX_UNION_ROOM_LEADERS; i++) + { + if (leaders[i].groupScheduledAnim == UNION_ROOM_SPAWN_IN) + SpawnGroupLeaderAndMembers(i, &leaders[i].rfu.data); + else if (leaders[i].groupScheduledAnim == UNION_ROOM_SPAWN_OUT) + DespawnGroupLeaderAndMembers(i, &leaders[i].rfu.data); + } +} + +void ScheduleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom) +{ + sUnionObjRefreshTimer = 300; +} + +void HandleUnionRoomPlayerRefresh(struct WirelessLink_URoom *uroom) +{ + if (++sUnionObjRefreshTimer > 300) + UpdateUnionRoomPlayerSprites(uroom); +} + +bool32 TryInteractWithUnionRoomMember(struct RfuPlayerList *list, s16 *memberIdPtr, s16 *leaderIdPtr, u8 *spriteIds) +{ + s16 x, y; + s32 leaderId, memberId; + struct RfuPlayer * leaders; + if (!IsPlayerStandingStill()) + return FALSE; + + GetXYCoordsOneStepInFrontOfPlayer(&x, &y); + for (leaderId = 0, leaders = list->players; leaderId < MAX_UNION_ROOM_LEADERS; leaderId++) + { + for (memberId = 0; memberId < MAX_RFU_PLAYERS; memberId++) + { + s32 objId = UR_PLAYER_SPRITE_ID(leaderId, memberId); + + // Is the player in front of a group member position? + if (x != sUnionRoomPlayerCoords[leaderId][0] + sUnionRoomGroupOffsets[memberId][0] + 7) + continue; + if (y != sUnionRoomPlayerCoords[leaderId][1] + sUnionRoomGroupOffsets[memberId][1] + 7) + continue; + + // Has a group member spawned at this position? + if (IsVirtualObjectInvisible(objId - UR_SPRITE_START_ID) != FALSE) + continue; + if (IsVirtualObjectAnimating(objId - UR_SPRITE_START_ID) != FALSE) + continue; + if (leaders[leaderId].groupScheduledAnim != UNION_ROOM_SPAWN_IN) + continue; + + // Interaction attempt successful, face player + SetUnionRoomObjectFacingDirection(memberId, leaderId, sOppositeFacingDirection[GetPlayerFacingDirection()]); + *memberIdPtr = memberId; + *leaderIdPtr = leaderId; + return TRUE; + } + } + return FALSE; +} + +static void SetUnionRoomObjectFacingDirection(s32 memberId, s32 leaderId, u8 direction) +{ + TurnVirtualObject(MAX_RFU_PLAYERS * leaderId - UR_SPRITE_START_ID + memberId, direction); +} + +void UpdateUnionRoomMemberFacing(u32 memberId, u32 leaderId, struct RfuPlayerList *list) +{ + return SetUnionRoomObjectFacingDirection(memberId, leaderId, GetNewFacingDirectionForUnionRoomPlayer(memberId, leaderId, &list->players[leaderId].rfu.data)); +} diff --git a/sym_ewram.txt b/sym_ewram.txt index 0dc0544c1..f957d320b 100644 --- a/sym_ewram.txt +++ b/sym_ewram.txt @@ -102,7 +102,7 @@ .include "src/help_message.o" .include "src/quest_log_events.o" .include "src/union_room.o" - .include "src/rfu_union_tool.o" + .include "src/union_room_player_avatar.o" .include "src/union_room_battle.o" .include "src/pokemon_special_anim.o" .include "src/party_menu.o" From 91915c5662318efcc04e193ee053c737617683c7 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Tue, 8 Nov 2022 13:39:39 -0500 Subject: [PATCH 09/12] Fix player list array sizes --- include/link_rfu.h | 6 +++--- include/union_room.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/link_rfu.h b/include/link_rfu.h index 47588004c..e3b60ccb4 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -240,8 +240,8 @@ void MG_DrawCheckerboardPattern(void); void Rfu_SetCloseLinkCallback(void); bool8 IsLinkRfuTaskFinished(void); void DestroyWirelessStatusIndicatorSprite(void); -void CreateTask_LinkMysteryGiftWithFriend(u32 arg0); -void CreateTask_LinkMysteryGiftOverWireless(u32 arg0); +void CreateTask_LinkMysteryGiftWithFriend(u32 activity); +void CreateTask_LinkMysteryGiftOverWireless(u32 activity); void CreateTask_SendMysteryGift(u32 activity); void Rfu_SendPacket(void *data); u8 CreateTask_ListenToWireless(void); @@ -292,7 +292,7 @@ bool8 LmanAcceptSlotFlagIsNotZero(void); void LinkRfu_StopManagerAndFinalizeSlots(void); bool32 RfuTryDisconnectLeavingChildren(void); bool32 IsRfuCommunicatingWithAllChildren(void); -bool32 WaitRfuState(bool32 a0); +bool32 WaitRfuState(bool32 force); bool32 HasTrainerLeftPartnersList(u16 trainerId, const u8 *trainerName); void SendRfuStatusToPartner(u8 status, u16 trainerId, const u8 *name); u32 WaitSendRfuStatusToPartner(u16 trainerId, const u8 *name); diff --git a/include/union_room.h b/include/union_room.h index 51390c637..0e1fd6260 100644 --- a/include/union_room.h +++ b/include/union_room.h @@ -38,7 +38,7 @@ struct RfuPlayer struct RfuPlayerList { - struct RfuPlayer players[0]; // TODO: Should be size MAX_RFU_PLAYER_LIST_SIZE + struct RfuPlayer players[MAX_RFU_PLAYER_LIST_SIZE]; }; struct RfuIncomingPlayer @@ -49,7 +49,7 @@ struct RfuIncomingPlayer struct RfuIncomingPlayerList { - struct RfuIncomingPlayer players[0]; // TODO: Should be size MAX_RFU_PLAYERS + struct RfuIncomingPlayer players[MAX_RFU_PLAYERS]; }; struct WirelessLink_Leader From d055ebad83ed1dd97697a9b81155054e4721e76f Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 27 Oct 2022 14:36:40 -0400 Subject: [PATCH 10/12] Document item_case --- include/item.h | 6 +- include/strings.h | 4 +- include/tm_case.h | 22 +- src/berry_pouch.c | 16 +- src/data/items.json | 750 +++++++++++++------------- src/data/items.json.txt | 2 +- src/item.c | 12 +- src/item_menu.c | 26 +- src/item_use.c | 4 +- src/party_menu.c | 2 +- src/shop.c | 10 +- src/strings.c | 4 +- src/tm_case.c | 1105 +++++++++++++++++++++++---------------- 13 files changed, 1086 insertions(+), 877 deletions(-) diff --git a/include/item.h b/include/item.h index e58348a78..1271e0d00 100644 --- a/include/item.h +++ b/include/item.h @@ -14,7 +14,7 @@ struct Item u8 holdEffectParam; const u8 *description; u8 importance; - u8 exitsBagOnUse; + u8 registrability; u8 pocket; u8 type; // unused for balls ItemUseFunc fieldUseFunc; @@ -69,7 +69,7 @@ ItemUseFunc ItemId_GetFieldFunc(u16 itemId); u8 ItemId_GetBattleUsage(u16 itemId); ItemUseFunc ItemId_GetBattleFunc(u16 itemId); u8 ItemId_GetSecondaryId(u16 itemId); -u16 itemid_get_market_price(u16 itemId); +u16 ItemId_GetPrice(u16 itemId); void ClearBag(void); void ClearPCItemSlots(void); void TrySetObtainedItemQuestLogEvent(u16 itemId); @@ -79,7 +79,7 @@ void SortPocketAndPlaceHMsFirst(struct BagPocket * pocket); u16 BagGetItemIdByPocketPosition(u8 pocketId, u16 itemId); u16 BagGetQuantityByPocketPosition(u8 pocketId, u16 itemId); u16 BagGetQuantityByItemId(u16 item); -bool8 itemid_is_unique(u16 itemId); +u8 ItemId_GetImportance(u16 itemId); void BagPocketCompaction(struct ItemSlot * slots, u8 capacity); u16 GetPcItemQuantity(u16 *); void SetBagPocketsPointers(void); diff --git a/include/strings.h b/include/strings.h index 222ed935d..c6df3df91 100644 --- a/include/strings.h +++ b/include/strings.h @@ -103,8 +103,8 @@ extern const u8 gText_ItemCantBeHeld[]; extern const u8 gText_TMCase[]; extern const u8 gText_Close[]; extern const u8 gText_TMCaseWillBePutAway[]; -extern const u8 gText_FontSize0[]; -extern const u8 gText_FontSize2[]; +extern const u8 gText_Font0[]; +extern const u8 gText_Font2[]; extern const u8 gText_OhNoICantBuyThat[]; extern const u8 gText_HowManyWouldYouLikeToSell[]; extern const u8 gText_ICanPayThisMuch_WouldThatBeOkay[]; diff --git a/include/tm_case.h b/include/tm_case.h index 22fb021e0..b940596f2 100644 --- a/include/tm_case.h +++ b/include/tm_case.h @@ -1,17 +1,21 @@ #ifndef GUARD_TM_CASE_H #define GUARD_TM_CASE_H -enum TmCaseType -{ - TMCASE_FROMFIELD, - TMCASE_FROMPARTYGIVE, - TMCASE_FROMMARTSELL, - TMCASE_FROMPOKEMONSTORAGEPC, - TMCASE_FROMBATTLE, - TMCASE_NA +// Values for 'type' argument to InitTMCase +enum { + TMCASE_FIELD, + TMCASE_GIVE_PARTY, + TMCASE_SELL, + TMCASE_GIVE_PC, + TMCASE_POKEDUDE, + TMCASE_REOPENING, }; -void InitTMCase(u8 a0, void (* a1)(void), u8 a2); +// Alternative value for 'allowSelectClose' argument to InitTMCase. +// Indicates that the previous value should be preserved +#define TMCASE_KEEP_PREV 0xFF + +void InitTMCase(u8 type, void (* exitCallback)(void), bool8 allowSelectClose); void ResetTMCaseCursorPos(void); void Pokedude_InitTMCase(void); diff --git a/src/berry_pouch.c b/src/berry_pouch.c index b18e0cd4a..2baf367de 100644 --- a/src/berry_pouch.c +++ b/src/berry_pouch.c @@ -684,13 +684,13 @@ static void SetUpListMenuTemplate(void) static void GetBerryNameAndIndexForMenu(u8 * dest, u16 itemId) { - StringCopy(gStringVar4, gText_FontSize0); + StringCopy(gStringVar4, gText_Font0); StringAppend(gStringVar4, gText_NumberClear01); ConvertIntToDecimalStringN(gStringVar1, itemId - FIRST_BERRY_INDEX + 1, STR_CONV_MODE_LEADING_ZEROS, 2); StringAppend(gStringVar4, gStringVar1); CopyItemName(itemId, gStringVar1); StringAppend(gStringVar4, sText_Space); - StringAppend(gStringVar4, gText_FontSize2); + StringAppend(gStringVar4, gText_Font2); StringAppend(gStringVar4, gStringVar1); StringCopy(dest, gStringVar4); } @@ -1265,7 +1265,7 @@ static void Task_ContextMenu_FromPokemonPC(u8 taskId) static void Task_ContextMenu_Sell(u8 taskId) { s16 * data = gTasks[taskId].data; - if (itemid_get_market_price(gSpecialVar_ItemId) == 0) + if (ItemId_GetPrice(gSpecialVar_ItemId) == 0) { CopyItemName(gSpecialVar_ItemId, gStringVar1); StringExpandPlaceholders(gStringVar4, gText_OhNoICantBuyThat); @@ -1293,7 +1293,7 @@ static void Task_ContextMenu_Sell(u8 taskId) static void Task_AskSellMultiple(u8 taskId) { s16 * data = gTasks[taskId].data; - ConvertIntToDecimalStringN(gStringVar3, itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_BERRY_POUCH, data[1])) / 2 * data[8], STR_CONV_MODE_LEFT_ALIGN, 6); + ConvertIntToDecimalStringN(gStringVar3, ItemId_GetPrice(BagGetItemIdByPocketPosition(POCKET_BERRY_POUCH, data[1])) / 2 * data[8], STR_CONV_MODE_LEFT_ALIGN, 6); StringExpandPlaceholders(gStringVar4, gText_ICanPayThisMuch_WouldThatBeOkay); DisplayItemMessageInBerryPouch(taskId, GetDialogBoxFontId(), gStringVar4, Task_SellMultiple_CreateYesNoMenu); } @@ -1323,7 +1323,7 @@ static void Task_Sell_PrintSelectMultipleUI(u8 taskId) ConvertIntToDecimalStringN(gStringVar1, 1, STR_CONV_MODE_LEADING_ZEROS, 2); StringExpandPlaceholders(gStringVar4, gText_TimesStrVar1); BerryPouchPrint(windowId, FONT_0, gStringVar4, 4, 10, 1, 0, 0xFF, 1); - SellMultiple_UpdateSellPriceDisplay(itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_BERRY_POUCH, data[1])) / 2 * data[8]); + SellMultiple_UpdateSellPriceDisplay(ItemId_GetPrice(BagGetItemIdByPocketPosition(POCKET_BERRY_POUCH, data[1])) / 2 * data[8]); PrintMoneyInWin2(); CreateScrollIndicatorArrows_SellQuantity(); gTasks[taskId].func = Task_Sell_SelectMultiple; @@ -1340,7 +1340,7 @@ static void Task_Sell_SelectMultiple(u8 taskId) if (AdjustQuantityAccordingToDPadInput(&data[8], data[2]) == TRUE) { PrintxQuantityOnWindow(1, data[8], 2); - SellMultiple_UpdateSellPriceDisplay(itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_BERRY_POUCH, data[1])) / 2 * data[8]); + SellMultiple_UpdateSellPriceDisplay(ItemId_GetPrice(BagGetItemIdByPocketPosition(POCKET_BERRY_POUCH, data[1])) / 2 * data[8]); } else if (JOY_NEW(A_BUTTON)) { @@ -1373,7 +1373,7 @@ static void Task_SellYes(u8 taskId) PutWindowTilemap(0); ScheduleBgCopyTilemapToVram(0); CopyItemName(gSpecialVar_ItemId, gStringVar1); - ConvertIntToDecimalStringN(gStringVar3, itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_BERRY_POUCH, data[1])) / 2 * data[8], STR_CONV_MODE_LEFT_ALIGN, 6); + ConvertIntToDecimalStringN(gStringVar3, ItemId_GetPrice(BagGetItemIdByPocketPosition(POCKET_BERRY_POUCH, data[1])) / 2 * data[8], STR_CONV_MODE_LEFT_ALIGN, 6); StringExpandPlaceholders(gStringVar4, gText_TurnedOverItemsWorthYen); DisplayItemMessageInBerryPouch(taskId, FONT_2, gStringVar4, Task_SellBerries_PlaySfxAndRemoveBerries); } @@ -1383,7 +1383,7 @@ static void Task_SellBerries_PlaySfxAndRemoveBerries(u8 taskId) s16 * data = gTasks[taskId].data; PlaySE(SE_SHOP); RemoveBagItem(gSpecialVar_ItemId, data[8]); - AddMoney(&gSaveBlock1Ptr->money, itemid_get_market_price(gSpecialVar_ItemId) / 2 * data[8]); + AddMoney(&gSaveBlock1Ptr->money, ItemId_GetPrice(gSpecialVar_ItemId) / 2 * data[8]); RecordItemPurchase(gSpecialVar_ItemId, data[8], 2); DestroyListMenuTask(data[0], &sStaticCnt.listMenuScrollOffset, &sStaticCnt.listMenuSelectedRow); SortAndCountBerries(); diff --git a/src/data/items.json b/src/data/items.json index 9527febe7..25c9056ff 100644 --- a/src/data/items.json +++ b/src/data/items.json @@ -8,7 +8,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -24,7 +24,7 @@ "holdEffectParam": 0, "description_english": "The best BALL with the ultimate\\nperformance. It will catch any wild\\nPOKéMON without fail.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_POKE_BALLS", "type": 0, "fieldUseFunc": "NULL", @@ -40,7 +40,7 @@ "holdEffectParam": 0, "description_english": "A very high-grade BALL that offers\\na higher POKéMON catch rate than\\na GREAT BALL.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_POKE_BALLS", "type": 1, "fieldUseFunc": "NULL", @@ -56,7 +56,7 @@ "holdEffectParam": 0, "description_english": "A good, quality BALL that offers\\na higher POKéMON catch rate than\\na standard POKé BALL.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_POKE_BALLS", "type": 2, "fieldUseFunc": "NULL", @@ -72,7 +72,7 @@ "holdEffectParam": 0, "description_english": "A BALL thrown to catch a wild\\nPOKéMON. It is designed in a\\ncapsule style.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_POKE_BALLS", "type": 3, "fieldUseFunc": "NULL", @@ -88,7 +88,7 @@ "holdEffectParam": 0, "description_english": "A special BALL that is used only in\\nthe SAFARI ZONE. It is finished in\\na camouflage pattern.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_POKE_BALLS", "type": 4, "fieldUseFunc": "NULL", @@ -104,7 +104,7 @@ "holdEffectParam": 0, "description_english": "A somewhat different BALL that\\nworks especially well on WATER- and\\nBUG-type POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_POKE_BALLS", "type": 5, "fieldUseFunc": "NULL", @@ -120,7 +120,7 @@ "holdEffectParam": 0, "description_english": "A somewhat different BALL that\\nworks especially well on POKéMON\\ndeep in the sea.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_POKE_BALLS", "type": 6, "fieldUseFunc": "NULL", @@ -136,7 +136,7 @@ "holdEffectParam": 0, "description_english": "A somewhat different BALL that\\nworks especially well on weaker\\nPOKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_POKE_BALLS", "type": 7, "fieldUseFunc": "NULL", @@ -152,7 +152,7 @@ "holdEffectParam": 0, "description_english": "A somewhat different BALL that\\nworks especially well on POKéMON\\ncaught before.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_POKE_BALLS", "type": 8, "fieldUseFunc": "NULL", @@ -168,7 +168,7 @@ "holdEffectParam": 0, "description_english": "A somewhat different BALL that\\nbecomes progressively better the\\nmore turns there are in a battle.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_POKE_BALLS", "type": 9, "fieldUseFunc": "NULL", @@ -184,7 +184,7 @@ "holdEffectParam": 0, "description_english": "A comfortable BALL that makes a\\ncaptured wild POKéMON quickly grow\\nfriendly.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_POKE_BALLS", "type": 10, "fieldUseFunc": "NULL", @@ -200,7 +200,7 @@ "holdEffectParam": 0, "description_english": "A rare BALL that has been\\nspecially made to commemorate an\\nevent of some sort.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_POKE_BALLS", "type": 11, "fieldUseFunc": "NULL", @@ -216,7 +216,7 @@ "holdEffectParam": 20, "description_english": "A spray-type wound medicine.\\nIt restores the HP of one POKéMON\\nby 20 points.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -232,7 +232,7 @@ "holdEffectParam": 0, "description_english": "A spray-type medicine.\\nIt heals one POKéMON from a\\npoisoning.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -248,7 +248,7 @@ "holdEffectParam": 0, "description_english": "A spray-type medicine.\\nIt heals one POKéMON of a burn.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -264,7 +264,7 @@ "holdEffectParam": 0, "description_english": "A spray-type medicine.\\nIt defrosts a frozen POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -280,7 +280,7 @@ "holdEffectParam": 0, "description_english": "A spray-type medicine.\\nIt awakens a sleeping POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -296,7 +296,7 @@ "holdEffectParam": 0, "description_english": "A spray-type medicine.\\nIt heals one POKéMON from\\nparalysis.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -312,7 +312,7 @@ "holdEffectParam": 255, "description_english": "A medicine that fully restores the\\nHP and heals any status problems\\nof one POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -328,7 +328,7 @@ "holdEffectParam": 255, "description_english": "A spray-type wound medicine.\\nIt fully restores the HP of one\\nPOKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -344,7 +344,7 @@ "holdEffectParam": 200, "description_english": "A spray-type wound medicine.\\nIt restores the HP of one POKéMON\\nby 200 points.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -360,7 +360,7 @@ "holdEffectParam": 50, "description_english": "A spray-type wound medicine.\\nIt restores the HP of one POKéMON\\nby 50 points.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -376,7 +376,7 @@ "holdEffectParam": 0, "description_english": "A spray-type medicine.\\nIt heals all the status problems of\\none POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -392,7 +392,7 @@ "holdEffectParam": 0, "description_english": "A medicine that revives a fainted\\nPOKéMON, restoring HP by half the\\nmaximum amount.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -408,7 +408,7 @@ "holdEffectParam": 0, "description_english": "A medicine that revives a fainted\\nPOKéMON, restoring HP fully.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -424,7 +424,7 @@ "holdEffectParam": 50, "description_english": "Water with a high mineral content.\\nIt restores the HP of one POKéMON\\nby 50 points.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -440,7 +440,7 @@ "holdEffectParam": 60, "description_english": "A fizzy soda drink.\\nIt restores the HP of one POKéMON\\nby 60 points.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -456,7 +456,7 @@ "holdEffectParam": 80, "description_english": "A very sweet drink.\\nIt restores the HP of one POKéMON\\nby 80 points.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -472,7 +472,7 @@ "holdEffectParam": 100, "description_english": "Highly nutritious milk.\\nIt restores the HP of one POKéMON\\nby 100 points.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -488,7 +488,7 @@ "holdEffectParam": 0, "description_english": "A very bitter medicine powder.\\nIt restores the HP of one POKéMON\\nby 50 points.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -504,7 +504,7 @@ "holdEffectParam": 0, "description_english": "A very bitter root.\\nIt restores the HP of one POKéMON\\nby 200 points.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -520,7 +520,7 @@ "holdEffectParam": 0, "description_english": "A very bitter medicine powder.\\nIt heals all the status problems of\\none POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -536,7 +536,7 @@ "holdEffectParam": 0, "description_english": "A very bitter medicinal herb.\\nIt revives a fainted POKéMON,\\nrestoring HP fully.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -552,7 +552,7 @@ "holdEffectParam": 10, "description_english": "Restores a selected move's PP by\\n10 points for one POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Ether", @@ -568,7 +568,7 @@ "holdEffectParam": 255, "description_english": "Fully restores a selected move's PP\\nfor one POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Ether", @@ -584,7 +584,7 @@ "holdEffectParam": 10, "description_english": "Restores the PP of all moves for\\none POKéMON by 10 points each.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Ether", @@ -600,7 +600,7 @@ "holdEffectParam": 255, "description_english": "Fully restores the PP of all moves\\nfor one POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Ether", @@ -616,7 +616,7 @@ "holdEffectParam": 0, "description_english": "LAVARIDGE TOWN's local specialty.\\nIt heals all the status problems of\\none POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -632,7 +632,7 @@ "holdEffectParam": 0, "description_english": "A blue glass flute that awakens\\na sleeping POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -648,7 +648,7 @@ "holdEffectParam": 0, "description_english": "A yellow glass flute that snaps one\\nPOKéMON out of confusion.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -664,7 +664,7 @@ "holdEffectParam": 0, "description_english": "A red glass flute that snaps one\\nPOKéMON out of infatuation.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -680,7 +680,7 @@ "holdEffectParam": 50, "description_english": "A black glass flute.\\nWhen blown, it makes wild POKéMON\\nless likely to appear.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_BlackWhiteFlute", @@ -696,7 +696,7 @@ "holdEffectParam": 150, "description_english": "A white glass flute.\\nWhen blown, it makes wild POKéMON\\nmore likely to appear.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_BlackWhiteFlute", @@ -712,7 +712,7 @@ "holdEffectParam": 20, "description_english": "A 100% pure juice.\\nIt restores the HP of one POKéMON\\nby 20 points.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -728,7 +728,7 @@ "holdEffectParam": 0, "description_english": "Revives all fainted POKéMON,\\nrestoring HP fully.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_SacredAsh", @@ -744,7 +744,7 @@ "holdEffectParam": 0, "description_english": "Pure salt obtained from deep inside\\nthe SHOAL CAVE. It is extremely\\nsalty.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -760,7 +760,7 @@ "holdEffectParam": 0, "description_english": "A pretty seashell found deep inside\\nthe SHOAL CAVE. It is striped in\\nblue and white.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -776,7 +776,7 @@ "holdEffectParam": 0, "description_english": "A small red shard.\\nIt appears to be from some sort of\\na tool made long ago.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -792,7 +792,7 @@ "holdEffectParam": 0, "description_english": "A small blue shard.\\nIt appears to be from some sort of\\na tool made long ago.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -808,7 +808,7 @@ "holdEffectParam": 0, "description_english": "A small yellow shard.\\nIt appears to be from some sort of\\na tool made long ago.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -824,7 +824,7 @@ "holdEffectParam": 0, "description_english": "A small green shard.\\nIt appears to be from some sort of\\na tool made long ago.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -840,7 +840,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -856,7 +856,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -872,7 +872,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -888,7 +888,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -904,7 +904,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -920,7 +920,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -936,7 +936,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -952,7 +952,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -968,7 +968,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -984,7 +984,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1000,7 +1000,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1016,7 +1016,7 @@ "holdEffectParam": 0, "description_english": "A nutritious drink for POKéMON.\\nIt raises the base HP of one\\nPOKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -1032,7 +1032,7 @@ "holdEffectParam": 0, "description_english": "A nutritious drink for POKéMON.\\nIt raises the base ATTACK stat of\\none POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -1048,7 +1048,7 @@ "holdEffectParam": 0, "description_english": "A nutritious drink for POKéMON.\\nIt raises the base DEFENSE stat of\\none POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -1064,7 +1064,7 @@ "holdEffectParam": 0, "description_english": "A nutritious drink for POKéMON.\\nIt raises the base SPEED stat of\\none POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -1080,7 +1080,7 @@ "holdEffectParam": 0, "description_english": "A nutritious drink for POKéMON.\\nIt raises the base SP. ATK stat\\nof one POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -1096,7 +1096,7 @@ "holdEffectParam": 0, "description_english": "A candy that is packed with energy.\\nIt raises the level of a POKéMON\\nby one.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_RareCandy", @@ -1112,7 +1112,7 @@ "holdEffectParam": 0, "description_english": "Slightly raises the maximum PP of\\na selected move for one POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_PpUp", @@ -1128,7 +1128,7 @@ "holdEffectParam": 0, "description_english": "A nutritious drink for POKéMON.\\nIt raises the base SP. DEF stat\\nof one POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -1144,7 +1144,7 @@ "holdEffectParam": 0, "description_english": "Raises the PP of a selected move\\nto its maximum level for one\\nPOKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_PpUp", @@ -1160,7 +1160,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1176,7 +1176,7 @@ "holdEffectParam": 0, "description_english": "An item that prevents stat reduction\\namong party POKéMON for five turns\\nafter use.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1192,7 +1192,7 @@ "holdEffectParam": 0, "description_english": "Raises the critical-hit ratio of\\nPOKéMON in battle. Wears off if the\\nPOKéMON is withdrawn.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1208,7 +1208,7 @@ "holdEffectParam": 0, "description_english": "Raises the ATTACK stat of POKéMON\\nin battle. Wears off if the POKéMON\\nis withdrawn.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1224,7 +1224,7 @@ "holdEffectParam": 0, "description_english": "Raises the DEFENSE stat of POKéMON\\nin battle. Wears off if the POKéMON\\nis withdrawn.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1240,7 +1240,7 @@ "holdEffectParam": 0, "description_english": "Raises the SPEED stat of POKéMON\\nin battle. Wears off if the POKéMON\\nis withdrawn.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1256,7 +1256,7 @@ "holdEffectParam": 0, "description_english": "Raises the accuracy stat of\\nPOKéMON in battle. Wears off if the\\nPOKéMON is withdrawn.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1272,7 +1272,7 @@ "holdEffectParam": 0, "description_english": "Raises the SP. ATK stat of\\nPOKéMON in battle. Wears off if the\\nPOKéMON is withdrawn.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1288,7 +1288,7 @@ "holdEffectParam": 0, "description_english": "An attractive doll.\\nUse it to flee from any battle with\\na wild POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1304,7 +1304,7 @@ "holdEffectParam": 0, "description_english": "An attractive item.\\nUse it to flee from any battle with\\na wild POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1320,7 +1320,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1336,7 +1336,7 @@ "holdEffectParam": 200, "description_english": "Prevents weak wild POKéMON from\\nappearing for 200 steps.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_Repel", @@ -1352,7 +1352,7 @@ "holdEffectParam": 250, "description_english": "Prevents weak wild POKéMON from\\nappearing for 250 steps.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_Repel", @@ -1368,7 +1368,7 @@ "holdEffectParam": 0, "description_english": "A long, durable rope.\\nUse it to escape instantly from a\\ncave or a dungeon.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_FIELD", "fieldUseFunc": "ItemUseOutOfBattle_EscapeRope", @@ -1384,7 +1384,7 @@ "holdEffectParam": 100, "description_english": "Prevents weak wild POKéMON from\\nappearing for 100 steps.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_Repel", @@ -1400,7 +1400,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1416,7 +1416,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1432,7 +1432,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1448,7 +1448,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1464,7 +1464,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1480,7 +1480,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1496,7 +1496,7 @@ "holdEffectParam": 0, "description_english": "A peculiar stone that makes certain\\nspecies of POKéMON evolve.\\nIt is as red as the sun.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_EvoItem", @@ -1512,7 +1512,7 @@ "holdEffectParam": 0, "description_english": "A peculiar stone that makes certain\\nspecies of POKéMON evolve.\\nIt is as black as the night sky.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_EvoItem", @@ -1528,7 +1528,7 @@ "holdEffectParam": 0, "description_english": "A peculiar stone that makes certain\\nspecies of POKéMON evolve.\\nIt is colored orange.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_EvoItem", @@ -1544,7 +1544,7 @@ "holdEffectParam": 0, "description_english": "A peculiar stone that makes certain\\nspecies of POKéMON evolve.\\nIt has a thunderbolt pattern.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_EvoItem", @@ -1560,7 +1560,7 @@ "holdEffectParam": 0, "description_english": "A peculiar stone that makes certain\\nspecies of POKéMON evolve.\\nIt is a clear light blue.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_EvoItem", @@ -1576,7 +1576,7 @@ "holdEffectParam": 0, "description_english": "A peculiar stone that makes certain\\nspecies of POKéMON evolve.\\nIt has a leaf pattern.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_EvoItem", @@ -1592,7 +1592,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1608,7 +1608,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1624,7 +1624,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1640,7 +1640,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1656,7 +1656,7 @@ "holdEffectParam": 0, "description_english": "A small and rare mushroom.\\nIt is quite popular among certain\\npeople.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1672,7 +1672,7 @@ "holdEffectParam": 0, "description_english": "A large and rare mushroom.\\nIt is very popular among certain\\npeople.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1688,7 +1688,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1704,7 +1704,7 @@ "holdEffectParam": 0, "description_english": "A relatively small pearl that\\nsparkles in a pretty silver color.\\nIt can be sold cheaply.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1720,7 +1720,7 @@ "holdEffectParam": 0, "description_english": "A quite-large pearl that sparkles\\nin a pretty silver color.\\nIt can be sold at a high price.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1736,7 +1736,7 @@ "holdEffectParam": 0, "description_english": "A pretty red sand with a loose,\\nsilky feel.\\nIt can be sold at a high price.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1752,7 +1752,7 @@ "holdEffectParam": 0, "description_english": "A shard of a pretty gem that\\nsparkles in a red color.\\nIt can be sold at a high price.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1768,7 +1768,7 @@ "holdEffectParam": 0, "description_english": "A nugget of pure gold that gives\\noff a lustrous gleam.\\nIt can be sold at a high price.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1784,7 +1784,7 @@ "holdEffectParam": 0, "description_english": "A pretty, heart-shaped scale that\\nis extremely rare. It glows faintly\\nin the colors of a rainbow.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1800,7 +1800,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1816,7 +1816,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1832,7 +1832,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1848,7 +1848,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1864,7 +1864,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1880,7 +1880,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1896,7 +1896,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1912,7 +1912,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1928,7 +1928,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -1944,7 +1944,7 @@ "holdEffectParam": 0, "description_english": "A piece of MAIL featuring a cute\\nZIGZAGOON print.\\nIt is to be held by a POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_MAIL", "fieldUseFunc": "FieldUseFunc_Mail", @@ -1960,7 +1960,7 @@ "holdEffectParam": 0, "description_english": "A piece of MAIL featuring a cute\\nWINGULL print.\\nIt is to be held by a POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_MAIL", "fieldUseFunc": "FieldUseFunc_Mail", @@ -1976,7 +1976,7 @@ "holdEffectParam": 0, "description_english": "A piece of MAIL featuring a cute\\nPIKACHU print.\\nIt is to be held by a POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_MAIL", "fieldUseFunc": "FieldUseFunc_Mail", @@ -1992,7 +1992,7 @@ "holdEffectParam": 0, "description_english": "A piece of MAIL featuring a cute\\nMAGNEMITE print.\\nIt is to be held by a POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_MAIL", "fieldUseFunc": "FieldUseFunc_Mail", @@ -2008,7 +2008,7 @@ "holdEffectParam": 0, "description_english": "A piece of MAIL featuring a cute\\nSLAKOTH print.\\nIt is to be held by a POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_MAIL", "fieldUseFunc": "FieldUseFunc_Mail", @@ -2024,7 +2024,7 @@ "holdEffectParam": 0, "description_english": "A piece of MAIL featuring a cute\\nWAILMER print.\\nIt is to be held by a POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_MAIL", "fieldUseFunc": "FieldUseFunc_Mail", @@ -2040,7 +2040,7 @@ "holdEffectParam": 0, "description_english": "A piece of MAIL to be held by a\\nPOKéMON. It will bear the print of\\nthe POKéMON holding it.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_MAIL", "fieldUseFunc": "FieldUseFunc_Mail", @@ -2056,7 +2056,7 @@ "holdEffectParam": 0, "description_english": "A piece of MAIL featuring a cute\\nDUSKULL print.\\nIt is to be held by a POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_MAIL", "fieldUseFunc": "FieldUseFunc_Mail", @@ -2072,7 +2072,7 @@ "holdEffectParam": 0, "description_english": "A piece of MAIL featuring a cute\\nBELLOSSOM print.\\nIt is to be held by a POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_MAIL", "fieldUseFunc": "FieldUseFunc_Mail", @@ -2088,7 +2088,7 @@ "holdEffectParam": 0, "description_english": "A piece of MAIL to be held by a\\nPOKéMON. It will bear the print of\\nthe POKéMON holding it.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_MAIL", "fieldUseFunc": "FieldUseFunc_Mail", @@ -2104,7 +2104,7 @@ "holdEffectParam": 0, "description_english": "A piece of MAIL featuring a\\ngorgeous, extravagant print.\\nIt is to be held by a POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_MAIL", "fieldUseFunc": "FieldUseFunc_Mail", @@ -2120,7 +2120,7 @@ "holdEffectParam": 0, "description_english": "A piece of MAIL featuring a print\\nof three cute POKéMON.\\nIt is to be held by a POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_MAIL", "fieldUseFunc": "FieldUseFunc_Mail", @@ -2136,7 +2136,7 @@ "holdEffectParam": 0, "description_english": "When held by a POKéMON, it will be\\nused in battle to heal paralysis.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -2152,7 +2152,7 @@ "holdEffectParam": 0, "description_english": "When held by a POKéMON, it will be\\nused in battle to wake up.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -2168,7 +2168,7 @@ "holdEffectParam": 0, "description_english": "When held by a POKéMON, it will be\\nused in battle to cure poison.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -2184,7 +2184,7 @@ "holdEffectParam": 0, "description_english": "When held by a POKéMON, it will be\\nused in battle to heal a burn.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -2200,7 +2200,7 @@ "holdEffectParam": 0, "description_english": "When held by a POKéMON, it will be\\nused in battle for defrosting.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -2216,7 +2216,7 @@ "holdEffectParam": 10, "description_english": "When held by a POKéMON, it will be\\nused in battle to restore 10 PP.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Ether", @@ -2232,7 +2232,7 @@ "holdEffectParam": 10, "description_english": "When held by a POKéMON, it will be\\nused in battle to restore 10 HP.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -2248,7 +2248,7 @@ "holdEffectParam": 0, "description_english": "When held by a POKéMON, it will be\\nused in battle to lift confusion.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2264,7 +2264,7 @@ "holdEffectParam": 0, "description_english": "When held by a POKéMON, it will be\\nused in battle to heal any problem.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -2280,7 +2280,7 @@ "holdEffectParam": 30, "description_english": "When held by a POKéMON, it will be\\nused in battle to restore 30 HP.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "FieldUseFunc_Medicine", @@ -2296,7 +2296,7 @@ "holdEffectParam": 8, "description_english": "A hold item that restores HP but\\nmay cause confusion when used.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2312,7 +2312,7 @@ "holdEffectParam": 8, "description_english": "A hold item that restores HP but\\nmay cause confusion when used.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2328,7 +2328,7 @@ "holdEffectParam": 8, "description_english": "A hold item that restores HP but\\nmay cause confusion when used.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2344,7 +2344,7 @@ "holdEffectParam": 8, "description_english": "A hold item that restores HP but\\nmay cause confusion when used.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2360,7 +2360,7 @@ "holdEffectParam": 8, "description_english": "A hold item that restores HP but\\nmay cause confusion when used.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2376,7 +2376,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2392,7 +2392,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2408,7 +2408,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2424,7 +2424,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2440,7 +2440,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2456,7 +2456,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2472,7 +2472,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2488,7 +2488,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2504,7 +2504,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2520,7 +2520,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2536,7 +2536,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2552,7 +2552,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2568,7 +2568,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2584,7 +2584,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2600,7 +2600,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2616,7 +2616,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2632,7 +2632,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2648,7 +2648,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2664,7 +2664,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2680,7 +2680,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2696,7 +2696,7 @@ "holdEffectParam": 4, "description_english": "When held by a POKéMON, it raises\\nthe ATTACK stat in a pinch.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2712,7 +2712,7 @@ "holdEffectParam": 4, "description_english": "When held by a POKéMON, it raises\\nthe DEFENSE stat in a pinch.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2728,7 +2728,7 @@ "holdEffectParam": 4, "description_english": "When held by a POKéMON, it raises\\nthe SPEED stat in a pinch.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2744,7 +2744,7 @@ "holdEffectParam": 4, "description_english": "When held by a POKéMON, it raises\\nthe SP. ATK stat in a pinch.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2760,7 +2760,7 @@ "holdEffectParam": 4, "description_english": "When held by a POKéMON, it raises\\nthe SP. DEF stat in a pinch.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2776,7 +2776,7 @@ "holdEffectParam": 4, "description_english": "When held by a POKéMON, it raises\\nthe critical-hit ratio in a pinch.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2792,7 +2792,7 @@ "holdEffectParam": 4, "description_english": "When held by a POKéMON, it sharply\\nraises one stat in a pinch.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2808,7 +2808,7 @@ "holdEffectParam": 0, "description_english": "Can be ground up into a powder as\\nan ingredient for medicine.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_BERRY_POUCH", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "ItemUseOutOfBattle_EnigmaBerry", @@ -2824,7 +2824,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2840,7 +2840,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2856,7 +2856,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2872,7 +2872,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nIt casts a tricky glare that lowers\\nthe opponent's accuracy.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2888,7 +2888,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nIt restores any lowered stat in\\nbattle. It can be used only once.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2904,7 +2904,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nIt promotes strong growth but\\nlowers SPEED while it is held.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2920,7 +2920,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nThe holder gets a share of EXP.\\npoints without having to battle.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2936,7 +2936,7 @@ "holdEffectParam": 20, "description_english": "An item to be held by a POKéMON.\\nA light and sharp claw. The holder\\nmay be able to strike first.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2952,7 +2952,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nA bell with a comforting chime that\\nmakes the holder calm and friendly.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2968,7 +2968,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nIt snaps the holder out of\\ninfatuation. It can be used once.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -2984,7 +2984,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nIt powers up one move, which\\nbecomes the only usable one.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3000,7 +3000,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nIt may cause the foe to flinch\\nupon taking damage.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3016,7 +3016,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA shiny silver powder that boosts\\nthe power of BUG-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3032,7 +3032,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nIt doubles the battle money if the\\nholding POKéMON takes part.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3048,7 +3048,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nIt repels wild POKéMON if the\\nholder is first in the party.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3064,7 +3064,7 @@ "holdEffectParam": 0, "description_english": "An orb to be held by a LATIOS or\\nLATIAS. It raises the SP. ATK\\nand SP. DEF stats.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3080,7 +3080,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nA fang that gleams a sharp silver.\\nIt raises the SP. ATK stat.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3096,7 +3096,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nA scale that shines a faint pink.\\nIt raises the SP. DEF stat.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3112,7 +3112,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nThe holding POKéMON can flee from\\nany wild POKéMON for sure.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3128,7 +3128,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nThe holding POKéMON is prevented\\nfrom evolving.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3144,7 +3144,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nThe holding POKéMON may endure an\\nattack, leaving just 1 HP.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3160,7 +3160,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nAn egg filled with happiness that\\nearns extra EXP. points in battle.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3176,7 +3176,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nA lens that boosts the critical-hit\\nratio of the holding POKéMON.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3192,7 +3192,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA special metallic film that boosts\\nthe power of STEEL-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3208,7 +3208,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nThe holding POKéMON gradually\\nregains HP during battle.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3224,7 +3224,7 @@ "holdEffectParam": 10, "description_english": "A thick and tough scale.\\nA DRAGON-type POKéMON may be\\nholding it.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3240,7 +3240,7 @@ "holdEffectParam": 0, "description_english": "An orb to be held by a PIKACHU\\nthat raises the SP. ATK stat.\\nTouching it may cause a shock.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3256,7 +3256,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA loose, silky sand that boosts the\\npower of GROUND-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3272,7 +3272,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nAn unbreakable stone that boosts\\nthe power of ROCK-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3288,7 +3288,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA seed imbued with life that boosts\\nthe power of GRASS-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3304,7 +3304,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA shady-looking pair of glasses\\nthat boosts DARK-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3320,7 +3320,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA belt that boosts determination\\nand FIGHTING-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3336,7 +3336,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA powerful magnet that boosts the\\npower of ELECTRIC-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3352,7 +3352,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA teardrop-shaped gem that boosts\\nthe power of WATER-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3368,7 +3368,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA long, sharp beak that boosts the\\npower of FLYING-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3384,7 +3384,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA small, poisonous barb that boosts\\nthe power of POISON-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3400,7 +3400,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA piece of ice that repels heat\\nand boosts ICE-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3416,7 +3416,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA sinister, eerie tag that boosts\\nGHOST-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3432,7 +3432,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA spoon imbued with telekinetic\\npower boosts PSYCHIC-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3448,7 +3448,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA combustible fuel that boosts the\\npower of FIRE-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3464,7 +3464,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA hard and sharp fang that boosts\\nthe power of DRAGON-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3480,7 +3480,7 @@ "holdEffectParam": 10, "description_english": "An item to be held by a POKéMON.\\nA sumptuous scarf that boosts the\\npower of NORMAL-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3496,7 +3496,7 @@ "holdEffectParam": 0, "description_english": "A transparent device filled with all\\nsorts of data.\\nIt is made by SILPH CO.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3512,7 +3512,7 @@ "holdEffectParam": 8, "description_english": "An item to be held by a POKéMON.\\nThe holding POKéMON regains some\\nHP upon striking the foe.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3528,7 +3528,7 @@ "holdEffectParam": 5, "description_english": "An item to be held by a POKéMON.\\nIt slightly boosts the power of\\nWATER-type moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3544,7 +3544,7 @@ "holdEffectParam": 5, "description_english": "An item to be held by a POKéMON.\\nIts tricky aroma slightly reduces\\nthe foe's accuracy.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3560,7 +3560,7 @@ "holdEffectParam": 0, "description_english": "A glove to be held by a CHANSEY.\\nIt raises CHANSEY's critical-hit\\nratio.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3576,7 +3576,7 @@ "holdEffectParam": 0, "description_english": "A fine, hard powder to be held by\\na DITTO.\\nIt raises DITTO's DEFENSE stat.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3592,7 +3592,7 @@ "holdEffectParam": 0, "description_english": "A hard bone of some sort to be\\nheld by a CUBONE or MAROWAK.\\nIt raises the ATTACK stat.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3608,7 +3608,7 @@ "holdEffectParam": 0, "description_english": "A stick of leek to be held by a\\nFARFETCH'D. It raises FARFETCH'D's\\ncritical-hit ratio.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3624,7 +3624,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3640,7 +3640,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3656,7 +3656,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3672,7 +3672,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3688,7 +3688,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3704,7 +3704,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3720,7 +3720,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3736,7 +3736,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3752,7 +3752,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3768,7 +3768,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3784,7 +3784,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3800,7 +3800,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3816,7 +3816,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3832,7 +3832,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3848,7 +3848,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3864,7 +3864,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3880,7 +3880,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3896,7 +3896,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3912,7 +3912,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3928,7 +3928,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3944,7 +3944,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3960,7 +3960,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3976,7 +3976,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -3992,7 +3992,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4008,7 +4008,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4024,7 +4024,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4040,7 +4040,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4056,7 +4056,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4072,7 +4072,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nIt boosts the holding POKéMON's\\nCOOL condition in CONTESTS.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4088,7 +4088,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nIt boosts the holding POKéMON's\\nBEAUTY condition in CONTESTS.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4104,7 +4104,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nIt boosts the holding POKéMON's\\nCUTE condition in CONTESTS.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4120,7 +4120,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nIt boosts the holding POKéMON's\\nSMART condition in CONTESTS.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4136,7 +4136,7 @@ "holdEffectParam": 0, "description_english": "An item to be held by a POKéMON.\\nIt boosts the holding POKéMON's\\nTOUGH condition in CONTESTS.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4152,7 +4152,7 @@ "holdEffectParam": 0, "description_english": "A folding bicycle that is at least\\ntwice as fast as walking.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_FIELD", "fieldUseFunc": "FieldUseFunc_Bike", @@ -4168,7 +4168,7 @@ "holdEffectParam": 0, "description_english": "A case for holding COINS obtained\\nat the GAME CORNER.\\nIt holds up to 9,999 COINS.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_CoinCase", @@ -4184,7 +4184,7 @@ "holdEffectParam": 0, "description_english": "A device used for finding items.\\nIf there is a hidden item nearby\\nwhen it is used, it emits a signal.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_FIELD", "fieldUseFunc": "ItemUseOutOfBattle_Itemfinder", @@ -4200,7 +4200,7 @@ "holdEffectParam": 0, "description_english": "An old and beat-up fishing rod.\\nUse it by any body of water to \\nfish for wild POKéMON.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_FIELD", "fieldUseFunc": "FieldUseFunc_Rod", @@ -4216,7 +4216,7 @@ "holdEffectParam": 0, "description_english": "A new, good-quality fishing rod.\\nUse it by any body of water to \\nfish for wild POKéMON.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_FIELD", "fieldUseFunc": "FieldUseFunc_Rod", @@ -4232,7 +4232,7 @@ "holdEffectParam": 0, "description_english": "An awesome, high-tech fishing rod.\\nUse it by any body of water to fish\\nfor wild POKéMON.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_FIELD", "fieldUseFunc": "FieldUseFunc_Rod", @@ -4248,7 +4248,7 @@ "holdEffectParam": 0, "description_english": "The ticket required for sailing on\\nthe ferry S.S. ANNE.\\nIt has a drawing of a ship on it.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4264,7 +4264,7 @@ "holdEffectParam": 0, "description_english": "The pass required for entering\\nPOKéMON CONTESTS. It has a\\ndrawing of an award ribbon on it.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4280,7 +4280,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4296,7 +4296,7 @@ "holdEffectParam": 0, "description_english": "A nifty watering pail.\\nUse it to promote strong growth in\\nBERRIES planted in soft soil.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4312,7 +4312,7 @@ "holdEffectParam": 0, "description_english": "A package that contains mechanical\\nparts of some sort made by the\\nDEVON CORPORATION.", "importance": 2, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4328,7 +4328,7 @@ "holdEffectParam": 0, "description_english": "A sack used to collect volcanic\\nash automatically during walks\\nover deep ash.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4344,7 +4344,7 @@ "holdEffectParam": 0, "description_english": "The key to NEW MAUVILLE, which\\nwas constructed beneath MAUVILLE\\nCITY.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4360,7 +4360,7 @@ "holdEffectParam": 0, "description_english": "A folding bicycle that is capable\\nof stunts like jumps and wheelies.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_FIELD", "fieldUseFunc": "FieldUseFunc_Bike", @@ -4376,7 +4376,7 @@ "holdEffectParam": 0, "description_english": "A case for holding {POKEBLOCK}S made\\nwith a BERRY BLENDER. It releases\\none {POKEBLOCK} when shaken.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4392,7 +4392,7 @@ "holdEffectParam": 0, "description_english": "An extremely important letter to\\nSTEVEN from the PRESIDENT of the\\nDEVON CORPORATION.", "importance": 2, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4408,7 +4408,7 @@ "holdEffectParam": 0, "description_english": "The ticket required for sailing on a\\nferry to a distant southern island.\\nIt features a drawing of an island.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4424,7 +4424,7 @@ "holdEffectParam": 0, "description_english": "An orb that glows red.\\nIt is said to contain an incredible\\npower from ancient times.", "importance": 2, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4440,7 +4440,7 @@ "holdEffectParam": 0, "description_english": "An orb that glows blue.\\nIt is said to contain an incredible\\npower from ancient times.", "importance": 2, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4456,7 +4456,7 @@ "holdEffectParam": 0, "description_english": "A device used to search for\\nlife-forms in water.\\nIt looks too difficult to use.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4472,7 +4472,7 @@ "holdEffectParam": 0, "description_english": "A pair of protective goggles.\\nThey enable a TRAINER to travel\\nthrough even desert sandstorms.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4488,7 +4488,7 @@ "holdEffectParam": 0, "description_english": "A meteorite that fell from space\\nonto MT. MOON long ago.\\nIt is very lumpy and hard.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4504,7 +4504,7 @@ "holdEffectParam": 0, "description_english": "A key that opens the door to Room\\n1 inside the ABANDONED SHIP.\\nIt is old and looks easily broken.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4520,7 +4520,7 @@ "holdEffectParam": 0, "description_english": "A key that opens the door to Room\\n2 inside the ABANDONED SHIP.\\nIt is old and looks easily broken.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4536,7 +4536,7 @@ "holdEffectParam": 0, "description_english": "A key that opens the door to Room\\n4 inside the ABANDONED SHIP.\\nIt is old and looks easily broken.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4552,7 +4552,7 @@ "holdEffectParam": 0, "description_english": "A key that opens the door to Room\\n6 inside the ABANDONED SHIP.\\nIt is old and looks easily broken.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4568,7 +4568,7 @@ "holdEffectParam": 0, "description_english": "A key that opens the storage hold\\ninside the ABANDONED SHIP.\\nIt is old and looks easily broken.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4584,7 +4584,7 @@ "holdEffectParam": 0, "description_english": "A fossil of an ancient, seafloor-\\ndwelling POKéMON. It appears to be\\npart of a plant root.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4600,7 +4600,7 @@ "holdEffectParam": 0, "description_english": "A fossil of an ancient, seafloor-\\ndwelling POKéMON. It appears to be\\npart of a claw.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4616,7 +4616,7 @@ "holdEffectParam": 0, "description_english": "A scope that signals the presence\\nof any unseeable POKéMON.\\nIt is made by the DEVON CORP.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -4632,7 +4632,7 @@ "holdEffectParam": 0, "description_english": "An extremely powerful attack.\\nHowever, if the user is hit before\\nusing the move, they will flinch.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4649,7 +4649,7 @@ "holdEffectParam": 0, "description_english": "Sharp, huge claws hook and slash\\nthe foe quickly and with great\\npower.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4666,7 +4666,7 @@ "holdEffectParam": 0, "description_english": "The foe is hit with a pulsing blast\\nof water. It may also confuse the\\ntarget.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4683,7 +4683,7 @@ "holdEffectParam": 0, "description_english": "The user calms its spirit and\\nfocuses its mind to raise its\\nSP. ATK and SP. DEF stats.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4700,7 +4700,7 @@ "holdEffectParam": 0, "description_english": "A savage roar that causes the foe\\nto switch out of battle. In the\\nwild, ROAR ends the battle.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4717,7 +4717,7 @@ "holdEffectParam": 0, "description_english": "A move that leaves the foe badly\\npoisoned. Its poison damage worsens\\nevery turn.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4734,7 +4734,7 @@ "holdEffectParam": 0, "description_english": "Summons a hailstorm that lasts for\\nfive turns. The hailstorm damages\\nall types except the ICE type.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4751,7 +4751,7 @@ "holdEffectParam": 0, "description_english": "The user tightens all its muscles\\nand bulks up, boosting both its\\nATTACK and DEFENSE stats.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4768,7 +4768,7 @@ "holdEffectParam": 0, "description_english": "The user shoots seeds at the foe\\nin rapid succession. Two to five\\nseeds are shot at once.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4785,7 +4785,7 @@ "holdEffectParam": 0, "description_english": "A variable move that changes type\\nand power depending on the POKéMON\\nusing it.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4802,7 +4802,7 @@ "holdEffectParam": 0, "description_english": "The weather is turned sunny for\\nfive turns. Over that time, FIRE-\\ntype moves are powered up.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4819,7 +4819,7 @@ "holdEffectParam": 0, "description_english": "A taunted foe may become enraged.\\nIt will then only be able to use\\nattack moves.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4836,7 +4836,7 @@ "holdEffectParam": 0, "description_english": "An icy-cold beam is shot at the\\nfoe. It may leave the target\\nfrozen.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4853,7 +4853,7 @@ "holdEffectParam": 0, "description_english": "A vicious snow-and-wind attack that\\nstrikes all foes in battle. It may\\ncause freezing.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4870,7 +4870,7 @@ "holdEffectParam": 0, "description_english": "A harsh attack that inflicts severe\\ndamage on the foe. However, the\\nuser must rest the next turn.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4887,7 +4887,7 @@ "holdEffectParam": 0, "description_english": "A wall of light is created over\\nfive turns. It reduces damage from\\nSP. ATK attacks.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4904,7 +4904,7 @@ "holdEffectParam": 0, "description_english": "The user is completely protected\\nfrom attack in the turn it is used.\\nIt may fail if used in succession.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4921,7 +4921,7 @@ "holdEffectParam": 0, "description_english": "A heavy rain is summoned for five\\nturns. Over that time, WATER-type\\nmoves are powered up.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4938,7 +4938,7 @@ "holdEffectParam": 0, "description_english": "The user strikes the foe with\\ntentacles or roots, stealing the\\ntarget's HP and healing itself.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4955,7 +4955,7 @@ "holdEffectParam": 0, "description_english": "Protects the party with a shield\\nagainst all status problems over\\nfive turns.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4972,7 +4972,7 @@ "holdEffectParam": 0, "description_english": "This attack move grows more\\npowerful the more the POKéMON\\ndislikes its TRAINER.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -4989,7 +4989,7 @@ "holdEffectParam": 0, "description_english": "A 2-turn attack that uses the first\\nturn for absorbing sunlight, then\\nblasting the foe in the next turn.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5006,7 +5006,7 @@ "holdEffectParam": 0, "description_english": "The foe is slammed with a sturdy\\ntail of steel. It may lower the\\ntarget's DEFENSE stat.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5023,7 +5023,7 @@ "holdEffectParam": 0, "description_english": "A massive jolt of electricity is\\nlaunched at the foe. It may cause\\nparalysis.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5040,7 +5040,7 @@ "holdEffectParam": 0, "description_english": "Strikes the foe with a huge\\nthunderbolt. It may cause\\nparalysis.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5057,7 +5057,7 @@ "holdEffectParam": 0, "description_english": "Causes an earthquake that strikes\\nall POKéMON in battle, excluding\\nthe user.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5074,7 +5074,7 @@ "holdEffectParam": 0, "description_english": "This attack move grows more\\npowerful the more the POKéMON\\nlikes its TRAINER.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5091,7 +5091,7 @@ "holdEffectParam": 0, "description_english": "A 2-turn attack in which the user\\ndigs underground, then strikes.\\nIt can be used to exit dungeons.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5108,7 +5108,7 @@ "holdEffectParam": 0, "description_english": "A powerful blast of telekinetic\\nenergy strikes the foe. It may\\nlower the target's SP. DEF stat.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5125,7 +5125,7 @@ "holdEffectParam": 0, "description_english": "The foe is attacked with a shadowy\\nlump. It may lower the target's\\nSP. DEF stat.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5142,7 +5142,7 @@ "holdEffectParam": 0, "description_english": "Strikes the foe with a rock-hard\\nfist, etc. It shatters barriers such\\nas REFLECT and LIGHT SCREEN.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5159,7 +5159,7 @@ "holdEffectParam": 0, "description_english": "The user begins moving so quickly\\nthat it creates illusory copies to\\nraise its evasiveness.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5176,7 +5176,7 @@ "holdEffectParam": 0, "description_english": "A tough barrier is put up over five\\nturns. It reduces damage from\\nphysical attacks over that time.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5193,7 +5193,7 @@ "holdEffectParam": 0, "description_english": "A rapid jolt of electricity strikes\\nthe foe. This attack is impossible\\nto evade.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5210,7 +5210,7 @@ "holdEffectParam": 0, "description_english": "The foe is roasted with a heavy\\nblast of fire. It may leave the\\ntarget with a burn.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5227,7 +5227,7 @@ "holdEffectParam": 0, "description_english": "Toxic sludge is hurled at the foe\\nwith great force. It may also\\npoison the target.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5244,7 +5244,7 @@ "holdEffectParam": 0, "description_english": "Summons a sandstorm that lasts for\\nfive turns. It damages all types\\nexcept ROCK, GROUND, and STEEL.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5261,7 +5261,7 @@ "holdEffectParam": 0, "description_english": "The foe is incinerated with an\\nintense flame. It may leave the\\ntarget with a burn.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5278,7 +5278,7 @@ "holdEffectParam": 0, "description_english": "Boulders are hurled at the foe.\\nIt also lowers the target's SPEED\\nstat if it hits.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5295,7 +5295,7 @@ "holdEffectParam": 0, "description_english": "An extremely fast attack against\\none target. It is impossible to\\nevade.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5312,7 +5312,7 @@ "holdEffectParam": 0, "description_english": "If enraged by this move, the target\\nbecomes incapable of using the same\\nmove twice in a row.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5329,7 +5329,7 @@ "holdEffectParam": 0, "description_english": "An attack move that becomes very\\npowerful if the user is poisoned,\\nburned, or paralyzed.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5346,7 +5346,7 @@ "holdEffectParam": 0, "description_english": "An attack move that may have an\\nadditional effect depending on the\\nbattle terrain.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5363,7 +5363,7 @@ "holdEffectParam": 0, "description_english": "A move that makes the user fall\\nasleep over two turns to restore HP\\nand heal any status problems.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5380,7 +5380,7 @@ "holdEffectParam": 0, "description_english": "The foe, if it is the opposite\\ngender as the user, becomes\\ninfatuated and may not attack.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5397,7 +5397,7 @@ "holdEffectParam": 0, "description_english": "An attack that gives the user an\\nopportunity to steal the foe's hold\\nitem.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5414,7 +5414,7 @@ "holdEffectParam": 0, "description_english": "The foe is struck with steel-hard\\nwings. It may also raise the user's\\nDEFENSE stat.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5431,7 +5431,7 @@ "holdEffectParam": 0, "description_english": "A special power is transmitted to\\nthe foe, causing it to switch\\nabilities with the user.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5448,7 +5448,7 @@ "holdEffectParam": 0, "description_english": "A move that steals the effects of\\nany status-changing or healing move\\nthat the foe tries to use.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5465,7 +5465,7 @@ "holdEffectParam": 0, "description_english": "A maximum-power attack of great\\nferocity, but one that also sharply\\nreduces the user's SP. ATK stat.", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5482,7 +5482,7 @@ "holdEffectParam": 0, "description_english": "Attacks the foe with sharp blades\\nor claws. It can also cut down thin\\ntrees and grass outside of battle.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5499,7 +5499,7 @@ "holdEffectParam": 0, "description_english": "The user flies up on the first turn,\\nthen attacks next turn. It can be\\nused to fly to any known town.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5516,7 +5516,7 @@ "holdEffectParam": 0, "description_english": "Creates a huge wave, then crashes\\nit down on the foe. It can be used\\nfor traveling on water.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5533,7 +5533,7 @@ "holdEffectParam": 0, "description_english": "The user builds enormous power,\\nthen slams the foe. It can be used\\nfor moving large, round boulders.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5550,7 +5550,7 @@ "holdEffectParam": 0, "description_english": "Looses a powerful blast of light\\nthat reduces the foe's accuracy.\\nIt also lights up dark caves.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5567,7 +5567,7 @@ "holdEffectParam": 0, "description_english": "Hits the foe with a rock-crushingly\\ntough attack. It can smash cracked\\nboulders.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5584,7 +5584,7 @@ "holdEffectParam": 0, "description_english": "A powerful charge attack. It can\\nbe used for climbing a torrential\\nwaterfall.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5601,7 +5601,7 @@ "holdEffectParam": 0, "description_english": "A 2-turn attack in which the user\\ndives underwater on the first turn,\\nthen strikes in the next turn.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_TM_CASE", "type": "ITEM_TYPE_PARTY_MENU", "fieldUseFunc": "NULL", @@ -5618,7 +5618,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5634,7 +5634,7 @@ "holdEffectParam": 0, "description_english": "?????", "importance": 0, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5650,7 +5650,7 @@ "holdEffectParam": 0, "description_english": "A parcel to be delivered to PROF.\\nOAK from VIRIDIAN CITY's POKéMON\\nMART.", "importance": 2, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5666,7 +5666,7 @@ "holdEffectParam": 0, "description_english": "A flute that is said to instantly\\nawaken any POKéMON. It has a\\nlovely tone.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_PokeFlute", @@ -5682,7 +5682,7 @@ "holdEffectParam": 0, "description_english": "The key to CINNABAR ISLAND GYM's\\nfront door. It is colored red and\\ndecorated.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5698,7 +5698,7 @@ "holdEffectParam": 0, "description_english": "Take this voucher to the BIKE SHOP\\nin CERULEAN CITY and exchange it\\nfor a bicycle.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5714,7 +5714,7 @@ "holdEffectParam": 0, "description_english": "A set of false teeth lost by the\\nSAFARI ZONE'S WARDEN. It makes his\\nsmile sparkle.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5730,7 +5730,7 @@ "holdEffectParam": 0, "description_english": "A piece of amber that contains\\nthe genes of an ancient POKéMON.\\nIt is clear with a reddish tint.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5746,7 +5746,7 @@ "holdEffectParam": 0, "description_english": "A card-type key that unlocks doors\\nin SILPH CO.'s HEAD OFFICE in\\nSAFFRON CITY.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5762,7 +5762,7 @@ "holdEffectParam": 0, "description_english": "A key that operates the elevator\\nin TEAM ROCKET's HIDEOUT.\\nIt bears the TEAM ROCKET logo.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5778,7 +5778,7 @@ "holdEffectParam": 0, "description_english": "A fossil of an ancient, seafloor-\\ndwelling POKéMON. It appears to be\\npart of a seashell.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5794,7 +5794,7 @@ "holdEffectParam": 0, "description_english": "A fossil of an ancient, seafloor-\\ndwelling POKéMON. It appears to be\\npart of a shell.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5810,7 +5810,7 @@ "holdEffectParam": 0, "description_english": "A scope that makes unseeable\\nPOKéMON visible.\\nIt is made by SILPH CO.", "importance": 1, - "exitsBagOnUse": 0, + "registrability": 0, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5826,7 +5826,7 @@ "holdEffectParam": 0, "description_english": "A folding bicycle that allows\\nfaster movement than the RUNNING\\nSHOES.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_FIELD", "fieldUseFunc": "FieldUseFunc_Bike", @@ -5842,7 +5842,7 @@ "holdEffectParam": 0, "description_english": "A very convenient map that can be\\nviewed anytime. It even shows your \\npresent location.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_TownMap", @@ -5858,7 +5858,7 @@ "holdEffectParam": 0, "description_english": "A device that indicates TRAINERS\\nwho want to battle. The battery\\ncharges while traveling.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_FIELD", "fieldUseFunc": "FieldUseFunc_VsSeeker", @@ -5874,7 +5874,7 @@ "holdEffectParam": 0, "description_english": "A device that enables you to\\nrecall what you've heard and seen\\nabout famous people.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_FameChecker", @@ -5890,7 +5890,7 @@ "holdEffectParam": 0, "description_english": "A case that holds TMs and HMs.\\nIt is attached to the BAG's\\ncompartment for important items.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_TmCase", @@ -5906,7 +5906,7 @@ "holdEffectParam": 0, "description_english": "A pouch for carrying BERRIES.\\nIt is attached to the BAG's\\ncompartment for important items.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_BerryPouch", @@ -5922,7 +5922,7 @@ "holdEffectParam": 0, "description_english": "A television set that is tuned to\\na program with useful tips for\\nnovice TRAINERS.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_FIELD", "fieldUseFunc": "FieldUseFunc_TeachyTv", @@ -5938,7 +5938,7 @@ "holdEffectParam": 0, "description_english": "A pass for ferries between ONE,\\nTWO, and THREE ISLAND.\\nIt has a drawing of three islands.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5954,7 +5954,7 @@ "holdEffectParam": 0, "description_english": "A pass for ferries between\\nVERMILION and the SEVII ISLANDS.\\nIt features a drawing of a rainbow.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5970,7 +5970,7 @@ "holdEffectParam": 0, "description_english": "An aromatic tea prepared by an old\\nlady. It will slake even the worst\\nthirst.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -5986,7 +5986,7 @@ "holdEffectParam": 0, "description_english": "A ticket required to board the ship\\nto NAVEL ROCK.\\nIt glows with a mystic light.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -6002,7 +6002,7 @@ "holdEffectParam": 0, "description_english": "A ticket required to board the ship\\nto BIRTH ISLAND.\\nIt glows beautifully.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -6018,7 +6018,7 @@ "holdEffectParam": 0, "description_english": "A jar for storing BERRY POWDER\\nmade using a BERRY CRUSHER.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_PowderJar", @@ -6034,7 +6034,7 @@ "holdEffectParam": 0, "description_english": "An exquisitely beautiful gem that\\nhas a red glow.\\nIt symbolizes passion.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", @@ -6050,7 +6050,7 @@ "holdEffectParam": 0, "description_english": "An exquisitely beautiful gem that\\nhas a blue glow.\\nIt symbolizes honesty.", "importance": 1, - "exitsBagOnUse": 1, + "registrability": 1, "pocket": "POCKET_KEY_ITEMS", "type": "ITEM_TYPE_BAG_MENU", "fieldUseFunc": "FieldUseFunc_OakStopsYou", diff --git a/src/data/items.json.txt b/src/data/items.json.txt index 0daa783aa..a389a5c83 100644 --- a/src/data/items.json.txt +++ b/src/data/items.json.txt @@ -20,7 +20,7 @@ const struct Item gItems[] = { .description = gItemDescription_{{ item.itemId }}, ## endif .importance = {{ item.importance }}, - .exitsBagOnUse = {{ item.exitsBagOnUse }}, + .registrability = {{ item.registrability }}, .pocket = {{ item.pocket }}, .type = {{ item.type }}, .fieldUseFunc = {{ item.fieldUseFunc }}, diff --git a/src/item.c b/src/item.c index 763838133..e072a5692 100644 --- a/src/item.c +++ b/src/item.c @@ -621,12 +621,13 @@ const u8 * ItemId_GetName(u16 itemId) return gItems[SanitizeItemId(itemId)].name; } -u16 itemid_get_number(u16 itemId) +// Unused +u16 ItemId_GetId(u16 itemId) { return gItems[SanitizeItemId(itemId)].itemId; } -u16 itemid_get_market_price(u16 itemId) +u16 ItemId_GetPrice(u16 itemId) { return gItems[SanitizeItemId(itemId)].price; } @@ -646,14 +647,15 @@ const u8 * ItemId_GetDescription(u16 itemId) return gItems[SanitizeItemId(itemId)].description; } -bool8 itemid_is_unique(u16 itemId) +u8 ItemId_GetImportance(u16 itemId) { return gItems[SanitizeItemId(itemId)].importance; } -u8 itemid_get_x19(u16 itemId) +// Unused +u8 ItemId_GetRegistrability(u16 itemId) { - return gItems[SanitizeItemId(itemId)].exitsBagOnUse; + return gItems[SanitizeItemId(itemId)].registrability; } u8 ItemId_GetPocket(u16 itemId) diff --git a/src/item_menu.c b/src/item_menu.c index 3ee223343..d499d6081 100644 --- a/src/item_menu.c +++ b/src/item_menu.c @@ -714,7 +714,7 @@ static void BagListMenuItemPrintFunc(u8 windowId, u32 itemId, u8 y) { bagItemId = BagGetItemIdByPocketPosition(gBagMenuState.pocket + 1, itemId); bagItemQuantity = BagGetQuantityByPocketPosition(gBagMenuState.pocket + 1, itemId); - if (gBagMenuState.pocket != POCKET_KEY_ITEMS - 1 && !itemid_is_unique(bagItemId)) + if (gBagMenuState.pocket != POCKET_KEY_ITEMS - 1 && ItemId_GetImportance(bagItemId) == 0) { ConvertIntToDecimalStringN(gStringVar1, bagItemQuantity, STR_CONV_MODE_RIGHT_ALIGN, 3); StringExpandPlaceholders(gStringVar4, gText_TimesStrVar1); @@ -1611,7 +1611,7 @@ static void Task_ItemMenuAction_Give(u8 taskId) CopyWindowToVram(0, COPYWIN_MAP); if (!CanWriteMailHere(itemId)) DisplayItemMessageInBag(taskId, FONT_2, gText_CantWriteMailHere, Task_WaitAButtonAndCloseContextMenu); - else if (!itemid_is_unique(itemId)) + else if (ItemId_GetImportance(itemId) == 0) { if (CalculatePlayerPartyCount() == 0) { @@ -1717,7 +1717,7 @@ static void Task_ItemContext_FieldGive(u8 taskId) ItemMenu_SetExitCallback(GoToBerryPouch_Give); ItemMenu_StartFadeToExitCallback(taskId); } - else if (gBagMenuState.pocket != POCKET_KEY_ITEMS - 1 && !itemid_is_unique(itemId)) + else if (gBagMenuState.pocket != POCKET_KEY_ITEMS - 1 && ItemId_GetImportance(itemId) == 0) { Bag_BeginCloseWin0Animation(); gTasks[taskId].func = ItemMenu_StartFadeToExitCallback; @@ -1730,7 +1730,7 @@ static void Task_ItemContext_FieldGive(u8 taskId) static void GoToTMCase_Give(void) { - InitTMCase(TMCASE_FROMPARTYGIVE, ReturnToBagMenuFromSubmenu_Give, FALSE); + InitTMCase(TMCASE_GIVE_PARTY, ReturnToBagMenuFromSubmenu_Give, FALSE); } static void GoToBerryPouch_Give(void) @@ -1761,7 +1761,7 @@ static void Task_ItemContext_PcBoxGive(u8 taskId) ItemMenu_SetExitCallback(GoToBerryPouch_PCBox); ItemMenu_StartFadeToExitCallback(taskId); } - else if (gBagMenuState.pocket != POCKET_KEY_ITEMS - 1 && !itemid_is_unique(itemId)) + else if (gBagMenuState.pocket != POCKET_KEY_ITEMS - 1 && ItemId_GetImportance(itemId) == 0) { Bag_BeginCloseWin0Animation(); gTasks[taskId].func = ItemMenu_StartFadeToExitCallback; @@ -1774,7 +1774,7 @@ static void Task_ItemContext_PcBoxGive(u8 taskId) static void GoToTMCase_PCBox(void) { - InitTMCase(TMCASE_FROMPOKEMONSTORAGEPC, ReturnToBagMenuFromSubmenu_PCBox, FALSE); + InitTMCase(TMCASE_GIVE_PC, ReturnToBagMenuFromSubmenu_PCBox, FALSE); } static void GoToBerryPouch_PCBox(void) @@ -1800,7 +1800,7 @@ static void Task_ItemContext_Sell(u8 taskId) ItemMenu_SetExitCallback(GoToBerryPouch_Sell); ItemMenu_StartFadeToExitCallback(taskId); } - else if (itemid_get_market_price(gSpecialVar_ItemId) == 0) + else if (ItemId_GetPrice(gSpecialVar_ItemId) == 0) { CopyItemName(gSpecialVar_ItemId, gStringVar1); StringExpandPlaceholders(gStringVar4, gText_OhNoICantBuyThat); @@ -1827,7 +1827,7 @@ static void Task_ItemContext_Sell(u8 taskId) static void GoToTMCase_Sell(void) { - InitTMCase(TMCASE_FROMMARTSELL, ReturnToBagMenuFromSubmenu_Sell, FALSE); + InitTMCase(TMCASE_SELL, ReturnToBagMenuFromSubmenu_Sell, FALSE); } static void GoToBerryPouch_Sell(void) @@ -1843,7 +1843,7 @@ static void ReturnToBagMenuFromSubmenu_Sell(void) static void Task_PrintSaleConfirmationText(u8 taskId) { s16 *data = gTasks[taskId].data; - ConvertIntToDecimalStringN(gStringVar3, itemid_get_market_price(BagGetItemIdByPocketPosition(gBagMenuState.pocket + 1, data[1])) / 2 * data[8], STR_CONV_MODE_LEFT_ALIGN, 6); + ConvertIntToDecimalStringN(gStringVar3, ItemId_GetPrice(BagGetItemIdByPocketPosition(gBagMenuState.pocket + 1, data[1])) / 2 * data[8], STR_CONV_MODE_LEFT_ALIGN, 6); StringExpandPlaceholders(gStringVar4, gText_ICanPayThisMuch_WouldThatBeOkay); DisplayItemMessageInBag(taskId, GetDialogBoxFontId(), gStringVar4, Task_ShowSellYesNoMenu); } @@ -1873,7 +1873,7 @@ static void Task_InitSaleQuantitySelectInterface(u8 taskId) ConvertIntToDecimalStringN(gStringVar1, 1, STR_CONV_MODE_LEADING_ZEROS, 2); StringExpandPlaceholders(gStringVar4, gText_TimesStrVar1); BagPrintTextOnWindow(r4, FONT_0, gStringVar4, 4, 10, 1, 0, 0xFF, 1); - UpdateSalePriceDisplay(itemid_get_market_price(BagGetItemIdByPocketPosition(gBagMenuState.pocket + 1, data[1])) / 2 * data[8]); + UpdateSalePriceDisplay(ItemId_GetPrice(BagGetItemIdByPocketPosition(gBagMenuState.pocket + 1, data[1])) / 2 * data[8]); BagPrintMoneyAmount(); CreatePocketScrollArrowPair_SellQuantity(); gTasks[taskId].func = Task_SelectQuantityToSell; @@ -1890,7 +1890,7 @@ static void Task_SelectQuantityToSell(u8 taskId) if (AdjustQuantityAccordingToDPadInput(&data[8], data[2]) == TRUE) { UpdateQuantityToTossOrDeposit(data[8], 2); - UpdateSalePriceDisplay(itemid_get_market_price(BagGetItemIdByPocketPosition(gBagMenuState.pocket + 1, data[1])) / 2 * data[8]); + UpdateSalePriceDisplay(ItemId_GetPrice(BagGetItemIdByPocketPosition(gBagMenuState.pocket + 1, data[1])) / 2 * data[8]); } else if (JOY_NEW(A_BUTTON)) { @@ -1923,7 +1923,7 @@ static void Task_SellItem_Yes(u8 taskId) PutWindowTilemap(0); ScheduleBgCopyTilemapToVram(0); CopyItemName(gSpecialVar_ItemId, gStringVar1); - ConvertIntToDecimalStringN(gStringVar3, itemid_get_market_price(BagGetItemIdByPocketPosition(gBagMenuState.pocket + 1, data[1])) / 2 * data[8], STR_CONV_MODE_LEFT_ALIGN, 6); + ConvertIntToDecimalStringN(gStringVar3, ItemId_GetPrice(BagGetItemIdByPocketPosition(gBagMenuState.pocket + 1, data[1])) / 2 * data[8], STR_CONV_MODE_LEFT_ALIGN, 6); StringExpandPlaceholders(gStringVar4, gText_TurnedOverItemsWorthYen); DisplayItemMessageInBag(taskId, FONT_2, gStringVar4, Task_FinalizeSaleToShop); } @@ -1933,7 +1933,7 @@ static void Task_FinalizeSaleToShop(u8 taskId) s16 *data = gTasks[taskId].data; PlaySE(SE_SHOP); RemoveBagItem(gSpecialVar_ItemId, data[8]); - AddMoney(&gSaveBlock1Ptr->money, itemid_get_market_price(gSpecialVar_ItemId) / 2 * data[8]); + AddMoney(&gSaveBlock1Ptr->money, ItemId_GetPrice(gSpecialVar_ItemId) / 2 * data[8]); RecordItemPurchase(gSpecialVar_ItemId, data[8], 2); DestroyListMenuTask(data[0], &gBagMenuState.cursorPos[gBagMenuState.pocket], &gBagMenuState.itemsAbove[gBagMenuState.pocket]); Pocket_CalculateNItemsAndMaxShowed(gBagMenuState.pocket); diff --git a/src/item_use.c b/src/item_use.c index 7c5091ccd..331aa5656 100644 --- a/src/item_use.c +++ b/src/item_use.c @@ -457,7 +457,7 @@ void FieldUseFunc_TmCase(u8 taskId) static void InitTMCaseFromBag(void) { - InitTMCase(0, CB2_BagMenuFromStartMenu, 0); + InitTMCase(TMCASE_FIELD, CB2_BagMenuFromStartMenu, FALSE); } static void Task_InitTMCaseFromField(u8 taskId) @@ -466,7 +466,7 @@ static void Task_InitTMCaseFromField(u8 taskId) { CleanupOverworldWindowsAndTilemaps(); SetFieldCallback2ForItemUse(); - InitTMCase(0, CB2_ReturnToField, 1); + InitTMCase(TMCASE_FIELD, CB2_ReturnToField, TRUE); DestroyTask(taskId); } } diff --git a/src/party_menu.c b/src/party_menu.c index 33293ed9c..4b64d8480 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -4258,7 +4258,7 @@ static void CB2_ReturnToBagMenu(void) static void CB2_ReturnToTMCaseMenu(void) { - InitTMCase(TMCASE_NA, NULL, 0xFF); + InitTMCase(TMCASE_REOPENING, NULL, TMCASE_KEEP_PREV); } static void CB2_ReturnToBerryPouchMenu(void) diff --git a/src/shop.c b/src/shop.c index 7327874ca..37c3c7ee0 100644 --- a/src/shop.c +++ b/src/shop.c @@ -614,7 +614,7 @@ static void BuyMenuPrintPriceInList(u8 windowId, u32 item, u8 y) if (item != INDEX_CANCEL) { - ConvertIntToDecimalStringN(gStringVar1, itemid_get_market_price(item), 0, 4); + ConvertIntToDecimalStringN(gStringVar1, ItemId_GetPrice(item), 0, 4); x = 4 - StringLength(gStringVar1); loc = gStringVar4; while (x-- != 0) @@ -902,7 +902,7 @@ static void Task_BuyMenu(u8 taskId) BuyMenuRemoveScrollIndicatorArrows(); BuyMenuPrintCursor(tListTaskId, 2); RecolorItemDescriptionBox(1); - gShopData.itemPrice = itemid_get_market_price(itemId); + gShopData.itemPrice = ItemId_GetPrice(itemId); if (!IsEnoughMoney(&gSaveBlock1Ptr->money, gShopData.itemPrice)) { BuyMenuDisplayMessage(taskId, gText_YouDontHaveMoney, BuyMenuReturnToItemList); @@ -931,7 +931,7 @@ static void Task_BuyHowManyDialogueInit(u8 taskId) BuyMenuQuantityBoxNormalBorder(3, 0); BuyMenuPrintItemQuantityAndPrice(taskId); ScheduleBgCopyTilemapToVram(0); - maxQuantity = GetMoney(&gSaveBlock1Ptr->money) / itemid_get_market_price(tItemId); + maxQuantity = GetMoney(&gSaveBlock1Ptr->money) / ItemId_GetPrice(tItemId); if (maxQuantity > 99) gShopData.maxQuantity = 99; else @@ -949,7 +949,7 @@ static void Task_BuyHowManyDialogueHandleInput(u8 taskId) if (AdjustQuantityAccordingToDPadInput(&tItemCount, gShopData.maxQuantity) == TRUE) { - gShopData.itemPrice = itemid_get_market_price(tItemId) * tItemCount; + gShopData.itemPrice = ItemId_GetPrice(tItemId) * tItemCount; BuyMenuPrintItemQuantityAndPrice(taskId); } else @@ -1102,7 +1102,7 @@ void RecordItemPurchase(u16 item, u16 quantity, u8 a2) if (history->unk0 < 999999) { - history->unk0 += (itemid_get_market_price(item) >> (a2 - 1)) * quantity; + history->unk0 += (ItemId_GetPrice(item) >> (a2 - 1)) * quantity; if (history->unk0 > 999999) history->unk0 = 999999; } diff --git a/src/strings.c b/src/strings.c index 9ce0e031c..e9b40707e 100644 --- a/src/strings.c +++ b/src/strings.c @@ -207,8 +207,8 @@ const u8 gText_PokeFluteAwakenedMon[] = _("The POKé FLUTE awakened sleeping\nPO const u8 gText_TMCase[] = _("TM CASE"); const u8 gText_Close[] = _("CLOSE"); const u8 gText_TMCaseWillBePutAway[] = _("The TM CASE will be\nput away."); -const u8 gText_FontSize0[] = _("{FONT_0}"); -const u8 gText_FontSize2[] = _("{FONT_2}"); +const u8 gText_Font0[] = _("{FONT_0}"); +const u8 gText_Font2[] = _("{FONT_2}"); const u8 gText_EmptySpace[] = _(" "); const u8 gText_BerryPouch[] = _("BERRY POUCH"); const u8 gText_TheBerryPouchWillBePutAway[] = _("The BERRY POUCH will be\nput away."); diff --git a/src/tm_case.c b/src/tm_case.c index 8ef9e7fbb..401a2a57c 100644 --- a/src/tm_case.c +++ b/src/tm_case.c @@ -1,4 +1,5 @@ #include "global.h" +#include "tm_case.h" #include "gflib.h" #include "decompress.h" #include "graphics.h" @@ -23,45 +24,96 @@ #include "constants/items.h" #include "constants/songs.h" -#define TM_CASE_TM_TAG 400 +// Any item in the TM Case with nonzero importance is considered an HM +#define IS_HM(itemId) (ItemId_GetImportance(itemId) != 0) -struct UnkStruct_203B10C -{ - void (* savedCallback)(void); - u8 tmCaseMenuType; - u8 unk_05; - u8 unk_06; - u16 selectedRow; - u16 scrollOffset; +#define TAG_SCROLL_ARROW 110 + +enum { + WIN_LIST, + WIN_DESCRIPTION, + WIN_SELECTED_MSG, + WIN_TITLE, + WIN_MOVE_INFO_LABELS, + WIN_MOVE_INFO, + WIN_MESSAGE, + WIN_SELL_QUANTITY, + WIN_MONEY, }; -struct UnkStruct_203B118 -{ - void (* savedCallback)(void); - u8 tmSpriteId; +// Window IDs for the context menu that opens when a TM/HM is selected +enum { + WIN_USE_GIVE_EXIT, + WIN_GIVE_EXIT, +}; + +// IDs for the actions in the context menu +enum { + ACTION_USE, + ACTION_GIVE, + ACTION_EXIT +}; + +enum { + COLOR_LIGHT, + COLOR_DARK, + COLOR_CURSOR_SELECTED, + COLOR_MOVE_INFO, + COLOR_CURSOR_ERASE = 0xFF +}; + +// Base position for TM/HM disc sprite +#define DISC_BASE_X 41 +#define DISC_BASE_Y 46 + +#define DISC_CASE_DISTANCE 20 // The total number of pixels a disc travels vertically in/out of the case +#define DISC_Y_MOVE 10 // The number of pixels a disc travels vertically per movement step + +#define TAG_DISC 400 + +#define DISC_HIDDEN 0xFF // When no TM/HM is selected, hide the disc sprite + +enum { + ANIM_TM, + ANIM_HM, +}; + +// The "static" resources are preserved even if the TM case is exited. This is +// useful for when its left temporarily (e.g. going to the party menu to teach a TM) +// but also to preserve the selected item when the TM case is fully closed. +static EWRAM_DATA struct { + void (* exitCallback)(void); + u8 menuType; + bool8 allowSelectClose; + u8 unused; + u16 selectedRow; + u16 scrollOffset; +} sTMCaseStaticResources = {}; + +// The "dynamic" resources will be reset any time the TM case is exited, even temporarily. +static EWRAM_DATA struct { + void (* nextScreenCallback)(void); + u8 discSpriteId; u8 maxTMsShown; u8 numTMs; u8 contextMenuWindowId; - u8 scrollIndicatorArrowPairId; + u8 scrollArrowsTaskId; u16 currItem; const u8 * menuActionIndices; u8 numMenuActions; s16 seqId; - u8 filler_14[8]; -}; + u8 unused[8]; +} * sTMCaseDynamicResources = NULL; -struct UnkStruct_203B11C -{ +// Save the player's bag state when the Pokedude's bag is being shown +static EWRAM_DATA struct { struct ItemSlot bagPocket_TMHM[BAG_TMHM_COUNT]; struct ItemSlot bagPocket_KeyItems[BAG_KEYITEMS_COUNT]; - u16 unk_160; - u16 unk_162; -}; + u16 selectedRow; + u16 scrollOffset; +} * sPokedudeBagBackup = NULL; -static EWRAM_DATA struct UnkStruct_203B10C sTMCaseStaticResources = {}; -static EWRAM_DATA struct UnkStruct_203B118 * sTMCaseDynamicResources = NULL; -static EWRAM_DATA struct UnkStruct_203B11C * sPokedudePackBackup = NULL; -static EWRAM_DATA void *sTilemapBuffer = NULL; // tilemap buffer +static EWRAM_DATA void *sTilemapBuffer = NULL; static EWRAM_DATA struct ListMenuItem * sListMenuItemsBuffer = NULL; static EWRAM_DATA u8 (* sListMenuStringsBuffer)[29] = NULL; static EWRAM_DATA u16 * sTMSpritePaletteBuffer = NULL; @@ -74,28 +126,29 @@ static bool8 HandleLoadTMCaseGraphicsAndPalettes(void); static void CreateTMCaseListMenuBuffers(void); static void InitTMCaseListMenuItems(void); static void GetTMNumberAndMoveString(u8 * dest, u16 itemId); -static void TMCase_MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu *list); -static void TMCase_ItemPrintFunc(u8 windowId, u32 itemId, u8 y); -static void TMCase_MoveCursor_UpdatePrintedDescription(s32 itemIndex); -static void PrintListMenuCursorAt_WithColorIdx(u8 a0, u8 a1); -static void CreateTMCaseScrollIndicatorArrowPair_Main(void); +static void List_MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu *list); +static void List_ItemPrintFunc(u8 windowId, u32 itemId, u8 y); +static void PrintDescription(s32 itemIndex); +static void PrintMoveInfo(u16 itemId); +static void PrintListCursorAtRow(u8 y, u8 colorIdx); +static void CreateListScrollArrows(void); static void TMCaseSetup_GetTMCount(void); static void TMCaseSetup_InitListMenuPositions(void); static void TMCaseSetup_UpdateVisualMenuOffset(void); static void Task_FadeOutAndCloseTMCase(u8 taskId); -static void Task_TMCaseMain(u8 taskId); -static void Task_SelectTMAction_FromFieldBag(u8 taskId); -static void Task_TMContextMenu_HandleInput(u8 taskId); -static void TMHMContextMenuAction_Use(u8 taskId); -static void TMHMContextMenuAction_Give(u8 taskId); +static void Task_HandleListInput(u8 taskId); +static void Task_SelectedTMHM_Field(u8 taskId); +static void Task_ContextMenu_HandleInput(u8 taskId); +static void Action_Use(u8 taskId); +static void Action_Give(u8 taskId); static void PrintError_ThereIsNoPokemon(u8 taskId); static void PrintError_ItemCantBeHeld(u8 taskId); static void Task_WaitButtonAfterErrorPrint(u8 taskId); -static void Subtask_CloseContextMenuAndReturnToMain(u8 taskId); -static void TMHMContextMenuAction_Exit(u8 taskId); -static void Task_SelectTMAction_Type1(u8 taskId); -static void Task_SelectTMAction_Type3(u8 taskId); -static void Task_SelectTMAction_FromSellMenu(u8 taskId); +static void CloseMessageAndReturnToList(u8 taskId); +static void Action_Exit(u8 taskId); +static void Task_SelectedTMHM_GiveParty(u8 taskId); +static void Task_SelectedTMHM_GivePC(u8 taskId); +static void Task_SelectedTMHM_Sell(u8 taskId); static void Task_AskConfirmSaleWithAmount(u8 taskId); static void Task_PlaceYesNoBox(u8 taskId); static void Task_SaleOfTMsCanceled(u8 taskId); @@ -105,28 +158,27 @@ static void Task_QuantitySelect_HandleInput(u8 taskId); static void Task_PrintSaleConfirmedText(u8 taskId); static void Task_DoSaleOfTMs(u8 taskId); static void Task_AfterSale_ReturnToList(u8 taskId); -static void Task_TMCaseDude1(u8 taskId); -static void Task_TMCaseDude_Playback(u8 taskId); +static void Task_Pokedude_Start(u8 taskId); +static void Task_Pokedude_Run(u8 taskId); static void InitWindowTemplatesAndPals(void); -static void AddTextPrinterParameterized_ColorByIndex(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, u8 speed, u8 colorIdx); +static void TMCase_Print(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, u8 speed, u8 colorIdx); static void TMCase_SetWindowBorder1(u8 windowId); static void TMCase_SetWindowBorder2(u8 windowId); -static void TMCase_PrintMessageWithFollowupTask(u8 taskId, u8 fontId, const u8 * str, TaskFunc func); -static void PrintStringTMCaseOnWindow3(void); -static void DrawMoveInfoUIMarkers(void); -static void TMCase_MoveCursor_UpdatePrintedTMInfo(u16 itemId); +static void PrintMessageWithFollowupTask(u8 taskId, u8 fontId, const u8 * str, TaskFunc func); +static void PrintTitle(void); +static void DrawMoveInfoLabels(void); static void PlaceHMTileInWindow(u8 windowId, u8 x, u8 y); -static void HandlePrintMoneyOnHand(void); +static void PrintPlayersMoney(void); static void HandleCreateYesNoMenu(u8 taskId, const struct YesNoFuncTable * ptrs); -static u8 AddTMContextMenu(u8 * a0, u8 a1); -static void RemoveTMContextMenu(u8 * a0); -static u8 CreateTMSprite(u16 itemId); -static void SetTMSpriteAnim(struct Sprite *sprite, u8 var); -static void TintTMSpriteByType(u8 type); -static void UpdateTMSpritePosition(struct Sprite *sprite, u8 var); -static void InitSelectedTMSpriteData(u8 a0, u16 itemId); -static void SpriteCB_MoveTMSpriteInCase(struct Sprite *sprite); -static void LoadTMTypePalettes(void); +static u8 AddContextMenu(u8 * windowId, u8 windowIndex); +static void RemoveContextMenu(u8 * windowId); +static u8 CreateDiscSprite(u16 itemId); +static void SetDiscSpriteAnim(struct Sprite *sprite, u8 tmIdx); +static void TintDiscpriteByType(u8 type); +static void SetDiscSpritePosition(struct Sprite *sprite, u8 tmIdx); +static void SwapDisc(u8 spriteId, u16 itemId); +static void SpriteCB_SwapDisc(struct Sprite *sprite); +static void LoadDiscTypePalettes(void); static const struct BgTemplate sBGTemplates[] = { { @@ -156,21 +208,24 @@ static const struct BgTemplate sBGTemplates[] = { } }; +// The list of functions to run when a TM/HM is selected. +// What happens when one is selected depends on how the player arrived at the TM case static void (*const sSelectTMActionTasks[])(u8 taskId) = { - Task_SelectTMAction_FromFieldBag, - Task_SelectTMAction_Type1, - Task_SelectTMAction_FromSellMenu, - Task_SelectTMAction_Type3 + [TMCASE_FIELD] = Task_SelectedTMHM_Field, + [TMCASE_GIVE_PARTY] = Task_SelectedTMHM_GiveParty, + [TMCASE_SELL] = Task_SelectedTMHM_Sell, + [TMCASE_GIVE_PC] = Task_SelectedTMHM_GivePC }; -static const struct MenuAction sMenuActions_UseGiveExit[] = { - {gOtherText_Use, TMHMContextMenuAction_Use }, - {gOtherText_Give, TMHMContextMenuAction_Give}, - {gOtherText_Exit, TMHMContextMenuAction_Exit}, +static const struct MenuAction sMenuActions[] = { + [ACTION_USE] = {gOtherText_Use, Action_Use }, + [ACTION_GIVE] = {gOtherText_Give, Action_Give}, + [ACTION_EXIT] = {gOtherText_Exit, Action_Exit}, }; -static const u8 sMenuActionIndices_Field[] = {0, 1, 2}; -static const u8 sMenuActionIndices_UnionRoom[] = {1, 2}; +static const u8 sMenuActionIndices_Field[] = {ACTION_USE, ACTION_GIVE, ACTION_EXIT}; +static const u8 sMenuActionIndices_UnionRoom[] = {ACTION_GIVE, ACTION_EXIT}; + static const struct YesNoFuncTable sYesNoFuncTable = {Task_PrintSaleConfirmedText, Task_SaleOfTMsCanceled}; static const u8 sText_ClearTo18[] = _("{CLEAR_TO 18}"); @@ -179,30 +234,126 @@ static const u8 sText_SingleSpace[] = _(" "); static ALIGNED(4) const u16 sPal3Override[] = {RGB(8, 8, 8), RGB(30, 16, 6)}; static const u8 sTextColors[][3] = { - {0, 1, 2}, - {0, 2, 3}, - {0, 3, 6}, - {0, 14, 10} + [COLOR_LIGHT] = {0, 1, 2}, + [COLOR_DARK] = {0, 2, 3}, + [COLOR_CURSOR_SELECTED] = {0, 3, 6}, + [COLOR_MOVE_INFO] = {0, 14, 10}, }; static const struct WindowTemplate sWindowTemplates[] = { - {0x00, 0x0a, 0x01, 0x13, 0x0a, 0x0f, 0x0081}, - {0x00, 0x0c, 0x0c, 0x12, 0x08, 0x0a, 0x013f}, - {0x01, 0x05, 0x0f, 0x0f, 0x04, 0x0d, 0x01f9}, - {0x00, 0x00, 0x01, 0x0a, 0x02, 0x0f, 0x0235}, - {0x00, 0x01, 0x0d, 0x05, 0x06, 0x0c, 0x0249}, - {0x00, 0x07, 0x0d, 0x05, 0x06, 0x0c, 0x0267}, - {0x01, 0x02, 0x0f, 0x1a, 0x04, 0x0b, 0x0285}, - {0x01, 0x11, 0x09, 0x0c, 0x04, 0x0f, 0x02ed}, - {0x01, 0x01, 0x01, 0x08, 0x03, 0x0d, 0x031d}, + [WIN_LIST] = { + .bg = 0, + .tilemapLeft = 10, + .tilemapTop = 1, + .width = 19, + .height = 10, + .paletteNum = 15, + .baseBlock = 0x081 + }, + [WIN_DESCRIPTION] = { + .bg = 0, + .tilemapLeft = 12, + .tilemapTop = 12, + .width = 18, + .height = 8, + .paletteNum = 10, + .baseBlock = 0x13f + }, + [WIN_SELECTED_MSG] = { + .bg = 1, + .tilemapLeft = 5, + .tilemapTop = 15, + .width = 15, + .height = 4, + .paletteNum = 13, + .baseBlock = 0x1f9 + }, + [WIN_TITLE] = { + .bg = 0, + .tilemapLeft = 0, + .tilemapTop = 1, + .width = 10, + .height = 2, + .paletteNum = 15, + .baseBlock = 0x235 + }, + [WIN_MOVE_INFO_LABELS] = { + .bg = 0, + .tilemapLeft = 1, + .tilemapTop = 13, + .width = 5, + .height = 6, + .paletteNum = 12, + .baseBlock = 0x249 + }, + [WIN_MOVE_INFO] = { + .bg = 0, + .tilemapLeft = 7, + .tilemapTop = 13, + .width = 5, + .height = 6, + .paletteNum = 12, + .baseBlock = 0x267 + }, + [WIN_MESSAGE] = { + .bg = 1, + .tilemapLeft = 2, + .tilemapTop = 15, + .width = 26, + .height = 4, + .paletteNum = 11, + .baseBlock = 0x285 + }, + [WIN_SELL_QUANTITY] = { + .bg = 1, + .tilemapLeft = 17, + .tilemapTop = 9, + .width = 12, + .height = 4, + .paletteNum = 15, + .baseBlock = 0x2ed + }, + [WIN_MONEY] = { + .bg = 1, + .tilemapLeft = 1, + .tilemapTop = 1, + .width = 8, + .height = 3, + .paletteNum = 13, + .baseBlock = 0x31d + }, DUMMY_WIN_TEMPLATE }; -static const struct WindowTemplate sYesNoWindowTemplate = {0x01, 0x15, 0x09, 0x06, 0x04, 0x0f, 0x0335}; +static const struct WindowTemplate sYesNoWindowTemplate = { + .bg = 1, + .tilemapLeft = 21, + .tilemapTop = 9, + .width = 6, + .height = 4, + .paletteNum = 15, + .baseBlock = 0x335 +}; -static const struct WindowTemplate sTMContextWindowTemplates[] = { - {0x01, 0x16, 0x0d, 0x07, 0x06, 0x0f, 0x01cf}, - {0x01, 0x16, 0x0f, 0x07, 0x04, 0x0f, 0x01cf} +static const struct WindowTemplate sWindowTemplates_ContextMenu[] = { + [WIN_USE_GIVE_EXIT] = { + .bg = 1, + .tilemapLeft = 22, + .tilemapTop = 13, + .width = 7, + .height = 6, + .paletteNum = 15, + .baseBlock = 0x1cf + }, + [WIN_GIVE_EXIT] = { + .bg = 1, + .tilemapLeft = 22, + .tilemapTop = 15, + .width = 7, + .height = 4, + .paletteNum = 15, + .baseBlock = 0x1cf + }, }; static const struct OamData sTMSpriteOamData = { @@ -210,35 +361,35 @@ static const struct OamData sTMSpriteOamData = { .priority = 2 }; -static const union AnimCmd sTMSpriteAnim0[] = { +static const union AnimCmd sAnim_TM[] = { ANIMCMD_FRAME(0, 0), ANIMCMD_END }; -static const union AnimCmd sTMSpriteAnim1[] = { +static const union AnimCmd sAnim_HM[] = { ANIMCMD_FRAME(16, 0), ANIMCMD_END }; -static const union AnimCmd *const sTMSpriteAnims[] = { - sTMSpriteAnim0, - sTMSpriteAnim1 +static const union AnimCmd *const sAnims_Disc[] = { + [ANIM_TM] = sAnim_TM, + [ANIM_HM] = sAnim_HM }; -static const struct CompressedSpriteSheet sTMSpriteSheet = { - (const void *)gTMCaseDisc_Gfx, - 0x400, - TM_CASE_TM_TAG +static const struct CompressedSpriteSheet sSpriteSheet_Disc = { + .data = gTMCaseDisc_Gfx, + .size = 0x400, + .tag = TAG_DISC }; -static const struct SpriteTemplate sTMSpriteTemplate = { - TM_CASE_TM_TAG, - TM_CASE_TM_TAG, - &sTMSpriteOamData, - sTMSpriteAnims, - NULL, - gDummySpriteAffineAnimTable, - SpriteCallbackDummy +static const struct SpriteTemplate sSpriteTemplate_Disc = { + .tileTag = TAG_DISC, + .paletteTag = TAG_DISC, + .oam = &sTMSpriteOamData, + .anims = sAnims_Disc, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbackDummy }; static const u16 sTMSpritePaletteOffsetByType[NUMBER_OF_MON_TYPES] = { @@ -261,19 +412,19 @@ static const u16 sTMSpritePaletteOffsetByType[NUMBER_OF_MON_TYPES] = { [TYPE_DRAGON] = 0x100 }; -void InitTMCase(u8 type, void (* callback)(void), u8 a2) +void InitTMCase(u8 type, void (* exitCallback)(void), bool8 allowSelectClose) { ResetBufferPointers_NoFree(); - sTMCaseDynamicResources = Alloc(sizeof(struct UnkStruct_203B118)); - sTMCaseDynamicResources->savedCallback = 0; - sTMCaseDynamicResources->scrollIndicatorArrowPairId = 0xFF; - sTMCaseDynamicResources->contextMenuWindowId = 0xFF; - if (type != 5) - sTMCaseStaticResources.tmCaseMenuType = type; - if (callback != NULL) - sTMCaseStaticResources.savedCallback = callback; - if (a2 != 0xFF) - sTMCaseStaticResources.unk_05 = a2; + sTMCaseDynamicResources = Alloc(sizeof(*sTMCaseDynamicResources)); + sTMCaseDynamicResources->nextScreenCallback = NULL; + sTMCaseDynamicResources->scrollArrowsTaskId = TASK_NONE; + sTMCaseDynamicResources->contextMenuWindowId = WINDOW_NONE; + if (type != TMCASE_REOPENING) + sTMCaseStaticResources.menuType = type; + if (exitCallback != NULL) + sTMCaseStaticResources.exitCallback = exitCallback; + if (allowSelectClose != TMCASE_KEEP_PREV) + sTMCaseStaticResources.allowSelectClose = allowSelectClose; gTextFlags.autoScroll = FALSE; SetMainCallback2(CB2_SetUpTMCaseUI_Blocking); } @@ -307,6 +458,14 @@ static void CB2_SetUpTMCaseUI_Blocking(void) } } +#define tListTaskId data[0] +#define tSelection data[1] +#define tQuantityOwned data[2] +#define tQuantitySelected data[8] + +#define tPokedudeState data[8] // Re-used +#define tPokedudeTimer data[9] + static bool8 DoSetUpTMCaseUI(void) { u8 taskId; @@ -362,7 +521,7 @@ static bool8 DoSetUpTMCaseUI(void) gMain.state++; break; case 11: - DrawMoveInfoUIMarkers(); + DrawMoveInfoLabels(); gMain.state++; break; case 12: @@ -371,23 +530,23 @@ static bool8 DoSetUpTMCaseUI(void) gMain.state++; break; case 13: - PrintStringTMCaseOnWindow3(); + PrintTitle(); gMain.state++; break; case 14: - if (sTMCaseStaticResources.tmCaseMenuType == 4) - taskId = CreateTask(Task_TMCaseDude1, 0); + if (sTMCaseStaticResources.menuType == TMCASE_POKEDUDE) + taskId = CreateTask(Task_Pokedude_Start, 0); else - taskId = CreateTask(Task_TMCaseMain, 0); - gTasks[taskId].data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sTMCaseStaticResources.scrollOffset, sTMCaseStaticResources.selectedRow); + taskId = CreateTask(Task_HandleListInput, 0); + gTasks[taskId].tListTaskId = ListMenuInit(&gMultiuseListMenuTemplate, sTMCaseStaticResources.scrollOffset, sTMCaseStaticResources.selectedRow); gMain.state++; break; case 15: - CreateTMCaseScrollIndicatorArrowPair_Main(); + CreateListScrollArrows(); gMain.state++; break; case 16: - sTMCaseDynamicResources->tmSpriteId = CreateTMSprite(BagGetItemIdByPocketPosition(POCKET_TM_CASE, sTMCaseStaticResources.scrollOffset + sTMCaseStaticResources.selectedRow)); + sTMCaseDynamicResources->discSpriteId = CreateDiscSprite(BagGetItemIdByPocketPosition(POCKET_TM_CASE, sTMCaseStaticResources.scrollOffset + sTMCaseStaticResources.selectedRow)); gMain.state++; break; case 17: @@ -423,7 +582,7 @@ static void LoadBGTemplates(void) ptr = &sTilemapBuffer; *ptr = AllocZeroed(0x800); ResetBgsAndClearDma3BusyFlags(0); - InitBgsFromTemplates(0, sBGTemplates, NELEMS(sBGTemplates)); + InitBgsFromTemplates(0, sBGTemplates, ARRAY_COUNT(sBGTemplates)); SetBgTilemapBuffer(2, *ptr); ScheduleBgCopyTilemapToVram(1); ScheduleBgCopyTilemapToVram(2); @@ -462,11 +621,11 @@ static bool8 HandleLoadTMCaseGraphicsAndPalettes(void) sTMCaseDynamicResources->seqId++; break; case 4: - LoadCompressedSpriteSheet(&sTMSpriteSheet); + LoadCompressedSpriteSheet(&sSpriteSheet_Disc); sTMCaseDynamicResources->seqId++; break; default: - LoadTMTypePalettes(); + LoadDiscTypePalettes(); sTMCaseDynamicResources->seqId = 0; return TRUE; } @@ -493,10 +652,11 @@ static void InitTMCaseListMenuItems(void) sListMenuItemsBuffer[i].index = i; } sListMenuItemsBuffer[i].label = gText_Close; - sListMenuItemsBuffer[i].index = -2; + sListMenuItemsBuffer[i].index = LIST_CANCEL; + gMultiuseListMenuTemplate.items = sListMenuItemsBuffer; - gMultiuseListMenuTemplate.totalItems = sTMCaseDynamicResources->numTMs + 1; - gMultiuseListMenuTemplate.windowId = 0; + gMultiuseListMenuTemplate.totalItems = sTMCaseDynamicResources->numTMs + 1; // +1 for Cancel + gMultiuseListMenuTemplate.windowId = WIN_LIST; gMultiuseListMenuTemplate.header_X = 0; gMultiuseListMenuTemplate.item_X = 8; gMultiuseListMenuTemplate.cursor_X = 0; @@ -508,15 +668,15 @@ static void InitTMCaseListMenuItems(void) gMultiuseListMenuTemplate.cursorPal = 2; gMultiuseListMenuTemplate.fillValue = 0; gMultiuseListMenuTemplate.cursorShadowPal = 3; - gMultiuseListMenuTemplate.moveCursorFunc = TMCase_MoveCursorFunc; - gMultiuseListMenuTemplate.itemPrintFunc = TMCase_ItemPrintFunc; + gMultiuseListMenuTemplate.moveCursorFunc = List_MoveCursorFunc; + gMultiuseListMenuTemplate.itemPrintFunc = List_ItemPrintFunc; gMultiuseListMenuTemplate.cursorKind = 0; gMultiuseListMenuTemplate.scrollMultiple = 0; } static void GetTMNumberAndMoveString(u8 * dest, u16 itemId) { - StringCopy(gStringVar4, gText_FontSize0); + StringCopy(gStringVar4, gText_Font0); if (itemId >= ITEM_HM01) { StringAppend(gStringVar4, sText_ClearTo18); @@ -531,38 +691,38 @@ static void GetTMNumberAndMoveString(u8 * dest, u16 itemId) StringAppend(gStringVar4, gStringVar1); } StringAppend(gStringVar4, sText_SingleSpace); - StringAppend(gStringVar4, gText_FontSize2); + StringAppend(gStringVar4, gText_Font2); StringAppend(gStringVar4, gMoveNames[ItemIdToBattleMoveId(itemId)]); StringCopy(dest, gStringVar4); } -static void TMCase_MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu *list) +static void List_MoveCursorFunc(s32 itemIndex, bool8 onInit, struct ListMenu *list) { u16 itemId; - if (itemIndex == -2) - itemId = 0; + if (itemIndex == LIST_CANCEL) + itemId = ITEM_NONE; else itemId = BagGetItemIdByPocketPosition(POCKET_TM_CASE, itemIndex); if (onInit != TRUE) { PlaySE(SE_SELECT); - InitSelectedTMSpriteData(sTMCaseDynamicResources->tmSpriteId, itemId); + SwapDisc(sTMCaseDynamicResources->discSpriteId, itemId); } - TMCase_MoveCursor_UpdatePrintedDescription(itemIndex); - TMCase_MoveCursor_UpdatePrintedTMInfo(itemId); + PrintDescription(itemIndex); + PrintMoveInfo(itemId); } -static void TMCase_ItemPrintFunc(u8 windowId, u32 itemId, u8 y) +static void List_ItemPrintFunc(u8 windowId, u32 itemIndex, u8 y) { - if (itemId != -2) + if (itemIndex != LIST_CANCEL) { - if (!itemid_is_unique(BagGetItemIdByPocketPosition(POCKET_TM_CASE, itemId))) + if (!IS_HM(BagGetItemIdByPocketPosition(POCKET_TM_CASE, itemIndex))) { - ConvertIntToDecimalStringN(gStringVar1, BagGetQuantityByPocketPosition(POCKET_TM_CASE, itemId), STR_CONV_MODE_RIGHT_ALIGN, 3); + ConvertIntToDecimalStringN(gStringVar1, BagGetQuantityByPocketPosition(POCKET_TM_CASE, itemIndex), STR_CONV_MODE_RIGHT_ALIGN, 3); StringExpandPlaceholders(gStringVar4, gText_TimesStrVar1); - AddTextPrinterParameterized_ColorByIndex(windowId, FONT_0, gStringVar4, 0x7E, y, 0, 0, 0xFF, 1); + TMCase_Print(windowId, FONT_0, gStringVar4, 126, y, 0, 0, TEXT_SKIP_DRAW, COLOR_DARK); } else { @@ -571,62 +731,69 @@ static void TMCase_ItemPrintFunc(u8 windowId, u32 itemId, u8 y) } } -static void TMCase_MoveCursor_UpdatePrintedDescription(s32 itemIndex) +static void PrintDescription(s32 itemIndex) { const u8 * str; - if (itemIndex != -2) - { + if (itemIndex != LIST_CANCEL) str = ItemId_GetDescription(BagGetItemIdByPocketPosition(POCKET_TM_CASE, itemIndex)); - } else - { str = gText_TMCaseWillBePutAway; - } - FillWindowPixelBuffer(1, 0); - AddTextPrinterParameterized_ColorByIndex(1, FONT_2, str, 2, 3, 1, 0, 0, 0); + FillWindowPixelBuffer(WIN_DESCRIPTION, 0); + TMCase_Print(WIN_DESCRIPTION, FONT_2, str, 2, 3, 1, 0, 0, COLOR_LIGHT); } -static void FillBG2RowWithPalette_2timesNplus1(s32 a0) +// Darkens (or subsequently lightens) the blue bg tiles around the description window when a TM/HM is selected. +// shade=0: lighten, shade=1: darken +static void SetDescriptionWindowShade(s32 shade) { - SetBgTilemapPalette(2, 0, 12, 30, 8, 2 * a0 + 1); + SetBgTilemapPalette(2, 0, 12, 30, 8, 2 * shade + 1); ScheduleBgCopyTilemapToVram(2); } -static void PrintListMenuCursorByID_WithColorIdx(u8 a0, u8 a1) +static void PrintListCursor(u8 listTaskId, u8 colorIdx) { - PrintListMenuCursorAt_WithColorIdx(ListMenuGetYCoordForPrintingArrowCursor(a0), a1); + PrintListCursorAtRow(ListMenuGetYCoordForPrintingArrowCursor(listTaskId), colorIdx); } -static void PrintListMenuCursorAt_WithColorIdx(u8 a0, u8 a1) +static void PrintListCursorAtRow(u8 y, u8 colorIdx) { - if (a1 == 0xFF) + if (colorIdx == COLOR_CURSOR_ERASE) { - FillWindowPixelRect(0, 0, 0, a0, GetFontAttribute(FONT_2, FONTATTR_MAX_LETTER_WIDTH), GetFontAttribute(FONT_2, FONTATTR_MAX_LETTER_HEIGHT)); - CopyWindowToVram(0, COPYWIN_GFX); + // Never used. Would erase cursor (but also a portion of the list text) + FillWindowPixelRect(WIN_LIST, 0, 0, y, GetFontAttribute(FONT_2, FONTATTR_MAX_LETTER_WIDTH), GetFontAttribute(FONT_2, FONTATTR_MAX_LETTER_HEIGHT)); + CopyWindowToVram(WIN_LIST, COPYWIN_GFX); } else { - AddTextPrinterParameterized_ColorByIndex(0, FONT_2, gText_SelectorArrow2, 0, a0, 0, 0, 0, a1); + TMCase_Print(WIN_LIST, FONT_2, gText_SelectorArrow2, 0, y, 0, 0, 0, colorIdx); } } -static void CreateTMCaseScrollIndicatorArrowPair_Main(void) +static void CreateListScrollArrows(void) { - sTMCaseDynamicResources->scrollIndicatorArrowPairId = AddScrollIndicatorArrowPairParameterized(2, 0xA0, 0x08, 0x58, sTMCaseDynamicResources->numTMs - sTMCaseDynamicResources->maxTMsShown + 1, 0x6E, 0x6E, &sTMCaseStaticResources.scrollOffset); + sTMCaseDynamicResources->scrollArrowsTaskId = AddScrollIndicatorArrowPairParameterized(SCROLL_ARROW_UP, + 160, 8, 88, + sTMCaseDynamicResources->numTMs - sTMCaseDynamicResources->maxTMsShown + 1, + TAG_SCROLL_ARROW, TAG_SCROLL_ARROW, + &sTMCaseStaticResources.scrollOffset); } -static void CreateTMCaseScrollIndicatorArrowPair_SellQuantitySelect(void) +static void CreateQuantityScrollArrows(void) { sTMCaseDynamicResources->currItem = 1; - sTMCaseDynamicResources->scrollIndicatorArrowPairId = AddScrollIndicatorArrowPairParameterized(2, 0x98, 0x48, 0x68, 2, 0x6E, 0x6E, &sTMCaseDynamicResources->currItem); + sTMCaseDynamicResources->scrollArrowsTaskId = AddScrollIndicatorArrowPairParameterized(SCROLL_ARROW_UP, + 152, 72, 104, + 2, + TAG_SCROLL_ARROW, TAG_SCROLL_ARROW, + &sTMCaseDynamicResources->currItem); } -static void RemoveTMCaseScrollIndicatorArrowPair(void) +static void RemoveScrollArrows(void) { - if (sTMCaseDynamicResources->scrollIndicatorArrowPairId != 0xFF) + if (sTMCaseDynamicResources->scrollArrowsTaskId != TASK_NONE) { - RemoveScrollIndicatorArrowPair(sTMCaseDynamicResources->scrollIndicatorArrowPairId); - sTMCaseDynamicResources->scrollIndicatorArrowPairId = 0xFF; + RemoveScrollIndicatorArrowPair(sTMCaseDynamicResources->scrollArrowsTaskId); + sTMCaseDynamicResources->scrollArrowsTaskId = TASK_NONE; } } @@ -709,18 +876,18 @@ static void Task_FadeOutAndCloseTMCase(u8 taskId) if (!gPaletteFade.active) { - DestroyListMenuTask(data[0], &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); - if (sTMCaseDynamicResources->savedCallback != NULL) - SetMainCallback2(sTMCaseDynamicResources->savedCallback); + DestroyListMenuTask(tListTaskId, &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); + if (sTMCaseDynamicResources->nextScreenCallback != NULL) + SetMainCallback2(sTMCaseDynamicResources->nextScreenCallback); else - SetMainCallback2(sTMCaseStaticResources.savedCallback); - RemoveTMCaseScrollIndicatorArrowPair(); + SetMainCallback2(sTMCaseStaticResources.exitCallback); + RemoveScrollArrows(); DestroyTMCaseBuffers(); DestroyTask(taskId); } } -static void Task_TMCaseMain(u8 taskId) +static void Task_HandleListInput(u8 taskId) { s16 * data = gTasks[taskId].data; s32 input; @@ -729,9 +896,9 @@ static void Task_TMCaseMain(u8 taskId) { if (MenuHelpers_CallLinkSomething() != TRUE) { - input = ListMenu_ProcessInput(data[0]); - ListMenuGetScrollAndRow(data[0], &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); - if (JOY_NEW(SELECT_BUTTON) && sTMCaseStaticResources.unk_05 == 1) + input = ListMenu_ProcessInput(tListTaskId); + ListMenuGetScrollAndRow(tListTaskId, &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); + if (JOY_NEW(SELECT_BUTTON) && sTMCaseStaticResources.allowSelectClose == TRUE) { PlaySE(SE_SELECT); gSpecialVar_ItemId = ITEM_NONE; @@ -741,22 +908,22 @@ static void Task_TMCaseMain(u8 taskId) { switch (input) { - case -1: + case LIST_NOTHING_CHOSEN: break; - case -2: + case LIST_CANCEL: PlaySE(SE_SELECT); - gSpecialVar_ItemId = 0; + gSpecialVar_ItemId = ITEM_NONE; Task_BeginFadeOutFromTMCase(taskId); break; default: PlaySE(SE_SELECT); - FillBG2RowWithPalette_2timesNplus1(1); - RemoveTMCaseScrollIndicatorArrowPair(); - PrintListMenuCursorByID_WithColorIdx(data[0], 2); - data[1] = input; - data[2] = BagGetQuantityByPocketPosition(POCKET_TM_CASE, input); + SetDescriptionWindowShade(1); + RemoveScrollArrows(); + PrintListCursor(tListTaskId, COLOR_CURSOR_SELECTED); + tSelection = input; + tQuantityOwned = BagGetQuantityByPocketPosition(POCKET_TM_CASE, input); gSpecialVar_ItemId = BagGetItemIdByPocketPosition(POCKET_TM_CASE, input); - gTasks[taskId].func = sSelectTMActionTasks[sTMCaseStaticResources.tmCaseMenuType]; + gTasks[taskId].func = sSelectTMActionTasks[sTMCaseStaticResources.menuType]; break; } } @@ -764,47 +931,67 @@ static void Task_TMCaseMain(u8 taskId) } } -static void Subtask_ReturnToTMCaseMain(u8 taskId) +static void ReturnToList(u8 taskId) { - FillBG2RowWithPalette_2timesNplus1(0); - CreateTMCaseScrollIndicatorArrowPair_Main(); - gTasks[taskId].func = Task_TMCaseMain; + SetDescriptionWindowShade(0); + CreateListScrollArrows(); + gTasks[taskId].func = Task_HandleListInput; } -static void Task_SelectTMAction_FromFieldBag(u8 taskId) +// When a TM/HM in the list is selected in the field, create a context +// menu with a list of actions that can be taken. +static void Task_SelectedTMHM_Field(u8 taskId) { u8 * strbuf; - TMCase_SetWindowBorder2(2); + + // Create context window + TMCase_SetWindowBorder2(WIN_SELECTED_MSG); if (!MenuHelpers_LinkSomething() && InUnionRoom() != TRUE) { - AddTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId, 0); + // Regular TM/HM context menu + AddContextMenu(&sTMCaseDynamicResources->contextMenuWindowId, WIN_USE_GIVE_EXIT); sTMCaseDynamicResources->menuActionIndices = sMenuActionIndices_Field; - sTMCaseDynamicResources->numMenuActions = NELEMS(sMenuActionIndices_Field); + sTMCaseDynamicResources->numMenuActions = ARRAY_COUNT(sMenuActionIndices_Field); } else { - AddTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId, 1); + // In Union Room, "Use" is removed from the context menu + AddContextMenu(&sTMCaseDynamicResources->contextMenuWindowId, WIN_GIVE_EXIT); sTMCaseDynamicResources->menuActionIndices = sMenuActionIndices_UnionRoom; - sTMCaseDynamicResources->numMenuActions = NELEMS(sMenuActionIndices_UnionRoom); + sTMCaseDynamicResources->numMenuActions = ARRAY_COUNT(sMenuActionIndices_UnionRoom); } - AddItemMenuActionTextPrinters(sTMCaseDynamicResources->contextMenuWindowId, FONT_2, GetMenuCursorDimensionByFont(FONT_2, 0), 2, 0, GetFontAttribute(FONT_2, FONTATTR_MAX_LETTER_HEIGHT) + 2, sTMCaseDynamicResources->numMenuActions, sMenuActions_UseGiveExit, sTMCaseDynamicResources->menuActionIndices); + + // Print context window actions + AddItemMenuActionTextPrinters(sTMCaseDynamicResources->contextMenuWindowId, + FONT_2, + GetMenuCursorDimensionByFont(FONT_2, 0), + 2, + 0, + GetFontAttribute(FONT_2, FONTATTR_MAX_LETTER_HEIGHT) + 2, + sTMCaseDynamicResources->numMenuActions, + sMenuActions, + sTMCaseDynamicResources->menuActionIndices); + Menu_InitCursor(sTMCaseDynamicResources->contextMenuWindowId, FONT_2, 0, 2, GetFontAttribute(FONT_2, FONTATTR_MAX_LETTER_HEIGHT) + 2, sTMCaseDynamicResources->numMenuActions, 0); + + // Print label text next to the context window strbuf = Alloc(256); GetTMNumberAndMoveString(strbuf, gSpecialVar_ItemId); StringAppend(strbuf, gText_Var1IsSelected + 2); // +2 skips over the stringvar - AddTextPrinterParameterized_ColorByIndex(2, FONT_2, strbuf, 0, 2, 1, 0, 0, 1); + TMCase_Print(WIN_SELECTED_MSG, FONT_2, strbuf, 0, 2, 1, 0, 0, COLOR_DARK); Free(strbuf); - if (itemid_is_unique(gSpecialVar_ItemId)) + if (IS_HM(gSpecialVar_ItemId)) { - PlaceHMTileInWindow(2, 0, 2); - CopyWindowToVram(2, COPYWIN_GFX); + PlaceHMTileInWindow(WIN_SELECTED_MSG, 0, 2); + CopyWindowToVram(WIN_SELECTED_MSG, COPYWIN_GFX); } + ScheduleBgCopyTilemapToVram(0); ScheduleBgCopyTilemapToVram(1); - gTasks[taskId].func = Task_TMContextMenu_HandleInput; + gTasks[taskId].func = Task_ContextMenu_HandleInput; } -static void Task_TMContextMenu_HandleInput(u8 taskId) +static void Task_ContextMenu_HandleInput(u8 taskId) { s8 input; @@ -813,26 +1000,27 @@ static void Task_TMContextMenu_HandleInput(u8 taskId) input = Menu_ProcessInputNoWrapAround(); switch (input) { - case -1: + case MENU_B_PRESSED: + // Run last action in list (Exit) PlaySE(SE_SELECT); - sMenuActions_UseGiveExit[sTMCaseDynamicResources->menuActionIndices[sTMCaseDynamicResources->numMenuActions - 1]].func.void_u8(taskId); + sMenuActions[sTMCaseDynamicResources->menuActionIndices[sTMCaseDynamicResources->numMenuActions - 1]].func.void_u8(taskId); break; - case -2: + case MENU_NOTHING_CHOSEN: break; default: PlaySE(SE_SELECT); - sMenuActions_UseGiveExit[sTMCaseDynamicResources->menuActionIndices[input]].func.void_u8(taskId); + sMenuActions[sTMCaseDynamicResources->menuActionIndices[input]].func.void_u8(taskId); break; } } } -static void TMHMContextMenuAction_Use(u8 taskId) +static void Action_Use(u8 taskId) { - RemoveTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId); - ClearStdWindowAndFrameToTransparent(2, FALSE); - ClearWindowTilemap(2); - PutWindowTilemap(0); + RemoveContextMenu(&sTMCaseDynamicResources->contextMenuWindowId); + ClearStdWindowAndFrameToTransparent(WIN_SELECTED_MSG, FALSE); + ClearWindowTilemap(WIN_SELECTED_MSG); + PutWindowTilemap(WIN_LIST); ScheduleBgCopyTilemapToVram(0); ScheduleBgCopyTilemapToVram(1); if (CalculatePlayerPartyCount() == 0) @@ -841,25 +1029,26 @@ static void TMHMContextMenuAction_Use(u8 taskId) } else { + // Chose a TM/HM to use, exit TM case for party menu gItemUseCB = ItemUseCB_TMHM; - sTMCaseDynamicResources->savedCallback = CB2_ShowPartyMenuForItemUse; + sTMCaseDynamicResources->nextScreenCallback = CB2_ShowPartyMenuForItemUse; Task_BeginFadeOutFromTMCase(taskId); } } -static void TMHMContextMenuAction_Give(u8 taskId) +static void Action_Give(u8 taskId) { s16 * data = gTasks[taskId].data; - u16 itemId = BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1]); - RemoveTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId); - ClearStdWindowAndFrameToTransparent(2, FALSE); - ClearWindowTilemap(2); - PutWindowTilemap(1); - PutWindowTilemap(4); - PutWindowTilemap(5); + u16 itemId = BagGetItemIdByPocketPosition(POCKET_TM_CASE, tSelection); + RemoveContextMenu(&sTMCaseDynamicResources->contextMenuWindowId); + ClearStdWindowAndFrameToTransparent(WIN_SELECTED_MSG, FALSE); + ClearWindowTilemap(WIN_SELECTED_MSG); + PutWindowTilemap(WIN_DESCRIPTION); + PutWindowTilemap(WIN_MOVE_INFO_LABELS); + PutWindowTilemap(WIN_MOVE_INFO); ScheduleBgCopyTilemapToVram(0); ScheduleBgCopyTilemapToVram(1); - if (!itemid_is_unique(itemId)) + if (!IS_HM(itemId)) { if (CalculatePlayerPartyCount() == 0) { @@ -867,7 +1056,7 @@ static void TMHMContextMenuAction_Give(u8 taskId) } else { - sTMCaseDynamicResources->savedCallback = CB2_ChooseMonToGiveItem; + sTMCaseDynamicResources->nextScreenCallback = CB2_ChooseMonToGiveItem; Task_BeginFadeOutFromTMCase(taskId); } } @@ -879,14 +1068,14 @@ static void TMHMContextMenuAction_Give(u8 taskId) static void PrintError_ThereIsNoPokemon(u8 taskId) { - TMCase_PrintMessageWithFollowupTask(taskId, FONT_2, gText_ThereIsNoPokemon, Task_WaitButtonAfterErrorPrint); + PrintMessageWithFollowupTask(taskId, FONT_2, gText_ThereIsNoPokemon, Task_WaitButtonAfterErrorPrint); } static void PrintError_ItemCantBeHeld(u8 taskId) { CopyItemName(gSpecialVar_ItemId, gStringVar1); StringExpandPlaceholders(gStringVar4, gText_ItemCantBeHeld); - TMCase_PrintMessageWithFollowupTask(taskId, FONT_2, gStringVar4, Task_WaitButtonAfterErrorPrint); + PrintMessageWithFollowupTask(taskId, FONT_2, gStringVar4, Task_WaitButtonAfterErrorPrint); } static void Task_WaitButtonAfterErrorPrint(u8 taskId) @@ -894,99 +1083,102 @@ static void Task_WaitButtonAfterErrorPrint(u8 taskId) if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); - Subtask_CloseContextMenuAndReturnToMain(taskId); + CloseMessageAndReturnToList(taskId); } } -static void Subtask_CloseContextMenuAndReturnToMain(u8 taskId) +static void CloseMessageAndReturnToList(u8 taskId) { s16 * data = gTasks[taskId].data; - DestroyListMenuTask(data[0], &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); - data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sTMCaseStaticResources.scrollOffset, sTMCaseStaticResources.selectedRow); - PrintListMenuCursorByID_WithColorIdx(data[0], 1); - ClearDialogWindowAndFrameToTransparent(6, FALSE); - ClearWindowTilemap(6); - PutWindowTilemap(1); - PutWindowTilemap(4); - PutWindowTilemap(5); + DestroyListMenuTask(tListTaskId, &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); + tListTaskId = ListMenuInit(&gMultiuseListMenuTemplate, sTMCaseStaticResources.scrollOffset, sTMCaseStaticResources.selectedRow); + PrintListCursor(tListTaskId, COLOR_DARK); + ClearDialogWindowAndFrameToTransparent(WIN_MESSAGE, FALSE); + ClearWindowTilemap(WIN_MESSAGE); + PutWindowTilemap(WIN_DESCRIPTION); + PutWindowTilemap(WIN_MOVE_INFO_LABELS); + PutWindowTilemap(WIN_MOVE_INFO); ScheduleBgCopyTilemapToVram(0); ScheduleBgCopyTilemapToVram(1); - Subtask_ReturnToTMCaseMain(taskId); + ReturnToList(taskId); } -static void TMHMContextMenuAction_Exit(u8 taskId) +static void Action_Exit(u8 taskId) { s16 * data = gTasks[taskId].data; - RemoveTMContextMenu(&sTMCaseDynamicResources->contextMenuWindowId); - ClearStdWindowAndFrameToTransparent(2, FALSE); - ClearWindowTilemap(2); - PutWindowTilemap(0); - PrintListMenuCursorByID_WithColorIdx(data[0], 1); - PutWindowTilemap(1); - PutWindowTilemap(4); - PutWindowTilemap(5); + RemoveContextMenu(&sTMCaseDynamicResources->contextMenuWindowId); + ClearStdWindowAndFrameToTransparent(WIN_SELECTED_MSG, FALSE); + ClearWindowTilemap(WIN_SELECTED_MSG); + PutWindowTilemap(WIN_LIST); + PrintListCursor(tListTaskId, COLOR_DARK); + PutWindowTilemap(WIN_DESCRIPTION); + PutWindowTilemap(WIN_MOVE_INFO_LABELS); + PutWindowTilemap(WIN_MOVE_INFO); ScheduleBgCopyTilemapToVram(0); ScheduleBgCopyTilemapToVram(1); - Subtask_ReturnToTMCaseMain(taskId); + ReturnToList(taskId); } -static void Task_SelectTMAction_Type1(u8 taskId) +static void Task_SelectedTMHM_GiveParty(u8 taskId) { s16 * data = gTasks[taskId].data; - if (!itemid_is_unique(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1]))) + if (!IS_HM(BagGetItemIdByPocketPosition(POCKET_TM_CASE, tSelection))) { - sTMCaseDynamicResources->savedCallback = CB2_GiveHoldItem; + sTMCaseDynamicResources->nextScreenCallback = CB2_GiveHoldItem; Task_BeginFadeOutFromTMCase(taskId); } else { + // Can't hold "important" items (e.g. key items) PrintError_ItemCantBeHeld(taskId); } } -static void Task_SelectTMAction_Type3(u8 taskId) +static void Task_SelectedTMHM_GivePC(u8 taskId) { s16 * data = gTasks[taskId].data; - if (!itemid_is_unique(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1]))) + if (!IS_HM(BagGetItemIdByPocketPosition(POCKET_TM_CASE, tSelection))) { - sTMCaseDynamicResources->savedCallback = CB2_ReturnToPokeStorage; + sTMCaseDynamicResources->nextScreenCallback = CB2_ReturnToPokeStorage; Task_BeginFadeOutFromTMCase(taskId); } else { + // Can't hold "important" items (e.g. key items) PrintError_ItemCantBeHeld(taskId); } } -static void Task_SelectTMAction_FromSellMenu(u8 taskId) +static void Task_SelectedTMHM_Sell(u8 taskId) { s16 * data = gTasks[taskId].data; - if (itemid_get_market_price(gSpecialVar_ItemId) == 0) + if (ItemId_GetPrice(gSpecialVar_ItemId) == 0) { + // Can't sell TM/HMs with no price (by default this is just the HMs) CopyItemName(gSpecialVar_ItemId, gStringVar1); StringExpandPlaceholders(gStringVar4, gText_OhNoICantBuyThat); - TMCase_PrintMessageWithFollowupTask(taskId, GetDialogBoxFontId(), gStringVar4, Subtask_CloseContextMenuAndReturnToMain); + PrintMessageWithFollowupTask(taskId, GetDialogBoxFontId(), gStringVar4, CloseMessageAndReturnToList); } else { - data[8] = 1; - if (data[2] == 1) + tQuantitySelected = 1; + if (tQuantityOwned == 1) { - HandlePrintMoneyOnHand(); + PrintPlayersMoney(); Task_AskConfirmSaleWithAmount(taskId); } else { - if (data[2] > 99) - data[2] = 99; + if (tQuantityOwned > 99) + tQuantityOwned = 99; CopyItemName(gSpecialVar_ItemId, gStringVar1); StringExpandPlaceholders(gStringVar4, gText_HowManyWouldYouLikeToSell); - TMCase_PrintMessageWithFollowupTask(taskId, GetDialogBoxFontId(), gStringVar4, Task_InitQuantitySelectUI); + PrintMessageWithFollowupTask(taskId, GetDialogBoxFontId(), gStringVar4, Task_InitQuantitySelectUI); } } } @@ -995,9 +1187,9 @@ static void Task_AskConfirmSaleWithAmount(u8 taskId) { s16 * data = gTasks[taskId].data; - ConvertIntToDecimalStringN(gStringVar3, itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1])) / 2 * data[8], STR_CONV_MODE_LEFT_ALIGN, 6); + ConvertIntToDecimalStringN(gStringVar3, ItemId_GetPrice(BagGetItemIdByPocketPosition(POCKET_TM_CASE, tSelection)) / 2 * tQuantitySelected, STR_CONV_MODE_LEFT_ALIGN, 6); StringExpandPlaceholders(gStringVar4, gText_ICanPayThisMuch_WouldThatBeOkay); - TMCase_PrintMessageWithFollowupTask(taskId, GetDialogBoxFontId(), gStringVar4, Task_PlaceYesNoBox); + PrintMessageWithFollowupTask(taskId, GetDialogBoxFontId(), gStringVar4, Task_PlaceYesNoBox); } static void Task_PlaceYesNoBox(u8 taskId) @@ -1009,30 +1201,30 @@ static void Task_SaleOfTMsCanceled(u8 taskId) { s16 * data = gTasks[taskId].data; - ClearStdWindowAndFrameToTransparent(8, FALSE); - ClearDialogWindowAndFrameToTransparent(6, FALSE); - PutWindowTilemap(0); - PutWindowTilemap(1); - PutWindowTilemap(3); - PutWindowTilemap(4); - PutWindowTilemap(5); + ClearStdWindowAndFrameToTransparent(WIN_MONEY, FALSE); + ClearDialogWindowAndFrameToTransparent(WIN_MESSAGE, FALSE); + PutWindowTilemap(WIN_LIST); + PutWindowTilemap(WIN_DESCRIPTION); + PutWindowTilemap(WIN_TITLE); + PutWindowTilemap(WIN_MOVE_INFO_LABELS); + PutWindowTilemap(WIN_MOVE_INFO); ScheduleBgCopyTilemapToVram(0); ScheduleBgCopyTilemapToVram(1); - PrintListMenuCursorByID_WithColorIdx(data[0], 1); - Subtask_ReturnToTMCaseMain(taskId); + PrintListCursor(tListTaskId, COLOR_DARK); + ReturnToList(taskId); } static void Task_InitQuantitySelectUI(u8 taskId) { s16 * data = gTasks[taskId].data; - TMCase_SetWindowBorder1(7); + TMCase_SetWindowBorder1(WIN_SELL_QUANTITY); ConvertIntToDecimalStringN(gStringVar1, 1, STR_CONV_MODE_LEADING_ZEROS, 2); StringExpandPlaceholders(gStringVar4, gText_TimesStrVar1); - AddTextPrinterParameterized_ColorByIndex(7, FONT_0, gStringVar4, 4, 10, 1, 0, 0, 1); - SellTM_PrintQuantityAndSalePrice(1, itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1])) / 2 * data[8]); - HandlePrintMoneyOnHand(); - CreateTMCaseScrollIndicatorArrowPair_SellQuantitySelect(); + TMCase_Print(WIN_SELL_QUANTITY, FONT_0, gStringVar4, 4, 10, 1, 0, 0, COLOR_DARK); + SellTM_PrintQuantityAndSalePrice(1, ItemId_GetPrice(BagGetItemIdByPocketPosition(POCKET_TM_CASE, tSelection)) / 2 * tQuantitySelected); + PrintPlayersMoney(); + CreateQuantityScrollArrows(); ScheduleBgCopyTilemapToVram(0); ScheduleBgCopyTilemapToVram(1); gTasks[taskId].func = Task_QuantitySelect_HandleInput; @@ -1040,44 +1232,44 @@ static void Task_InitQuantitySelectUI(u8 taskId) static void SellTM_PrintQuantityAndSalePrice(s16 quantity, s32 amount) { - FillWindowPixelBuffer(7, 0x11); + FillWindowPixelBuffer(WIN_SELL_QUANTITY, 0x11); ConvertIntToDecimalStringN(gStringVar1, quantity, STR_CONV_MODE_LEADING_ZEROS, 2); StringExpandPlaceholders(gStringVar4, gText_TimesStrVar1); - AddTextPrinterParameterized_ColorByIndex(7, FONT_0, gStringVar4, 4, 10, 1, 0, 0, 1); - PrintMoneyAmount(7, 0x38, 0x0A, amount, 0); + TMCase_Print(WIN_SELL_QUANTITY, FONT_0, gStringVar4, 4, 10, 1, 0, 0, COLOR_DARK); + PrintMoneyAmount(WIN_SELL_QUANTITY, 0x38, 0x0A, amount, 0); } static void Task_QuantitySelect_HandleInput(u8 taskId) { s16 * data = gTasks[taskId].data; - if (AdjustQuantityAccordingToDPadInput(&data[8], data[2]) == 1) + if (AdjustQuantityAccordingToDPadInput(&tQuantitySelected, tQuantityOwned) == 1) { - SellTM_PrintQuantityAndSalePrice(data[8], itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1])) / 2 * data[8]); + SellTM_PrintQuantityAndSalePrice(tQuantitySelected, ItemId_GetPrice(BagGetItemIdByPocketPosition(POCKET_TM_CASE, tSelection)) / 2 * tQuantitySelected); } else if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); - ClearStdWindowAndFrameToTransparent(7, FALSE); + ClearStdWindowAndFrameToTransparent(WIN_SELL_QUANTITY, FALSE); ScheduleBgCopyTilemapToVram(0); ScheduleBgCopyTilemapToVram(1); - RemoveTMCaseScrollIndicatorArrowPair(); + RemoveScrollArrows(); Task_AskConfirmSaleWithAmount(taskId); } else if (JOY_NEW(B_BUTTON)) { PlaySE(SE_SELECT); - ClearStdWindowAndFrameToTransparent(7, FALSE); - ClearStdWindowAndFrameToTransparent(8, FALSE); - ClearDialogWindowAndFrameToTransparent(6, FALSE); - PutWindowTilemap(3); - PutWindowTilemap(0); - PutWindowTilemap(1); + ClearStdWindowAndFrameToTransparent(WIN_SELL_QUANTITY, FALSE); + ClearStdWindowAndFrameToTransparent(WIN_MONEY, FALSE); + ClearDialogWindowAndFrameToTransparent(WIN_MESSAGE, FALSE); + PutWindowTilemap(WIN_TITLE); + PutWindowTilemap(WIN_LIST); + PutWindowTilemap(WIN_DESCRIPTION); ScheduleBgCopyTilemapToVram(0); ScheduleBgCopyTilemapToVram(1); - RemoveTMCaseScrollIndicatorArrowPair(); - PrintListMenuCursorByID_WithColorIdx(data[0], 1); - Subtask_ReturnToTMCaseMain(taskId); + RemoveScrollArrows(); + PrintListCursor(tListTaskId, COLOR_DARK); + ReturnToList(taskId); } } @@ -1085,12 +1277,12 @@ static void Task_PrintSaleConfirmedText(u8 taskId) { s16 * data = gTasks[taskId].data; - PutWindowTilemap(0); + PutWindowTilemap(WIN_LIST); ScheduleBgCopyTilemapToVram(0); CopyItemName(gSpecialVar_ItemId, gStringVar1); - ConvertIntToDecimalStringN(gStringVar3, itemid_get_market_price(BagGetItemIdByPocketPosition(POCKET_TM_CASE, data[1])) / 2 * data[8], STR_CONV_MODE_LEFT_ALIGN, 6); + ConvertIntToDecimalStringN(gStringVar3, ItemId_GetPrice(BagGetItemIdByPocketPosition(POCKET_TM_CASE, tSelection)) / 2 * tQuantitySelected, STR_CONV_MODE_LEFT_ALIGN, 6); StringExpandPlaceholders(gStringVar4, gText_TurnedOverItemsWorthYen); - TMCase_PrintMessageWithFollowupTask(taskId, FONT_2, gStringVar4, Task_DoSaleOfTMs); + PrintMessageWithFollowupTask(taskId, FONT_2, gStringVar4, Task_DoSaleOfTMs); } static void Task_DoSaleOfTMs(u8 taskId) @@ -1098,16 +1290,16 @@ static void Task_DoSaleOfTMs(u8 taskId) s16 * data = gTasks[taskId].data; PlaySE(SE_SHOP); - RemoveBagItem(gSpecialVar_ItemId, data[8]); - AddMoney(&gSaveBlock1Ptr->money, itemid_get_market_price(gSpecialVar_ItemId) / 2 * data[8]); - RecordItemPurchase(gSpecialVar_ItemId, data[8], 2); - DestroyListMenuTask(data[0], &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); + RemoveBagItem(gSpecialVar_ItemId, tQuantitySelected); + AddMoney(&gSaveBlock1Ptr->money, ItemId_GetPrice(gSpecialVar_ItemId) / 2 * tQuantitySelected); + RecordItemPurchase(gSpecialVar_ItemId, tQuantitySelected, 2); + DestroyListMenuTask(tListTaskId, &sTMCaseStaticResources.scrollOffset, &sTMCaseStaticResources.selectedRow); TMCaseSetup_GetTMCount(); TMCaseSetup_InitListMenuPositions(); InitTMCaseListMenuItems(); - data[0] = ListMenuInit(&gMultiuseListMenuTemplate, sTMCaseStaticResources.scrollOffset, sTMCaseStaticResources.selectedRow); - PrintListMenuCursorByID_WithColorIdx(data[0], 2); - PrintMoneyAmountInMoneyBox(8, GetMoney(&gSaveBlock1Ptr->money), 0); + tListTaskId = ListMenuInit(&gMultiuseListMenuTemplate, sTMCaseStaticResources.scrollOffset, sTMCaseStaticResources.selectedRow); + PrintListCursor(tListTaskId, COLOR_CURSOR_SELECTED); + PrintMoneyAmountInMoneyBox(WIN_MONEY, GetMoney(&gSaveBlock1Ptr->money), 0); gTasks[taskId].func = Task_AfterSale_ReturnToList; } @@ -1116,74 +1308,75 @@ static void Task_AfterSale_ReturnToList(u8 taskId) if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON)) { PlaySE(SE_SELECT); - ClearStdWindowAndFrameToTransparent(8, FALSE); - ClearDialogWindowAndFrameToTransparent(6, FALSE); - PutWindowTilemap(1); - PutWindowTilemap(3); - PutWindowTilemap(4); - PutWindowTilemap(5); - Subtask_CloseContextMenuAndReturnToMain(taskId); + ClearStdWindowAndFrameToTransparent(WIN_MONEY, FALSE); + ClearDialogWindowAndFrameToTransparent(WIN_MESSAGE, FALSE); + PutWindowTilemap(WIN_DESCRIPTION); + PutWindowTilemap(WIN_TITLE); + PutWindowTilemap(WIN_MOVE_INFO_LABELS); + PutWindowTilemap(WIN_MOVE_INFO); + CloseMessageAndReturnToList(taskId); } } void Pokedude_InitTMCase(void) { - sPokedudePackBackup = AllocZeroed(sizeof(*sPokedudePackBackup)); - memcpy(sPokedudePackBackup->bagPocket_TMHM, gSaveBlock1Ptr->bagPocket_TMHM, sizeof(gSaveBlock1Ptr->bagPocket_TMHM)); - memcpy(sPokedudePackBackup->bagPocket_KeyItems, gSaveBlock1Ptr->bagPocket_KeyItems, sizeof(gSaveBlock1Ptr->bagPocket_KeyItems)); - sPokedudePackBackup->unk_160 = sTMCaseStaticResources.selectedRow; - sPokedudePackBackup->unk_162 = sTMCaseStaticResources.scrollOffset; - ClearItemSlots(gSaveBlock1Ptr->bagPocket_TMHM, NELEMS(gSaveBlock1Ptr->bagPocket_TMHM)); - ClearItemSlots(gSaveBlock1Ptr->bagPocket_KeyItems, NELEMS(gSaveBlock1Ptr->bagPocket_KeyItems)); + sPokedudeBagBackup = AllocZeroed(sizeof(*sPokedudeBagBackup)); + memcpy(sPokedudeBagBackup->bagPocket_TMHM, gSaveBlock1Ptr->bagPocket_TMHM, sizeof(gSaveBlock1Ptr->bagPocket_TMHM)); + memcpy(sPokedudeBagBackup->bagPocket_KeyItems, gSaveBlock1Ptr->bagPocket_KeyItems, sizeof(gSaveBlock1Ptr->bagPocket_KeyItems)); + sPokedudeBagBackup->selectedRow = sTMCaseStaticResources.selectedRow; + sPokedudeBagBackup->scrollOffset = sTMCaseStaticResources.scrollOffset; + ClearItemSlots(gSaveBlock1Ptr->bagPocket_TMHM, ARRAY_COUNT(gSaveBlock1Ptr->bagPocket_TMHM)); + ClearItemSlots(gSaveBlock1Ptr->bagPocket_KeyItems, ARRAY_COUNT(gSaveBlock1Ptr->bagPocket_KeyItems)); ResetTMCaseCursorPos(); AddBagItem(ITEM_TM01, 1); AddBagItem(ITEM_TM03, 1); AddBagItem(ITEM_TM09, 1); AddBagItem(ITEM_TM35, 1); - InitTMCase(4, CB2_ReturnToTeachyTV, 0); + InitTMCase(TMCASE_POKEDUDE, CB2_ReturnToTeachyTV, 0); } -static void Task_TMCaseDude1(u8 taskId) +static void Task_Pokedude_Start(u8 taskId) { s16 * data = gTasks[taskId].data; if (!gPaletteFade.active) { - data[8] = 0; - data[9] = 0; - gTasks[taskId].func = Task_TMCaseDude_Playback; + tPokedudeState = 0; + tPokedudeTimer = 0; + gTasks[taskId].func = Task_Pokedude_Run; } } -static void Task_TMCaseDude_Playback(u8 taskId) +#define POKEDUDE_INPUT_DELAY 101 + +static void Task_Pokedude_Run(u8 taskId) { s16 * data = gTasks[taskId].data; if (JOY_NEW(B_BUTTON)) { - if (data[8] < 21) + if (tPokedudeState < 21) { - data[8] = 21; + tPokedudeState = 21; SetTeachyTvControllerModeToResume(); } } - switch (data[8]) + switch (tPokedudeState) { case 0: BeginNormalPaletteFade(0xFFFF8405, 4, 0, 6, 0); - FillBG2RowWithPalette_2timesNplus1(1); - data[8]++; + SetDescriptionWindowShade(1); + tPokedudeState++; break; case 1: case 11: if (!gPaletteFade.active) { - data[9]++; - if (data[9] > 0x65) + if (++tPokedudeTimer > POKEDUDE_INPUT_DELAY) { - data[9] = 0; - data[8]++; + tPokedudeTimer = 0; + tPokedudeState++; } } break; @@ -1193,17 +1386,16 @@ static void Task_TMCaseDude_Playback(u8 taskId) case 12: case 13: case 14: - if (data[9] == 0) + if (tPokedudeTimer == 0) { gMain.newKeys = 0; gMain.newAndRepeatedKeys = DPAD_DOWN; - ListMenu_ProcessInput(data[0]); + ListMenu_ProcessInput(tListTaskId); } - data[9]++; - if (data[9] > 0x65) + if (++tPokedudeTimer > POKEDUDE_INPUT_DELAY) { - data[9] = 0; - data[8]++; + tPokedudeTimer = 0; + tPokedudeState++; } break; case 5: @@ -1212,71 +1404,71 @@ static void Task_TMCaseDude_Playback(u8 taskId) case 15: case 16: case 17: - if (data[9] == 0) + if (tPokedudeTimer == 0) { gMain.newKeys = 0; gMain.newAndRepeatedKeys = DPAD_UP; - ListMenu_ProcessInput(data[0]); + ListMenu_ProcessInput(tListTaskId); } - data[9]++; - if (data[9] > 0x65) + if (++tPokedudeTimer > POKEDUDE_INPUT_DELAY) { - data[9] = 0; - data[8]++; + tPokedudeTimer = 0; + tPokedudeState++; } break; case 8: - FillBG2RowWithPalette_2timesNplus1(1); - TMCase_PrintMessageWithFollowupTask(taskId, FONT_4, gPokedudeText_TMTypes, 0); - gTasks[taskId].func = Task_TMCaseDude_Playback; - data[8]++; + SetDescriptionWindowShade(1); + PrintMessageWithFollowupTask(taskId, FONT_4, gPokedudeText_TMTypes, NULL); + gTasks[taskId].func = Task_Pokedude_Run; + tPokedudeState++; break; case 9: case 19: RunTextPrinters(); - if (!IsTextPrinterActive(6)) - data[8]++; + if (!IsTextPrinterActive(WIN_MESSAGE)) + tPokedudeState++; break; case 10: if (JOY_NEW(A_BUTTON | B_BUTTON)) { - FillBG2RowWithPalette_2timesNplus1(0); + SetDescriptionWindowShade(0); BeginNormalPaletteFade(0x00000400, 0, 6, 0, 0); - ClearDialogWindowAndFrameToTransparent(6, FALSE); + ClearDialogWindowAndFrameToTransparent(WIN_MESSAGE, FALSE); ScheduleBgCopyTilemapToVram(1); - data[8]++; + tPokedudeState++; } break; case 18: - FillBG2RowWithPalette_2timesNplus1(1); - TMCase_PrintMessageWithFollowupTask(taskId, FONT_4, gPokedudeText_ReadTMDescription, NULL); - gTasks[taskId].func = Task_TMCaseDude_Playback; // this function - data[8]++; + SetDescriptionWindowShade(1); + PrintMessageWithFollowupTask(taskId, FONT_4, gPokedudeText_ReadTMDescription, NULL); + gTasks[taskId].func = Task_Pokedude_Run; // this function + tPokedudeState++; break; case 20: if (JOY_NEW(A_BUTTON | B_BUTTON)) - data[8]++; + tPokedudeState++; break; case 21: if (!gPaletteFade.active) { - memcpy(gSaveBlock1Ptr->bagPocket_TMHM, sPokedudePackBackup->bagPocket_TMHM, sizeof(gSaveBlock1Ptr->bagPocket_TMHM)); - memcpy(gSaveBlock1Ptr->bagPocket_KeyItems, sPokedudePackBackup->bagPocket_KeyItems, sizeof(gSaveBlock1Ptr->bagPocket_KeyItems)); - DestroyListMenuTask(data[0], NULL, NULL); - sTMCaseStaticResources.selectedRow = sPokedudePackBackup->unk_160; - sTMCaseStaticResources.scrollOffset = sPokedudePackBackup->unk_162; - Free(sPokedudePackBackup); + // Restore the player's bag + memcpy(gSaveBlock1Ptr->bagPocket_TMHM, sPokedudeBagBackup->bagPocket_TMHM, sizeof(gSaveBlock1Ptr->bagPocket_TMHM)); + memcpy(gSaveBlock1Ptr->bagPocket_KeyItems, sPokedudeBagBackup->bagPocket_KeyItems, sizeof(gSaveBlock1Ptr->bagPocket_KeyItems)); + DestroyListMenuTask(tListTaskId, NULL, NULL); + sTMCaseStaticResources.selectedRow = sPokedudeBagBackup->selectedRow; + sTMCaseStaticResources.scrollOffset = sPokedudeBagBackup->scrollOffset; + Free(sPokedudeBagBackup); CpuFastCopy(gPlttBufferFaded, gPlttBufferUnfaded, 0x400); CB2_SetUpReshowBattleScreenAfterMenu(); BeginNormalPaletteFade(PALETTES_ALL, -2, 0, 16, 0); - data[8]++; + tPokedudeState++; } break; default: if (!gPaletteFade.active) { - SetMainCallback2(sTMCaseStaticResources.savedCallback); - RemoveTMCaseScrollIndicatorArrowPair(); + SetMainCallback2(sTMCaseStaticResources.exitCallback); + RemoveScrollArrows(); DestroyTMCaseBuffers(); DestroyTask(taskId); } @@ -1298,17 +1490,17 @@ static void InitWindowTemplatesAndPals(void) LoadPalette(sPal3Override, 0xF6, 0x04); LoadPalette(sPal3Override, 0xD6, 0x04); ListMenuLoadStdPalAt(0xc0, 0x01); - for (i = 0; i < 9; i++) + for (i = 0; i < ARRAY_COUNT(sWindowTemplates) - 1; i++) FillWindowPixelBuffer(i, 0x00); - PutWindowTilemap(0); - PutWindowTilemap(1); - PutWindowTilemap(3); - PutWindowTilemap(4); - PutWindowTilemap(5); + PutWindowTilemap(WIN_LIST); + PutWindowTilemap(WIN_DESCRIPTION); + PutWindowTilemap(WIN_TITLE); + PutWindowTilemap(WIN_MOVE_INFO_LABELS); + PutWindowTilemap(WIN_MOVE_INFO); ScheduleBgCopyTilemapToVram(0); } -static void AddTextPrinterParameterized_ColorByIndex(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, u8 speed, u8 colorIdx) +static void TMCase_Print(u8 windowId, u8 fontId, const u8 * str, u8 x, u8 y, u8 letterSpacing, u8 lineSpacing, u8 speed, u8 colorIdx) { AddTextPrinterParameterized4(windowId, fontId, x, y, letterSpacing, lineSpacing, sTextColors[colorIdx], speed, str); } @@ -1323,46 +1515,47 @@ static void TMCase_SetWindowBorder2(u8 windowId) DrawStdFrameWithCustomTileAndPalette(windowId, FALSE, 0x78, 0x0D); } -static void TMCase_PrintMessageWithFollowupTask(u8 taskId, u8 fontId, const u8 * str, TaskFunc func) +static void PrintMessageWithFollowupTask(u8 taskId, u8 fontId, const u8 * str, TaskFunc func) { - DisplayMessageAndContinueTask(taskId, 6, 0x64, 0x0B, fontId, GetTextSpeedSetting(), str, func); + DisplayMessageAndContinueTask(taskId, WIN_MESSAGE, 0x64, 0x0B, fontId, GetTextSpeedSetting(), str, func); ScheduleBgCopyTilemapToVram(1); } -static void PrintStringTMCaseOnWindow3(void) +static void PrintTitle(void) { u32 distance = 72 - GetStringWidth(FONT_1, gText_TMCase, 0); - AddTextPrinterParameterized3(3, FONT_1, distance / 2, 1, sTextColors[0], 0, gText_TMCase); + AddTextPrinterParameterized3(WIN_TITLE, FONT_1, distance / 2, 1, sTextColors[COLOR_LIGHT], 0, gText_TMCase); } -static void DrawMoveInfoUIMarkers(void) +static void DrawMoveInfoLabels(void) { - BlitMoveInfoIcon(4, 19, 0, 0); - BlitMoveInfoIcon(4, 20, 0, 12); - BlitMoveInfoIcon(4, 21, 0, 24); - BlitMoveInfoIcon(4, 22, 0, 36); - CopyWindowToVram(4, COPYWIN_GFX); + BlitMoveInfoIcon(WIN_MOVE_INFO_LABELS, 19, 0, 0); + BlitMoveInfoIcon(WIN_MOVE_INFO_LABELS, 20, 0, 12); + BlitMoveInfoIcon(WIN_MOVE_INFO_LABELS, 21, 0, 24); + BlitMoveInfoIcon(WIN_MOVE_INFO_LABELS, 22, 0, 36); + CopyWindowToVram(WIN_MOVE_INFO_LABELS, COPYWIN_GFX); } -static void TMCase_MoveCursor_UpdatePrintedTMInfo(u16 itemId) +static void PrintMoveInfo(u16 itemId) { u8 i; u16 move; const u8 * str; - FillWindowPixelRect(5, 0, 0, 0, 40, 48); + FillWindowPixelRect(WIN_MOVE_INFO, 0, 0, 0, 40, 48); if (itemId == ITEM_NONE) { for (i = 0; i < 4; i++) - { - AddTextPrinterParameterized_ColorByIndex(5, FONT_3, gText_ThreeHyphens, 7, 12 * i, 0, 0, 0xFF, 3); - } - CopyWindowToVram(5, COPYWIN_GFX); + TMCase_Print(WIN_MOVE_INFO, FONT_3, gText_ThreeHyphens, 7, 12 * i, 0, 0, TEXT_SKIP_DRAW, COLOR_MOVE_INFO); + CopyWindowToVram(WIN_MOVE_INFO, COPYWIN_GFX); } else { + // Draw type icon move = ItemIdToBattleMoveId(itemId); - BlitMoveInfoIcon(5, gBattleMoves[move].type + 1, 0, 0); + BlitMoveInfoIcon(WIN_MOVE_INFO, gBattleMoves[move].type + 1, 0, 0); + + // Print power if (gBattleMoves[move].power < 2) str = gText_ThreeHyphens; else @@ -1370,7 +1563,9 @@ static void TMCase_MoveCursor_UpdatePrintedTMInfo(u16 itemId) ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[move].power, STR_CONV_MODE_RIGHT_ALIGN, 3); str = gStringVar1; } - AddTextPrinterParameterized_ColorByIndex(5, FONT_3, str, 7, 12, 0, 0, 0xFF, 3); + TMCase_Print(WIN_MOVE_INFO, FONT_3, str, 7, 12, 0, 0, TEXT_SKIP_DRAW, COLOR_MOVE_INFO); + + // Print accuracy if (gBattleMoves[move].accuracy == 0) str = gText_ThreeHyphens; else @@ -1378,10 +1573,13 @@ static void TMCase_MoveCursor_UpdatePrintedTMInfo(u16 itemId) ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[move].accuracy, STR_CONV_MODE_RIGHT_ALIGN, 3); str = gStringVar1; } - AddTextPrinterParameterized_ColorByIndex(5, FONT_3, str, 7, 24, 0, 0, 0xFF, 3); + TMCase_Print(WIN_MOVE_INFO, FONT_3, str, 7, 24, 0, 0, TEXT_SKIP_DRAW, COLOR_MOVE_INFO); + + // Print PP ConvertIntToDecimalStringN(gStringVar1, gBattleMoves[move].pp, STR_CONV_MODE_RIGHT_ALIGN, 3); - AddTextPrinterParameterized_ColorByIndex(5, FONT_3, gStringVar1, 7, 36, 0, 0, 0xFF, 3); - CopyWindowToVram(5, COPYWIN_GFX); + TMCase_Print(WIN_MOVE_INFO, FONT_3, gStringVar1, 7, 36, 0, 0, TEXT_SKIP_DRAW, COLOR_MOVE_INFO); + + CopyWindowToVram(WIN_MOVE_INFO, COPYWIN_GFX); } } @@ -1390,144 +1588,149 @@ static void PlaceHMTileInWindow(u8 windowId, u8 x, u8 y) BlitBitmapToWindow(windowId, gTMCaseHM_Gfx, x, y, 16, 12); } -static void HandlePrintMoneyOnHand(void) +static void PrintPlayersMoney(void) { - PrintMoneyAmountInMoneyBoxWithBorder(8, 0x78, 0xD, GetMoney(&gSaveBlock1Ptr->money)); + PrintMoneyAmountInMoneyBoxWithBorder(WIN_MONEY, 120, 13, GetMoney(&gSaveBlock1Ptr->money)); } static void HandleCreateYesNoMenu(u8 taskId, const struct YesNoFuncTable *ptrs) { - CreateYesNoMenuWithCallbacks(taskId, &sYesNoWindowTemplate, FONT_2, 0, 2, 0x5B, 0x0E, ptrs); + CreateYesNoMenuWithCallbacks(taskId, &sYesNoWindowTemplate, FONT_2, 0, 2, 91, 14, ptrs); } -static u8 AddTMContextMenu(u8 * a0, u8 a1) +static u8 AddContextMenu(u8 * windowId, u8 windowIndex) { - if (*a0 == 0xFF) + if (*windowId == WINDOW_NONE) { - *a0 = AddWindow(&sTMContextWindowTemplates[a1]); - TMCase_SetWindowBorder1(*a0); + *windowId = AddWindow(&sWindowTemplates_ContextMenu[windowIndex]); + TMCase_SetWindowBorder1(*windowId); ScheduleBgCopyTilemapToVram(0); } - return *a0; + return *windowId; } -static void RemoveTMContextMenu(u8 * a0) +static void RemoveContextMenu(u8 * windowId) { - ClearStdWindowAndFrameToTransparent(*a0, FALSE); - ClearWindowTilemap(*a0); - RemoveWindow(*a0); + ClearStdWindowAndFrameToTransparent(*windowId, FALSE); + ClearWindowTilemap(*windowId); + RemoveWindow(*windowId); ScheduleBgCopyTilemapToVram(0); - *a0 = 0xFF; + *windowId = WINDOW_NONE; } -static u8 CreateTMSprite(u16 itemId) +static u8 CreateDiscSprite(u16 itemId) { - u8 spriteId = CreateSprite(&sTMSpriteTemplate, 0x29, 0x2E, 0); + u8 spriteId = CreateSprite(&sSpriteTemplate_Disc, DISC_BASE_X, DISC_BASE_Y, 0); u8 tmIdx; if (itemId == ITEM_NONE) { - UpdateTMSpritePosition(&gSprites[spriteId], 0xFF); + SetDiscSpritePosition(&gSprites[spriteId], DISC_HIDDEN); return spriteId; } else { tmIdx = itemId - ITEM_TM01; - SetTMSpriteAnim(&gSprites[spriteId], tmIdx); - TintTMSpriteByType(gBattleMoves[ItemIdToBattleMoveId(itemId)].type); - UpdateTMSpritePosition(&gSprites[spriteId], tmIdx); + SetDiscSpriteAnim(&gSprites[spriteId], tmIdx); + TintDiscpriteByType(gBattleMoves[ItemIdToBattleMoveId(itemId)].type); + SetDiscSpritePosition(&gSprites[spriteId], tmIdx); return spriteId; } } -static void SetTMSpriteAnim(struct Sprite *sprite, u8 idx) +static void SetDiscSpriteAnim(struct Sprite *sprite, u8 tmIdx) { - if (idx >= NUM_TECHNICAL_MACHINES) - StartSpriteAnim(sprite, 1); + if (tmIdx >= NUM_TECHNICAL_MACHINES) + StartSpriteAnim(sprite, ANIM_HM); else - StartSpriteAnim(sprite, 0); + StartSpriteAnim(sprite, ANIM_TM); } -static void TintTMSpriteByType(u8 type) +static void TintDiscpriteByType(u8 type) { - u8 palIndex = IndexOfSpritePaletteTag(TM_CASE_TM_TAG) << 4; + u8 palIndex = IndexOfSpritePaletteTag(TAG_DISC) << 4; LoadPalette(sTMSpritePaletteBuffer + sTMSpritePaletteOffsetByType[type], 0x100 | palIndex, 0x20); - if (sTMCaseStaticResources.tmCaseMenuType == 4) - { + if (sTMCaseStaticResources.menuType == TMCASE_POKEDUDE) BlendPalettes(1 << (0x10 + palIndex), 4, RGB_BLACK); - } } -static void UpdateTMSpritePosition(struct Sprite *sprite, u8 var) +static void SetDiscSpritePosition(struct Sprite *sprite, u8 tmIdx) { s32 x, y; - if (var == 0xFF) + if (tmIdx == DISC_HIDDEN) { - x = 0x1B; - y = 0x36; - sprite->y2 = 0x14; + x = 27; + y = 54; + sprite->y2 = DISC_CASE_DISTANCE; } else { - if (var >= 50) - var -= 50; + if (tmIdx >= NUM_TECHNICAL_MACHINES) + tmIdx -= NUM_TECHNICAL_MACHINES; else - var += 8; - x = 0x29 - (((0xE00 * var) / 58) >> 8); - y = 0x2E + (((0x800 * var) / 58) >> 8); + tmIdx += NUM_HIDDEN_MACHINES; + + x = DISC_BASE_X - Q_24_8_TO_INT(Q_24_8(14 * tmIdx) / (NUM_TECHNICAL_MACHINES + NUM_HIDDEN_MACHINES)); + y = DISC_BASE_Y + Q_24_8_TO_INT(Q_24_8(8 * tmIdx) / (NUM_TECHNICAL_MACHINES + NUM_HIDDEN_MACHINES)); } sprite->x = x; sprite->y = y; } -static void InitSelectedTMSpriteData(u8 spriteId, u16 itemId) +#define sItemId data[0] +#define sState data[1] + +static void SwapDisc(u8 spriteId, u16 itemId) { - gSprites[spriteId].data[0] = itemId; - gSprites[spriteId].data[1] = 0; - gSprites[spriteId].callback = SpriteCB_MoveTMSpriteInCase; + gSprites[spriteId].sItemId = itemId; + gSprites[spriteId].sState = 0; + gSprites[spriteId].callback = SpriteCB_SwapDisc; } -static void SpriteCB_MoveTMSpriteInCase(struct Sprite *sprite) +static void SpriteCB_SwapDisc(struct Sprite *sprite) { - switch (sprite->data[1]) + switch (sprite->sState) { case 0: - if (sprite->y2 >= 20) + // Lower old disc back into case + if (sprite->y2 >= DISC_CASE_DISTANCE) { - if (sprite->data[0] != ITEM_NONE) + // Old disc is hidden, set up new disc + if (sprite->sItemId != ITEM_NONE) { - sprite->data[1]++; - TintTMSpriteByType(gBattleMoves[ItemIdToBattleMoveId(sprite->data[0])].type); - sprite->data[0] -= ITEM_TM01; - SetTMSpriteAnim(sprite, sprite->data[0]); - UpdateTMSpritePosition(sprite, sprite->data[0]); + sprite->sState++; + TintDiscpriteByType(gBattleMoves[ItemIdToBattleMoveId(sprite->sItemId)].type); + sprite->sItemId -= ITEM_TM01; + SetDiscSpriteAnim(sprite, sprite->sItemId); + SetDiscSpritePosition(sprite, sprite->sItemId); } else sprite->callback = SpriteCallbackDummy; } else { - sprite->y2 += 10; + sprite->y2 += DISC_Y_MOVE; } break; case 1: + // Raise new disc out of case if (sprite->y2 <= 0) sprite->callback = SpriteCallbackDummy; else - sprite->y2 -= 10; + sprite->y2 -= DISC_Y_MOVE; } } // - 1 excludes TYPE_MYSTERY -#define NUM_TM_COLORS ((NUMBER_OF_MON_TYPES - 1) * 16) +#define NUM_DISC_COLORS ((NUMBER_OF_MON_TYPES - 1) * 16) -static void LoadTMTypePalettes(void) +static void LoadDiscTypePalettes(void) { struct SpritePalette spritePalette; - sTMSpritePaletteBuffer = Alloc(NUM_TM_COLORS * sizeof(u16)); + sTMSpritePaletteBuffer = Alloc(NUM_DISC_COLORS * sizeof(u16)); LZDecompressWram(gTMCaseDiscTypes1_Pal, sTMSpritePaletteBuffer); // Decompress the first 16 LZDecompressWram(gTMCaseDiscTypes2_Pal, sTMSpritePaletteBuffer + 0x100); // Decompress the rest (Only 17 total, this is just Dragon type) - spritePalette.data = sTMSpritePaletteBuffer + NUM_TM_COLORS; - spritePalette.tag = TM_CASE_TM_TAG; + spritePalette.data = sTMSpritePaletteBuffer + NUM_DISC_COLORS; + spritePalette.tag = TAG_DISC; LoadSpritePalette(&spritePalette); } From c257ba1e6bcd86b1c30bb9a9aeb098799dd8e8aa Mon Sep 17 00:00:00 2001 From: cbt6 <91667135+cbt6@users.noreply.github.com> Date: Mon, 14 Nov 2022 23:50:20 +0800 Subject: [PATCH 11/12] Document src/battle_interface.c --- graphics/battle_interface/ball_display.png | Bin 210 -> 0 bytes .../ball_display_unused_extra.png | Bin 156 -> 0 bytes graphics/battle_interface/exp_bar.png | Bin 109 -> 0 bytes graphics/battle_interface/healthbar.pal | 19 + graphics/battle_interface/healthbox.pal | 19 + .../healthbox_doubles_opponent.png | Bin 270 -> 371 bytes .../healthbox_doubles_player.png | Bin 277 -> 377 bytes .../battle_interface/healthbox_elements.png | Bin 0 -> 1226 bytes .../healthbox_singles_opponent.png | Bin 282 -> 377 bytes .../healthbox_singles_player.png | Bin 369 -> 462 bytes graphics/battle_interface/hp_bar.png | Bin 161 -> 0 bytes graphics/battle_interface/hp_bar_anim.png | Bin 149 -> 0 bytes graphics/battle_interface/misc.png | Bin 96 -> 0 bytes graphics/battle_interface/misc_frame_end.png | Bin 82 -> 0 bytes ...l_status_bar.png => party_summary_bar.png} | Bin graphics/battle_interface/status2.png | Bin 196 -> 0 bytes graphics/battle_interface/status3.png | Bin 198 -> 0 bytes graphics/battle_interface/status4.png | Bin 195 -> 0 bytes graphics/battle_interface/status_brn.png | Bin 116 -> 0 bytes graphics/battle_interface/status_frz.png | Bin 116 -> 0 bytes graphics/battle_interface/status_par.png | Bin 112 -> 0 bytes graphics/battle_interface/status_psn.png | Bin 116 -> 0 bytes graphics/battle_interface/status_slp.png | Bin 117 -> 0 bytes .../textbox.bin} | Bin .../{window.png => textbox.png} | Bin .../{window1.pal => textbox1.pal} | 0 .../{window2.pal => textbox2.pal} | 0 graphics_file_rules.mk | 2 +- include/battle.h | 2 +- include/battle_interface.h | 36 +- include/graphics.h | 17 +- src/battle_anim_special.c | 9 - src/battle_bg.c | 12 +- src/battle_gfx_sfx_util.c | 4 +- src/battle_interface.c | 1459 +++++++++-------- src/battle_main.c | 2 +- src/daycare.c | 6 +- src/graphics.c | 37 +- src/trade_scene.c | 12 +- 39 files changed, 844 insertions(+), 792 deletions(-) delete mode 100644 graphics/battle_interface/ball_display.png delete mode 100644 graphics/battle_interface/ball_display_unused_extra.png delete mode 100644 graphics/battle_interface/exp_bar.png create mode 100644 graphics/battle_interface/healthbar.pal create mode 100644 graphics/battle_interface/healthbox.pal create mode 100644 graphics/battle_interface/healthbox_elements.png delete mode 100644 graphics/battle_interface/hp_bar.png delete mode 100644 graphics/battle_interface/hp_bar_anim.png delete mode 100644 graphics/battle_interface/misc.png delete mode 100644 graphics/battle_interface/misc_frame_end.png rename graphics/battle_interface/{ball_status_bar.png => party_summary_bar.png} (100%) delete mode 100644 graphics/battle_interface/status2.png delete mode 100644 graphics/battle_interface/status3.png delete mode 100644 graphics/battle_interface/status4.png delete mode 100644 graphics/battle_interface/status_brn.png delete mode 100644 graphics/battle_interface/status_frz.png delete mode 100644 graphics/battle_interface/status_par.png delete mode 100644 graphics/battle_interface/status_psn.png delete mode 100644 graphics/battle_interface/status_slp.png rename graphics/{interface/menu_map.bin => battle_interface/textbox.bin} (100%) rename graphics/battle_interface/{window.png => textbox.png} (100%) rename graphics/battle_interface/{window1.pal => textbox1.pal} (100%) rename graphics/battle_interface/{window2.pal => textbox2.pal} (100%) diff --git a/graphics/battle_interface/ball_display.png b/graphics/battle_interface/ball_display.png deleted file mode 100644 index 3072a91aef9caf964eaccaa99bee6474642da342..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^96+qV!VDzu-cxxDqznRlLR^8grKRQn|NpO^-P_#U z?d2F1loj>=YS8~Jj`y;nivO>Py4w8zndR9v9RH&%*Eo8)uQf^m>R~Ji@(X5gcy=QV z$O-UtaSY*@nVi7En~;!jb;hX!0v8R98x)VQp5PBM<4Z^|HA_ukIPJs`AuC|S(jd^p z(7kZAw|8m+hqpJkgVKSd7q4PsBpbqZIZS1dPQJm-U^P|jk#zopr E0OG7jU;qFB diff --git a/graphics/battle_interface/ball_display_unused_extra.png b/graphics/battle_interface/ball_display_unused_extra.png deleted file mode 100644 index d7c1958d4956edb87eecae346952f5e2bec58fb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 156 zcmeAS@N?(olHy`uVBq!ia0vp^93afX3?$7I7w-U41_3@Hu0Yz-((?cR|5wlMZEo)N za*PVfiu!*w=>HbSds$J%|JOuaZT|nv^6VOp|527}9KGDv8l?dBsC&9NhH%VGPGD%h zz`({9*1M92M^M(7S;8r%;g3S3QH>&DWDbxPgg&ebxsLQ0Gp*T A)Bpeg diff --git a/graphics/battle_interface/exp_bar.png b/graphics/battle_interface/exp_bar.png deleted file mode 100644 index b1a0c440e33c36529f2162a738fc8758fd92ab22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^9ze{&0wfrA>2ZGpQYM}*jv*3LlP#QC5?&}U8JtmJ zGMK~0l&?_6n5c00C~M2!#v5Rw)xy;!(tXOJ|1Jy+^O$xN-VhX#1)1aN>gTe~DWM4f DVX7VB diff --git a/graphics/battle_interface/healthbar.pal b/graphics/battle_interface/healthbar.pal new file mode 100644 index 000000000..829e6bd44 --- /dev/null +++ b/graphics/battle_interface/healthbar.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +0 0 0 +57 57 57 +255 255 255 +213 205 189 +131 131 139 +74 65 90 +82 106 90 +255 213 82 +255 180 65 +222 106 90 +115 255 172 +90 213 131 +255 230 57 +205 172 8 +255 90 57 +172 65 74 diff --git a/graphics/battle_interface/healthbox.pal b/graphics/battle_interface/healthbox.pal new file mode 100644 index 000000000..bc8e8f2bc --- /dev/null +++ b/graphics/battle_interface/healthbox.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +0 0 0 +65 65 65 +255 255 222 +222 213 180 +197 189 115 +123 148 131 +82 106 98 +32 57 0 +57 82 65 +255 230 0 +255 156 148 +65 205 255 +0 0 255 +0 255 0 +255 0 0 +106 148 255 diff --git a/graphics/battle_interface/healthbox_doubles_opponent.png b/graphics/battle_interface/healthbox_doubles_opponent.png index 5d38ffbfaf2134746ec4589930abfc56a8e23d51..3a494a52a0b2b3120f2dabf7ca917e3923e53be8 100644 GIT binary patch delta 355 zcmV-p0i6Dh0`mfp8Gi!+001ZqZ599k00d`2O+f$vv5yP2XskIMF-{!2oDV{MSw2E0000NbVXQn zQ*UN;cVTj607pzjP)*Mw;>uv=PAn$Mb}UXqJIdTe9Xz z%OTKcG}O=x@PJ*l^+qq;@+mNOnEr&I1&7H`cmr|7@5wo&iEID>002ovPDHLkV1kpB Bk$?aI delta 253 zcmV0*(TZ8Gir(00262XskIMF-{!2oDS@!vBgU0000NbVXQn zQ*UN;cVTj607pzjP)Vii&`ew)cfcaz!~g^$qD%g<1^@s{jF{Q-{7(_}MvK{?S>$D1AQP}m zKp=O5d`04E++rAr_Hy(49R)%dXD?VKk3!tOKGq4qPBO(6$H70<_kO1%&P0 zi`cV@C-DCGyAr?>0K}GKU>^Ws&J0un)mdi)%fJMbGgbG0Z-ww+P;FV300000NkvXX Hu0mjfgoKqi delta 260 zcmV+f0sH>>0+j-g8Gir(0026Dukr%T0dO)p8g@U9IHO%vraG9FqqY9YX#vE%{nSYpWo>h0Yi$pcOg zv>*#`8ZXEK#=R6E3Vbt-g7^UogaK>xjZFX=>IU?bOBJ?=0ewOnNK`oH03s@^u?%R0 z!2g+LH=vV<&uU>Hnad>xdJaf7V||SZy0-5~0IudsSMz|R$D0%Y1;g+*B4FyuiU4^0 z-FX_Y=?$VcUTqkl001-P6!-uD?iu)=2e>Q`6kw5N16IQ>>HGi&Y6uJE9TV#S0000< KMNUMnLSTYqX>2I~ diff --git a/graphics/battle_interface/healthbox_elements.png b/graphics/battle_interface/healthbox_elements.png new file mode 100644 index 0000000000000000000000000000000000000000..aadcc8554e65c1f27a301cbb5cb7c922edf88077 GIT binary patch literal 1226 zcmV;*1U37KP)i}00Cl4M??UK1szBL00Ztx zL_t(|oV}L4Zrnx`g$FS7B3CI~@CWcZN+Vm10=J9A3Q`&ZveFYs4`9I97f6v8aIv*r zZN~trrrJQ|G&G=c3I?ht=L~0N`M0711R3kD4#{usz2|aCS*ho&7pud|11DEEw^z5f zE16gxSP{6ny1c;pir6wBwh%3FyM9!N_3S~I{OpA)OaCZpI=I}yyVE)O~Zh z1Hv*OtYthPEaPDw_z&lBvFr!dF>h9&UL3vrT^;e?>NjxJgW7LuHA@7*m|+PI?3)ZgXcF0sZ*tb=p$o^hUA*VHz<->DgpzM- zv2{^f)i!5L$Evq&Yg-g`T|{7Kg4Hg-9LoFWTtWuPTiX^TtkkuN{>{Eb0IWrcS_S{9 z$vBI*0DP0PHf`r%N~_{q@+_9xiY;u=wG^tb$+Jz`CT%Bx!cG8!Pj6h6 zx{*?FUIovN4SDU7Mx)5k2TC^p8pVtv-nckFoS=Cgyb7LsC0xqTu*m>~CXvmxP5SfC zusOUSKYUO=;$NJy^^AtvGQ9Yz2e|(IC-AWgL`z-ZR07*qoM6N<$f)(mAh5!Hn literal 0 HcmV?d00001 diff --git a/graphics/battle_interface/healthbox_singles_opponent.png b/graphics/battle_interface/healthbox_singles_opponent.png index 5f02199b5312b6579d069aedced02bed2763f41e..be88c22f6d818d563782ae55508095209ebfceb9 100644 GIT binary patch delta 361 zcmV-v0ha!n0{H@v8Gi!+001ZqZ599k00d`2O+f$vv5yP2XskIMF-{!2oDPoOR~jN0000NbVXQn zQ*UN;cVTj607pzjP)%fHr zYOHF2^K(y3WZ<%6-zWmg;$omIHw49fIY2~>I40=_GGN&rlL!b?9^_3sv3q8sc3tHH zTosYmcFYAb;$mrS{{z5#kX`_ITQMHe0e3C8woeDV54v2S{dZvXFnpJr0O0ocJq8Bt z00Mp~qxxlQ1WI%I0=puk=3EmW}PQKO;idG`Z5tr4_00000NkvXX Hu0mjf$imDGbh#T9y95F}J%Igq>=J?jyM%Bc13>Hx$K(qq&nF Q00000NkvXXt^-0~f;mfW%K!iX diff --git a/graphics/battle_interface/healthbox_singles_player.png b/graphics/battle_interface/healthbox_singles_player.png index 2478cc57d947c5f187ca2bb2cc919ef15e77c9fe..a395b6543e1304d7fc221ff0058921dff0bbb6f5 100644 GIT binary patch delta 447 zcmV;w0YLuo0?q@F8Gi!+001EPVoU%400d`2O+f$vv5yPKF}I?sD-8z%#e%?Km!M8KLEUzS^F@+A0dZ+c}`A$A+kZ{#g_r( z@o(k&NCzM*=(>{Xffxn70K5Zdb-@FW88ce|Y8Vcuu@#`3DzXC5I@(gW9uYvu16&9o z-~lEW5Jp^p+<*v@QSu delta 353 zcmV-n0iOQO1Mvco8Gir(001&g&7uGR0XRuSK~z|U?bW>wfW~ z!f0@Dg`m5M;Ob!D34k3I#oy#w?x&uECUm9ur3KovE*eoyQ(;(N0%|4-J)oYuqR<0Y zqirk*Jz%jDCTIb*BTmo)s);EeN$7xI0enNCW|IHp2KdYoj(!QP{c<fd|K<0jS5o6aWcjd5n#KrmMsVz|Z+Dg@6PB84VaB zAg2K*2xJKr;93)40b~FckOs^_kaQqi$hzn z>-#280qFxQ4hNZTwkU4$T=GQTsG+j(#9401?{ddJR_(G~Z4iA@_j#T4Ca$@ymyWeo z2pm#yl54R!p?5{1kZnHCf)>ZAOd6~g_D@Liy&E@Ucf$RLPo~?gZ)b~*Yd)|ZWVffQ KpUXO@geCxRK0AT{ diff --git a/graphics/battle_interface/hp_bar_anim.png b/graphics/battle_interface/hp_bar_anim.png deleted file mode 100644 index 5d1fc5f5274347f368ce7928d63cc62c283a89dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^6M&e51xPS_dvU}YNX2-%IEH9UTzhdL?@6su_4wp2F)MnvXk)&~*XwrOlaf~?A3kv(WS^(2pUXO@geCws*E{F{ diff --git a/graphics/battle_interface/misc.png b/graphics/battle_interface/misc.png deleted file mode 100644 index cf1d76046616f9c67218b20060ed28fac845eebe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^5kSnr0wfsbHgw4WDRoa5#}J9B$v^s8-YsG*v1D7N sIj@t2L+hOb6N~74MZ$L!KeUP0q8hbZj-E@g=~%IStlcwMK@hr?QFC5E6yuX zS2RsF6l>nOZTTP3bD#emKH_ij?&QUccG0LkU)fi-L}X^HTeZ<&UV(3aZ*2OGAFIvu vtjcx^+R03BEZxB_rrWS~eWP!`?axs8Wgjk{zpp;!7RY&?u6{1-oD!M;Lx v?`Qtiy+ATzc6Gu`rm}k8H&;HKUth)i?D?A8$-?H$AlG@i`njxgN@xNAPM=bY diff --git a/graphics/battle_interface/status_brn.png b/graphics/battle_interface/status_brn.png deleted file mode 100644 index 16b441367a1d0ef0e508c36c8beb9827dfaf4dc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^5i7!-Jz4*cu9 zx^LfR;njbRX8G!H?`%on)(_rP;8;?iGQqc8NZg5eh4PCk(fln(gB`bc};<0!#5bsr!3*rZ}8n;7s1Yn80_0A!RY6=}w)8{y(0t P1{vq+>gTe~DWM4fE3PG4 diff --git a/graphics/battle_interface/status_par.png b/graphics/battle_interface/status_par.png deleted file mode 100644 index 3df34c5f6b27ff63d7002bceee75b0cdd9fc40ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^5?GRo7{ K&t;ucLK6UOnj(_` diff --git a/graphics/battle_interface/status_psn.png b/graphics/battle_interface/status_psn.png deleted file mode 100644 index 8b79b24647cb24423ddc32cc8f93858a3011486f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^5gTe~DWM4fDDEZp diff --git a/graphics/battle_interface/status_slp.png b/graphics/battle_interface/status_slp.png deleted file mode 100644 index e3da5c0f32dd879aad17f1cd869b153fac996cc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^5 $@ $(UNUSEDGFXDIR)/old_contest.4bpp: $(UNUSEDGFXDIR)/old_contest_frame_1.4bpp \ diff --git a/include/battle.h b/include/battle.h index 3acfadaab..1086fa3ec 100644 --- a/include/battle.h +++ b/include/battle.h @@ -581,7 +581,7 @@ struct BattleBarInfo u8 healthboxSpriteId; s32 maxValue; s32 oldValue; - s32 receivedValue; + s32 receivedValue; // if positive/negative, fills the bar to the left/right respectively s32 currValue; }; diff --git a/include/battle_interface.h b/include/battle_interface.h index 3415836a8..067436c05 100644 --- a/include/battle_interface.h +++ b/include/battle_interface.h @@ -25,25 +25,31 @@ enum HP_BAR_FULL, }; -#define TAG_HEALTHBOX_PLAYER1_TILE 0xD6FF -#define TAG_HEALTHBOX_PLAYER2_TILE 0xD700 -#define TAG_HEALTHBOX_OPPONENT1_TILE 0xD701 -#define TAG_HEALTHBOX_OPPONENT2_TILE 0xD702 +#define TAG_HEALTHBOX_PLAYER1_TILE 55039 +#define TAG_HEALTHBOX_PLAYER2_TILE 55040 +#define TAG_HEALTHBOX_OPPONENT1_TILE 55041 +#define TAG_HEALTHBOX_OPPONENT2_TILE 55042 -#define TAG_HEALTHBAR_PLAYER1_TILE 0xD704 -#define TAG_HEALTHBAR_OPPONENT1_TILE 0xD705 -#define TAG_HEALTHBAR_PLAYER2_TILE 0xD706 -#define TAG_HEALTHBAR_OPPONENT2_TILE 0xD707 +#define TAG_HEALTHBAR_PLAYER1_TILE 55044 +#define TAG_HEALTHBAR_OPPONENT1_TILE 55045 +#define TAG_HEALTHBAR_PLAYER2_TILE 55046 +#define TAG_HEALTHBAR_OPPONENT2_TILE 55047 -#define TAG_HEALTHBOX_SAFARI_TILE 0xD70B +#define TAG_HEALTHBOX_PALS_1 55049 +#define TAG_HEALTHBOX_PALS_2 55050 +#define TAG_HEALTHBOX_SAFARI_TILE 55051 +#define TAG_PARTY_SUMMARY_BAR_PLAYER_TILE 55052 +#define TAG_PARTY_SUMMARY_BAR_OPPONENT_TILE 55053 -#define TAG_STATUS_SUMMARY_BAR_TILE 0xD70C -#define TAG_STATUS_SUMMARY_BALLS_TILE 0xD714 +#define TAG_PARTY_SUMMARY_BAR_PLAYER_PAL 55056 +#define TAG_PARTY_SUMMARY_BAR_OPPONENT_PAL 55057 +#define TAG_PARTY_SUMMARY_BALL_PLAYER_PAL 55058 +#define TAG_PARTY_SUMMARY_BALL_OPPONENT_PAL 55059 +#define TAG_PARTY_SUMMARY_BALL_PLAYER_TILE 55060 +#define TAG_PARTY_SUMMARY_BALL_OPPONENT_TILE 55061 -#define TAG_HEALTHBOX_PAL 0xD6FF -#define TAG_HEALTHBAR_PAL 0xD704 -#define TAG_STATUS_SUMMARY_BAR_PAL 0xD710 -#define TAG_STATUS_SUMMARY_BALLS_PAL 0xD712 +#define TAG_HEALTHBOX_PAL TAG_HEALTHBOX_PLAYER1_TILE +#define TAG_HEALTHBAR_PAL TAG_HEALTHBAR_PLAYER1_TILE enum { diff --git a/include/graphics.h b/include/graphics.h index 8abeb08b1..7c4ebc051 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -2878,9 +2878,6 @@ extern const u8 gUnknown_8E99118[]; extern const u16 gStandardMenuPalette[]; // egg_hatch -extern const u32 gBattleTextboxTiles[]; -extern const u32 gBattleTextboxTilemap[]; -extern const u32 gBattleTextboxPalette[]; extern const u32 gTradeGba2_Pal[]; extern const u32 gTradeGba_Gfx[]; @@ -4322,8 +4319,6 @@ extern const u32 gHealthboxDoublesPlayerGfx[]; extern const u32 gHealthboxDoublesOpponentGfx[]; extern const u32 gHealthboxSafariGfx[]; extern const u32 gBlankGfxCompressed[]; -extern const u16 gBattleInterface_BallStatusBarPal[]; -extern const u16 gBattleInterface_BallDisplayPal[]; extern const u32 gInterfaceGfx_HPNumbers[]; extern const u32 gGhostFrontPic[]; extern const u32 gGhostPalette[]; @@ -4861,11 +4856,13 @@ extern const u16 gHoennTrainerCard_Pal[]; extern const u32 gHoennTrainerCard_Gfx[]; // battle_interface -extern const u32 gFile_graphics_battle_interface_ball_status_bar_sheet[]; -extern const u8 gHealthboxElementsGfxTable[][32]; -extern const u16 gBattleInterface_BallStatusBarPal[]; -extern const u16 gBattleInterface_BallDisplayPal[]; -extern const u16 gBattleInterface_SummaryBallDisplayGfx[]; +extern const u32 gBattleInterface_Textbox_Gfx[]; +extern const u32 gBattleInterface_Textbox_Pal[]; +extern const u32 gBattleInterface_Textbox_Tilemap[]; +extern const u32 gBattleInterface_PartySummaryBar_Gfx[]; +extern const u8 gBattleInterface_Gfx[][32]; +extern const u16 gBattleInterface_Healthbox_Pal[]; +extern const u16 gBattleInterface_Healthbar_Pal[]; // item_menu extern const u32 gUnknown_8E830CC[]; diff --git a/src/battle_anim_special.c b/src/battle_anim_special.c index 78400812d..48f7435b7 100644 --- a/src/battle_anim_special.c +++ b/src/battle_anim_special.c @@ -17,7 +17,6 @@ #include "constants/moves.h" #include "constants/songs.h" -// Defines #define TAG_PARTICLES_POKEBALL 55020 #define TAG_PARTICLES_GREATBALL 55021 #define TAG_PARTICLES_SAFARIBALL 55022 @@ -31,15 +30,10 @@ #define TAG_PARTICLES_LUXURYBALL 55030 #define TAG_PARTICLES_PREMIERBALL 55031 -#define TAG_HEALTHBOX_PALS_1 55049 -#define TAG_HEALTHBOX_PALS_2 55050 - -// RAM u32 gMonShrinkDuration; u16 gMonShrinkDelta; u16 gMonShrinkDistance; -// Function Declarations static void AnimTask_UnusedLevelUpHealthBox_Step(u8); static void AnimTask_FlashHealthboxOnLevelUp_Step(u8); static void AnimTask_ThrowBall_WaitAnimObjComplete(u8); @@ -94,7 +88,6 @@ static void TimerBallOpenParticleAnimation(u8); static void PremierBallOpenParticleAnimation(u8); static void SpriteCB_SafariBaitOrRock_Init(struct Sprite *); -// Data struct CaptureStar { s8 xOffset; @@ -408,8 +401,6 @@ const struct SpriteTemplate gSafariRockTemplate = .callback = SpriteCB_SafariBaitOrRock_Init, }; -// Functions - // Unused void AnimTask_LevelUpHealthBox(u8 taskId) { diff --git a/src/battle_bg.c b/src/battle_bg.c index 4b5b17b72..8260e7091 100644 --- a/src/battle_bg.c +++ b/src/battle_bg.c @@ -713,10 +713,10 @@ void DrawMainBattleBackground(void) void LoadBattleTextboxAndBackground(void) { - LZDecompressVram(gBattleTextboxTiles, (void *)BG_CHAR_ADDR(0)); - CopyToBgTilemapBuffer(0, gBattleTextboxTilemap, 0, 0x000); + LZDecompressVram(gBattleInterface_Textbox_Gfx, (void *)BG_CHAR_ADDR(0)); + CopyToBgTilemapBuffer(0, gBattleInterface_Textbox_Tilemap, 0, 0x000); CopyBgTilemapBufferToVram(0); - LoadCompressedPalette(gBattleTextboxPalette, 0x00, 0x40); + LoadCompressedPalette(gBattleInterface_Textbox_Pal, 0x00, 0x40); LoadBattleMenuWindowGfx(); DrawMainBattleBackground(); } @@ -1076,14 +1076,14 @@ bool8 LoadChosenBattleElement(u8 caseId) switch (caseId) { case 0: - LZDecompressVram(gBattleTextboxTiles, (void *)BG_CHAR_ADDR(0)); + LZDecompressVram(gBattleInterface_Textbox_Gfx, (void *)BG_CHAR_ADDR(0)); break; case 1: - CopyToBgTilemapBuffer(0, gBattleTextboxTilemap, 0, 0x000); + CopyToBgTilemapBuffer(0, gBattleInterface_Textbox_Tilemap, 0, 0x000); CopyBgTilemapBufferToVram(0); break; case 2: - LoadCompressedPalette(gBattleTextboxPalette, 0x00, 0x40); + LoadCompressedPalette(gBattleInterface_Textbox_Pal, 0x00, 0x40); break; case 3: battleScene = GetBattleTerrainOverride(); diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index bd43270e0..a681dfec6 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -98,11 +98,11 @@ static const struct CompressedSpriteSheet sSpriteSheets_HealthBar[MAX_BATTLERS_C static const struct SpritePalette sSpritePalettes_HealthBoxHealthBar[2] = { { - .data = gBattleInterface_BallStatusBarPal, + .data = gBattleInterface_Healthbox_Pal, .tag = TAG_HEALTHBOX_PAL, }, { - .data = gBattleInterface_BallDisplayPal, + .data = gBattleInterface_Healthbar_Pal, .tag = TAG_HEALTHBAR_PAL, }, }; diff --git a/src/battle_interface.c b/src/battle_interface.c index c9575d373..5bad50de9 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -11,11 +11,6 @@ #include "safari_zone.h" #include "constants/songs.h" -#define GetStringRightAlignXOffset(fontId, string, destWidth) ({ \ - s32 w = GetStringWidth(fontId, string, 0); \ - destWidth - w; \ -}) - #undef abs #define abs(a) ((a) < 0 ? -(a) : (a)) @@ -28,171 +23,90 @@ struct TestingBar u32 tileOffset; }; -enum -{ // Corresponds to gHealthboxElementsGfxTable (and the tables after it) in graphics.c - // These are indexes into the tables, which are filled with 8x8 square pixel data. - HEALTHBOX_GFX_0, //hp bar [black section] - HEALTHBOX_GFX_1, //hp bar "H" - HEALTHBOX_GFX_2, //hp bar "P" - HEALTHBOX_GFX_HP_BAR_GREEN, //hp bar [0 pixels] - HEALTHBOX_GFX_4, //hp bar [1 pixels] - HEALTHBOX_GFX_5, //hp bar [2 pixels] - HEALTHBOX_GFX_6, //hp bar [3 pixels] - HEALTHBOX_GFX_7, //hp bar [4 pixels] - HEALTHBOX_GFX_8, //hp bar [5 pixels] - HEALTHBOX_GFX_9, //hp bar [6 pixels] - HEALTHBOX_GFX_10, //hp bar [7 pixels] - HEALTHBOX_GFX_11, //hp bar [8 pixels] - HEALTHBOX_GFX_12, //exp bar [0 pixels] - HEALTHBOX_GFX_13, //exp bar [1 pixels] - HEALTHBOX_GFX_14, //exp bar [2 pixels] - HEALTHBOX_GFX_15, //exp bar [3 pixels] - HEALTHBOX_GFX_16, //exp bar [4 pixels] - HEALTHBOX_GFX_17, //exp bar [5 pixels] - HEALTHBOX_GFX_18, //exp bar [6 pixels] - HEALTHBOX_GFX_19, //exp bar [7 pixels] - HEALTHBOX_GFX_20, //exp bar [8 pixels] - HEALTHBOX_GFX_STATUS_PSN_BATTLER0, //status psn "(P" - HEALTHBOX_GFX_22, //status psn "SN" - HEALTHBOX_GFX_23, //status psn "|)"" - HEALTHBOX_GFX_STATUS_PRZ_BATTLER0, //status prz - HEALTHBOX_GFX_25, - HEALTHBOX_GFX_26, - HEALTHBOX_GFX_STATUS_SLP_BATTLER0, //status slp - HEALTHBOX_GFX_28, - HEALTHBOX_GFX_29, - HEALTHBOX_GFX_STATUS_FRZ_BATTLER0, //status frz - HEALTHBOX_GFX_31, - HEALTHBOX_GFX_32, - HEALTHBOX_GFX_STATUS_BRN_BATTLER0, //status brn - HEALTHBOX_GFX_34, - HEALTHBOX_GFX_35, - HEALTHBOX_GFX_36, //misc [Black section] - HEALTHBOX_GFX_37, //misc [Black section] - HEALTHBOX_GFX_38, //misc [Black section] - HEALTHBOX_GFX_39, //misc [Blank Health Window?] - HEALTHBOX_GFX_40, //misc [Blank Health Window?] - HEALTHBOX_GFX_41, //misc [Blank Health Window?] - HEALTHBOX_GFX_42, //misc [Blank Health Window?] - HEALTHBOX_GFX_43, //misc [Top of Health Window?] - HEALTHBOX_GFX_44, //misc [Top of Health Window?] - HEALTHBOX_GFX_45, //misc [Top of Health Window?] - HEALTHBOX_GFX_46, //misc [Blank Health Window?] - HEALTHBOX_GFX_HP_BAR_YELLOW, //hp bar yellow [0 pixels] - HEALTHBOX_GFX_48, //hp bar yellow [1 pixels] - HEALTHBOX_GFX_49, //hp bar yellow [2 pixels] - HEALTHBOX_GFX_50, //hp bar yellow [3 pixels] - HEALTHBOX_GFX_51, //hp bar yellow [4 pixels] - HEALTHBOX_GFX_52, //hp bar yellow [5 pixels] - HEALTHBOX_GFX_53, //hp bar yellow [6 pixels] - HEALTHBOX_GFX_54, //hp bar yellow [7 pixels] - HEALTHBOX_GFX_55, //hp bar yellow [8 pixels] - HEALTHBOX_GFX_HP_BAR_RED, //hp bar red [0 pixels] - HEALTHBOX_GFX_57, //hp bar red [1 pixels] - HEALTHBOX_GFX_58, //hp bar red [2 pixels] - HEALTHBOX_GFX_59, //hp bar red [3 pixels] - HEALTHBOX_GFX_60, //hp bar red [4 pixels] - HEALTHBOX_GFX_61, //hp bar red [5 pixels] - HEALTHBOX_GFX_62, //hp bar red [6 pixels] - HEALTHBOX_GFX_63, //hp bar red [7 pixels] - HEALTHBOX_GFX_64, //hp bar red [8 pixels] - HEALTHBOX_GFX_65, //hp bar frame end - HEALTHBOX_GFX_66, //status ball [full] - HEALTHBOX_GFX_67, //status ball [empty] - HEALTHBOX_GFX_68, //status ball [fainted] - HEALTHBOX_GFX_69, //status ball [statused] - HEALTHBOX_GFX_70, //status ball [unused extra] - HEALTHBOX_GFX_STATUS_PSN_BATTLER1, //status2 "PSN" - HEALTHBOX_GFX_72, - HEALTHBOX_GFX_73, - HEALTHBOX_GFX_STATUS_PRZ_BATTLER1, //status2 "PRZ" - HEALTHBOX_GFX_75, - HEALTHBOX_GFX_76, - HEALTHBOX_GFX_STATUS_SLP_BATTLER1, //status2 "SLP" - HEALTHBOX_GFX_78, - HEALTHBOX_GFX_79, - HEALTHBOX_GFX_STATUS_FRZ_BATTLER1, //status2 "FRZ" - HEALTHBOX_GFX_81, - HEALTHBOX_GFX_82, - HEALTHBOX_GFX_STATUS_BRN_BATTLER1, //status2 "BRN" - HEALTHBOX_GFX_84, - HEALTHBOX_GFX_85, - HEALTHBOX_GFX_STATUS_PSN_BATTLER2, //status3 "PSN" - HEALTHBOX_GFX_87, - HEALTHBOX_GFX_88, - HEALTHBOX_GFX_STATUS_PRZ_BATTLER2, //status3 "PRZ" - HEALTHBOX_GFX_90, - HEALTHBOX_GFX_91, - HEALTHBOX_GFX_STATUS_SLP_BATTLER2, //status3 "SLP" - HEALTHBOX_GFX_93, - HEALTHBOX_GFX_94, - HEALTHBOX_GFX_STATUS_FRZ_BATTLER2, //status3 "FRZ" - HEALTHBOX_GFX_96, - HEALTHBOX_GFX_97, - HEALTHBOX_GFX_STATUS_BRN_BATTLER2, //status3 "BRN" - HEALTHBOX_GFX_99, - HEALTHBOX_GFX_100, - HEALTHBOX_GFX_STATUS_PSN_BATTLER3, //status4 "PSN" - HEALTHBOX_GFX_102, - HEALTHBOX_GFX_103, - HEALTHBOX_GFX_STATUS_PRZ_BATTLER3, //status4 "PRZ" - HEALTHBOX_GFX_105, - HEALTHBOX_GFX_106, - HEALTHBOX_GFX_STATUS_SLP_BATTLER3, //status4 "SLP" - HEALTHBOX_GFX_108, - HEALTHBOX_GFX_109, - HEALTHBOX_GFX_STATUS_FRZ_BATTLER3, //status4 "FRZ" - HEALTHBOX_GFX_111, - HEALTHBOX_GFX_112, - HEALTHBOX_GFX_STATUS_BRN_BATTLER3, //status4 "BRN" - HEALTHBOX_GFX_114, - HEALTHBOX_GFX_115, - HEALTHBOX_GFX_116, //unknown_D12FEC - HEALTHBOX_GFX_117, //unknown_D1300C -}; +// These are used as indexes for each "section of tiles" in gBattleInterface_Gfx +#define B_INTERFACE_GFX_TRANSPARENT 0 +#define B_INTERFACE_GFX_HP_BAR_HP_TEXT 1 +#define B_INTERFACE_GFX_HP_BAR_GREEN 3 +#define B_INTERFACE_GFX_EXP_BAR 12 +#define B_INTERFACE_GFX_STATUS_PSN_BATTLER0 21 // BATTLER0: B_POSITION_PLAYER_LEFT +#define B_INTERFACE_GFX_STATUS_PAR_BATTLER0 24 +#define B_INTERFACE_GFX_STATUS_SLP_BATTLER0 27 +#define B_INTERFACE_GFX_STATUS_FRZ_BATTLER0 30 +#define B_INTERFACE_GFX_STATUS_BRN_BATTLER0 33 +// tiles 36 through 38 are unused +#define B_INTERFACE_GFX_STATUS_NONE 39 +// tiles 40 through 42 are unused +#define B_INTERFACE_GFX_SAFARI_HEALTHBOX_0 43 +#define B_INTERFACE_GFX_SAFARI_HEALTHBOX_1 44 +#define B_INTERFACE_GFX_SAFARI_HEALTHBOX_2 45 +// tile 46 is unused +#define B_INTERFACE_GFX_HP_BAR_YELLOW 47 +#define B_INTERFACE_GFX_HP_BAR_RED 56 +#define B_INTERFACE_GFX_HP_BAR_LEFT_BORDER 65 // Used in place of the HP text graphic if the pokemon is statused +#define B_INTERFACE_GFX_BALL_PARTY_SUMMARY 66 +#define B_INTERFACE_GFX_BALL_CAUGHT 70 +#define B_INTERFACE_GFX_STATUS_PSN_BATTLER1 71 // BATTLER1: B_POSITION_OPPONENT_LEFT +#define B_INTERFACE_GFX_STATUS_PAR_BATTLER1 74 +#define B_INTERFACE_GFX_STATUS_SLP_BATTLER1 77 +#define B_INTERFACE_GFX_STATUS_FRZ_BATTLER1 80 +#define B_INTERFACE_GFX_STATUS_BRN_BATTLER1 83 +#define B_INTERFACE_GFX_STATUS_PSN_BATTLER2 86 // BATTLER2: B_POSITION_PLAYER_RIGHT +#define B_INTERFACE_GFX_STATUS_PAR_BATTLER2 89 +#define B_INTERFACE_GFX_STATUS_SLP_BATTLER2 92 +#define B_INTERFACE_GFX_STATUS_FRZ_BATTLER2 95 +#define B_INTERFACE_GFX_STATUS_BRN_BATTLER2 98 +#define B_INTERFACE_GFX_STATUS_PSN_BATTLER3 101 // BATTLER3: B_POSITION_OPPONENT_RIGHT +#define B_INTERFACE_GFX_STATUS_PAR_BATTLER3 104 +#define B_INTERFACE_GFX_STATUS_SLP_BATTLER3 107 +#define B_INTERFACE_GFX_STATUS_FRZ_BATTLER3 110 +#define B_INTERFACE_GFX_STATUS_BRN_BATTLER3 113 +#define B_INTERFACE_GFX_BOTTOM_RIGHT_CORNER_HP_AS_TEXT 116 // Used in the player's +#define B_INTERFACE_GFX_BOTTOM_RIGHT_CORNER_HP_AS_BAR 117 // healthbox in double battles + static void SpriteCB_HealthBoxOther(struct Sprite *sprite); static void SpriteCB_HealthBar(struct Sprite *sprite); -static const u8 *GetHealthboxElementGfxPtr(u8 which); +static const u8 *GetBattleInterfaceGfxPtr(u8 which); static void UpdateHpTextInHealthboxInDoubles(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent); -static void sub_8049388(u8 taskId); -static void sub_80493E4(u8 taskId); -static void sub_8049568(struct Sprite *sprite); -static void sub_8049630(struct Sprite *sprite); -static void sub_804948C(u8 taskId); -static void SpriteCB_StatusSummaryBallsOnSwitchout(struct Sprite *sprite); +static void Task_HidePartyStatusSummary_BattleStart_1(u8 taskId); +static void Task_HidePartyStatusSummary_BattleStart_2(u8 taskId); +static void SpriteCB_PartySummaryBar_Exit(struct Sprite *sprite); +static void SpriteCB_PartySummaryBall_Exit(struct Sprite *sprite); +static void Task_HidePartyStatusSummary_DuringBattle(u8 taskId); +static void SpriteCB_PartySummaryBall_OnSwitchout(struct Sprite *sprite); static void UpdateStatusIconInHealthbox(u8 spriteId); -static void SpriteCB_StatusSummaryBar(struct Sprite *sprite); -static void SpriteCB_StatusSummaryBallsOnBattleStart(struct Sprite *sprite); +static void SpriteCB_PartySummaryBar(struct Sprite *sprite); +static void SpriteCB_PartySummaryBall_OnBattleStart(struct Sprite *sprite); static u8 GetStatusIconForBattlerId(u8 statusElementId, u8 battlerId); static void MoveBattleBarGraphically(u8 battlerId, u8 whichBar); -static u8 GetScaledExpFraction(s32 oldValue, s32 receivedValue, s32 maxValue, u8 scale); +static u8 GetReceivedValueInPixels(s32 oldValue, s32 receivedValue, s32 maxValue, u8 scale); static u8 CalcBarFilledPixels(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *currValue, u8 *arg4, u8 scale); static s32 CalcNewBarValue(s32 maxValue, s32 currValue, s32 receivedValue, s32 *arg3, u8 arg4, u16 arg5); -static void sub_804A510(struct TestingBar *barInfo, s32 *currValue, u8 bg, u8 x, u8 y); +static void DrawHealthbarOntoScreen(struct TestingBar *barInfo, s32 *currValue, u8 bg, u8 x, u8 y); static void SafariTextIntoHealthboxObject(void *dest, u8 *windowTileData, u32 windowWidth); static u8 *AddTextPrinterAndCreateWindowOnHealthbox(const u8 *str, u32 x, u32 y, u32 *windowId); static void RemoveWindowOnHealthbox(u32 windowId); static void TextIntoHealthboxObject(void *dest, u8 *windowTileData, s32 windowWidth); -static const struct OamData gOamData_8260270 = { +static const struct OamData sOamData_Healthbox = { .shape = SPRITE_SHAPE(64x32), .size = SPRITE_SIZE(64x32), .priority = 1 }; static const struct SpriteTemplate sHealthboxPlayerSpriteTemplates[] = { - { - .tileTag = 55039, - .paletteTag = 55039, - .oam = &gOamData_8260270, + [B_POSITION_PLAYER_LEFT / 2] = { + .tileTag = TAG_HEALTHBOX_PLAYER1_TILE, + .paletteTag = TAG_HEALTHBOX_PAL, + .oam = &sOamData_Healthbox, .anims = gDummySpriteAnimTable, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy - }, { - .tileTag = 55040, - .paletteTag = 55039, - .oam = &gOamData_8260270, + }, + [B_POSITION_PLAYER_RIGHT / 2] = { + .tileTag = TAG_HEALTHBOX_PLAYER2_TILE, + .paletteTag = TAG_HEALTHBOX_PAL, + .oam = &sOamData_Healthbox, .anims = gDummySpriteAnimTable, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy @@ -200,17 +114,18 @@ static const struct SpriteTemplate sHealthboxPlayerSpriteTemplates[] = { }; static const struct SpriteTemplate sHealthboxOpponentSpriteTemplates[] = { - { - .tileTag = 55041, - .paletteTag = 55039, - .oam = &gOamData_8260270, + [B_POSITION_OPPONENT_LEFT / 2] = { + .tileTag = TAG_HEALTHBOX_OPPONENT1_TILE, + .paletteTag = TAG_HEALTHBOX_PAL, + .oam = &sOamData_Healthbox, .anims = gDummySpriteAnimTable, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy - }, { - .tileTag = 55042, - .paletteTag = 55039, - .oam = &gOamData_8260270, + }, + [B_POSITION_OPPONENT_RIGHT / 2] = { + .tileTag = TAG_HEALTHBOX_OPPONENT2_TILE, + .paletteTag = TAG_HEALTHBOX_PAL, + .oam = &sOamData_Healthbox, .anims = gDummySpriteAnimTable, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy @@ -219,205 +134,312 @@ static const struct SpriteTemplate sHealthboxOpponentSpriteTemplates[] = { static const struct SpriteTemplate sHealthboxSafariSpriteTemplate = { - .tileTag = 55051, - .paletteTag = 55039, - .oam = &gOamData_8260270, + .tileTag = TAG_HEALTHBOX_SAFARI_TILE, + .paletteTag = TAG_HEALTHBOX_PAL, + .oam = &sOamData_Healthbox, .anims = gDummySpriteAnimTable, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy }; -static const struct OamData gUnknown_82602F0 = { +static const struct OamData sOamData_Healthbar = { .shape = SPRITE_SHAPE(32x8), .size = SPRITE_SIZE(32x8), .priority = 1 }; -static const struct SpriteTemplate gUnknown_82602F8[] = { - { - .tileTag = 55044, - .paletteTag = 55044, - .oam = &gUnknown_82602F0, +static const struct SpriteTemplate sHealthbarSpriteTemplates[] = { + [B_POSITION_PLAYER_LEFT] = { + .tileTag = TAG_HEALTHBAR_PLAYER1_TILE, + .paletteTag = TAG_HEALTHBAR_PAL, + .oam = &sOamData_Healthbar, .anims = gDummySpriteAnimTable, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCB_HealthBar - }, { - .tileTag = 55045, - .paletteTag = 55044, - .oam = &gUnknown_82602F0, + }, + [B_POSITION_OPPONENT_LEFT] = { + .tileTag = TAG_HEALTHBAR_OPPONENT1_TILE, + .paletteTag = TAG_HEALTHBAR_PAL, + .oam = &sOamData_Healthbar, .anims = gDummySpriteAnimTable, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCB_HealthBar - }, { - .tileTag = 55046, - .paletteTag = 55044, - .oam = &gUnknown_82602F0, + }, + [B_POSITION_PLAYER_RIGHT] = { + .tileTag = TAG_HEALTHBAR_PLAYER2_TILE, + .paletteTag = TAG_HEALTHBAR_PAL, + .oam = &sOamData_Healthbar, .anims = gDummySpriteAnimTable, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCB_HealthBar - }, { - .tileTag = 55047, - .paletteTag = 55044, - .oam = &gUnknown_82602F0, + }, + [B_POSITION_OPPONENT_RIGHT] = { + .tileTag = TAG_HEALTHBAR_OPPONENT2_TILE, + .paletteTag = TAG_HEALTHBAR_PAL, + .oam = &sOamData_Healthbar, .anims = gDummySpriteAnimTable, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCB_HealthBar } }; -static const struct Subsprite gUnknown_8260358[] = { - { 240, 0, SPRITE_SHAPE(64x32), SPRITE_SIZE(64x32), 0x0000, 1 }, - { 48, 0, SPRITE_SHAPE(32x32), SPRITE_SIZE(32x32), 0x0020, 1 }, - { 240, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0030, 1 }, - { 16, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0034, 1 }, - { 48, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0038, 1 } +static const struct Subsprite sUnused_Subsprites_0[] = { + { -16, 0, SPRITE_SHAPE(64x32), SPRITE_SIZE(64x32), 0, 1 }, + { 48, 0, SPRITE_SHAPE(32x32), SPRITE_SIZE(32x32), 32, 1 }, + { -16, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 48, 1 }, + { 16, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 52, 1 }, + { 48, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 56, 1 } }; -static const struct Subsprite gUnknown_826036C[] = { - { 240, 0, SPRITE_SHAPE(64x32), SPRITE_SIZE(64x32), 0x0040, 1 }, - { 48, 0, SPRITE_SHAPE(32x32), SPRITE_SIZE(32x32), 0x0060, 1 }, - { 240, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0070, 1 }, - { 16, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0074, 1 }, - { 48, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0078, 1 } +static const struct Subsprite sUnused_Subsprites_2[] = { + { -16, 0, SPRITE_SHAPE(64x32), SPRITE_SIZE(64x32), 64, 1 }, + { 48, 0, SPRITE_SHAPE(32x32), SPRITE_SIZE(32x32), 96, 1 }, + { -16, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 112, 1 }, + { 16, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 116, 1 }, + { 48, 32, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 120, 1 } }; -static const struct Subsprite gUnknown_8260380[] = { - { 240, 0, SPRITE_SHAPE(64x32), SPRITE_SIZE(64x32), 0x0000, 1 }, - { 48, 0, SPRITE_SHAPE(32x32), SPRITE_SIZE(32x32), 0x0020, 1 } +static const struct Subsprite sUnused_Subsprites_1[] = { + { -16, 0, SPRITE_SHAPE(64x32), SPRITE_SIZE(64x32), 0, 1 }, + { 48, 0, SPRITE_SHAPE(32x32), SPRITE_SIZE(32x32), 32, 1 } }; -static const struct Subsprite gUnknown_8260388[] = { - { 240, 0, SPRITE_SHAPE(64x32), SPRITE_SIZE(64x32), 0x0000, 1 }, - { 48, 0, SPRITE_SHAPE(32x32), SPRITE_SIZE(32x32), 0x0020, 1 } +static const struct Subsprite sUnused_Subsprites_3[] = { + { -16, 0, SPRITE_SHAPE(64x32), SPRITE_SIZE(64x32), 0, 1 }, + { 48, 0, SPRITE_SHAPE(32x32), SPRITE_SIZE(32x32), 32, 1 } }; -static const struct Subsprite gUnknown_8260390[] = { - { 240, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0000, 1 }, - { 16, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0004, 1 } +static const struct Subsprite sHealthBar_Subsprites_Player[] = { + { + .x = -16, + .y = 0, + .shape = SPRITE_SHAPE(32x8), + .size = SPRITE_SIZE(32x8), + .tileOffset = 0, + .priority = 1 + }, + { + .x = 16, + .y = 0, + .shape = SPRITE_SHAPE(32x8), + .size = SPRITE_SIZE(32x8), + .tileOffset = 4, + .priority = 1 + } }; -static const struct Subsprite gUnknown_8260398[] = { - { 240, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0000, 1 }, - { 16, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0004, 1 }, - { 224, 0, SPRITE_SHAPE(8x8), SPRITE_SIZE(8x8), 0x0008, 1 } +static const struct Subsprite sHealthBar_Subsprites_Opponent[] = { + { + .x = -16, + .y = 0, + .shape = SPRITE_SHAPE(32x8), + .size = SPRITE_SIZE(32x8), + .tileOffset = 0, + .priority = 1 + }, + { + .x = 16, + .y = 0, + .shape = SPRITE_SHAPE(32x8), + .size = SPRITE_SIZE(32x8), + .tileOffset = 4, + .priority = 1 + }, + { + .x = -32, + .y = 0, + .shape = SPRITE_SHAPE(8x8), + .size = SPRITE_SIZE(8x8), + .tileOffset = 8, + .priority = 1 + }, }; -static const struct SubspriteTable gUnknown_82603A4[] = { - {NELEMS(gUnknown_8260358), gUnknown_8260358}, - {NELEMS(gUnknown_8260380), gUnknown_8260380}, - {NELEMS(gUnknown_826036C), gUnknown_826036C}, - {NELEMS(gUnknown_8260388), gUnknown_8260388} +// Unused +static const struct SubspriteTable sUnused_SubspriteTable[] = { + {ARRAY_COUNT(sUnused_Subsprites_0), sUnused_Subsprites_0}, + {ARRAY_COUNT(sUnused_Subsprites_1), sUnused_Subsprites_1}, + {ARRAY_COUNT(sUnused_Subsprites_2), sUnused_Subsprites_2}, + {ARRAY_COUNT(sUnused_Subsprites_3), sUnused_Subsprites_3} }; -static const struct SubspriteTable gUnknown_82603C4[] = { - {NELEMS(gUnknown_8260390), gUnknown_8260390}, - {NELEMS(gUnknown_8260398), gUnknown_8260398} +static const struct SubspriteTable sHealthBar_SubspriteTable[] = { + [B_SIDE_PLAYER] = {ARRAY_COUNT(sHealthBar_Subsprites_Player), sHealthBar_Subsprites_Player}, + [B_SIDE_OPPONENT] = {ARRAY_COUNT(sHealthBar_Subsprites_Opponent), sHealthBar_Subsprites_Opponent}, }; -static const struct Subsprite gUnknown_82603D4[] = { - { 160, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0000, 1 }, - { 192, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0004, 1 }, - { 224, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0008, 1 }, - { 0, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x000c, 1 } +static const struct Subsprite sStatusSummaryBar_Subsprites_Enter[] = { + { + .x = -96, + .y = 0, + .shape = SPRITE_SHAPE(32x8), + .size = SPRITE_SIZE(32x8), + .tileOffset = 0, + .priority = 1 + }, + { + .x = -64, + .y = 0, + .shape = SPRITE_SHAPE(32x8), + .size = SPRITE_SIZE(32x8), + .tileOffset = 4, + .priority = 1 + }, + { + .x = -32, + .y = 0, + .shape = SPRITE_SHAPE(32x8), + .size = SPRITE_SIZE(32x8), + .tileOffset = 8, + .priority = 1 + }, + { + .x = 0, + .y = 0, + .shape = SPRITE_SHAPE(32x8), + .size = SPRITE_SIZE(32x8), + .tileOffset = 12, + .priority = 1 + } }; -static const struct Subsprite gUnknown_82603E4[] = { - { 160, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0000, 1 }, - { 192, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0004, 1 }, - { 224, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0008, 1 }, - { 0, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0008, 1 }, - { 32, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x0008, 1 }, - { 64, 0, SPRITE_SHAPE(32x8), SPRITE_SIZE(32x8), 0x000c, 1 } +static const struct Subsprite sStatusSummaryBar_Subsprites_Exit[] = { + { + .x = -96, + .y = 0, + .shape = SPRITE_SHAPE(32x8), + .size = SPRITE_SIZE(32x8), + .tileOffset = 0, + .priority = 1 + }, + { + .x = -64, + .y = 0, + .shape = SPRITE_SHAPE(32x8), + .size = SPRITE_SIZE(32x8), + .tileOffset = 4, + .priority = 1 + }, + { + .x = -32, + .y = 0, + .shape = SPRITE_SHAPE(32x8), + .size = SPRITE_SIZE(32x8), + .tileOffset = 8, + .priority = 1 + }, + { + .x = 0, + .y = 0, + .shape = SPRITE_SHAPE(32x8), + .size = SPRITE_SIZE(32x8), + .tileOffset = 8, + .priority = 1 + }, + { + .x = 32, + .y = 0, + .shape = SPRITE_SHAPE(32x8), + .size = SPRITE_SIZE(32x8), + .tileOffset = 8, + .priority = 1 + }, + { + .x = 64, + .y = 0, + .shape = SPRITE_SHAPE(32x8), + .size = SPRITE_SIZE(32x8), + .tileOffset = 12, + .priority = 1 + } }; -static const struct SubspriteTable sStatusSummaryBar_SubspriteTable[] = -{ - {NELEMS(gUnknown_82603D4), gUnknown_82603D4} +static const struct SubspriteTable sStatusSummaryBar_SubspriteTable_Enter[] = { + {ARRAY_COUNT(sStatusSummaryBar_Subsprites_Enter), sStatusSummaryBar_Subsprites_Enter} }; -static const struct SubspriteTable gUnknown_8260404[] = { - {NELEMS(gUnknown_82603E4), gUnknown_82603E4} +static const struct SubspriteTable sStatusSummaryBar_SubspriteTable_Exit[] = { + {ARRAY_COUNT(sStatusSummaryBar_Subsprites_Exit), sStatusSummaryBar_Subsprites_Exit} }; static const u16 sBattleInterface_Unused[] = INCBIN_U16("graphics/battle_interface/unused.4bpp"); -static const struct CompressedSpriteSheet sStatusSummaryBarSpriteSheets[] = { - {gFile_graphics_battle_interface_ball_status_bar_sheet, 0x0200, 55052}, - {gFile_graphics_battle_interface_ball_status_bar_sheet, 0x0200, 55053} +static const struct CompressedSpriteSheet sPartySummaryBarSpriteSheets[] = { + {gBattleInterface_PartySummaryBar_Gfx, 16 * TILE_SIZE_4BPP, TAG_PARTY_SUMMARY_BAR_PLAYER_TILE}, + {gBattleInterface_PartySummaryBar_Gfx, 16 * TILE_SIZE_4BPP, TAG_PARTY_SUMMARY_BAR_OPPONENT_TILE} }; -static const struct SpritePalette sStatusSummaryBarSpritePals[] = { - {gBattleInterface_BallStatusBarPal, 55056}, - {gBattleInterface_BallStatusBarPal, 55057} +static const struct SpritePalette sPartySummaryBarSpritePals[] = { + {gBattleInterface_Healthbox_Pal, TAG_PARTY_SUMMARY_BAR_PLAYER_PAL}, + {gBattleInterface_Healthbox_Pal, TAG_PARTY_SUMMARY_BAR_OPPONENT_PAL} }; -static const struct SpritePalette sStatusSummaryBallsSpritePals[] = { - {gBattleInterface_BallDisplayPal, 55058}, - {gBattleInterface_BallDisplayPal, 55059} +static const struct SpritePalette sPartySummaryBallSpritePals[] = { + {gBattleInterface_Healthbar_Pal, TAG_PARTY_SUMMARY_BALL_PLAYER_PAL}, + {gBattleInterface_Healthbar_Pal, TAG_PARTY_SUMMARY_BALL_OPPONENT_PAL} }; -static const struct SpriteSheet sStatusSummaryBallsSpriteSheets[] = { - {gBattleInterface_SummaryBallDisplayGfx, 0x0080, 55060}, - {gBattleInterface_SummaryBallDisplayGfx, 0x0080, 55061} +static const struct SpriteSheet sPartySummaryBallSpriteSheets[] = { + {gBattleInterface_Gfx + B_INTERFACE_GFX_BALL_PARTY_SUMMARY, 4 * TILE_SIZE_4BPP, TAG_PARTY_SUMMARY_BALL_PLAYER_TILE}, + {gBattleInterface_Gfx + B_INTERFACE_GFX_BALL_PARTY_SUMMARY, 4 * TILE_SIZE_4BPP, TAG_PARTY_SUMMARY_BALL_OPPONENT_TILE} }; -static const struct OamData gUnknown_82604AC = { +// Unused +static const struct OamData sOamData_Healthbox2 = { .shape = SPRITE_SHAPE(64x32), .size = SPRITE_SIZE(64x32), .priority = 1 }; -static const struct OamData gUnknown_82604B4 = { +static const struct OamData sOamData_PartySummaryBall = { .shape = SPRITE_SHAPE(8x8), .size = SPRITE_SIZE(8x8), .priority = 1 }; -static const struct SpriteTemplate sStatusSummaryBarSpriteTemplates[] = { +static const struct SpriteTemplate sPartySummaryBarSpriteTemplates[] = { { - .tileTag = 55052, - .paletteTag = 55056, - .oam = &gOamData_8260270, + .tileTag = TAG_PARTY_SUMMARY_BAR_PLAYER_TILE, + .paletteTag = TAG_PARTY_SUMMARY_BAR_PLAYER_PAL, + .oam = &sOamData_Healthbox, .anims = gDummySpriteAnimTable, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_StatusSummaryBar + .callback = SpriteCB_PartySummaryBar }, { - .tileTag = 55053, - .paletteTag = 55057, - .oam = &gOamData_8260270, + .tileTag = TAG_PARTY_SUMMARY_BAR_OPPONENT_TILE, + .paletteTag = TAG_PARTY_SUMMARY_BAR_OPPONENT_PAL, + .oam = &sOamData_Healthbox, .anims = gDummySpriteAnimTable, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_StatusSummaryBar + .callback = SpriteCB_PartySummaryBar } }; -static const struct SpriteTemplate sStatusSummaryBallsSpriteTemplates[] = { +static const struct SpriteTemplate sPartySummaryBallSpriteTemplates[] = { { - .tileTag = 55060, - .paletteTag = 55058, - .oam = &gUnknown_82604B4, + .tileTag = TAG_PARTY_SUMMARY_BALL_PLAYER_TILE, + .paletteTag = TAG_PARTY_SUMMARY_BALL_PLAYER_PAL, + .oam = &sOamData_PartySummaryBall, .anims = gDummySpriteAnimTable, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_StatusSummaryBallsOnBattleStart + .callback = SpriteCB_PartySummaryBall_OnBattleStart }, { - .tileTag = 55061, - .paletteTag = 55059, - .oam = &gUnknown_82604B4, + .tileTag = TAG_PARTY_SUMMARY_BALL_OPPONENT_TILE, + .paletteTag = TAG_PARTY_SUMMARY_BALL_OPPONENT_PAL, + .oam = &sOamData_PartySummaryBall, .anims = gDummySpriteAnimTable, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCB_StatusSummaryBallsOnBattleStart + .callback = SpriteCB_PartySummaryBall_OnBattleStart } }; -static void sub_8047B0C(s16 number, u16 *dest, bool8 unk) +static void Debug_DrawNumber(s16 number, u16 *dest, bool8 singleRow) { s8 i, j; u8 buff[4]; for (i = 0; i < 4; i++) - { buff[i] = 0; - } for (i = 3; ; i--) { @@ -428,35 +450,35 @@ static void sub_8047B0C(s16 number, u16 *dest, bool8 unk) } else { - for (; i > -1; i--) + while (i > -1) { buff[i] = 0xFF; + i--; } + if (buff[3] == 0xFF) buff[3] = 0; break; } } - - - if (!unk) + if (!singleRow) { for (i = 0, j = 0; i < 4; i++) { if (buff[j] == 0xFF) { dest[j + 0x00] &= 0xFC00; - dest[j + 0x00] |= 0x1E; + dest[j + 0x00] |= 30; dest[i + 0x20] &= 0xFC00; - dest[i + 0x20] |= 0x1E; + dest[i + 0x20] |= 30; } else { dest[j + 0x00] &= 0xFC00; - dest[j + 0x00] |= 0x14 + buff[j]; + dest[j + 0x00] |= 20 + buff[j]; dest[i + 0x20] &= 0xFC00; - dest[i + 0x20] |= 0x34 + buff[i]; + dest[i + 0x20] |= 20 + buff[i] + 1 * TILE_SIZE_4BPP; } j++; } @@ -468,174 +490,181 @@ static void sub_8047B0C(s16 number, u16 *dest, bool8 unk) if (buff[i] == 0xFF) { dest[i + 0x00] &= 0xFC00; - dest[i + 0x00] |= 0x1E; + dest[i + 0x00] |= 30; dest[i + 0x20] &= 0xFC00; - dest[i + 0x20] |= 0x1E; + dest[i + 0x20] |= 30; } else { dest[i + 0x00] &= 0xFC00; - dest[i + 0x00] |= 0x14 + buff[i]; + dest[i + 0x00] |= 20 + buff[i]; dest[i + 0x20] &= 0xFC00; - dest[i + 0x20] |= 0x34 + buff[i]; + dest[i + 0x20] |= 20 + buff[i] + 1 * TILE_SIZE_4BPP; } } } } -static void sub_8047CAC(s16 num1, s16 num2, u16 *dest) +// Unused +static void Debug_DrawNumberPair(s16 num1, s16 num2, u16 *dest) { - dest[4] = 0x1E; - sub_8047B0C(num2, &dest[0], FALSE); - sub_8047B0C(num1, &dest[5], TRUE); + dest[4] = 30; + Debug_DrawNumber(num2, &dest[0], FALSE); + Debug_DrawNumber(num1, &dest[5], TRUE); } -// Because the healthbox is too large to fit into one sprite, it is divided into two sprites. -// healthboxLeft or healthboxMain is the left part that is used as the 'main' sprite. -// healthboxRight or healthboxOther is the right part of the healthbox. -// There's also the third sprite under name of healthbarSprite that refers to the healthbar visible on the healtbox. +// Because the healthbox is too large to fit into one sprite, it is divided +// into two sprites. The left sprite is used as the 'main' healthbox sprite, +// while the right sprite is the 'other' healthbox sprite. +// There is also a third sprite for the healthbar, visible on the healthbox. -// data fields for healthboxMain -// oam.affineParam holds healthboxRight spriteId -#define hMain_HealthBarSpriteId data[5] -#define hMain_Battler data[6] -#define hMain_Data7 data[7] +// sprite data for main (left) healthbox sprite +#define sHealthboxOtherSpriteId oam.affineParam +#define sHealthBarSpriteId data[5] +#define sBattlerId data[6] -// data fields for healthboxRight -#define hOther_HealthBoxSpriteId data[5] +// sprite data for other (right) healthbox sprite +#define sHealthboxSpriteId data[5] -// data fields for healthbar -#define hBar_HealthBoxSpriteId data[5] -#define hBar_Data6 data[6] +// sprite data for healthbar sprite +#define sHealthboxSpriteId data[5] +#define sHealthbarType data[6] -u8 CreateBattlerHealthboxSprites(u8 a) +enum { - s16 data6 = 0; - u8 healthboxLeftSpriteId; - u8 healthboxRightSpriteId; + HEALTHBAR_TYPE_PLAYER_SINGLE, + HEALTHBAR_TYPE_PLAYER_DOUBLE, + HEALTHBAR_TYPE_OPPONENT, +}; + +u8 CreateBattlerHealthboxSprites(u8 battlerId) +{ + s16 healthbarType = HEALTHBAR_TYPE_PLAYER_SINGLE; + u8 healthboxSpriteId; + u8 healthboxOtherSpriteId; u8 healthbarSpriteId; - struct Sprite *sprite; + struct Sprite *healthbarSprite; if (!IsDoubleBattle()) { - if (GetBattlerSide(a) == B_SIDE_PLAYER) + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) { - healthboxLeftSpriteId = CreateSprite(&sHealthboxPlayerSpriteTemplates[0], 240, 160, 1); - healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxPlayerSpriteTemplates[0], 240, 160, 1); + healthboxSpriteId = CreateSprite(&sHealthboxPlayerSpriteTemplates[B_POSITION_PLAYER_LEFT / 2], 240, 160, 1); + healthboxOtherSpriteId = CreateSpriteAtEnd(&sHealthboxPlayerSpriteTemplates[B_POSITION_PLAYER_LEFT / 2], 240, 160, 1); - gSprites[healthboxLeftSpriteId].oam.shape = SPRITE_SHAPE(64x64); - gSprites[healthboxRightSpriteId].oam.shape = SPRITE_SHAPE(64x64); - gSprites[healthboxRightSpriteId].oam.tileNum += 64; + gSprites[healthboxSpriteId].oam.shape = SPRITE_SHAPE(64x64); + gSprites[healthboxOtherSpriteId].oam.shape = SPRITE_SHAPE(64x64); + gSprites[healthboxOtherSpriteId].oam.tileNum += 2 * TILE_SIZE_4BPP; } else { - healthboxLeftSpriteId = CreateSprite(&sHealthboxOpponentSpriteTemplates[0], 240, 160, 1); - healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxOpponentSpriteTemplates[0], 240, 160, 1); + healthboxSpriteId = CreateSprite(&sHealthboxOpponentSpriteTemplates[B_POSITION_OPPONENT_LEFT / 2], 240, 160, 1); + healthboxOtherSpriteId = CreateSpriteAtEnd(&sHealthboxOpponentSpriteTemplates[B_POSITION_OPPONENT_LEFT / 2], 240, 160, 1); - gSprites[healthboxRightSpriteId].oam.tileNum += 32; - data6 = 2; + gSprites[healthboxOtherSpriteId].oam.tileNum += 1 * TILE_SIZE_4BPP; + healthbarType = HEALTHBAR_TYPE_OPPONENT; } - gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId; - gSprites[healthboxRightSpriteId].hBar_HealthBoxSpriteId = healthboxLeftSpriteId; - gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther; + gSprites[healthboxSpriteId].sHealthboxOtherSpriteId = healthboxOtherSpriteId; + gSprites[healthboxOtherSpriteId].sHealthboxSpriteId = healthboxSpriteId; + gSprites[healthboxOtherSpriteId].callback = SpriteCB_HealthBoxOther; } else { - if (GetBattlerSide(a) == B_SIDE_PLAYER) + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) { - healthboxLeftSpriteId = CreateSprite(&sHealthboxPlayerSpriteTemplates[GetBattlerPosition(a) / 2], 240, 160, 1); - healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxPlayerSpriteTemplates[GetBattlerPosition(a) / 2], 240, 160, 1); + healthboxSpriteId = CreateSprite(&sHealthboxPlayerSpriteTemplates[GetBattlerPosition(battlerId) / 2], 240, 160, 1); + healthboxOtherSpriteId = CreateSpriteAtEnd(&sHealthboxPlayerSpriteTemplates[GetBattlerPosition(battlerId) / 2], 240, 160, 1); - gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId; - gSprites[healthboxRightSpriteId].hBar_HealthBoxSpriteId = healthboxLeftSpriteId; - gSprites[healthboxRightSpriteId].oam.tileNum += 32; - gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther; - data6 = 1; + gSprites[healthboxSpriteId].sHealthboxOtherSpriteId = healthboxOtherSpriteId; + gSprites[healthboxOtherSpriteId].sHealthboxSpriteId = healthboxSpriteId; + gSprites[healthboxOtherSpriteId].oam.tileNum += 1 * TILE_SIZE_4BPP; + gSprites[healthboxOtherSpriteId].callback = SpriteCB_HealthBoxOther; + healthbarType = HEALTHBAR_TYPE_PLAYER_DOUBLE; } else { - healthboxLeftSpriteId = CreateSprite(&sHealthboxOpponentSpriteTemplates[GetBattlerPosition(a) / 2], 240, 160, 1); - healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxOpponentSpriteTemplates[GetBattlerPosition(a) / 2], 240, 160, 1); + healthboxSpriteId = CreateSprite(&sHealthboxOpponentSpriteTemplates[GetBattlerPosition(battlerId) / 2], 240, 160, 1); + healthboxOtherSpriteId = CreateSpriteAtEnd(&sHealthboxOpponentSpriteTemplates[GetBattlerPosition(battlerId) / 2], 240, 160, 1); - gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId; - gSprites[healthboxRightSpriteId].hBar_HealthBoxSpriteId = healthboxLeftSpriteId; - gSprites[healthboxRightSpriteId].oam.tileNum += 32; - gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther; - data6 = 2; + gSprites[healthboxSpriteId].sHealthboxOtherSpriteId = healthboxOtherSpriteId; + gSprites[healthboxOtherSpriteId].sHealthboxSpriteId = healthboxSpriteId; + gSprites[healthboxOtherSpriteId].oam.tileNum += 1 * TILE_SIZE_4BPP; + gSprites[healthboxOtherSpriteId].callback = SpriteCB_HealthBoxOther; + healthbarType = HEALTHBAR_TYPE_OPPONENT; } } - healthbarSpriteId = CreateSpriteAtEnd(&gUnknown_82602F8[gBattlerPositions[a]], 140, 60, 0); - sprite = &gSprites[healthbarSpriteId]; - SetSubspriteTables(sprite, &gUnknown_82603C4[GetBattlerSide(a)]); - sprite->subspriteMode = SUBSPRITES_IGNORE_PRIORITY; - sprite->oam.priority = 1; - CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_1), OBJ_VRAM0 + sprite->oam.tileNum * 32, 64); + healthbarSpriteId = CreateSpriteAtEnd(&sHealthbarSpriteTemplates[gBattlerPositions[battlerId]], 140, 60, 0); + healthbarSprite = &gSprites[healthbarSpriteId]; + SetSubspriteTables(healthbarSprite, &sHealthBar_SubspriteTable[GetBattlerSide(battlerId)]); + healthbarSprite->subspriteMode = SUBSPRITES_IGNORE_PRIORITY; + healthbarSprite->oam.priority = 1; + CpuCopy32(GetBattleInterfaceGfxPtr(B_INTERFACE_GFX_HP_BAR_HP_TEXT), OBJ_VRAM0 + healthbarSprite->oam.tileNum * TILE_SIZE_4BPP, 2 * TILE_SIZE_4BPP); - gSprites[healthboxLeftSpriteId].hBar_HealthBoxSpriteId = healthbarSpriteId; - gSprites[healthboxLeftSpriteId].hBar_Data6 = a; - gSprites[healthboxLeftSpriteId].invisible = TRUE; - gSprites[healthboxRightSpriteId].invisible = TRUE; - sprite->data[5] = healthboxLeftSpriteId; - sprite->data[6] = data6; - sprite->invisible = TRUE; + gSprites[healthboxSpriteId].sHealthBarSpriteId = healthbarSpriteId; + gSprites[healthboxSpriteId].sBattlerId = battlerId; + gSprites[healthboxSpriteId].invisible = TRUE; + gSprites[healthboxOtherSpriteId].invisible = TRUE; + healthbarSprite->sHealthboxSpriteId = healthboxSpriteId; + healthbarSprite->sHealthbarType = healthbarType; + healthbarSprite->invisible = TRUE; - return healthboxLeftSpriteId; + return healthboxSpriteId; } u8 CreateSafariPlayerHealthboxSprites(void) { - u8 healthboxLeftSpriteId = CreateSprite(&sHealthboxSafariSpriteTemplate, 240, 160, 1); - u8 healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxSafariSpriteTemplate, 240, 160, 1); + u8 healthboxSpriteId = CreateSprite(&sHealthboxSafariSpriteTemplate, 240, 160, 1); + u8 healthboxOtherSpriteId = CreateSpriteAtEnd(&sHealthboxSafariSpriteTemplate, 240, 160, 1); - gSprites[healthboxLeftSpriteId].oam.shape = SPRITE_SHAPE(64x64); - gSprites[healthboxRightSpriteId].oam.shape = SPRITE_SHAPE(64x64); - gSprites[healthboxRightSpriteId].oam.tileNum += 0x40; - gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId; - gSprites[healthboxRightSpriteId].hBar_HealthBoxSpriteId = healthboxLeftSpriteId; - gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther; - return healthboxLeftSpriteId; + gSprites[healthboxSpriteId].oam.shape = SPRITE_SHAPE(64x64); + gSprites[healthboxOtherSpriteId].oam.shape = SPRITE_SHAPE(64x64); + gSprites[healthboxOtherSpriteId].oam.tileNum += 2 * TILE_SIZE_4BPP; + gSprites[healthboxSpriteId].sHealthboxOtherSpriteId = healthboxOtherSpriteId; + gSprites[healthboxOtherSpriteId].sHealthboxSpriteId = healthboxSpriteId; + gSprites[healthboxOtherSpriteId].callback = SpriteCB_HealthBoxOther; + return healthboxSpriteId; } -static const u8 *GetHealthboxElementGfxPtr(u8 elementId) +static const u8 *GetBattleInterfaceGfxPtr(u8 elementId) { - return gHealthboxElementsGfxTable[elementId]; + return gBattleInterface_Gfx[elementId]; } // Syncs the position of healthbar accordingly with the healthbox. static void SpriteCB_HealthBar(struct Sprite *sprite) { - u8 r5 = sprite->data[5]; + u8 healthboxSpriteId = sprite->sHealthboxSpriteId; - switch (sprite->data[6]) + switch (sprite->sHealthbarType) { - case 0: - sprite->x = gSprites[r5].x + 16; - sprite->y = gSprites[r5].y; + case HEALTHBAR_TYPE_PLAYER_SINGLE: + sprite->x = gSprites[healthboxSpriteId].x + 16; + sprite->y = gSprites[healthboxSpriteId].y; break; - case 1: - sprite->x = gSprites[r5].x + 16; - sprite->y = gSprites[r5].y; + case HEALTHBAR_TYPE_PLAYER_DOUBLE: + sprite->x = gSprites[healthboxSpriteId].x + 16; + sprite->y = gSprites[healthboxSpriteId].y; break; default: - case 2: - sprite->x = gSprites[r5].x + 8; - sprite->y = gSprites[r5].y; + case HEALTHBAR_TYPE_OPPONENT: + sprite->x = gSprites[healthboxSpriteId].x + 8; + sprite->y = gSprites[healthboxSpriteId].y; break; } - sprite->x2 = gSprites[r5].x2; - sprite->y2 = gSprites[r5].y2; + sprite->x2 = gSprites[healthboxSpriteId].x2; + sprite->y2 = gSprites[healthboxSpriteId].y2; } static void SpriteCB_HealthBoxOther(struct Sprite *sprite) { - u8 healthboxMainSpriteId = sprite->hOther_HealthBoxSpriteId; + u8 healthboxSpriteId = sprite->sHealthboxSpriteId; - sprite->x = gSprites[healthboxMainSpriteId].x + 64; - sprite->y = gSprites[healthboxMainSpriteId].y; + sprite->x = gSprites[healthboxSpriteId].x + 64; + sprite->y = gSprites[healthboxSpriteId].y; - sprite->x2 = gSprites[healthboxMainSpriteId].x2; - sprite->y2 = gSprites[healthboxMainSpriteId].y2; + sprite->x2 = gSprites[healthboxSpriteId].x2; + sprite->y2 = gSprites[healthboxSpriteId].y2; } void SetBattleBarStruct(u8 battlerId, u8 healthboxSpriteId, s32 maxVal, s32 oldVal, s32 receivedValue) @@ -650,15 +679,15 @@ void SetBattleBarStruct(u8 battlerId, u8 healthboxSpriteId, s32 maxVal, s32 oldV void SetHealthboxSpriteInvisible(u8 healthboxSpriteId) { gSprites[healthboxSpriteId].invisible = TRUE; - gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId].invisible = TRUE; - gSprites[gSprites[healthboxSpriteId].oam.affineParam].invisible = TRUE; + gSprites[gSprites[healthboxSpriteId].sHealthBarSpriteId].invisible = TRUE; + gSprites[gSprites[healthboxSpriteId].sHealthboxOtherSpriteId].invisible = TRUE; } void SetHealthboxSpriteVisible(u8 healthboxSpriteId) { gSprites[healthboxSpriteId].invisible = FALSE; - gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId].invisible = FALSE; - gSprites[gSprites[healthboxSpriteId].oam.affineParam].invisible = FALSE; + gSprites[gSprites[healthboxSpriteId].sHealthBarSpriteId].invisible = FALSE; + gSprites[gSprites[healthboxSpriteId].sHealthboxOtherSpriteId].invisible = FALSE; } static void UpdateSpritePos(u8 spriteId, s16 x, s16 y) @@ -669,14 +698,13 @@ static void UpdateSpritePos(u8 spriteId, s16 x, s16 y) void DestoryHealthboxSprite(u8 healthboxSpriteId) { - DestroySprite(&gSprites[gSprites[healthboxSpriteId].oam.affineParam]); - DestroySprite(&gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId]); + DestroySprite(&gSprites[gSprites[healthboxSpriteId].sHealthboxOtherSpriteId]); + DestroySprite(&gSprites[gSprites[healthboxSpriteId].sHealthBarSpriteId]); DestroySprite(&gSprites[healthboxSpriteId]); } void DummyBattleInterfaceFunc(u8 healthboxSpriteId, bool8 isDoubleBattleBattlerOnly) { - } void UpdateOamPriorityInAllHealthboxes(u8 priority) @@ -685,12 +713,12 @@ void UpdateOamPriorityInAllHealthboxes(u8 priority) for (i = 0; i < gBattlersCount; i++) { - u8 healthboxLeftSpriteId = gHealthboxSpriteIds[i]; - u8 healthboxRightSpriteId = gSprites[gHealthboxSpriteIds[i]].oam.affineParam; - u8 healthbarSpriteId = gSprites[gHealthboxSpriteIds[i]].hMain_HealthBarSpriteId; + u8 healthboxSpriteId = gHealthboxSpriteIds[i]; + u8 healthboxOtherSpriteId = gSprites[gHealthboxSpriteIds[i]].sHealthboxOtherSpriteId; + u8 healthbarSpriteId = gSprites[gHealthboxSpriteIds[i]].sHealthBarSpriteId; - gSprites[healthboxLeftSpriteId].oam.priority = priority; - gSprites[healthboxRightSpriteId].oam.priority = priority; + gSprites[healthboxSpriteId].oam.priority = priority; + gSprites[healthboxOtherSpriteId].oam.priority = priority; gSprites[healthbarSpriteId].oam.priority = priority; } } @@ -742,7 +770,7 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl) windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, xPos, 3, &windowId); spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * TILE_SIZE_4BPP; - if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER) + if (GetBattlerSide(gSprites[healthboxSpriteId].sBattlerId) == B_SIDE_PLAYER) { objVram = (void *)(OBJ_VRAM0); if (!IsDoubleBattle()) @@ -763,22 +791,22 @@ void UpdateHpTextInHealthbox(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent) { u32 windowId, spriteTileNum; u8 *windowTileData; - u8 *strptr; - void *objVram; - if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER && !IsDoubleBattle()) + if (GetBattlerSide(gSprites[healthboxSpriteId].sBattlerId) == B_SIDE_PLAYER && !IsDoubleBattle()) { + // Only in the Japanese release can HP be displayed as text outside of double battles u8 text[8]; if (maxOrCurrent != HP_CURRENT) // singles, max { ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3); windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 0, 5, &windowId); spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum; - TextIntoHealthboxObject( (void *)(OBJ_VRAM0) + spriteTileNum * TILE_SIZE_4BPP + 0xA40, windowTileData, 2); + TextIntoHealthboxObject((void *)(OBJ_VRAM0) + spriteTileNum * TILE_SIZE_4BPP + 0xA40, windowTileData, 2); RemoveWindowOnHealthbox(windowId); } else // singles, current { + u8 *strptr; strptr = ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3); *strptr++ = CHAR_SLASH; *strptr++ = EOS; @@ -794,17 +822,16 @@ void UpdateHpTextInHealthbox(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent) u8 battler; u8 text[20] = __("{COLOR 01}{HIGHLIGHT 02}"); - battler = gSprites[healthboxSpriteId].hMain_Battler; + battler = gSprites[healthboxSpriteId].sBattlerId; if (IsDoubleBattle() == TRUE || GetBattlerSide(battler) == B_SIDE_OPPONENT) - { UpdateHpTextInHealthboxInDoubles(healthboxSpriteId, value, maxOrCurrent); - } else { + // Only in the Japanese release can HP be displayed as text outside of double battles u32 var; u8 i; - if (GetBattlerSide(gSprites[healthboxSpriteId].data[6]) == B_SIDE_PLAYER) + if (GetBattlerSide(gSprites[healthboxSpriteId].sBattlerId) == B_SIDE_PLAYER) { if (maxOrCurrent == HP_CURRENT) var = 29; @@ -826,39 +853,39 @@ void UpdateHpTextInHealthbox(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent) { CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[i * 64 + 32], (void *)((OBJ_VRAM0) + TILE_SIZE_4BPP * (gSprites[healthboxSpriteId].oam.tileNum + var + i)), - 0x20); + 1 * TILE_SIZE_4BPP); } } } } -static const u8 gUnknown_8260540[] = _("/"); +static const u8 sText_Slash[] = _("/"); static void UpdateHpTextInHealthboxInDoubles(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent) { u32 windowId, spriteTileNum; u8 *windowTileData; - void *objVram; u8 battlerId; u8 text[20] = __("{COLOR 01}{HIGHLIGHT 00}"); - battlerId = gSprites[healthboxSpriteId].hMain_Battler; + battlerId = gSprites[healthboxSpriteId].sBattlerId; - if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars) // don't print text if only bars are visible + if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars) { u8 var = 4; - u8 r7; + u8 healthBarSpriteId; u8 *txtPtr; u8 i; if (maxOrCurrent == HP_CURRENT) var = 0; - r7 = gSprites[healthboxSpriteId].data[5]; + healthBarSpriteId = gSprites[healthboxSpriteId].sHealthBarSpriteId; txtPtr = ConvertIntToDecimalStringN(text + 6, value, STR_CONV_MODE_RIGHT_ALIGN, 3); - if (!maxOrCurrent) - StringCopy(txtPtr, gUnknown_8260540); + if (maxOrCurrent == HP_CURRENT) + StringCopy(txtPtr, sText_Slash); + RenderTextFont9(gMonSpritesGfxPtr->barFontGfx, 0, text, 0, 0, 0, 0, 0); for (i = var; i < var + 3; i++) @@ -866,31 +893,33 @@ static void UpdateHpTextInHealthboxInDoubles(u8 healthboxSpriteId, s16 value, u8 if (i < 3) { CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32], - (void *)((OBJ_VRAM0) + 32 * (1 + gSprites[r7].oam.tileNum + i)), - 0x20); + (void *)((OBJ_VRAM0) + (1 + gSprites[healthBarSpriteId].oam.tileNum + i) * TILE_SIZE_4BPP), + 1 * TILE_SIZE_4BPP); } else { CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32], - (void *)((OBJ_VRAM0 + 0x20) + 32 * (i + gSprites[r7].oam.tileNum)), - 0x20); + (void *)((OBJ_VRAM0 + 0x20) + (i + gSprites[healthBarSpriteId].oam.tileNum) * TILE_SIZE_4BPP), + 1 * TILE_SIZE_4BPP); } } if (maxOrCurrent == HP_CURRENT) { CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[224], - (void *)((OBJ_VRAM0) + ((gSprites[r7].oam.tileNum + 4) * TILE_SIZE_4BPP)), - 0x20); - CpuFill32(0, (void *)((OBJ_VRAM0) + (gSprites[r7].oam.tileNum * TILE_SIZE_4BPP)), 0x20); + (void *)((OBJ_VRAM0) + ((gSprites[healthBarSpriteId].oam.tileNum + 4) * TILE_SIZE_4BPP)), + 1 * TILE_SIZE_4BPP); + CpuFill32(0, + (void *)((OBJ_VRAM0) + (gSprites[healthBarSpriteId].oam.tileNum * TILE_SIZE_4BPP)), + 1 * TILE_SIZE_4BPP); } else { - if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) // Impossible to reach part, because the battlerId is from the opponent's side. + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) { - CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_116), + CpuCopy32(GetBattleInterfaceGfxPtr(B_INTERFACE_GFX_BOTTOM_RIGHT_CORNER_HP_AS_TEXT), (void *)(OBJ_VRAM0) + ((gSprites[healthboxSpriteId].oam.tileNum + 52) * TILE_SIZE_4BPP), - 0x20); + 1 * TILE_SIZE_4BPP); } } } @@ -904,7 +933,7 @@ static void PrintSafariMonInfo(u8 healthboxSpriteId, struct Pokemon *mon) u8 *barFontGfx; u8 i, var, nature, healthBarSpriteId; - barFontGfx = &gMonSpritesGfxPtr->barFontGfx[0x520 + (GetBattlerPosition(gSprites[healthboxSpriteId].hMain_Battler) * 384)]; + barFontGfx = &gMonSpritesGfxPtr->barFontGfx[0x520 + (GetBattlerPosition(gSprites[healthboxSpriteId].sBattlerId) * 384)]; var = 5; nature = GetNature(mon); StringCopy(text + 6, gNatureNamePointers[nature]); @@ -915,13 +944,13 @@ static void PrintSafariMonInfo(u8 healthboxSpriteId, struct Pokemon *mon) u8 elementId; if ((text[j] >= 55 && text[j] <= 74) || (text[j] >= 135 && text[j] <= 154)) - elementId = HEALTHBOX_GFX_44; + elementId = B_INTERFACE_GFX_SAFARI_HEALTHBOX_1; else if ((text[j] >= 75 && text[j] <= 79) || (text[j] >= 155 && text[j] <= 159)) - elementId = HEALTHBOX_GFX_45; + elementId = B_INTERFACE_GFX_SAFARI_HEALTHBOX_2; else - elementId = HEALTHBOX_GFX_43; + elementId = B_INTERFACE_GFX_SAFARI_HEALTHBOX_0; - CpuCopy32(GetHealthboxElementGfxPtr(elementId), barFontGfx + (i * 64), 0x20); + CpuCopy32(GetBattleInterfaceGfxPtr(elementId), barFontGfx + (i * 64), 0x20); } for (j = 1; j < var + 1; j++) @@ -935,7 +964,7 @@ static void PrintSafariMonInfo(u8 healthboxSpriteId, struct Pokemon *mon) barFontGfx += 0x20; } - healthBarSpriteId = gSprites[healthboxSpriteId].hMain_HealthBarSpriteId; + healthBarSpriteId = gSprites[healthboxSpriteId].sHealthBarSpriteId; ConvertIntToDecimalStringN(text + 6, gBattleStruct->safariCatchFactor, STR_CONV_MODE_RIGHT_ALIGN, 2); ConvertIntToDecimalStringN(text + 9, gBattleStruct->safariEscapeFactor, STR_CONV_MODE_RIGHT_ALIGN, 2); text[5] = CHAR_SPACE; @@ -984,9 +1013,9 @@ void SwapHpBarsWithHpText(void) if (noBars == TRUE) // bars to text { - healthBarSpriteId = gSprites[gHealthboxSpriteIds[i]].hMain_HealthBarSpriteId; + healthBarSpriteId = gSprites[gHealthboxSpriteIds[i]].sHealthBarSpriteId; - CpuFill32(0, (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * TILE_SIZE_4BPP), 0x100); + CpuFill32(0, (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * TILE_SIZE_4BPP), 8 * TILE_SIZE_4BPP); UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_HP), HP_CURRENT); UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP), HP_MAX); } @@ -994,7 +1023,9 @@ void SwapHpBarsWithHpText(void) { UpdateStatusIconInHealthbox(gHealthboxSpriteIds[i]); UpdateHealthboxAttribute(gHealthboxSpriteIds[i], &gPlayerParty[gBattlerPartyIndexes[i]], HEALTHBOX_HEALTH_BAR); - CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_117), (void *)(OBJ_VRAM0 + 0x680 + gSprites[gHealthboxSpriteIds[i]].oam.tileNum * TILE_SIZE_4BPP), 32); + CpuCopy32(GetBattleInterfaceGfxPtr(B_INTERFACE_GFX_BOTTOM_RIGHT_CORNER_HP_AS_BAR), + (void *)(OBJ_VRAM0 + 0x680 + gSprites[gHealthboxSpriteIds[i]].oam.tileNum * TILE_SIZE_4BPP), + 1 * TILE_SIZE_4BPP); } } else @@ -1008,9 +1039,9 @@ void SwapHpBarsWithHpText(void) } else { - healthBarSpriteId = gSprites[gHealthboxSpriteIds[i]].hMain_HealthBarSpriteId; + healthBarSpriteId = gSprites[gHealthboxSpriteIds[i]].sHealthBarSpriteId; - CpuFill32(0, (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * 32), 0x100); + CpuFill32(0, (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * 32), 8 * TILE_SIZE_4BPP); UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_HP), HP_CURRENT); UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP), HP_MAX); } @@ -1023,7 +1054,7 @@ void SwapHpBarsWithHpText(void) UpdateHealthboxAttribute(gHealthboxSpriteIds[i], &gEnemyParty[gBattlerPartyIndexes[i]], HEALTHBOX_NICK); } } - gSprites[gHealthboxSpriteIds[i]].hMain_Data7 ^= 1; + gSprites[gHealthboxSpriteIds[i]].data[7] ^= 1; } } } @@ -1032,13 +1063,25 @@ void SwapHpBarsWithHpText(void) #define tSummaryBarSpriteId data[1] #define tBallIconSpriteId(n) data[3 + n] #define tIsBattleStart data[10] -#define tData15 data[15] +#define tTimer data[11] +#define tBlendWeight data[15] + +// sprite data for party summary bar +#define sEnterSpeed data[0] +#define sExitSpeed data[1] + +// sprite data for party summary ball icon +#define sSummaryBarSpriteId data[0] +#define sTimer data[1] +#define sIsOpponent data[2] +#define sSpeed data[3] +#define sIsEmptyBall data[7] u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo, bool8 isSwitchingMons, bool8 isBattleStart) { bool8 isOpponent; s8 nValidMons; - s16 bar_X, bar_Y, bar_pos2_X, bar_data0; + s16 x, y, x2, speed; s32 i; u8 summaryBarSpriteId; u8 ballIconSpritesIds[PARTY_SIZE]; @@ -1049,46 +1092,46 @@ u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo, if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) { isOpponent = FALSE; - bar_X = 136, bar_Y = 96; - bar_pos2_X = 100; - bar_data0 = -5; + x = 136, y = 96; + x2 = 100; + speed = -5; } else { isOpponent = TRUE; if (!isSwitchingMons || !IsDoubleBattle()) - bar_X = 104, bar_Y = 40; + x = 104, y = 40; else - bar_X = 104, bar_Y = 16; + x = 104, y = 16; - bar_pos2_X = -100; - bar_data0 = 5; + x2 = -100; + speed = 5; } } else { isOpponent = TRUE; - bar_X = 104, bar_Y = 40; - bar_pos2_X = -100; - bar_data0 = 5; + x = 104, y = 40; + x2 = -100; + speed = 5; } for (i = 0, nValidMons = 0; i < PARTY_SIZE; i++) { - if (partyInfo[i].hp != 0xFFFF) + if (partyInfo[i].hp != HP_EMPTY_SLOT) nValidMons++; } - LoadCompressedSpriteSheetUsingHeap(&sStatusSummaryBarSpriteSheets[isOpponent]); - LoadSpriteSheet(&sStatusSummaryBallsSpriteSheets[isOpponent]); - LoadSpritePalette(&sStatusSummaryBarSpritePals[isOpponent]); - LoadSpritePalette(&sStatusSummaryBallsSpritePals[isOpponent]); + LoadCompressedSpriteSheetUsingHeap(&sPartySummaryBarSpriteSheets[isOpponent]); + LoadSpriteSheet(&sPartySummaryBallSpriteSheets[isOpponent]); + LoadSpritePalette(&sPartySummaryBarSpritePals[isOpponent]); + LoadSpritePalette(&sPartySummaryBallSpritePals[isOpponent]); - summaryBarSpriteId = CreateSprite(&sStatusSummaryBarSpriteTemplates[isOpponent], bar_X, bar_Y, 10); - SetSubspriteTables(&gSprites[summaryBarSpriteId], sStatusSummaryBar_SubspriteTable); - gSprites[summaryBarSpriteId].x2 = bar_pos2_X; - gSprites[summaryBarSpriteId].data[0] = bar_data0; + summaryBarSpriteId = CreateSprite(&sPartySummaryBarSpriteTemplates[isOpponent], x, y, 10); + SetSubspriteTables(&gSprites[summaryBarSpriteId], sStatusSummaryBar_SubspriteTable_Enter); + gSprites[summaryBarSpriteId].x2 = x2; + gSprites[summaryBarSpriteId].sEnterSpeed = speed; if (isOpponent) { @@ -1096,16 +1139,14 @@ u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo, gSprites[summaryBarSpriteId].oam.matrixNum = ST_OAM_HFLIP; } else - { gSprites[summaryBarSpriteId].x += 96; - } for (i = 0; i < PARTY_SIZE; i++) { - ballIconSpritesIds[i] = CreateSpriteAtEnd(&sStatusSummaryBallsSpriteTemplates[isOpponent], bar_X, bar_Y - 4, 9); + ballIconSpritesIds[i] = CreateSpriteAtEnd(&sPartySummaryBallSpriteTemplates[isOpponent], x, y - 4, 9); if (!isBattleStart) - gSprites[ballIconSpritesIds[i]].callback = SpriteCB_StatusSummaryBallsOnSwitchout; + gSprites[ballIconSpritesIds[i]].callback = SpriteCB_PartySummaryBall_OnSwitchout; if (!isOpponent) { @@ -1113,22 +1154,22 @@ u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo, gSprites[ballIconSpritesIds[i]].y2 = 0; } - gSprites[ballIconSpritesIds[i]].data[0] = summaryBarSpriteId; + gSprites[ballIconSpritesIds[i]].sSummaryBarSpriteId = summaryBarSpriteId; if (!isOpponent) { gSprites[ballIconSpritesIds[i]].x += 10 * i + 24; - gSprites[ballIconSpritesIds[i]].data[1] = i * 7 + 10; + gSprites[ballIconSpritesIds[i]].sTimer = i * 7 + 10; gSprites[ballIconSpritesIds[i]].x2 = 120; } else { gSprites[ballIconSpritesIds[i]].x -= 10 * (5 - i) + 24; - gSprites[ballIconSpritesIds[i]].data[1] = (6 - i) * 7 + 10; + gSprites[ballIconSpritesIds[i]].sTimer = (6 - i) * 7 + 10; gSprites[ballIconSpritesIds[i]].x2 = -120; } - gSprites[ballIconSpritesIds[i]].data[2] = isOpponent; + gSprites[ballIconSpritesIds[i]].sIsOpponent = isOpponent; } if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) @@ -1139,37 +1180,25 @@ u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo, { if (partyInfo[i].hp == HP_EMPTY_SLOT) { - // empty slot or an egg gSprites[ballIconSpritesIds[i]].oam.tileNum += 1; - gSprites[ballIconSpritesIds[i]].data[7] = 1; + gSprites[ballIconSpritesIds[i]].sIsEmptyBall = TRUE; } - else if (partyInfo[i].hp == 0) // fainted mon - { + else if (partyInfo[i].hp == 0) gSprites[ballIconSpritesIds[i]].oam.tileNum += 3; - } - else if (partyInfo[i].status != 0) // mon with major status - { + else if (partyInfo[i].status != STATUS1_NONE) gSprites[ballIconSpritesIds[i]].oam.tileNum += 2; - } } else { if (i >= nValidMons) { - // empty slot or an egg gSprites[ballIconSpritesIds[i]].oam.tileNum += 1; - gSprites[ballIconSpritesIds[i]].data[7] = 1; + gSprites[ballIconSpritesIds[i]].sIsEmptyBall = TRUE; } else if (partyInfo[i].hp == 0) - { - // fainted mon gSprites[ballIconSpritesIds[i]].oam.tileNum += 3; - } - else if (partyInfo[i].status != 0) - { - // mon with major status + else if (partyInfo[i].status != STATUS1_NONE) gSprites[ballIconSpritesIds[i]].oam.tileNum += 2; - } } } } @@ -1181,34 +1210,25 @@ u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo, { if (partyInfo[i].hp == HP_EMPTY_SLOT) { - // empty slot or an egg gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 1; - gSprites[ballIconSpritesIds[5 - i]].data[7] = 1; + gSprites[ballIconSpritesIds[5 - i]].sIsEmptyBall = TRUE; } else if (partyInfo[i].hp == 0) - { - // fainted mon gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 3; - } - else if (partyInfo[i].status != 0) - { - // mon with major status + else if (partyInfo[i].status != STATUS1_NONE) gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 2; - } } else { ballIconSpritesIds[5 - i] += 0; - if (i >= nValidMons) // empty slot or an egg + if (i >= nValidMons) { gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 1; - gSprites[ballIconSpritesIds[5 - i]].data[7] = 1; + gSprites[ballIconSpritesIds[5 - i]].sIsEmptyBall = TRUE; } - else if (partyInfo[i].hp == 0) // fainted mon - { + else if (partyInfo[i].hp == 0) gSprites[ballIconSpritesIds[5 - i]].oam.tileNum += 3; - } - else if (partyInfo[i].status != 0) // mon with major status + else if (partyInfo[i].status != STATUS1_NONE) { do { @@ -1250,7 +1270,7 @@ void Task_HidePartyStatusSummary(u8 taskId) SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(16, 0)); - gTasks[taskId].tData15 = 16; + gTasks[taskId].tBlendWeight = 16; for (i = 0; i < PARTY_SIZE; i++) gSprites[ballIconSpriteIds[i]].oam.objMode = ST_OAM_OBJ_BLEND; @@ -1263,51 +1283,50 @@ void Task_HidePartyStatusSummary(u8 taskId) { if (GetBattlerSide(battlerId) != B_SIDE_PLAYER) { - gSprites[ballIconSpriteIds[5 - i]].data[1] = 7 * i; - gSprites[ballIconSpriteIds[5 - i]].data[3] = 0; + gSprites[ballIconSpriteIds[5 - i]].sTimer = 7 * i; + gSprites[ballIconSpriteIds[5 - i]].sSpeed = 0; gSprites[ballIconSpriteIds[5 - i]].data[4] = 0; - gSprites[ballIconSpriteIds[5 - i]].callback = sub_8049630; + gSprites[ballIconSpriteIds[5 - i]].callback = SpriteCB_PartySummaryBall_Exit; } else { - gSprites[ballIconSpriteIds[i]].data[1] = 7 * i; - gSprites[ballIconSpriteIds[i]].data[3] = 0; + gSprites[ballIconSpriteIds[i]].sTimer = 7 * i; + gSprites[ballIconSpriteIds[i]].sSpeed = 0; gSprites[ballIconSpriteIds[i]].data[4] = 0; - gSprites[ballIconSpriteIds[i]].callback = sub_8049630; + gSprites[ballIconSpriteIds[i]].callback = SpriteCB_PartySummaryBall_Exit; } } - gSprites[summaryBarSpriteId].data[0] /= 2; - gSprites[summaryBarSpriteId].data[1] = 0; - gSprites[summaryBarSpriteId].callback = sub_8049568; - SetSubspriteTables(&gSprites[summaryBarSpriteId], gUnknown_8260404); - gTasks[taskId].func = sub_8049388; + gSprites[summaryBarSpriteId].sEnterSpeed /= 2; + gSprites[summaryBarSpriteId].sExitSpeed = 0; + gSprites[summaryBarSpriteId].callback = SpriteCB_PartySummaryBar_Exit; + SetSubspriteTables(&gSprites[summaryBarSpriteId], sStatusSummaryBar_SubspriteTable_Exit); + gTasks[taskId].func = Task_HidePartyStatusSummary_BattleStart_1; } else - { - gTasks[taskId].func = sub_804948C; - } + gTasks[taskId].func = Task_HidePartyStatusSummary_DuringBattle; + } -static void sub_8049388(u8 taskId) +static void Task_HidePartyStatusSummary_BattleStart_1(u8 taskId) { - if ((gTasks[taskId].data[11]++ % 2) == 0) + if ((gTasks[taskId].tTimer++ % 2) == 0) { - if (--gTasks[taskId].tData15 < 0) + if (--gTasks[taskId].tBlendWeight < 0) return; - SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[15], 16 - gTasks[taskId].data[15])); + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].tBlendWeight, 16 - gTasks[taskId].tBlendWeight)); } - if (gTasks[taskId].tData15 == 0) - gTasks[taskId].func = sub_80493E4; + if (gTasks[taskId].tBlendWeight == 0) + gTasks[taskId].func = Task_HidePartyStatusSummary_BattleStart_2; } -static void sub_80493E4(u8 taskId) +static void Task_HidePartyStatusSummary_BattleStart_2(u8 taskId) { u8 ballIconSpriteIds[PARTY_SIZE]; s32 i; u8 battlerId = gTasks[taskId].tBattler; - if (--gTasks[taskId].tData15 == -1) + if (--gTasks[taskId].tBlendWeight == -1) { u8 summaryBarSpriteId = gTasks[taskId].tSummaryBarSpriteId; @@ -1320,7 +1339,7 @@ static void sub_80493E4(u8 taskId) for (i = 1; i < PARTY_SIZE; i++) DestroySprite(&gSprites[ballIconSpriteIds[i]]); } - else if (gTasks[taskId].tData15 == -3) + else if (gTasks[taskId].tBlendWeight == -3) { SetGpuReg(REG_OFFSET_BLDCNT, 0); SetGpuReg(REG_OFFSET_BLDALPHA, 0); @@ -1328,17 +1347,15 @@ static void sub_80493E4(u8 taskId) } } -static void sub_804948C(u8 taskId) +static void Task_HidePartyStatusSummary_DuringBattle(u8 taskId) { u8 ballIconSpriteIds[PARTY_SIZE]; s32 i; u8 battlerId = gTasks[taskId].tBattler; - if (--gTasks[taskId].tData15 >= 0) - { - SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].data[15], 16 - gTasks[taskId].data[15])); - } - else if (gTasks[taskId].tData15 == -1) + if (--gTasks[taskId].tBlendWeight >= 0) + SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gTasks[taskId].tBlendWeight, 16 - gTasks[taskId].tBlendWeight)); + else if (gTasks[taskId].tBlendWeight == -1) { u8 summaryBarSpriteId = gTasks[taskId].tSummaryBarSpriteId; @@ -1351,7 +1368,7 @@ static void sub_804948C(u8 taskId) for (i = 1; i < PARTY_SIZE; i++) DestroySprite(&gSprites[ballIconSpriteIds[i]]); } - else if (gTasks[taskId].tData15 == -3) + else if (gTasks[taskId].tBlendWeight == -3) { SetGpuReg(REG_OFFSET_BLDCNT, 0); SetGpuReg(REG_OFFSET_BLDALPHA, 0); @@ -1363,61 +1380,57 @@ static void sub_804948C(u8 taskId) #undef tSummaryBarSpriteId #undef tBallIconSpriteId #undef tIsBattleStart -#undef tData15 +#undef tBlendWeight -static void SpriteCB_StatusSummaryBar(struct Sprite *sprite) +static void SpriteCB_PartySummaryBar(struct Sprite *sprite) { if (sprite->x2 != 0) - sprite->x2 += sprite->data[0]; + sprite->x2 += sprite->sEnterSpeed; } -static void sub_8049568(struct Sprite *sprite) +static void SpriteCB_PartySummaryBar_Exit(struct Sprite *sprite) { - sprite->data[1] += 32; - if (sprite->data[0] > 0) - sprite->x2 += sprite->data[1] >> 4; + sprite->sExitSpeed += 32; + if (sprite->sEnterSpeed > 0) + sprite->x2 += sprite->sExitSpeed >> 4; else - sprite->x2 -= sprite->data[1] >> 4; - sprite->data[1] &= 0xF; + sprite->x2 -= sprite->sExitSpeed >> 4; + sprite->sExitSpeed &= 0xF; } -static void SpriteCB_StatusSummaryBallsOnBattleStart(struct Sprite *sprite) +static void SpriteCB_PartySummaryBall_OnBattleStart(struct Sprite *sprite) { - u8 var1; - u16 var2; - s8 pan; + bool8 isOpponent; + u16 speed; - if (sprite->data[1] > 0) + if (sprite->sTimer > 0) { - sprite->data[1]--; + sprite->sTimer--; return; } - var1 = sprite->data[2]; - var2 = sprite->data[3]; - var2 += 56; - sprite->data[3] = var2 & 0xFFF0; + isOpponent = sprite->sIsOpponent; + speed = sprite->sSpeed; + speed += 56; + sprite->sSpeed = speed & 0xFFF0; - if (var1 != 0) + if (isOpponent != FALSE) { - sprite->x2 += var2 >> 4; + sprite->x2 += speed / 16; if (sprite->x2 > 0) sprite->x2 = 0; } else { - sprite->x2 -= var2 >> 4; + sprite->x2 -= speed / 16; if (sprite->x2 < 0) sprite->x2 = 0; } if (sprite->x2 == 0) { - pan = SOUND_PAN_TARGET; - if (var1 != 0) - pan = SOUND_PAN_ATTACKER; - - if (sprite->data[7] != 0) + s8 pan = isOpponent ? SOUND_PAN_ATTACKER : SOUND_PAN_TARGET; + if (sprite->sIsEmptyBall != FALSE) PlaySE2WithPanning(SE_BALL_TRAY_EXIT, pan); else PlaySE1WithPanning(SE_BALL_TRAY_BALL, pan); @@ -1426,41 +1439,51 @@ static void SpriteCB_StatusSummaryBallsOnBattleStart(struct Sprite *sprite) } } -static void sub_8049630(struct Sprite *sprite) +static void SpriteCB_PartySummaryBall_Exit(struct Sprite *sprite) { - u8 var1; - u16 var2; + bool8 isOpponent; + u16 speed; - if (sprite->data[1] > 0) + if (sprite->sTimer > 0) { - sprite->data[1]--; + sprite->sTimer--; return; } - var1 = sprite->data[2]; - var2 = sprite->data[3]; - var2 += 56; - sprite->data[3] = var2 & 0xFFF0; - if (var1 != 0) - sprite->x2 += var2 >> 4; + isOpponent = sprite->sIsOpponent; + speed = sprite->sSpeed; + speed += 56; + sprite->sSpeed = speed & 0xFFF0; + if (isOpponent != FALSE) + sprite->x2 += speed / 16; else - sprite->x2 -= var2 >> 4; - if (sprite->x2 + sprite->x > 248 - || sprite->x2 + sprite->x < -8) + sprite->x2 -= speed / 16; + + if (sprite->x2 + sprite->x > DISPLAY_WIDTH + 8 || sprite->x2 + sprite->x < -8) { sprite->invisible = TRUE; sprite->callback = SpriteCallbackDummy; } } -static void SpriteCB_StatusSummaryBallsOnSwitchout(struct Sprite *sprite) +static void SpriteCB_PartySummaryBall_OnSwitchout(struct Sprite *sprite) { - u8 barSpriteId = sprite->data[0]; + u8 summaryBarSpriteId = sprite->sSummaryBarSpriteId; - sprite->x2 = gSprites[barSpriteId].x2; - sprite->y2 = gSprites[barSpriteId].y2; + sprite->x2 = gSprites[summaryBarSpriteId].x2; + sprite->y2 = gSprites[summaryBarSpriteId].y2; } -static const u8 gUnknown_8260556[] = _("{HIGHLIGHT 02}"); + +#undef sSummaryBarSpriteId +#undef sTimer +#undef sIsOpponent +#undef sSpeed +#undef sIsEmptyBall + +#undef sEnterSpeed +#undef sExitSpeed + +static const u8 sText_HealthboxNickname[] = _("{HIGHLIGHT 02}"); void UpdateNickInHealthbox(u8 healthboxSpriteId, struct Pokemon *mon) { @@ -1471,7 +1494,7 @@ void UpdateNickInHealthbox(u8 healthboxSpriteId, struct Pokemon *mon) u16 species; u8 gender; - ptr = StringCopy(gDisplayedStringBattle, gUnknown_8260556); + ptr = StringCopy(gDisplayedStringBattle, sText_HealthboxNickname); GetMonData(mon, MON_DATA_NICKNAME, nickname); StringGet_Nickname(nickname); ptr = StringCopy(ptr, nickname); @@ -1484,7 +1507,7 @@ void UpdateNickInHealthbox(u8 healthboxSpriteId, struct Pokemon *mon) if ((species == SPECIES_NIDORAN_F || species == SPECIES_NIDORAN_M) && StringCompare(nickname, gSpeciesNames[species]) == 0) gender = 100; - if (CheckBattleTypeGhost(mon, gSprites[healthboxSpriteId].hMain_Battler)) + if (CheckBattleTypeGhost(mon, gSprites[healthboxSpriteId].sBattlerId)) gender = 100; // AddTextPrinterAndCreateWindowOnHealthbox's arguments are the same in all 3 cases. @@ -1512,7 +1535,7 @@ void UpdateNickInHealthbox(u8 healthboxSpriteId, struct Pokemon *mon) spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * TILE_SIZE_4BPP; - if (GetBattlerSide(gSprites[healthboxSpriteId].data[6]) == B_SIDE_PLAYER) + if (GetBattlerSide(gSprites[healthboxSpriteId].sBattlerId) == B_SIDE_PLAYER) { TextIntoHealthboxObject((void *)(OBJ_VRAM0 + 0x40 + spriteTileNum), windowTileData, 6); ptr = (void *)(OBJ_VRAM0); @@ -1520,15 +1543,15 @@ void UpdateNickInHealthbox(u8 healthboxSpriteId, struct Pokemon *mon) ptr += spriteTileNum + 0x800; else ptr += spriteTileNum + 0x400; + TextIntoHealthboxObject(ptr, windowTileData + 0xC0, 1); } else - { TextIntoHealthboxObject((void *)(OBJ_VRAM0 + 0x20 + spriteTileNum), windowTileData, 7); - } RemoveWindowOnHealthbox(windowId); } + void TryAddPokeballIconToHealthbox(u8 healthboxSpriteId, bool8 noStatus) { u8 battlerId, healthBarSpriteId; @@ -1539,7 +1562,7 @@ void TryAddPokeballIconToHealthbox(u8 healthboxSpriteId, bool8 noStatus) if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) return; - battlerId = gSprites[healthboxSpriteId].hMain_Battler; + battlerId = gSprites[healthboxSpriteId].sBattlerId; if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) return; if (CheckBattleTypeGhost(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId)) @@ -1547,12 +1570,12 @@ void TryAddPokeballIconToHealthbox(u8 healthboxSpriteId, bool8 noStatus) if (!GetSetPokedexFlag(SpeciesToNationalPokedexNum(GetMonData(&gEnemyParty[gBattlerPartyIndexes[battlerId]], MON_DATA_SPECIES)), FLAG_GET_CAUGHT)) return; - healthBarSpriteId = gSprites[healthboxSpriteId].hMain_HealthBarSpriteId; + healthBarSpriteId = gSprites[healthboxSpriteId].sHealthBarSpriteId; if (noStatus) - CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_70), (void *)(OBJ_VRAM0 + (gSprites[healthBarSpriteId].oam.tileNum + 8) * TILE_SIZE_4BPP), 32); + CpuCopy32(GetBattleInterfaceGfxPtr(B_INTERFACE_GFX_BALL_CAUGHT), (void *)(OBJ_VRAM0 + (gSprites[healthBarSpriteId].oam.tileNum + 8) * TILE_SIZE_4BPP), 1 * TILE_SIZE_4BPP); else - CpuFill32(0, (void *)(OBJ_VRAM0 + (gSprites[healthBarSpriteId].oam.tileNum + 8) * TILE_SIZE_4BPP), 32); + CpuFill32(0, (void *)(OBJ_VRAM0 + (gSprites[healthBarSpriteId].oam.tileNum + 8) * TILE_SIZE_4BPP), 1 * TILE_SIZE_4BPP); } enum @@ -1581,8 +1604,8 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId) s16 tileNumAdder; u8 statusPalId; - battlerId = gSprites[healthboxSpriteId].hMain_Battler; - healthBarSpriteId = gSprites[healthboxSpriteId].hMain_HealthBarSpriteId; + battlerId = gSprites[healthboxSpriteId].sBattlerId; + healthBarSpriteId = gSprites[healthboxSpriteId].sHealthBarSpriteId; if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) { status = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_STATUS); @@ -1599,38 +1622,42 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId) if (status & STATUS1_SLEEP) { - statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_SLP_BATTLER0, battlerId)); + statusGfxPtr = GetBattleInterfaceGfxPtr(GetStatusIconForBattlerId(B_INTERFACE_GFX_STATUS_SLP_BATTLER0, battlerId)); statusPalId = PAL_STATUS_SLP; } else if (status & STATUS1_PSN_ANY) { - statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_PSN_BATTLER0, battlerId)); + statusGfxPtr = GetBattleInterfaceGfxPtr(GetStatusIconForBattlerId(B_INTERFACE_GFX_STATUS_PSN_BATTLER0, battlerId)); statusPalId = PAL_STATUS_PSN; } else if (status & STATUS1_BURN) { - statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_BRN_BATTLER0, battlerId)); + statusGfxPtr = GetBattleInterfaceGfxPtr(GetStatusIconForBattlerId(B_INTERFACE_GFX_STATUS_BRN_BATTLER0, battlerId)); statusPalId = PAL_STATUS_BRN; } else if (status & STATUS1_FREEZE) { - statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_FRZ_BATTLER0, battlerId)); + statusGfxPtr = GetBattleInterfaceGfxPtr(GetStatusIconForBattlerId(B_INTERFACE_GFX_STATUS_FRZ_BATTLER0, battlerId)); statusPalId = PAL_STATUS_FRZ; } else if (status & STATUS1_PARALYSIS) { - statusGfxPtr = GetHealthboxElementGfxPtr(GetStatusIconForBattlerId(HEALTHBOX_GFX_STATUS_PRZ_BATTLER0, battlerId)); + statusGfxPtr = GetBattleInterfaceGfxPtr(GetStatusIconForBattlerId(B_INTERFACE_GFX_STATUS_PAR_BATTLER0, battlerId)); statusPalId = PAL_STATUS_PAR; } else { - statusGfxPtr = GetHealthboxElementGfxPtr(HEALTHBOX_GFX_39); + statusGfxPtr = GetBattleInterfaceGfxPtr(B_INTERFACE_GFX_STATUS_NONE); for (i = 0; i < 3; i++) - CpuCopy32(statusGfxPtr, (void *)(OBJ_VRAM0 + (gSprites[healthboxSpriteId].oam.tileNum + tileNumAdder + i) * TILE_SIZE_4BPP), 32); + CpuCopy32(statusGfxPtr, + (void *)(OBJ_VRAM0 + (gSprites[healthboxSpriteId].oam.tileNum + tileNumAdder + i) * TILE_SIZE_4BPP), + 1 * TILE_SIZE_4BPP); if (!gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars) - CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_1), (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * TILE_SIZE_4BPP), 64); + CpuCopy32(GetBattleInterfaceGfxPtr(B_INTERFACE_GFX_HP_BAR_HP_TEXT), + (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * TILE_SIZE_4BPP), + 2 * TILE_SIZE_4BPP); TryAddPokeballIconToHealthbox(healthboxSpriteId, TRUE); return; @@ -1641,13 +1668,17 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId) FillPalette(sStatusIconColors[statusPalId], pltAdder + 0x100, 2); CpuCopy16(gPlttBufferUnfaded + 0x100 + pltAdder, (void *)(OBJ_PLTT + pltAdder * 2), 2); - CpuCopy32(statusGfxPtr, (void *)(OBJ_VRAM0 + (gSprites[healthboxSpriteId].oam.tileNum + tileNumAdder) * TILE_SIZE_4BPP), 96); + CpuCopy32(statusGfxPtr, (void *)(OBJ_VRAM0 + (gSprites[healthboxSpriteId].oam.tileNum + tileNumAdder) * TILE_SIZE_4BPP), 3 * TILE_SIZE_4BPP); if (IsDoubleBattle() == TRUE || GetBattlerSide(battlerId) == B_SIDE_OPPONENT) { if (!gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars) { - CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_0), (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * TILE_SIZE_4BPP), 32); - CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_65), (void *)(OBJ_VRAM0 + (gSprites[healthBarSpriteId].oam.tileNum + 1) * TILE_SIZE_4BPP), 32); + CpuCopy32(GetBattleInterfaceGfxPtr(B_INTERFACE_GFX_TRANSPARENT), + (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * TILE_SIZE_4BPP), + 1 * TILE_SIZE_4BPP); + CpuCopy32(GetBattleInterfaceGfxPtr(B_INTERFACE_GFX_HP_BAR_LEFT_BORDER), + (void *)(OBJ_VRAM0 + (gSprites[healthBarSpriteId].oam.tileNum + 1) * TILE_SIZE_4BPP), + 1 * TILE_SIZE_4BPP); } } TryAddPokeballIconToHealthbox(healthboxSpriteId, FALSE); @@ -1659,55 +1690,55 @@ static u8 GetStatusIconForBattlerId(u8 statusElementId, u8 battlerId) switch (statusElementId) { - case HEALTHBOX_GFX_STATUS_PSN_BATTLER0: + case B_INTERFACE_GFX_STATUS_PSN_BATTLER0: if (battlerId == 0) - ret = HEALTHBOX_GFX_STATUS_PSN_BATTLER0; + ret = B_INTERFACE_GFX_STATUS_PSN_BATTLER0; else if (battlerId == 1) - ret = HEALTHBOX_GFX_STATUS_PSN_BATTLER1; + ret = B_INTERFACE_GFX_STATUS_PSN_BATTLER1; else if (battlerId == 2) - ret = HEALTHBOX_GFX_STATUS_PSN_BATTLER2; + ret = B_INTERFACE_GFX_STATUS_PSN_BATTLER2; else - ret = HEALTHBOX_GFX_STATUS_PSN_BATTLER3; + ret = B_INTERFACE_GFX_STATUS_PSN_BATTLER3; break; - case HEALTHBOX_GFX_STATUS_PRZ_BATTLER0: + case B_INTERFACE_GFX_STATUS_PAR_BATTLER0: if (battlerId == 0) - ret = HEALTHBOX_GFX_STATUS_PRZ_BATTLER0; + ret = B_INTERFACE_GFX_STATUS_PAR_BATTLER0; else if (battlerId == 1) - ret = HEALTHBOX_GFX_STATUS_PRZ_BATTLER1; + ret = B_INTERFACE_GFX_STATUS_PAR_BATTLER1; else if (battlerId == 2) - ret = HEALTHBOX_GFX_STATUS_PRZ_BATTLER2; + ret = B_INTERFACE_GFX_STATUS_PAR_BATTLER2; else - ret = HEALTHBOX_GFX_STATUS_PRZ_BATTLER3; + ret = B_INTERFACE_GFX_STATUS_PAR_BATTLER3; break; - case HEALTHBOX_GFX_STATUS_SLP_BATTLER0: + case B_INTERFACE_GFX_STATUS_SLP_BATTLER0: if (battlerId == 0) - ret = HEALTHBOX_GFX_STATUS_SLP_BATTLER0; + ret = B_INTERFACE_GFX_STATUS_SLP_BATTLER0; else if (battlerId == 1) - ret = HEALTHBOX_GFX_STATUS_SLP_BATTLER1; + ret = B_INTERFACE_GFX_STATUS_SLP_BATTLER1; else if (battlerId == 2) - ret = HEALTHBOX_GFX_STATUS_SLP_BATTLER2; + ret = B_INTERFACE_GFX_STATUS_SLP_BATTLER2; else - ret = HEALTHBOX_GFX_STATUS_SLP_BATTLER3; + ret = B_INTERFACE_GFX_STATUS_SLP_BATTLER3; break; - case HEALTHBOX_GFX_STATUS_FRZ_BATTLER0: + case B_INTERFACE_GFX_STATUS_FRZ_BATTLER0: if (battlerId == 0) - ret = HEALTHBOX_GFX_STATUS_FRZ_BATTLER0; + ret = B_INTERFACE_GFX_STATUS_FRZ_BATTLER0; else if (battlerId == 1) - ret = HEALTHBOX_GFX_STATUS_FRZ_BATTLER1; + ret = B_INTERFACE_GFX_STATUS_FRZ_BATTLER1; else if (battlerId == 2) - ret = HEALTHBOX_GFX_STATUS_FRZ_BATTLER2; + ret = B_INTERFACE_GFX_STATUS_FRZ_BATTLER2; else - ret = HEALTHBOX_GFX_STATUS_FRZ_BATTLER3; + ret = B_INTERFACE_GFX_STATUS_FRZ_BATTLER3; break; - case HEALTHBOX_GFX_STATUS_BRN_BATTLER0: + case B_INTERFACE_GFX_STATUS_BRN_BATTLER0: if (battlerId == 0) - ret = HEALTHBOX_GFX_STATUS_BRN_BATTLER0; + ret = B_INTERFACE_GFX_STATUS_BRN_BATTLER0; else if (battlerId == 1) - ret = HEALTHBOX_GFX_STATUS_BRN_BATTLER1; + ret = B_INTERFACE_GFX_STATUS_BRN_BATTLER1; else if (battlerId == 2) - ret = HEALTHBOX_GFX_STATUS_BRN_BATTLER2; + ret = B_INTERFACE_GFX_STATUS_BRN_BATTLER2; else - ret = HEALTHBOX_GFX_STATUS_BRN_BATTLER3; + ret = B_INTERFACE_GFX_STATUS_BRN_BATTLER3; break; } return ret; @@ -1735,7 +1766,7 @@ static void UpdateLeftNoOfBallsTextOnHealthbox(u8 healthboxSpriteId) txtPtr = StringCopy(text, gText_HighlightRed_Left); ConvertIntToDecimalStringN(txtPtr, gNumSafariBalls, STR_CONV_MODE_LEFT_ALIGN, 2); - windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, GetStringRightAlignXOffset(0, text, 0x2F), 3, &windowId); + windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 47 - GetStringWidth(FONT_0, text, 0), 3, &windowId); spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * TILE_SIZE_4BPP; SafariTextIntoHealthboxObject((void *)(OBJ_VRAM0 + 0x2C0) + spriteTileNum, windowTileData, 2); SafariTextIntoHealthboxObject((void *)(OBJ_VRAM0 + 0xA00) + spriteTileNum, windowTileData + 0x40, 4); @@ -1745,12 +1776,12 @@ static void UpdateLeftNoOfBallsTextOnHealthbox(u8 healthboxSpriteId) void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elementId) { s32 maxHp, currHp; - u8 battlerId = gSprites[healthboxSpriteId].hMain_Battler; + u8 battlerId = gSprites[healthboxSpriteId].sBattlerId; if (elementId == HEALTHBOX_ALL && !IsDoubleBattle()) GetBattlerSide(battlerId); // Pointless function call. - if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER) + if (GetBattlerSide(gSprites[healthboxSpriteId].sBattlerId) == B_SIDE_PLAYER) { u8 isDoubles; @@ -1814,35 +1845,41 @@ void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elem } } -#define B_EXPBAR_PIXELS 64 -#define B_HEALTHBAR_PIXELS 48 +#define B_HEALTHBAR_NUM_PIXELS 48 +#define B_HEALTHBAR_NUM_TILES (B_HEALTHBAR_NUM_PIXELS / 8) +#define B_EXPBAR_NUM_PIXELS 64 +#define B_EXPBAR_NUM_TILES (B_EXPBAR_NUM_PIXELS / 8) s32 MoveBattleBar(u8 battlerId, u8 healthboxSpriteId, u8 whichBar, u8 unused) { s32 currentBarValue; - if (whichBar == HEALTH_BAR) // health bar + if (whichBar == HEALTH_BAR) { currentBarValue = CalcNewBarValue(gBattleSpritesDataPtr->battleBars[battlerId].maxValue, gBattleSpritesDataPtr->battleBars[battlerId].oldValue, gBattleSpritesDataPtr->battleBars[battlerId].receivedValue, &gBattleSpritesDataPtr->battleBars[battlerId].currValue, - B_HEALTHBAR_PIXELS / 8, 1); + B_HEALTHBAR_NUM_TILES, + 1); } else // exp bar { - u16 expFraction = GetScaledExpFraction(gBattleSpritesDataPtr->battleBars[battlerId].oldValue, - gBattleSpritesDataPtr->battleBars[battlerId].receivedValue, - gBattleSpritesDataPtr->battleBars[battlerId].maxValue, 8); - if (expFraction == 0) - expFraction = 1; - expFraction = abs(gBattleSpritesDataPtr->battleBars[battlerId].receivedValue / expFraction); + u16 increment = GetReceivedValueInPixels(gBattleSpritesDataPtr->battleBars[battlerId].oldValue, + gBattleSpritesDataPtr->battleBars[battlerId].receivedValue, + gBattleSpritesDataPtr->battleBars[battlerId].maxValue, + B_EXPBAR_NUM_TILES); + + if (increment == 0) + increment = 1; + increment = abs(gBattleSpritesDataPtr->battleBars[battlerId].receivedValue / increment); currentBarValue = CalcNewBarValue(gBattleSpritesDataPtr->battleBars[battlerId].maxValue, gBattleSpritesDataPtr->battleBars[battlerId].oldValue, gBattleSpritesDataPtr->battleBars[battlerId].receivedValue, &gBattleSpritesDataPtr->battleBars[battlerId].currValue, - B_EXPBAR_PIXELS / 8, expFraction); + B_EXPBAR_NUM_TILES, + increment); } if (whichBar == EXP_BAR || (whichBar == HEALTH_BAR && !gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars)) @@ -1856,36 +1893,39 @@ s32 MoveBattleBar(u8 battlerId, u8 healthboxSpriteId, u8 whichBar, u8 unused) static void MoveBattleBarGraphically(u8 battlerId, u8 whichBar) { - u8 array[8]; - u8 filledPixelsCount, level; + u8 filledPixels[B_HEALTHBAR_NUM_TILES > B_EXPBAR_NUM_TILES ? B_HEALTHBAR_NUM_TILES : B_EXPBAR_NUM_TILES]; + u8 totalFilledPixels, level; u8 barElementId; u8 i; switch (whichBar) { case HEALTH_BAR: - filledPixelsCount = CalcBarFilledPixels(gBattleSpritesDataPtr->battleBars[battlerId].maxValue, + totalFilledPixels = CalcBarFilledPixels(gBattleSpritesDataPtr->battleBars[battlerId].maxValue, gBattleSpritesDataPtr->battleBars[battlerId].oldValue, gBattleSpritesDataPtr->battleBars[battlerId].receivedValue, &gBattleSpritesDataPtr->battleBars[battlerId].currValue, - array, B_HEALTHBAR_PIXELS / 8); + filledPixels, + B_HEALTHBAR_NUM_TILES); - if (filledPixelsCount > (B_HEALTHBAR_PIXELS * 50 / 100)) // more than 50 % hp - barElementId = HEALTHBOX_GFX_HP_BAR_GREEN; - else if (filledPixelsCount > (B_HEALTHBAR_PIXELS * 20 / 100)) // more than 20% hp - barElementId = HEALTHBOX_GFX_HP_BAR_YELLOW; + if (totalFilledPixels > (B_HEALTHBAR_NUM_PIXELS * 50 / 100)) // more than 50 % hp + barElementId = B_INTERFACE_GFX_HP_BAR_GREEN; + else if (totalFilledPixels > (B_HEALTHBAR_NUM_PIXELS * 20 / 100)) // more than 20% hp + barElementId = B_INTERFACE_GFX_HP_BAR_YELLOW; else - barElementId = HEALTHBOX_GFX_HP_BAR_RED; // 20 % or less + barElementId = B_INTERFACE_GFX_HP_BAR_RED; // 20 % or less - for (i = 0; i < 6; i++) + for (i = 0; i < B_HEALTHBAR_NUM_TILES; i++) { - u8 healthbarSpriteId = gSprites[gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId].hMain_HealthBarSpriteId; - if (i < 2) - CpuCopy32(GetHealthboxElementGfxPtr(barElementId) + array[i] * 32, - (void *)(OBJ_VRAM0 + (gSprites[healthbarSpriteId].oam.tileNum + 2 + i) * TILE_SIZE_4BPP), 32); - else - CpuCopy32(GetHealthboxElementGfxPtr(barElementId) + array[i] * 32, - (void *)(OBJ_VRAM0 + 64 + (i + gSprites[healthbarSpriteId].oam.tileNum) * TILE_SIZE_4BPP), 32); + u8 healthbarSpriteId = gSprites[gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId].sHealthBarSpriteId; + if (i < 2) // first 2 tiles are on left healthbar sprite + CpuCopy32(GetBattleInterfaceGfxPtr(barElementId) + filledPixels[i] * TILE_SIZE_4BPP, + (void *)(OBJ_VRAM0 + (gSprites[healthbarSpriteId].oam.tileNum + 2 + i) * TILE_SIZE_4BPP), // + 2 here is due to B_INTERFACE_GFX_HP_BAR_HP_TEXT + 1 * TILE_SIZE_4BPP); + else // remaining 4 tiles are on right healthbar sprite + CpuCopy32(GetBattleInterfaceGfxPtr(barElementId) + filledPixels[i] * TILE_SIZE_4BPP, + (void *)(OBJ_VRAM0 + 64 + (i + gSprites[healthbarSpriteId].oam.tileNum) * TILE_SIZE_4BPP), + 1 * TILE_SIZE_4BPP); } break; case EXP_BAR: @@ -1893,33 +1933,37 @@ static void MoveBattleBarGraphically(u8 battlerId, u8 whichBar) gBattleSpritesDataPtr->battleBars[battlerId].oldValue, gBattleSpritesDataPtr->battleBars[battlerId].receivedValue, &gBattleSpritesDataPtr->battleBars[battlerId].currValue, - array, B_EXPBAR_PIXELS / 8); + filledPixels, + B_EXPBAR_NUM_TILES); level = GetMonData(&gPlayerParty[gBattlerPartyIndexes[battlerId]], MON_DATA_LEVEL); if (level == MAX_LEVEL) { - for (i = 0; i < 8; i++) - array[i] = 0; + for (i = 0; i < B_EXPBAR_NUM_TILES; i++) + filledPixels[i] = 0; } - for (i = 0; i < 8; i++) + for (i = 0; i < B_EXPBAR_NUM_TILES; i++) { - if (i < 4) - CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_12) + array[i] * 32, - (void *)(OBJ_VRAM0 + (gSprites[gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId].oam.tileNum + 0x24 + i) * TILE_SIZE_4BPP), 32); - else - CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_12) + array[i] * 32, - (void *)(OBJ_VRAM0 + 0xB80 + (i + gSprites[gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId].oam.tileNum) * TILE_SIZE_4BPP), 32); + if (i < 4) // first 4 tiles are on left healthbox sprite + CpuCopy32(GetBattleInterfaceGfxPtr(B_INTERFACE_GFX_EXP_BAR) + filledPixels[i] * TILE_SIZE_4BPP, + (void *)(OBJ_VRAM0 + (gSprites[gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId].oam.tileNum + 36 + i) * TILE_SIZE_4BPP), + 1 * TILE_SIZE_4BPP); + else // remaining 4 tiles are on right healthbox sprite + CpuCopy32(GetBattleInterfaceGfxPtr(B_INTERFACE_GFX_EXP_BAR) + filledPixels[i] * TILE_SIZE_4BPP, + (void *)(OBJ_VRAM0 + 0xB80 + (i + gSprites[gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId].oam.tileNum) * TILE_SIZE_4BPP), + 1 * TILE_SIZE_4BPP); } break; } } -static s32 CalcNewBarValue(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *currValue, u8 scale, u16 toAdd) + +static s32 CalcNewBarValue(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *currValue, u8 totalPixels, u16 increment) { s32 ret, newValue; - scale *= 8; + totalPixels *= 8; if (*currValue == -32768) // first function call { - if (maxValue < scale) + if (maxValue < totalPixels) *currValue = Q_24_8(oldValue); else *currValue = oldValue; @@ -1931,7 +1975,7 @@ static s32 CalcNewBarValue(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *c else if (newValue > maxValue) newValue = maxValue; - if (maxValue < scale) + if (maxValue < totalPixels) { if (newValue == Q_24_8_TO_INT(*currValue) && (*currValue & 0xFF) == 0) return -1; @@ -1942,13 +1986,13 @@ static s32 CalcNewBarValue(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *c return -1; } - if (maxValue < scale) // handle cases of max var having less pixels than the whole bar + if (maxValue < totalPixels) // handle cases of max var having less pixels than the whole bar { - s32 toAdd_ = Q_24_8(maxValue) / scale; + s32 incrementInQ = Q_24_8(maxValue) / totalPixels; if (receivedValue < 0) // fill bar right { - *currValue += toAdd_; + *currValue += incrementInQ; ret = Q_24_8_TO_INT(*currValue); if (ret >= newValue) { @@ -1958,7 +2002,7 @@ static s32 CalcNewBarValue(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *c } else // move bar left { - *currValue -= toAdd_; + *currValue -= incrementInQ; ret = Q_24_8_TO_INT(*currValue); // try round up if ((*currValue & 0xFF) > 0) @@ -1974,14 +2018,14 @@ static s32 CalcNewBarValue(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *c { if (receivedValue < 0) // fill bar right { - *currValue += toAdd; + *currValue += increment; if (*currValue > newValue) *currValue = newValue; ret = *currValue; } else // move bar left { - *currValue -= toAdd; + *currValue -= increment; if (*currValue < newValue) *currValue = newValue; ret = *currValue; @@ -1991,9 +2035,9 @@ static s32 CalcNewBarValue(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *c return ret; } -static u8 CalcBarFilledPixels(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *currValue, u8 *arg4, u8 scale) +static u8 CalcBarFilledPixels(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *currValue, u8 *filledPixels, u8 numTiles) { - u8 pixels, filledPixels, totalPixels; + u8 numPixelsToFill, totalFilledPixels, totalPixels; u8 i; s32 newValue = oldValue - receivedValue; @@ -2002,100 +2046,102 @@ static u8 CalcBarFilledPixels(s32 maxValue, s32 oldValue, s32 receivedValue, s32 else if (newValue > maxValue) newValue = maxValue; - totalPixels = scale * 8; + totalPixels = numTiles * 8; - for (i = 0; i < scale; i++) - arg4[i] = 0; + for (i = 0; i < numTiles; i++) + filledPixels[i] = 0; if (maxValue < totalPixels) - pixels = (*currValue * totalPixels / maxValue) >> 8; + numPixelsToFill = Q_24_8_TO_INT(*currValue * totalPixels / maxValue); else - pixels = *currValue * totalPixels / maxValue; + numPixelsToFill = *currValue * totalPixels / maxValue; - filledPixels = pixels; + totalFilledPixels = numPixelsToFill; - if (filledPixels == 0 && newValue > 0) + if (numPixelsToFill == 0 && newValue > 0) { - arg4[0] = 1; - filledPixels = 1; + filledPixels[0] = 1; + totalFilledPixels = 1; } else { - for (i = 0; i < scale; i++) + for (i = 0; i < numTiles; i++) { - if (pixels >= 8) - { - arg4[i] = 8; - } + if (numPixelsToFill >= 8) // too many to fill into a single tile + filledPixels[i] = 8; else { - arg4[i] = pixels; + filledPixels[i] = numPixelsToFill; break; } - pixels -= 8; + numPixelsToFill -= 8; } } - return filledPixels; + return totalFilledPixels; } +// Unused // These functions seem as if they were made for testing the health bar. -static s16 sub_804A460(struct TestingBar *barInfo, s32 *currValue, u8 bg, u8 x, u8 y) +static s16 UpdateAndDrawHealthbarOntoScreen(struct TestingBar *barInfo, s32 *currValue, u8 bg, u8 x, u8 y) { - s16 ret; + s16 hpVal; - ret = CalcNewBarValue(barInfo->maxValue, + hpVal = CalcNewBarValue(barInfo->maxValue, barInfo->oldValue, barInfo->receivedValue, - currValue, B_HEALTHBAR_PIXELS / 8, 1); + currValue, + B_HEALTHBAR_NUM_TILES, + 1); - sub_804A510(barInfo, currValue, bg, x, y); + DrawHealthbarOntoScreen(barInfo, currValue, bg, x, y); - return ret; + return hpVal; } -static s16 sub_804A4C8(struct TestingBar *barInfo, s32 *currValue) +// Unused +static s16 CalcNewHealthbarValue(struct TestingBar *barInfo, s32 *currValue) { - s16 ret; - - ret = CalcNewBarValue(barInfo->maxValue, + return CalcNewBarValue(barInfo->maxValue, barInfo->oldValue, barInfo->receivedValue, - currValue, B_HEALTHBAR_PIXELS / 8, 1); - - return ret; + currValue, + B_HEALTHBAR_NUM_TILES, + 1); } -static void sub_804A4F0(struct TestingBar *barInfo, s32 *currValue, u8 bg, u8 x, u8 y) +// Unused +static void DoDrawHealthbarOntoScreen(struct TestingBar *barInfo, s32 *currValue, u8 bg, u8 x, u8 y) { - sub_804A510(barInfo, currValue, bg, x, y); + DrawHealthbarOntoScreen(barInfo, currValue, bg, x, y); } -static void sub_804A510(struct TestingBar *barInfo, s32 *currValue, u8 bg, u8 x, u8 y) +// Unused +static void DrawHealthbarOntoScreen(struct TestingBar *barInfo, s32 *currValue, u8 bg, u8 x, u8 y) { - u8 spC[B_HEALTHBAR_PIXELS / 8]; - u16 tiles[B_HEALTHBAR_PIXELS / 8]; + u8 filledPixels[B_HEALTHBAR_NUM_TILES]; + u16 tiles[B_HEALTHBAR_NUM_TILES]; u8 i; CalcBarFilledPixels(barInfo->maxValue, barInfo->oldValue, barInfo->receivedValue, - currValue, spC, B_HEALTHBAR_PIXELS / 8); + currValue, + filledPixels, + B_HEALTHBAR_NUM_TILES); - for (i = 0; i < B_HEALTHBAR_PIXELS / 8; i++) - { - tiles[i] = (barInfo->pal << 12) | (barInfo->tileOffset + spC[i]); - } + for (i = 0; i < ARRAY_COUNT(tiles); i++) + tiles[i] = (barInfo->pal << 12) | (barInfo->tileOffset + filledPixels[i]); CopyToBgTilemapBufferRect_ChangePalette(bg, tiles, x, y, 6, 1, 17); } -static u8 GetScaledExpFraction(s32 oldValue, s32 receivedValue, s32 maxValue, u8 scale) +static u8 GetReceivedValueInPixels(s32 oldValue, s32 receivedValue, s32 maxValue, u8 totalPixels) { s32 newVal, result; s8 oldToMax, newToMax; - scale *= 8; + totalPixels *= 8; newVal = oldValue - receivedValue; if (newVal < 0) @@ -2103,8 +2149,8 @@ static u8 GetScaledExpFraction(s32 oldValue, s32 receivedValue, s32 maxValue, u8 else if (newVal > maxValue) newVal = maxValue; - oldToMax = oldValue * scale / maxValue; - newToMax = newVal * scale / maxValue; + oldToMax = oldValue * totalPixels / maxValue; + newToMax = newVal * totalPixels / maxValue; result = oldToMax - newToMax; return abs(result); @@ -2125,15 +2171,13 @@ u8 GetHPBarLevel(s16 hp, s16 maxhp) u8 result; if (hp == maxhp) - { result = HP_BAR_FULL; - } else { - u8 fraction = GetScaledHPFraction(hp, maxhp, B_HEALTHBAR_PIXELS); - if (fraction > (B_HEALTHBAR_PIXELS * 50 / 100)) // more than 50 % hp + u8 fraction = GetScaledHPFraction(hp, maxhp, B_HEALTHBAR_NUM_PIXELS); + if (fraction > (B_HEALTHBAR_NUM_PIXELS * 50 / 100)) result = HP_BAR_GREEN; - else if (fraction > (B_HEALTHBAR_PIXELS * 20 / 100)) // more than 20% hp + else if (fraction > (B_HEALTHBAR_NUM_PIXELS * 20 / 100)) result = HP_BAR_YELLOW; else if (fraction > 0) result = HP_BAR_RED; @@ -2151,10 +2195,9 @@ static const struct WindowTemplate sHealthboxWindowTemplate = { .width = 8, .height = 2, .paletteNum = 0, - .baseBlock = 0x000 + .baseBlock = 0 }; - static u8 *AddTextPrinterAndCreateWindowOnHealthbox(const u8 *str, u32 x, u32 y, u32 *windowId) { u16 winId; diff --git a/src/battle_main.c b/src/battle_main.c index 24615d154..9b66cd75c 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -1773,7 +1773,7 @@ void CB2_InitEndLinkBattle(void) gBattle_BG3_X = 0; gBattle_BG3_Y = 0; InitBattleBgsVideo(); - LoadCompressedPalette(gBattleTextboxPalette, 0, 64); + LoadCompressedPalette(gBattleInterface_Textbox_Pal, 0, 64); LoadBattleMenuWindowGfx(); ResetSpriteData(); ResetTasks(); diff --git a/src/daycare.c b/src/daycare.c index d7d2a8caa..7284ea22f 100644 --- a/src/daycare.c +++ b/src/daycare.c @@ -1816,9 +1816,9 @@ static void CB2_EggHatch_0(void) gMain.state++; break; case 2: - DecompressAndLoadBgGfxUsingHeap(0, gBattleTextboxTiles, 0, 0, 0); - CopyToBgTilemapBuffer(0, gBattleTextboxTilemap, 0, 0); - LoadCompressedPalette(gBattleTextboxPalette, 0, 0x20); + DecompressAndLoadBgGfxUsingHeap(0, gBattleInterface_Textbox_Gfx, 0, 0, 0); + CopyToBgTilemapBuffer(0, gBattleInterface_Textbox_Tilemap, 0, 0); + LoadCompressedPalette(gBattleInterface_Textbox_Pal, 0, 0x20); gMain.state++; break; case 3: diff --git a/src/graphics.c b/src/graphics.c index eb07dbecd..47dfaea23 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -1,8 +1,8 @@ #include "global.h" -const u32 gBattleTextboxTiles[] = INCBIN_U32("graphics/battle_interface/window.4bpp.lz"); -const u32 gBattleTextboxPalette[] = INCBIN_U32("graphics/battle_interface/window.gbapal.lz"); -const u32 gBattleTextboxTilemap[] = INCBIN_U32("graphics/interface/menu_map.bin.lz"); +const u32 gBattleInterface_Textbox_Gfx[] = INCBIN_U32("graphics/battle_interface/textbox.4bpp.lz"); +const u32 gBattleInterface_Textbox_Pal[] = INCBIN_U32("graphics/battle_interface/textbox.gbapal.lz"); +const u32 gBattleInterface_Textbox_Tilemap[] = INCBIN_U32("graphics/battle_interface/textbox.bin.lz"); const u32 gMonFrontPic_CircledQuestionMark[] = INCBIN_U32("graphics/pokemon/question_mark/circled/front.4bpp.lz"); const u32 gMonBackPic_CircledQuestionMark[] = INCBIN_U32("graphics/pokemon/question_mark/circled/back.4bpp.lz"); @@ -348,33 +348,10 @@ const u32 gUnusedGfx_BasicFrame[] = INCBIN_U32("graphics/unused/basic_frame.4bpp const u32 gUnusedPal_BasicFrame[] = INCBIN_U32("graphics/unused/basic_frame.gbapal.lz"); const u32 gUnusedTilemap_BasicFrame[] = INCBIN_U32("graphics/unused/basic_frame.bin.lz"); -// Battle Interface +const u16 gBattleInterface_Healthbox_Pal[] = INCBIN_U16("graphics/battle_interface/healthbox.gbapal"); +const u16 gBattleInterface_Healthbar_Pal[] = INCBIN_U16("graphics/battle_interface/healthbar.gbapal"); +const u8 gBattleInterface_Gfx[] = INCBIN_U8("graphics/battle_interface/healthbox_elements.4bpp"); -const u16 gBattleInterface_BallStatusBarPal[] = INCBIN_U16("graphics/battle_interface/ball_status_bar.gbapal"); - -const u16 gBattleInterface_BallDisplayPal[] = INCBIN_U16("graphics/battle_interface/ball_display.gbapal"); - -//Originally an array? -const u8 gHealthboxElementsGfxTable[] = INCBIN_U8("graphics/battle_interface/hp_bar.4bpp"); -const u8 gHealthboxElementsGfxTable_ExpBar[] = INCBIN_U8("graphics/battle_interface/exp_bar.4bpp"); -const u8 gHealthboxElementsGfxTable_StatusPsn[] = INCBIN_U8("graphics/battle_interface/status_psn.4bpp"); -const u8 gHealthboxElementsGfxTable_StatusPar[] = INCBIN_U8("graphics/battle_interface/status_par.4bpp"); -const u8 gHealthboxElementsGfxTable_StatusSlp[] = INCBIN_U8("graphics/battle_interface/status_slp.4bpp"); -const u8 gHealthboxElementsGfxTable_StatusFrz[] = INCBIN_U8("graphics/battle_interface/status_frz.4bpp"); -const u8 gHealthboxElementsGfxTable_StatusBrn[] = INCBIN_U8("graphics/battle_interface/status_brn.4bpp"); -const u8 gHealthboxElementsGfxTable_Misc[] = INCBIN_U8("graphics/battle_interface/misc.4bpp"); -const u8 gHealthboxElementsGfxTable_HpBarAnim[] = INCBIN_U8("graphics/battle_interface/hp_bar_anim.4bpp"); -const u8 gHealthboxElementsGfxTable_MiscFrameEnd[] = INCBIN_U8("graphics/battle_interface/misc_frame_end.4bpp"); - -const u8 gBattleInterface_SummaryBallDisplayGfx[] = INCBIN_U8("graphics/battle_interface/ball_display.4bpp"); - -//Originally an array? -const u8 gBattleInterface_UnusedSummaryBallDisplayGfx[] = INCBIN_U8("graphics/battle_interface/ball_display_unused_extra.4bpp"); -const u8 gBattleInterfaceGfx_Status2[] = INCBIN_U8("graphics/battle_interface/status2.4bpp"); // these three duplicate sets of graphics are for the opponent pokemon -const u8 gBattleInterfaceGfx_Status3[] = INCBIN_U8("graphics/battle_interface/status3.4bpp"); // and are also for use in double battles. they use dynamic palettes so -const u8 gBattleInterfaceGfx_Status4[] = INCBIN_U8("graphics/battle_interface/status4.4bpp"); // coloring them is an extreme headache and wont be done for now -const u8 gUnknown_8D12A44[] = INCBIN_U8("graphics/unknown/unknown_D12A44.4bpp"); -const u8 gUnknown_8D12A64[] = INCBIN_U8("graphics/unknown/unknown_D12A64.4bpp"); const u32 gBattleInterfaceGfx_UnusedWindow3[] = INCBIN_U32("graphics/battle_interface/unused_window3.4bpp.lz"); const u32 gBattleInterfaceGfx_UnusedWindow4[] = INCBIN_U32("graphics/battle_interface/unused_window4.4bpp.lz"); @@ -1023,7 +1000,7 @@ const u32 gBattleAnimBgPalette_MuddyWater[] = INCBIN_U32("graphics/battle_anims/ const u32 gEnemyMonShadow_Gfx[] = INCBIN_U32("graphics/battle_interface/enemy_mon_shadow.4bpp.lz"); -const u32 gFile_graphics_battle_interface_ball_status_bar_sheet[] = INCBIN_U32("graphics/battle_interface/ball_status_bar.4bpp.lz"); +const u32 gBattleInterface_PartySummaryBar_Gfx[] = INCBIN_U32("graphics/battle_interface/party_summary_bar.4bpp.lz"); const u8 gMonIcon_Egg[] = INCBIN_U8("graphics/pokemon/egg/icon.4bpp"); diff --git a/src/trade_scene.c b/src/trade_scene.c index a946299b9..c02b28320 100644 --- a/src/trade_scene.c +++ b/src/trade_scene.c @@ -937,16 +937,16 @@ static void TradeAnimInit_LoadGfx(void) SetBgTilemapBuffer(3, Alloc(BG_SCREEN_SIZE)); DeactivateAllTextPrinters(); // Doing the graphics load... - DecompressAndLoadBgGfxUsingHeap(0, gBattleTextboxTiles, 0, 0, 0); - LZDecompressWram(gBattleTextboxTilemap, gDecompressionBuffer); + DecompressAndLoadBgGfxUsingHeap(0, gBattleInterface_Textbox_Gfx, 0, 0, 0); + LZDecompressWram(gBattleInterface_Textbox_Tilemap, gDecompressionBuffer); CopyToBgTilemapBuffer(0, gDecompressionBuffer, BG_SCREEN_SIZE, 0); - LoadCompressedPalette(gBattleTextboxPalette, 0x000, 0x20); + LoadCompressedPalette(gBattleInterface_Textbox_Pal, 0x000, 0x20); InitWindows(sTradeMessageWindowTemplates); // ... and doing the same load again - DecompressAndLoadBgGfxUsingHeap(0, gBattleTextboxTiles, 0, 0, 0); - LZDecompressWram(gBattleTextboxTilemap, gDecompressionBuffer); + DecompressAndLoadBgGfxUsingHeap(0, gBattleInterface_Textbox_Gfx, 0, 0, 0); + LZDecompressWram(gBattleInterface_Textbox_Tilemap, gDecompressionBuffer); CopyToBgTilemapBuffer(0, gDecompressionBuffer, BG_SCREEN_SIZE, 0); - LoadCompressedPalette(gBattleTextboxPalette, 0x000, 0x20); + LoadCompressedPalette(gBattleInterface_Textbox_Pal, 0x000, 0x20); } static void CB2_InitTradeAnim_InGameTrade(void) From a0f41da30d0da423d106967c879852d590dd1026 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 14 Nov 2022 11:33:17 -0500 Subject: [PATCH 12/12] Label missed symbol --- src/data/union_room.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/data/union_room.h b/src/data/union_room.h index 6c8254d1b..557a93297 100644 --- a/src/data/union_room.h +++ b/src/data/union_room.h @@ -467,4 +467,5 @@ static const u8 sLinkGroupToURoomActivity[] = { [LINK_GROUP_WONDER_NEWS] = ACTIVITY_WONDER_NEWS }; -static const u8 sUnref_84570D1[] = _("{DYNAMIC 00}·{DYNAMIC 01}"); +// Unused +static const u8 sDotSeparatedValues[] = _("{DYNAMIC 00}·{DYNAMIC 01}");