diff --git a/asm/code_805D8C8.s b/asm/code_805D8C8.s index c0b70f853..93f413c11 100644 --- a/asm/code_805D8C8.s +++ b/asm/code_805D8C8.s @@ -6,66 +6,7 @@ .text - thumb_func_start sub_80637BC -sub_80637BC: - push {r4,r5,lr} - adds r4, r0, 0 - adds r5, r2, 0 - ldr r0, _080637E0 - lsls r1, 2 - adds r1, r0 - ldrh r1, [r1] - adds r0, r4, 0 - bl SetMonsterActionFields - strb r5, [r4, 0x4] - ldr r0, _080637E4 - ldr r0, [r0] - strb r0, [r4, 0xC] - pop {r4,r5} - pop {r0} - bx r0 - .align 2, 0 -_080637E0: .4byte gUnknown_202EE44 -_080637E4: .4byte gUnknown_202F2D8 - thumb_func_end sub_80637BC - thumb_func_start sub_80637E8 -sub_80637E8: - push {lr} - adds r3, r0, 0 - ldr r0, _08063828 - ldr r1, [r0] - ldrb r0, [r3, 0x4] - lsls r0, 2 - ldr r2, _0806382C - adds r1, r2 - adds r1, r0 - ldr r0, [r1] - ldr r0, [r0, 0x70] - ldrb r1, [r3, 0xC] - lsls r1, 3 - adds r1, r0, r1 - ldr r2, _08063830 - adds r2, r1 - mov r12, r2 - ldrb r2, [r2] - movs r1, 0x2 - orrs r1, r2 - mov r2, r12 - strb r1, [r2] - movs r1, 0x8C - lsls r1, 1 - adds r0, r1 - ldrb r1, [r3, 0xC] - movs r2, 0x4 - bl sub_8063834 - pop {r0} - bx r0 - .align 2, 0 -_08063828: .4byte gDungeon -_0806382C: .4byte 0x0001357c -_08063830: .4byte 0x00000119 - thumb_func_end sub_80637E8 thumb_func_start sub_8063834 sub_8063834: @@ -1115,7 +1056,7 @@ _08064058: _0806406E: movs r1, 0x18 ldrsh r0, [r4, r1] - bl sub_8044F3C + bl CanSubMenuItemBeChosen lsls r0, 24 cmp r0, 0 beq _08064098 @@ -1488,7 +1429,7 @@ _08064340: pop {r0} bx r0 .align 2, 0 -_08064350: .4byte gUnknown_202EE6C +_08064350: .4byte gDungeonSubMenuItemsCount _08064354: .4byte gUnknown_202F2D8 thumb_func_end sub_8064310 @@ -1682,7 +1623,7 @@ _080644CC: .4byte gRealInputs _080644D0: movs r2, 0x18 ldrsh r0, [r5, r2] - bl sub_8044F3C + bl CanSubMenuItemBeChosen lsls r0, 24 cmp r0, 0 beq _0806450C @@ -1820,7 +1761,7 @@ sub_80645D4: pop {r0} bx r0 .align 2, 0 -_080645F4: .4byte gUnknown_202EE6C +_080645F4: .4byte gDungeonSubMenuItemsCount thumb_func_end sub_80645D4 thumb_func_start sub_80645F8 @@ -2209,7 +2150,7 @@ _08064910: .4byte gRealInputs _08064914: movs r2, 0x18 ldrsh r0, [r5, r2] - bl sub_8044F3C + bl CanSubMenuItemBeChosen lsls r0, 24 cmp r0, 0 beq _08064950 @@ -2353,7 +2294,7 @@ sub_8064A18: pop {r0} bx r0 .align 2, 0 -_08064A38: .4byte gUnknown_202EE6C +_08064A38: .4byte gDungeonSubMenuItemsCount thumb_func_end sub_8064A18 thumb_func_start sub_8064A3C diff --git a/include/dungeon_main.h b/include/dungeon_main.h new file mode 100644 index 000000000..232533bdc --- /dev/null +++ b/include/dungeon_main.h @@ -0,0 +1,16 @@ +#ifndef GUARD_DUNGEON_MAIN_H +#define GUARD_DUNGEON_MAIN_H + +#include "structs/str_text.h" + +void DungeonHandlePlayerInput(void); +void sub_805E804(void); +void sub_805EE30(void); +void sub_805EFB4(Entity *a0, bool8 a1); +void sub_805F02C(void); +ActionContainer *GetLeaderActionContainer(void); +u16 GetLeaderActionId(void); +bool8 sub_805FBE8(u8 *a0); +void CreateDungeonMenuSubWindow(Window *mainWindow, s32 subWindowX); + +#endif diff --git a/ld_script.txt b/ld_script.txt index 3508fe4a8..e3b4ce6b9 100755 --- a/ld_script.txt +++ b/ld_script.txt @@ -226,7 +226,8 @@ SECTIONS { src/move_actions.o(.text); src/status_actions.o(.text); src/move_checks.o(.text); - src/code_805D8C8_1.o(.text); + src/dungeon_main.o(.text); + src/code_805D8C8_2.o(.text); asm/code_805D8C8.o(.text); src/code_8066D04.o(.text); src/code_805D8C8.o(.text); diff --git a/src/code_8044CC8.c b/src/code_8044CC8.c index 1de1a7fde..52423405f 100644 --- a/src/code_8044CC8.c +++ b/src/code_8044CC8.c @@ -23,7 +23,7 @@ typedef struct unkStr_80F7C54 EWRAM_DATA unkStruct_202EE44 gUnknown_202EE44[10] = {0}; -extern s32 gUnknown_202EE6C; +extern s32 gDungeonSubMenuItemsCount; extern const ItemText gActions[]; extern u16 gUnknown_80F6964[NUM_ITEM_CATEGORIES]; @@ -159,7 +159,7 @@ void sub_8044E24(Entity *entity,int index,u32 unused) } // Similar to sub_8044BA8 -u8 *sub_8044EC8(s32 param_1) +u8 *GetDungeonSubMenuItemString(s32 param_1) { u16 uVar1; u32 uVar3; @@ -185,7 +185,7 @@ u8 *sub_8044EC8(s32 param_1) } } -bool8 sub_8044F3C(s32 param_1) +bool8 CanSubMenuItemBeChosen(s32 param_1) { if(param_1 < 0) return FALSE; @@ -197,17 +197,17 @@ void sub_8044F5C(u16 param_1, u8 param_2) { int index; - if (gUnknown_202EE6C < 10) { - for(index = 0; index < gUnknown_202EE6C; index++) + if (gDungeonSubMenuItemsCount < 10) { + for(index = 0; index < gDungeonSubMenuItemsCount; index++) { if (gUnknown_202EE44[index].unk0 == param_1) { return; } } - gUnknown_202EE44[gUnknown_202EE6C].unk0 = param_1; - gUnknown_202EE44[gUnknown_202EE6C].unk2 = param_2; - gUnknown_202EE44[gUnknown_202EE6C].unk3 = TRUE; - gUnknown_202EE6C++; + gUnknown_202EE44[gDungeonSubMenuItemsCount].unk0 = param_1; + gUnknown_202EE44[gDungeonSubMenuItemsCount].unk2 = param_2; + gUnknown_202EE44[gDungeonSubMenuItemsCount].unk3 = TRUE; + gDungeonSubMenuItemsCount++; } } @@ -215,7 +215,7 @@ s32 sub_8044FB4(u16 param_1) { int index; - for(index = 0; index < gUnknown_202EE6C; index++) + for(index = 0; index < gDungeonSubMenuItemsCount; index++) { if (gUnknown_202EE44[index].unk0 == param_1) { return index; @@ -228,7 +228,7 @@ void sub_8044FF0(u16 param_1) { int index; - for(index = 0; index < gUnknown_202EE6C; index++) + for(index = 0; index < gDungeonSubMenuItemsCount; index++) { if (gUnknown_202EE44[index].unk0 == param_1) { gUnknown_202EE44[index].unk3 = FALSE; @@ -269,8 +269,8 @@ void sub_8045064(void) unkStruct_202EE44 *jPtr; unkStruct_202EE44 temp; - for (i = 0; i < gUnknown_202EE6C; i++) { - for (j = i + 1; j < gUnknown_202EE6C; j++) { + for (i = 0; i < gDungeonSubMenuItemsCount; i++) { + for (j = i + 1; j < gDungeonSubMenuItemsCount; j++) { iPtr = &gUnknown_202EE44[i]; jPtr = &gUnknown_202EE44[j]; if ((s32)gUnknown_80F7C54[iPtr->unk0].unk0 > (s32)gUnknown_80F7C54[jPtr->unk0].unk0) { diff --git a/src/code_805D8C8_1.c b/src/code_805D8C8_2.c similarity index 62% rename from src/code_805D8C8_1.c rename to src/code_805D8C8_2.c index d2763ef80..e2648ba2b 100644 --- a/src/code_805D8C8_1.c +++ b/src/code_805D8C8_2.c @@ -3,6 +3,7 @@ #include "number_util.h" #include "input.h" #include "structs/map.h" +#include "dungeon_main.h" #include "dungeon_message.h" #include "dungeon_action.h" #include "dungeon_ai_targeting.h" @@ -87,7 +88,6 @@ void sub_806A914(u8 a0, u8 a1, u8 a2); void SetLeaderActionToNothing(u8 a0); u16 GetLeaderActionId(void); void sub_80978C8(s16 a0); -static void TryCreateModeArrows(Entity *leader); bool8 sub_8094C48(void); bool8 sub_805EC4C(Entity *a0, u8 a1); void sub_803E724(s32 a0); @@ -141,1410 +141,6 @@ extern const u8 *gTeamToolboxBPtr; extern const u8 *gFieldItemMenuGroundTextPtr; extern const u8 *gUnknown_80FE940; extern const u8 *gWhichTextPtr1; - -static EWRAM_DATA bool8 sInDiagonalMode = 0; -static EWRAM_DATA bool8 sInRotateMode = 0; -// Frames counter for arrows in diagonal/rotate mode. -static EWRAM_DATA s16 sArrowsFrames = 0; -// If both of these are set to TRUE, there are 3 arrows visible instead of 1 in rotate mode -static EWRAM_DATA bool8 sShowThreeArrows1 = 0; -static EWRAM_DATA bool8 sShowThreeArrows2 = 0; - -void DungeonHandlePlayerInput(void) -{ - struct UnkMenuBitsStruct r6; - bool8 triggers[5]; // Always FALSE, if one of these is TRUE - they can open various menus or cause an item throw. Most likely used for debugging/testing. - s32 frames; - s32 var_38; - UnkDungeonGlobal_unk181E8_sub *unkPtr; - - unkPtr = &gDungeon->unk181e8; - var_38 = 3; - gDungeon->unk12 = 0; - sub_806A2BC(GetLeader(), 1); - if (sub_80701A4(GetLeader())) { - sub_803E708(60, 16); - return; - } - - gDungeon->unk644.unk2F = 0; - sub_8040A78(); - if (gDungeon->unk1 != 0) { - gDungeon->unk1 = 0; - if (!ShouldMonsterRunAwayAndShowEffect(GetLeader(), TRUE)) { - SetLeaderActionToNothing(TRUE); - sub_805E804(); - ShowDungeonStairsMenu(GetLeader()); - ResetRepeatTimers(); - ResetUnusedInputStruct(); - if (GetLeaderActionId() != 0) { - return; - } - } - } - - sub_806A914(1, 1, 1); - while (1) { - Entity *leader = GetLeader(); - EntityInfo *leaderInfo = GetEntInfo(leader); - - sub_80978C8(leaderInfo->id); - if (gDungeon->unk644.unk28 != 0) { - if (sub_805E874() != 0) { - leaderInfo->action.action = 2; - leaderInfo->action.actionParameters[0].actionUseIndex = 0; - break; - } - sub_805E804(); - } - sInRotateMode = FALSE; - sInDiagonalMode = FALSE; - if (gDungeon->unk5C0 >= 0) { - r6.a0_8 = 1; - r6.a0_16 = 0; - r6.a0_24 = 0; - } - else { - r6.a0_8 = 0; - r6.a0_16 = 0; - r6.a0_24 = 0; - } - - frames = 0; - sub_8044C50(ACTION_NOTHING); - sShowThreeArrows1 = FALSE; - sShowThreeArrows2 = FALSE; - - while (r6.a0_8 == 0) { - u32 dpadDiagonal, dpadSimple; - bool32 highlightTiles, tryItemThrow; - bool32 bPress, rPress, unkBool; // Always FALSE, might've been used as debug variables. - s32 directionNew; - - sArrowsFrames++; - if (unkPtr->unk1821A != 0) { - frames = 0; - } - else { - frames++; - } - - if (var_38 != 0 && --var_38 == 0) { - sub_8075680(0); - } - - TryCreateModeArrows(leader); - unkBool = FALSE; - { - s32 i; - for (i = 0; i < 5; i++) { - triggers[i] = FALSE; - } - } - - if (gRealInputs.held & A_BUTTON && gRealInputs.held & B_BUTTON && FixedPointToInt(leaderInfo->belly) != 0) { - sub_8044C50(ACTION_PASS_TURN); - gDungeon->unk644.unk2F = 1; - break; - } - - bPress = FALSE; - rPress = FALSE; - - if (gRealInputs.pressed & A_BUTTON) { - if (gRealInputs.held & B_BUTTON) { - if (FixedPointToInt(leaderInfo->belly) != 0) { - sub_8044C50(ACTION_PASS_TURN); - gDungeon->unk644.unk2F = 1; - break; - } - } - else if (ShouldMonsterRunAwayAndShowEffect(leader, TRUE)) { - LogMessageByIdWithPopupCheckUser(leader, gUnknown_80FD4B0); - sub_8044C50(ACTION_PASS_TURN); - gDungeon->unk644.unk2F = 1; - break; - } - else if (gRealInputs.held & L_BUTTON) { - bool32 canUseMove; - s32 i, j; - - for (i = 0; i < MAX_MON_MOVES; i++) { - if (MoveFlagExists(&leaderInfo->moves.moves[i]) && MoveFlagSet(&leaderInfo->moves.moves[i])) { - break; - } - } - if (i == MAX_MON_MOVES) { - LogMessageByIdWithPopupCheckUser(leader, gUnknown_80F8A28); - break; - } - - for (j = 0; j < MAX_MON_MOVES; j++) { - if (MoveFlagExists(&leaderInfo->moves.moves[j])) { - if (leaderInfo->moves.moves[j].PP != 0) - break; - } - } - if (j == MAX_MON_MOVES) { - SetMonsterActionFields(&leaderInfo->action, ACTION_STRUGGLE); - break; - } - - canUseMove = FALSE; - for (j = i; j < MAX_MON_MOVES; j++) { - if (j != i && !(leaderInfo->moves.moves[j].moveFlags & MOVE_FLAG_SUBSEQUENT_IN_LINK_CHAIN)) { - break; - } - if (leaderInfo->moves.moves[j].PP != 0) { - canUseMove = TRUE; - break; - } - } - if (!canUseMove) { - LogMessageByIdWithPopupCheckUser(leader, gUnknown_80F8A4C); - } - else { - SetMonsterActionFields(&leaderInfo->action, ACTION_USE_MOVE_PLAYER); - leaderInfo->action.actionParameters[0].actionUseIndex = GetTeamMemberEntityIndex(leader); - leaderInfo->action.actionParameters[1].actionUseIndex = i; - } - break; - } - else { - if (!sub_805EF60(leader, leaderInfo)) { - SetMonsterActionFields(&leaderInfo->action, ACTION_REGULAR_ATTACK); - } - break; - } - } - - if (gRealInputs.shortPress & B_BUTTON) { - r6.a0_8 = 1; - r6.a0_16 = 0; - r6.a0_24 = 0; - break; - } - else if (triggers[1]) { // Opens moves menu - gDungeon->unk5C0 = 0; - r6.a0_8 = 1; - r6.a0_16 = 0; - r6.a0_24 = 1; - break; - } - else if (triggers[2]) { // Opens item menu - gDungeon->unk5C0 = 1; - r6.a0_8 = 1; - r6.a0_16 = 0; - r6.a0_24 = 1; - break; - } - else if (triggers[3]) { // Opens pokemon menu - gDungeon->unk5C0 = 2; - r6.a0_8 = 1; - r6.a0_16 = 0; - r6.a0_24 = 1; - break; - } - else if (triggers[4]) { // Opens regular menu - r6.a0_8 = 1; - r6.a0_16 = 0; - r6.a0_24 = 1; - break; - } - else if (frames > 0x707) { // Opens simple menu when idling - r6.a0_8 = 1; - r6.a0_16 = 1; - r6.a0_24 = 0; - break; - } - - if (gGameOptionsRef->unk9 == 0 - && (gRealInputs.pressed & B_BUTTON || (!unkBool && bPress)) - && unkPtr->unk1821A != 0) - { - sub_804AA60(); - sInRotateMode = FALSE; - ResetRepeatTimers(); - ResetUnusedInputStruct(); - } - - if (gRealInputs.held & L_BUTTON) { - if (gRealInputs.pressed & B_BUTTON) { - DisplayMessageLog(); - ResetRepeatTimers(); - ResetUnusedInputStruct(); - } - } - - tryItemThrow = FALSE; - if (gRealInputs.held & R_BUTTON) { - if (!sInDiagonalMode) { - sArrowsFrames = 0; - } - sInDiagonalMode = TRUE; - } - else { - sInDiagonalMode = FALSE; - } - - highlightTiles = FALSE; - if (gGameOptionsRef->unk9 == 0) { - if (gRealInputs.shortPress & R_BUTTON || rPress || gRealInputs.pressed & START_BUTTON) { - highlightTiles = TRUE; - } - } - if (highlightTiles) { - sub_805E738(leader); - sInRotateMode = TRUE; - unkPtr->unk1821B = leaderInfo->action.direction; - unkPtr->unk1821C = 0xFF; - ResetRepeatTimers(); - } - - if ((gRealInputs.held & L_BUTTON) == L_BUTTON && (gRealInputs.pressed & R_BUTTON) == R_BUTTON) { - tryItemThrow = TRUE; - } - if (triggers[0]) { - tryItemThrow = TRUE; - } - if (tryItemThrow) { - s32 i; - for (i = 0; i < INVENTORY_SIZE; i++) { - if (ItemExists(&gTeamInventoryRef->teamItems[i]) && ItemSet(&gTeamInventoryRef->teamItems[i])) { - sub_8044C50(ACTION_THROW_ITEM_PLAYER); - leaderInfo->action.actionParameters[0].actionUseIndex = i +1; - leaderInfo->action.actionParameters[0].itemPos.x = 0; - leaderInfo->action.actionParameters[0].itemPos.y = 0; - break; - } - } - if (leaderInfo->action.action != 0) { - break; - } - } - - // SELECT button - if (!gDungeon->unk181e8.blinded && gGameOptionsRef->mapOption != 6 && gRealInputs.pressed & SELECT_BUTTON) { - s32 prevMapOption = gGameOptionsRef->mapOption; - gUnknown_202EE00 = 1; - gDungeon->unk181e8.unk18214 = 1; - if (!sub_8094C48()) { - sub_8094C88(); - } - sub_8052210(1); - sub_8040A84(); - SetBGOBJEnableFlags(0x1E); - sub_803E708(0xA, 0x2F); - while (1) { - DungeonRunFrameActions(0x2F); - if (gRealInputs.pressed & SELECT_BUTTON) - break; - if (gRealInputs.pressed & B_BUTTON) - break; - - if (gRealInputs.pressed & A_BUTTON) { - gUnknown_202EE00 = (gUnknown_202EE00 == 0) ? 1 : 0; // Flip - sub_8040A84(); - } - } - gDungeon->unk181e8.unk18214 = 0; - gGameOptionsRef->mapOption = prevMapOption; - gUnknown_202EE00 = 1; - sub_8040A84(); - SetBGOBJEnableFlags(0); - DungeonRunFrameActions(0x2F); - DungeonRunFrameActions(0x2F); - } - - if (gDungeon->unk644.unk29 != 0 && !sInDiagonalMode) { - dpadDiagonal = dpadSimple = gRealInputs.pressed; - } - else { - dpadDiagonal = gRealInputs.held; - dpadSimple = (unkPtr->unk1821A == 0) ? gRealInputs.held : gRealInputs.pressed; - } - - dpadDiagonal &= DPAD_ANY; - dpadSimple &= DPAD_ANY; - directionNew = -1; - if (dpadDiagonal == (DPAD_UP | DPAD_RIGHT)) - directionNew = DIRECTION_NORTHEAST; - if (dpadDiagonal == (DPAD_UP | DPAD_LEFT)) - directionNew = DIRECTION_NORTHWEST; - if (dpadDiagonal == (DPAD_DOWN | DPAD_RIGHT)) - directionNew = DIRECTION_SOUTHEAST; - if (dpadDiagonal == (DPAD_DOWN | DPAD_LEFT)) - directionNew = DIRECTION_SOUTHWEST; - - if (dpadSimple == DPAD_UP) - directionNew = DIRECTION_NORTH; - if (dpadSimple == DPAD_DOWN) - directionNew = DIRECTION_SOUTH; - if (dpadSimple == DPAD_RIGHT) - directionNew = DIRECTION_EAST; - if (dpadSimple == DPAD_LEFT) - directionNew = DIRECTION_WEST; - - if (directionNew >= 0 && (!sInDiagonalMode || (directionNew & 1))) { - bool32 directionChanged = (leaderInfo->action.direction != directionNew); - leaderInfo->action.direction = directionNew & DIRECTION_MASK; - if (sInRotateMode) { - unkPtr->unk1821B = directionNew; - sub_806CDD4(leader, sub_806CEBC(leader), directionNew); - } - else { - u8 canMoveFlags = 0; - const u8 *immobilizedMsg = NULL; - - if (sub_805EC4C(leader, 1)) - break; - - if (leaderInfo->frozenClassStatus.status == STATUS_SHADOW_HOLD) { - immobilizedMsg = gUnknown_80F8A84, canMoveFlags |= 1; - } - else if (leaderInfo->frozenClassStatus.status == STATUS_CONSTRICTION) { - immobilizedMsg = gUnknown_80F8A6C, canMoveFlags |= 1; - } - else if (leaderInfo->frozenClassStatus.status == STATUS_INGRAIN) { - immobilizedMsg = gUnknown_80F8AB0, canMoveFlags |= 1; - } - else if (leaderInfo->frozenClassStatus.status == STATUS_WRAP) { - immobilizedMsg = gUnknown_80F8ADC, canMoveFlags |= 1; - } - else if (leaderInfo->frozenClassStatus.status == STATUS_WRAPPED) { - immobilizedMsg = gUnknown_80F8B0C, canMoveFlags |= 1; - } - - if (!CanMoveInDirection(leader, directionNew)) - canMoveFlags |= 2; - - if (directionChanged) { - sub_806CDD4(leader, sub_806CEBC(leader), directionNew); - } - - if (!(canMoveFlags & 2)) { - if (canMoveFlags & 1) { - if (immobilizedMsg != NULL) { - LogMessageByIdWithPopupCheckUser(leader, immobilizedMsg); - } - sub_8044C50(ACTION_PASS_TURN); - gDungeon->unk644.unk2F = 1; - } - else { - sub_8044C50(ACTION_WALK); - if ((gRealInputs.held & B_BUTTON || bPress) && FixedPointToInt(leaderInfo->belly) != 0) { - if (GetEntInfo(leader)->cringeClassStatus.status != STATUS_CONFUSED) { - gDungeon->unk644.unk28 = 1; - } - leaderInfo->action.actionParameters[0].actionUseIndex = 0; - } - else { - leaderInfo->action.actionParameters[0].actionUseIndex = 1; - } - } - break; - } - else if (canMoveFlags & 1) { - sub_803E724(0x23); - } - - } - } - DungeonRunFrameActions(0xF); - } - - if (unkPtr->unk1821A != 0) { - sub_804AA60(); - } - - if (leaderInfo->action.action == 0x2D || leaderInfo->action.action == 0x13) { - HandleTalkFieldAction(leader); - if (sub_8044B28()) - break; - sub_8044C50(ACTION_NOTHING); - } - else if ((r6.a0_8) == 0) { - gDungeon->unk644.unk29 = 0; - if (leaderInfo->action.action != 0) { - if (!IsNotAttacking(leader, FALSE)) { - DungeonRunFrameActions(0xF); - } - break; - } - DungeonRunFrameActions(0xF); - } - else { - DungeonRunFrameActions(0xF); - sub_8047158(); - ShowMainMenu((r6.a0_16 == 0), r6.a0_24); - ResetRepeatTimers(); - ResetUnusedInputStruct(); - sInRotateMode = FALSE; - unkPtr->unk1821A = 0; - sub_804AA60(); - if (sub_8044B28()) - break; - if (leaderInfo->action.action != 0) { - if (leaderInfo->action.action == 0x2B) { - gDungeon->unk4 = 1; - gDungeon->unk3 = 1; - } - if (leaderInfo->action.action == 0x2E) { - gDungeon->unk4 = 1; - gDungeon->unk3 = 0; - } - break; - } - DungeonRunFrameActions(0xF); - if (gDungeon->unk4 != 0) - break; - } - } -} - -struct UnkStruct_8106AC8 -{ - s16 unk0; - s16 unk2; - u8 unk4; - u8 unk5; -}; - -extern const struct UnkStruct_8106AC8 gUnknown_8106AC8[]; - -struct UnkStruct_8106AE8 -{ - s16 unk0; - s16 unk2; - u32 unk4; - u8 unk8; - u8 unk9; - u8 unkA; -}; - -extern const struct UnkStruct_8106AE8 gUnknown_8106AE8[]; - -// Creates arrow sprites which are used when in rotate or diagonal modes. -static void TryCreateModeArrows(Entity *leader) -{ - UnkDungeonGlobal_unk181E8_sub *unkPtr = &gDungeon->unk181e8; - - if (sInDiagonalMode) { - s32 i; - SpriteOAM sprite; - - for (i = 0; i < 4; i++) { - u32 matrixNum; - s32 x, xMul, x2; - s32 y, yMul, y2; - - SpriteSetAffine1(&sprite, 0); - SpriteSetAffine2(&sprite, 0); - SpriteSetObjMode(&sprite, 1); - SpriteSetMosaic(&sprite, 0); - SpriteSetBpp(&sprite, 0); - SpriteSetShape(&sprite, 0); - - matrixNum = (gUnknown_8106AC8[i].unk4 != 0) ? 8 : 0; - - if (gUnknown_8106AC8[i].unk5) - matrixNum += 16; - - SpriteSetMatrixNum_UseLocalVar(&sprite, matrixNum); - SpriteSetSize(&sprite, 0); - - SpriteSetTileNum(&sprite, 0x213); - SpriteSetPriority(&sprite, 2); - SpriteSetPalNum(&sprite, 0); - - SpriteSetUnk6_0(&sprite, 0); - SpriteSetUnk6_1(&sprite, 0); - - xMul = gUnknown_8106AC8[i].unk0 * 10; - x2 = (sArrowsFrames / 2) & 7; - x = (x2 * gUnknown_8106AC8[i].unk0) + xMul + 116; - SpriteSetX(&sprite, x); - - yMul = gUnknown_8106AC8[i].unk2 * 10; - y2 = (sArrowsFrames / 2) & 7; - y = (y2 * gUnknown_8106AC8[i].unk2) + yMul + 82; - SpriteSetY(&sprite, y); - - AddSprite(&sprite, 0x100, NULL, NULL); - } - } - - else if (unkPtr->unk1821A) { - s32 i; - SpriteOAM sprite; - s32 var_2C = unkPtr->unk1821B; - - if (unkPtr->unk1821B < 8) { - s32 x, xMul, x2; - s32 y, yMul, y2; - s32 to = (sShowThreeArrows2 != FALSE && sShowThreeArrows1 != FALSE) ? 3 : 1; - - xMul = gUnknown_8106AE8[var_2C].unk0 * 10; - x2 = (sArrowsFrames / 2) & 7; - x = (gUnknown_8106AE8[var_2C].unk0 * x2) + xMul + 116; - - yMul = gUnknown_8106AE8[var_2C].unk2 * 10; - y2 = (sArrowsFrames / 2) & 7; - y = (y2 * gUnknown_8106AE8[var_2C].unk2) + yMul + 82; - for (i = 0; i < to; i++) { - u32 matrixNum; - - SpriteSetAffine1(&sprite, 0); - SpriteSetAffine2(&sprite, 0); - SpriteSetObjMode(&sprite, 1); - SpriteSetMosaic(&sprite, 0); - SpriteSetBpp(&sprite, 0); - SpriteSetShape(&sprite, 0); - - matrixNum = (gUnknown_8106AE8[var_2C].unk8 != 0) ? 8 : 0; - - if (gUnknown_8106AE8[var_2C].unk9) - matrixNum += 16; - - SpriteSetMatrixNum_UseLocalVar(&sprite, matrixNum); - SpriteSetSize(&sprite, 0); - - SpriteSetTileNum(&sprite, gUnknown_8106AE8[var_2C].unk4); - SpriteSetPriority(&sprite, 2); - SpriteSetPalNum(&sprite, 0); - - SpriteSetUnk6_0(&sprite, 0); - SpriteSetUnk6_1(&sprite, 0); - - SpriteSetX(&sprite, x); - SpriteSetY(&sprite, y); - - AddSprite(&sprite, 0x100, NULL, NULL); - x += gUnknown_8106AE8[var_2C].unk0 * 4; - y += gUnknown_8106AE8[var_2C].unk2 * 4; - } - } - } - - if (sInRotateMode && unkPtr->unk1821C != unkPtr->unk1821B) { - unkPtr->unk1821C = unkPtr->unk1821B; - ChangeDungeonCameraPos(&leader->pos, unkPtr->unk1821B, 0, sInRotateMode); - } -} - -void sub_805E738(Entity *a0) -{ - const Tile *tile; - s32 i, j; - EntityInfo *entityInfo = GetEntInfo(a0); - if (entityInfo->blinkerClassStatus.status != 1 && entityInfo->blinkerClassStatus.status != 2) { - // What??? - for (i = 0; i < 1; i++) { - bool8 r9 = FALSE; - u32 direction = entityInfo->action.direction; - direction++; - for (j = 1; j < 8; j++, direction++) { - direction &= DIRECTION_MASK; - tile = GetTile(a0->pos.x + gAdjacentTileOffsets[direction].x, a0->pos.y + gAdjacentTileOffsets[direction].y); - if (tile->monster != NULL && GetEntityType(tile->monster) == ENTITY_MONSTER) { - EntityInfo *tileMonsterInfo = GetEntInfo(tile->monster); - if (CanSeeTarget(a0, tile->monster)) { - if (i != 0 || tileMonsterInfo->isNotTeamMember) { - r9 = TRUE; - break; - } - } - } - } - if (r9) { - GetEntInfo(a0)->action.direction = direction & DIRECTION_MASK; - sub_806CDD4(a0, sub_806CEBC(a0), direction); - break; - } - } - } -} - -void sub_805E804(void) -{ - gDungeon->unk644.unk29 |= gDungeon->unk644.unk28; - gDungeon->unk644.unk28 = 0; - while (gDungeon->unk644.unk29 != 0 && gRealInputs.held & R_BUTTON) { - DungeonRunFrameActions(0x54); - } -} - -extern bool8 sub_8070F14(Entity * pokemon, s32 direction); -bool8 sub_805EC2C(Entity *a0, s32 x, s32 y); - -bool8 sub_805E874(void) -{ - u8 r7, r8, r0; - s32 i, j, k; - s32 xArray[3]; - s32 yArray[3]; - Dungeon *dungeon = gDungeon; - Entity *leader = GetLeader(); - s32 direction = GetEntInfo(leader)->action.direction; - s32 x = leader->pos.x; - s32 y = leader->pos.y; - const Tile *leaderTile = GetTile(x, y); - s32 xAdjacent = x + gAdjacentTileOffsets[direction].x; - s32 yAdjacent = y + gAdjacentTileOffsets[direction].y; - s32 room; - - if (dungeon->unk644.unk28 == 0) - return FALSE; - if (leaderTile->object != NULL) - return FALSE; - if (sub_805EC2C(leader, x, y)) - return FALSE; - if (!sub_8070F14(leader, direction)) - return FALSE; - - room = leaderTile->room; - if (room == 0xFF) { - if (GetTile(xAdjacent, yAdjacent)->room != 0xFF) - return FALSE; - } - else { - if (leaderTile->terrainType & TERRAIN_TYPE_NATURAL_JUNCTION) - return FALSE; - } - - for (j = -1; j < 2; j++) { - const Tile *tile = GetTile(x + gAdjacentTileOffsets[(direction + j) & 7].x, y + gAdjacentTileOffsets[(direction + j) & 7].y); - if (tile->monster != NULL) - return FALSE; - if (tile->terrainType & TERRAIN_TYPE_STAIRS) - return FALSE; - } - - xArray[0] = x + gAdjacentTileOffsets[(direction + 3) & 7].x; - xArray[1] = x + gAdjacentTileOffsets[(direction + 4) & 7].x; - xArray[2] = x + gAdjacentTileOffsets[(direction + 5) & 7].x; - - yArray[0] = y + gAdjacentTileOffsets[(direction + 3) & 7].y; - yArray[1] = y + gAdjacentTileOffsets[(direction + 4) & 7].y; - yArray[2] = y + gAdjacentTileOffsets[(direction + 5) & 7].y; - - for (i = -1; i < 2; i++) { - for (j = -1; j < 2; j++) { - const Tile *tile = GetTile(x + i, y + j); - if (tile->object != NULL) { - for (k = 0; k < 3; k++) { - if (x + i == xArray[k] && y + j == yArray[k]) - break; - } - if (k == 3 && GetEntityType(tile->object) == ENTITY_ITEM) - return FALSE; - } - - if (direction & 1) { - // This doesn't really have to be called two times... - if (tile->object != NULL && GetEntityType(tile->object) == ENTITY_TRAP && GetEntityType(tile->object) == ENTITY_TRAP) { - if (tile->object->isVisible) - return FALSE; - if (gDungeon->unk181e8.unk1820F) - return FALSE; - } - } - else if (i == 0 || j == 0) { - if (tile->object != NULL && GetEntityType(tile->object) == ENTITY_TRAP) { - if (tile->object->isVisible) - return FALSE; - if (gDungeon->unk181e8.unk1820F) - return FALSE; - } - } - - if (i != 0 && j != 0) continue; - if (i == 0 && j == 0) continue; - - if ((xArray[1] != x + i || yArray[1] != y + j) && !sub_805EC2C(leader, x + i, y + j) && room != 0xFF && room != tile->room) - return FALSE; - } - } - - if (!(direction & 1)) { - if (direction == 0 || direction == 4) { - r8 = sub_805EC2C(leader, x - 1, y - 1); - r7 = sub_805EC2C(leader, x - 1, y); - r0 = sub_805EC2C(leader, x - 1, y + 1); - if (r7 == 0) { - if (r8 != 0 || r7 != r0) - return FALSE; - } - - r8 = sub_805EC2C(leader, x + 1, y - 1); - r7 = sub_805EC2C(leader, x + 1, y); - r0 = sub_805EC2C(leader, x + 1, y + 1); - if (r7 == 0) { - if (r8 != 0 || r7 != r0) - return FALSE; - } - } - else { - r8 = sub_805EC2C(leader, x - 1, y - 1); - r7 = sub_805EC2C(leader, x, y - 1); - r0 = sub_805EC2C(leader, x + 1, y - 1); - if (r7 == 0) { - if (r8 != 0 || r7 != r0) - return FALSE; - } - - r8 = sub_805EC2C(leader, x - 1, y + 1); - r7 = sub_805EC2C(leader, x, y + 1); - r0 = sub_805EC2C(leader, x + 1, y + 1); - if (r7 == 0) { - if (r8 != 0 || r7 != r0) - return FALSE; - } - } - } - - return TRUE; -} - -bool8 sub_805EC2C(Entity *a0, s32 x, s32 y) -{ - DungeonPos pos = {.x = x, .y = y}; - return sub_8070564(a0, &pos); -} - -bool8 sub_805EC4C(Entity *a0, u8 a1) -{ - DungeonPos pos; - const Tile *tile; - EntityInfo *tileMonsterInfo; - Entity *tileMonster; - EntityInfo *entityInfo = GetEntInfo(a0); - - pos.x = a0->pos.x + gAdjacentTileOffsets[entityInfo->action.direction].x; - pos.y = a0->pos.y + gAdjacentTileOffsets[entityInfo->action.direction].y; - tile = GetTile(pos.x, pos.y); - tileMonster = tile->monster; - - if (tileMonster == NULL) return FALSE; - if (GetEntityType(tileMonster) != ENTITY_MONSTER) return FALSE; - - tileMonsterInfo = GetEntInfo(tileMonster); - if (tileMonsterInfo->isNotTeamMember - && (tileMonsterInfo->shopkeeper != 1 && tileMonsterInfo->shopkeeper != 2) - && !IsExperienceLocked(tileMonsterInfo->joinedAt.id) - && tileMonsterInfo->monsterBehavior != BEHAVIOR_RESCUE_TARGET) { - return FALSE; - } - - if (entityInfo->frozenClassStatus.status == STATUS_SHADOW_HOLD) return FALSE; - if (entityInfo->frozenClassStatus.status == STATUS_FROZEN) return FALSE; - if (entityInfo->frozenClassStatus.status == STATUS_CONSTRICTION) return FALSE; - if (entityInfo->frozenClassStatus.status == STATUS_INGRAIN) return FALSE; - if (entityInfo->frozenClassStatus.status == STATUS_WRAP) return FALSE; - if (entityInfo->frozenClassStatus.status == STATUS_WRAPPED) return FALSE; - - if (tileMonsterInfo->frozenClassStatus.status == STATUS_SHADOW_HOLD) return FALSE; - if (tileMonsterInfo->frozenClassStatus.status == STATUS_FROZEN) return FALSE; - if (tileMonsterInfo->frozenClassStatus.status == STATUS_CONSTRICTION) return FALSE; - if (tileMonsterInfo->frozenClassStatus.status == STATUS_INGRAIN) return FALSE; - if (tileMonsterInfo->frozenClassStatus.status == STATUS_WRAP) return FALSE; - if (tileMonsterInfo->frozenClassStatus.status == STATUS_WRAPPED) return FALSE; - - if (entityInfo->cringeClassStatus.status == STATUS_CONFUSED) return FALSE; - if (tileMonsterInfo->cringeClassStatus.status == STATUS_CONFUSED) return FALSE; - - if (tileMonsterInfo->sleepClassStatus.status != STATUS_NONE && tileMonsterInfo->sleepClassStatus.status != STATUS_SLEEPLESS && tileMonsterInfo->sleepClassStatus.status != STATUS_YAWNING) return FALSE; - if (entityInfo->sleepClassStatus.status != STATUS_NONE && entityInfo->sleepClassStatus.status != STATUS_SLEEPLESS && entityInfo->sleepClassStatus.status != STATUS_YAWNING) return FALSE; - - if (IsChargingAnyTwoTurnMove(tileMonster, FALSE)) return FALSE; - if (!sub_8070F80(a0, entityInfo->action.direction)) return FALSE; - - if (a1 != 0 && sub_807049C(tileMonster, &a0->pos) && !DisplayDungeonYesNoMessage(0, gUnknown_8100208, 0)) return FALSE; - - SetMonsterActionFields(&entityInfo->action, ACTION_WALK); - if (gRealInputs.held & B_BUTTON) { - entityInfo->action.actionParameters[0].actionUseIndex = 0; - } - else { - entityInfo->action.actionParameters[0].actionUseIndex = 1; - } - entityInfo->flags |= 0x8000; - - SetMonsterActionFields(&tileMonsterInfo->action, ACTION_WALK); - tileMonsterInfo->action.actionParameters[0].actionUseIndex = 0; - tileMonsterInfo->action.direction = (entityInfo->action.direction + 4) & 7; - tileMonsterInfo->flags |= 0x8000; - tileMonsterInfo->targetPos.x = tileMonster->pos.x; - tileMonsterInfo->targetPos.y = tileMonster->pos.y; - gDungeon->unkE = 1; - return TRUE; -} - -void sub_805EE30(void) -{ - Entity *tileObject; - Tile *tile; - Entity *leader = GetLeader(); - if (leader == NULL) - return; - if (sub_8044B28()) - return; - - tile = GetTileAtEntitySafe(leader); - if (IQSkillIsEnabled(leader, IQ_SUPER_MOBILE) && GetEntInfo(leader)->invisibleClassStatus.status != STATUS_MOBILE && !HasHeldItem(leader, ITEM_MOBILE_SCARF)) - sub_804AE84(&leader->pos); - if (tile->terrainType & TERRAIN_TYPE_STAIRS) - gDungeon->unk1 = 1; - - tileObject = tile->object; - if (tileObject == NULL) - return; - switch (GetEntityType(tileObject)) - { - case ENTITY_TRAP: { - Trap *trap = GetTrapData(tileObject); - bool32 r8 = FALSE; - bool32 r7 = FALSE; - if (IQSkillIsEnabled(leader, IQ_TRAP_SEER) && !tileObject->isVisible) { - tileObject->isVisible = TRUE; - sub_8049ED4(); - r7 = TRUE; - } - if (trap->unk1 != 0) { - if (trap->unk1 == 1) - break; - if (trap->unk1 == 2) - r8 = TRUE; - if (r8 == FALSE) - break; - } - if (!r7) { - HandleTrap(leader, &leader->pos, 0, 1); - } - } - break; - case ENTITY_ITEM: { - Item *item = GetItemData(tileObject); - if (!(item->flags & ITEM_FLAG_IN_SHOP)) { - sub_8045DB4(&leader->pos, 1); - } - else { - gDungeon->unk5C0 = 4; - } - } - break; - case ENTITY_NOTHING: - case ENTITY_MONSTER: - case ENTITY_UNK_4: - case ENTITY_UNK_5: - default: - break; - } -} - -extern Entity *sub_80696A8(Entity *a0); -extern u8 sub_806A538(s32); - -bool8 sub_805EF60(Entity *a0, EntityInfo *a1) -{ - Entity *r4 = sub_80696A8(a0); - - if (r4 == NULL) - return FALSE; - if (GetEntityType(r4) != ENTITY_MONSTER) - return FALSE; - if (!sub_8070BC0(a0)) - return FALSE; - if (GetEntInfo(r4)->isNotTeamMember && GetEntInfo(r4)->monsterBehavior != BEHAVIOR_RESCUE_TARGET && GetEntInfo(r4)->shopkeeper != 1) - return FALSE; - - SetMonsterActionFields(&a1->action, ACTION_TALK_FIELD); - return TRUE; -} - -void sub_805EFB4(Entity *a0, bool8 a1) -{ - s32 i; - EntityInfo *leaderInfo = GetLeaderInfo(); - if (a1 && leaderInfo->cringeClassStatus.status == STATUS_COWERING) { - leaderInfo->action.direction += 4; - leaderInfo->action.direction &= 7; - } - else if (leaderInfo->cringeClassStatus.status == STATUS_CONFUSED) { - s32 rnd = DungeonRandInt(8); - for (i = 0; i < 8; i++) { - if (a1 || CanMoveInDirection(a0, rnd)) { - leaderInfo->action.direction = rnd & 7; - return; - } - rnd = (rnd + 1) & 7; - } - } -} - -extern void sub_803EAF0(u32, u8 *); -extern void sub_803F508(Entity *); -extern void sub_8041AD0(Entity *pokemon); -extern void sub_8041AE0(Entity *pokemon); -extern void sub_807EC28(bool8); -extern void PlayDungeonCursorSE(u8 param_1); - -extern MenuInputStruct gDungeonMenu; - -void sub_805F02C(void) -{ - s32 i; - Entity *r7 = gDungeon->unkBC; - Entity *leader = GetLeader(); - EntityInfo *r8 = GetEntInfo(r7); - EntityInfo *leaderInfo = GetEntInfo(leader); - - if (r8->isTeamLeader) { - DisplayDungeonLoggableMessageTrue(r7, gUnknown_80F9BD8); - } - else if (sub_8047084(ITEM_FLAG_IN_SHOP) || sub_807EF48()) { - DisplayDungeonLoggableMessageTrue(r7, gUnknown_80F9C08); - } - else if (gDungeon->unk644.unk2A) { - DisplayDungeonLoggableMessageTrue(r7, gUnknown_80F9C2C); - } - else { - gDungeon->unk644.unk35 = 0; - r8->isTeamLeader = TRUE; - leaderInfo->isTeamLeader = FALSE; - for (i = 0; i < 4; i++) { - PokemonStruct2 *mon = &gRecruitedPokemonRef->pokemon2[i]; - PokemonStruct1 *r5 = NULL; - - if ((u8)mon->unk0 & 1) { - if (!sub_806A538(mon->unkA)) { - r5 = &gRecruitedPokemonRef->pokemon[mon->unkA]; - } - if (i == r8->teamIndex) { - mon->isTeamLeader = TRUE; - if (r5 != NULL) { - r5->isTeamLeader = TRUE; - } - } - else { - mon->isTeamLeader = FALSE; - if (r5 != NULL) { - r5->isTeamLeader = FALSE; - } - } - } - } - gLeaderPointer = NULL; - r8->action = leaderInfo->action; - sub_803F508(r7); - sub_8041AD0(leader); - sub_8041AE0(GetLeader()); - SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], r7, 0); - LogMessageByIdWithPopupCheckUser(r7, gUnknown_80F9BB0); - sub_807EC28(FALSE); - r8->unk64 = 0; - leaderInfo->unk64 = 0; - sub_806A6E8(leader); - sub_806A6E8(r7); - } -} - -ActionContainer *GetLeaderActionContainer(void) -{ - return &GetLeaderInfo()->action; -} - -u16 GetLeaderActionId(void) -{ - return GetLeaderInfo()->action.action; -} - -// Could this be a start of a new file? -static UNUSED EWRAM_DATA u8 sUnused[4] = {0}; -static EWRAM_DATA ActionParameter sUnknownActionUnk4 = {0}; -static EWRAM_DATA s32 sUnknown_202F240 = 0; -static UNUSED EWRAM_DATA u8 sUnused2[4] = {0}; -static EWRAM_DATA s16 sUnknown_202F248[8] = {0}; -static EWRAM_DATA s32 sUnknown_202F258 = 0; -static UNUSED EWRAM_DATA u8 sUnused3[4] = {0}; -static EWRAM_DATA s32 sTeamMenuChosenId = 0; -static UNUSED EWRAM_DATA u8 sUnused4[4] = {0}; - -enum -{ - MAIN_MENU_MOVES, - MAIN_MENU_ITEMS, - MAIN_MENU_TEAM, - MAIN_MENU_OTHERS, - MAIN_MENU_GROUND, -}; - -void ShowMainMenu(bool8 fromBPress, bool8 a1) -{ - Item *item; - s32 r10; - bool8 printAll = fromBPress; - s32 chosenOption; - s32 var_24; - struct UnkMenuBitsStruct var_30; - struct UnkMenuBitsStruct var_34; - - r10 = gDungeon->unk5C0; - chosenOption = 0; - var_24 = (gDungeon->unk5C0 > - 1); - gDungeon->unk5C0 = -1; - if (r10 >= 0) { - chosenOption = r10; - } - - if (a1) { - PlayFanfareSE(0x137, 0x100); - } - else { - PlayDungeonStartButtonSE(); - } - - while (1) { - if (r10 < 0) { - SetLeaderActionToNothing(1); - sTeamMenuChosenId = -1; - PrintOnMainMenu(printAll); - sub_806A2BC(GetLeader(), 0); - while (1) { - AddMenuCursorSprite(&gDungeonMenu); - DungeonRunFrameActions(0x1D); - if (gRealInputs.repeated & DPAD_DOWN) { - PlayDungeonCursorSE(1); - MoveMenuCursorDownWrapAround(&gDungeonMenu, TRUE); - } - if (gRealInputs.repeated & DPAD_UP) { - PlayDungeonCursorSE(1); - MoveMenuCursorUpWrapAround(&gDungeonMenu, TRUE); - } - if ((gRealInputs.pressed & A_BUTTON || gDungeonMenu.unk28.a_button)) { - if (gUnknown_202749A[gDungeonMenu.menuIndex + 1] == 7) { - PlayDungeonConfirmationSE(); - chosenOption = gDungeonMenu.menuIndex; - break; - } - PlayDungeonCancelSE(); - } - if ((gRealInputs.pressed & B_BUTTON) || gDungeonMenu.unk28.b_button) { - PlayDungeonCancelSE(); - chosenOption = -1; - break; - } - } - AddMenuCursorSprite(&gDungeonMenu); - DungeonRunFrameActions(0x1D); - printAll = TRUE; - } - - r10 = chosenOption; - if (chosenOption == MAIN_MENU_ITEMS) { - u16 action; - - SetLeaderActionToNothing(1); - var_34.a0_8 = 0; - var_34.a0_16 = 1; - var_34.a0_24 = 0; - var_34.a0_32 = 0; - if (ShowDungeonItemsMenu(GetLeader(), &var_34)) { - r10 = -1; - } - if (sub_805FD3C(&var_34) && ShowDungeonItemsMenu(GetLeader(), &var_34)) { - SetLeaderActionToNothing(1); - } - action = GetLeaderActionId(); - if (action == 12) { - sub_8044D90(GetLeader(), 0, 12)->flags |= ITEM_FLAG_UNPAID; - sub_8060D24(GetLeaderActionContainer()); - SetLeaderActionToNothing(1); - } - else if (action == 53) { - item = sub_8044D90(GetLeader(), 0, 13); - if (!sub_8048A68(GetLeader(), item)) { - SetLeaderActionToNothing(1); - } - } - else if (action == 16) { - item = sub_8044D90(GetLeader(), 0, 14); - if (!sub_8048950(GetLeader(), item)) { - SetLeaderActionToNothing(1); - } - } - else if (action == 44) { - item = sub_8044D90(GetLeader(), 0, 15); - if (!sub_8048B9C(GetLeader(), item)) { - SetLeaderActionToNothing(1); - } - } - else if (action == 60) { - HandleSetItemAction(GetLeader(), TRUE); - SetLeaderActionToNothing(1); - sub_803E708(0x50, 0x4D); - sub_8052210(0); - break; - } - else if (action == 61) { - HandleUnsetItemAction(GetLeader(), TRUE); - SetLeaderActionToNothing(1); - sub_803E708(0x50, 0x4D); - sub_8052210(0); - break; - } - - if (GetLeaderActionId() != 0) - break; - } - else if (chosenOption == MAIN_MENU_TEAM) { - SetLeaderActionToNothing(1); - if (ShowDungeonTeamMenu(GetLeader())) { - r10 = -1; - } - - if (GetLeaderActionId() == 0x1B) { - sub_8061A38(GetLeaderActionContainer(), FALSE); - SetLeaderActionToNothing(1); - } - else if (GetLeaderActionId() == 0x1C) { - sub_806752C(GetLeaderActionContainer()); - SetLeaderActionToNothing(1); - } - else if (GetLeaderActionId() == 0x34) { - sub_8067768(GetLeaderActionContainer()); - SetLeaderActionToNothing(1); - } - else if (GetLeaderActionId() == 0x1A) { - ShowTacticsMenu(GetLeaderActionContainer()); - SetLeaderActionToNothing(1); - } - else if (GetLeaderActionId() == 0x30) { - sub_8061A38(GetLeaderActionContainer(), TRUE); - SetLeaderActionToNothing(1); - } - else if (GetLeaderActionId() == 0x19) { - s32 i, count; - - sub_8062D8C(GetLeaderActionContainer()); - count = 0; - for (i = 0; i < MAX_TEAM_MEMBERS; i++) { - Entity *teamMon = gDungeon->teamPokemon[i]; - if (EntityIsValid(teamMon)) { - if (i == GetLeaderActionContainer()->actionParameters[0].actionUseIndex) { - sTeamMenuChosenId = count; - if (GetLeaderActionId() != 0) { - sub_806A2BC(teamMon, 0); - } - break; - } - count++; - } - } - } - - if (GetLeaderActionId() != 0) - break; - } - else if (chosenOption == MAIN_MENU_MOVES) { - s32 i, currMonId, teamMonsCount, r9; - Entity *currEntity; - - currMonId = 0; - SetLeaderActionToNothing(1); - for (i = 0; i < MAX_TEAM_MEMBERS; i++) { - Entity *teamMon = gDungeon->teamPokemon[i]; - if (EntityIsValid(teamMon)) { - if (GetEntInfo(teamMon)->isTeamLeader) { - currMonId = i; - break; - } - } - } - - - while (1) { - SetLeaderActionToNothing(0); - LOOP_START_NO_CALL: // Actions 6 and 7 don't call SetLeaderActionToNothing - currEntity = NULL; - r9 = 0; - teamMonsCount = 0; - for (i = 0; i < MAX_TEAM_MEMBERS; i++) { - Entity *teamMon = gDungeon->teamPokemon[i]; - if (sub_8071A8C(teamMon)) { - if (i == currMonId) { - r9 = teamMonsCount; - currEntity = teamMon; - } - teamMonsCount++; - } - } - if (currEntity == NULL) { - currEntity = GetLeader(); - } - - sub_806A2BC(currEntity, 0); - ChangeDungeonCameraPos(&currEntity->pos, 0, 1, 1); - GetLeaderInfo()->action.actionParameters[0].actionUseIndex = currMonId; - SetLeaderActionToNothing(FALSE); - if (ShowDungeonMovesMenu(currEntity, 0, 1, r9, teamMonsCount)) { - r10 = -1; - } - - if (GetLeaderActionId() == ACTION_MOVES_MENU_NEXT_MON) { - s32 prevMonId = currMonId; - for (i = 0; i < MAX_TEAM_MEMBERS; i++) { - if (++currMonId >= MAX_TEAM_MEMBERS) { - currMonId = 0; - } - currEntity = gDungeon->teamPokemon[currMonId]; - if (sub_8071A8C(currEntity)) - break; - } - GetLeaderInfo()->action.actionParameters[0].actionUseIndex = currMonId; - if (prevMonId != currMonId) { - PlayDungeonCursorSE(0); - } - goto LOOP_START_NO_CALL; - } - else if (GetLeaderActionId() == ACTION_MOVES_MENU_PREV_MON) { - s32 prevMonId = currMonId; - for (i = 0; i < MAX_TEAM_MEMBERS; i++) { - if (--currMonId < 0) { - currMonId = MAX_TEAM_MEMBERS - 1; - } - currEntity = gDungeon->teamPokemon[currMonId]; - if (sub_8071A8C(currEntity)) - break; - } - GetLeaderInfo()->action.actionParameters[0].actionUseIndex = currMonId; - if (prevMonId != currMonId) { - PlayDungeonCursorSE(0); - } - goto LOOP_START_NO_CALL; - } - else if (GetLeaderActionId() == ACTION_UNK1D) { - sub_80637E8(GetLeaderActionContainer()); - } - else if (GetLeaderActionId() == ACTION_SET_MOVE || GetLeaderActionId() == ACTION_UNSET_MOVE) { - sub_8063A70(GetLeaderActionContainer(), FALSE); - } - else if (GetLeaderActionId() == ACTION_UNK1F) { - sub_8063B54(GetLeaderActionContainer()); - } - else if (GetLeaderActionId() == ACTION_UNK20) { - sub_8063BB4(GetLeaderActionContainer()); - } - else if (GetLeaderActionId() == ACTION_UNK21) { - sub_8063CF0(GetLeaderActionContainer(), FALSE); - } - else { - break; - } - } - sub_806A2BC(GetLeader(), 0); - ChangeDungeonCameraPos(&GetLeader()->pos, 0, 1, 1); - if (GetLeaderActionId() != 0) - break; - } - else if (chosenOption == MAIN_MENU_GROUND) { - Entity *leader = GetLeader(); - const Tile *tile = GetTile(leader->pos.x, leader->pos.y); - Entity *tileObject = tile->object; - if (tileObject != NULL) { - if (GetEntityType(tileObject) == ENTITY_ITEM) { - u16 action; - - SetLeaderActionToNothing(1); - var_30.a0_8 = 0; - var_30.a0_16 = 1; - var_30.a0_24 = 1; - var_30.a0_32 = 1; - if (ShowDungeonItemsMenu(GetLeader(), &var_30)) { - // This actually doesn't do anything, it's just there to make the code match as the compiler does a `lsl r0, r0, #0x10, mov r0, r4` - ASM_MATCH_TRICK(leader); - } - if (sub_805FD3C(&var_30) && ShowDungeonItemsMenu(GetLeader(), &var_30)) { - SetLeaderActionToNothing(1); - } - - action = GetLeaderActionId(); - if (action == 0xC) { - sub_8044D90(GetLeader(), 0, 0x10)->flags |= ITEM_FLAG_UNPAID; - sub_8060D24(GetLeaderActionContainer()); - SetLeaderActionToNothing(1); - } - else if (action == 0x35) { - item = sub_8044D90(GetLeader(), 0, 0x11); - if (!sub_8048A68(GetLeader(), item)) { - SetLeaderActionToNothing(1); - } - } - else if (action == 0x10) { - item = sub_8044D90(GetLeader(), 0, 0x12); - if (!sub_8048950(GetLeader(), item)) { - SetLeaderActionToNothing(1); - } - } - else if (action == 0x2C) { - item = sub_8044D90(GetLeader(), 0, 0x13); - if (!sub_8048B9C(GetLeader(), item)) { - SetLeaderActionToNothing(1); - } - } - if (GetLeaderActionId() != 0) - break; - } - else if (GetEntityType(tileObject) == ENTITY_TRAP) { - SetLeaderActionToNothing(1); - sub_80643AC(GetLeader()); - if (GetLeaderActionId() != 0) - break; - } - } - else - { - if (tile->terrainType & TERRAIN_TYPE_STAIRS) { - SetLeaderActionToNothing(1); - ShowDungeonStairsMenu(GetLeader()); - if (GetLeaderActionId() != 0) - break; - } - else { - SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], GetLeader(), 0); - DisplayDungeonMessage(0, gUnknown_80FDE18, 1); - } - } - r10 = -1; - } - else if (chosenOption == MAIN_MENU_OTHERS) { - ShowDungeonOthersMenu(); - if (gDungeon->unk4) - break; - if (GetLeaderActionId() != 0) - break; - r10 = -1; - } - - // B button - if (chosenOption < 0) - break; - - if (var_24 == 0) { - ResetRepeatTimers(); - ResetUnusedInputStruct(); - } - else { - sub_806A2BC(GetLeader(), 0); - break; - } - } - - sub_803EAF0(0, NULL); - ResetRepeatTimers(); - ResetUnusedInputStruct(); -} - extern const u8 *const gFieldMenuMovesPtr; extern const u8 *const gFieldMenuItemsPtr; extern const u8 *const gFieldMenuTeamPtr; @@ -1557,210 +153,23 @@ extern const u8 *const gUnknown_80F91E0; extern const u8 *const gUnknown_80F91A8; extern const u8 *const gUnknown_80FE954; -const u8 *GetCurrentDungeonName(void); -void GetWeatherName(u8 *dst, u8 weatherId); - -extern s32 gFormatArgs[]; - -void PrintOnMainMenu(bool8 printAll) -{ - s32 i, x, y, yLoop; - - gDungeonMenu.menuIndex = 0; - gDungeonMenu.unk1A = 5; - gDungeonMenu.unk1C = 5; - gDungeonMenu.unk1E = 0; - gDungeonMenu.unk4 = 0; - gDungeonMenu.firstEntryY = 2; - gDungeonMenu.unkC = 0; - gDungeonMenu.unkE = 0; - gDungeonMenu.unk0 = 0; - gDungeonMenu.unk14.x = 0; - sub_801317C(&gDungeonMenu.unk28); - sub_80137B0(&gDungeonMenu, 0x38); - if (printAll) { - sub_803EAF0(7, NULL); - } - else { - sub_803EAF0(6, NULL); - } - - sub_80073B8(0); - if (ShouldMonsterRunAwayAndShowEffect(GetLeader(), TRUE)) { - gUnknown_202749A[1] = 2; - gUnknown_202749A[2] = 2; - gUnknown_202749A[3] = 2; - gUnknown_202749A[4] = 7; - gUnknown_202749A[5] = 2; - } - else - { - gUnknown_202749A[1] = 7; - gUnknown_202749A[2] = 7; - gUnknown_202749A[3] = 7; - gUnknown_202749A[4] = 7; - gUnknown_202749A[5] = 7; - } - - y = GetMenuEntryYCoord(&gDungeonMenu, 0); - PrintStringOnWindow(8, y, gFieldMenuMovesPtr, 0, 0); - - y = GetMenuEntryYCoord(&gDungeonMenu, 1); - PrintStringOnWindow(8, y, gFieldMenuItemsPtr, 0, 0); - - y = GetMenuEntryYCoord(&gDungeonMenu, 2); - PrintStringOnWindow(8, y, gFieldMenuTeamPtr, 0, 0); - - y = GetMenuEntryYCoord(&gDungeonMenu, 3); - PrintStringOnWindow(8, y, gFieldMenuOthersPtr, 0, 0); - - y = GetMenuEntryYCoord(&gDungeonMenu, 4); - PrintStringOnWindow(8, y, gFieldMenuGroundPtr, 0, 0); - - sub_80073E0(0); - if (printAll) { - u32 hours, minutes, seconds; - EntityInfo *leaderInfo = GetEntInfo(GetLeader()); - const u8 *dungeonName = GetCurrentDungeonName(); - - x = (136 - sub_8008ED0(dungeonName)) / 2; - sub_80073B8(1); - PrintStringOnWindow(x, 2, dungeonName, 1, 0); - sub_80073E0(1); - sub_80073B8(2); - DeconstructPlayTime(gPlayTimeRef, &hours, &minutes, &seconds); - - gFormatArgs[0] = FixedPointToInt(leaderInfo->belly); - gFormatArgs[1] = FixedPointToInt(leaderInfo->maxBelly); - PrintFormattedStringOnWindow(0x73, 0, gUnknown_80F9174, 2, 0); - - gFormatArgs[0] = gTeamInventoryRef->teamMoney; - PrintFormattedStringOnWindow(0x73, 12, gUnknown_80F9190, 2, 0); - - GetWeatherName(gFormatBuffer_Monsters[0], GetApparentWeather(NULL)); - PrintFormattedStringOnWindow(0x73, 24, gUnknown_80F91A8, 2, 0); - - gFormatArgs[0] = hours; - gFormatArgs[1] = minutes; - gFormatArgs[2] = seconds; - PrintFormattedStringOnWindow(0x73, 36, gUnknown_80F91C8, 2, 0); - for (yLoop = 0, i = 0; i < MAX_TEAM_MEMBERS; i++) { - Entity *teamMon = gDungeon->teamPokemon[i]; - if (EntityIsValid(teamMon)) { - EntityInfo *monInfo = GetEntInfo(teamMon); - SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], teamMon, 0); - gFormatArgs[0] = monInfo->HP; - gFormatArgs[1] = monInfo->maxHPStat; - PrintFormattedStringOnWindow(4, yLoop, gUnknown_80F91E0, 2, 0); - yLoop += 12; - if (yLoop >= 12 * MAX_TEAM_MEMBERS) - break; - } - } - sub_80073E0(2); - } -} - -bool8 sub_805FBE8(u8 *a0) -{ - s32 r4; - sub_803EAF0(8, a0); - do - { - DungeonRunFrameActions(0xE); - DrawDialogueBoxString(); - r4 = sub_8016080(); - } while (r4 == 0); - CleanConfirmNameMenu(); - DungeonRunFrameActions(0xE); - sub_803EAF0(0, NULL); - if (r4 == 3 && *a0 != 0) - return TRUE; - - return FALSE; -} - -extern u8 *sub_8044EC8(s32 param_1); -extern bool8 sub_8044F3C(s32 param_1); -extern s32 gUnknown_202EE6C; +extern bool8 sub_8070F14(Entity * pokemon, s32 direction); +bool8 sub_805EC2C(Entity *a0, s32 x, s32 y); +extern Entity *sub_80696A8(Entity *a0); +extern u8 sub_806A538(s32); +extern void sub_803EAF0(u32, u8 *); +extern void sub_803F508(Entity *); +extern void sub_8041AD0(Entity *pokemon); +extern void sub_8041AE0(Entity *pokemon); +extern void sub_807EC28(bool8); +extern void PlayDungeonCursorSE(u8 param_1); +extern u8 *GetDungeonSubMenuItemString(s32 param_1); +extern bool8 CanSubMenuItemBeChosen(s32 param_1); +extern s32 gDungeonSubMenuItemsCount; extern const u8 gUnknown_8106B50[]; - extern void DungeonShowWindows(Windows *a0, u8 a1); -static void PrintOnDungeonItemsMenu(s32 a0, Entity *a1, bool8 a2, bool8 a3, Windows *a4, WindowHeader *a5); -void CreateDungeonMenuSubWindow(Window *mainWindow, s32 subWindowX) -{ - s32 i; - Windows windows = { - .id = { - [0] = WINDOW_DUMMY, - [1] = { - .type = WINDOW_TYPE_NORMAL, - .pos = {22, 4}, - .width = 6, - .height = 4, - .unk10 = 4, - }, - [2] = WINDOW_DUMMY, - [3] = WINDOW_DUMMY, - } - }; - - windows.id[0] = *mainWindow; - windows.id[0].unk0 = 0x80; - - gDungeonMenu.menuIndex = 0; - gDungeonMenu.unk1C = gUnknown_202EE6C; - gDungeonMenu.unk1A = gUnknown_202EE6C; - gDungeonMenu.unk1E = 0; - gDungeonMenu.unk20 = 0; - gDungeonMenu.unk4 = 0; - gDungeonMenu.firstEntryY = 0; - gDungeonMenu.unk0 = 1; - gDungeonMenu.unkC = 0; - gDungeonMenu.unkE = 0; - gDungeonMenu.unk14 = gDungeonMenu.unk8; - - sub_801317C(&gDungeonMenu.unk28); - - windows.id[1].pos.x = subWindowX; - windows.id[1].width = 28 - subWindowX; - windows.id[1].height = windows.id[1].unk10 = sub_80095E4(gDungeonMenu.unk1C, 0); - DungeonShowWindows(&windows, FALSE); - sub_80137B0(&gDungeonMenu, windows.id[1].height * 8); - sub_80073B8(1); - - for (i = 0; i < gUnknown_202EE6C; i++) { - s32 colorId, y; - u8 text[20]; - - colorId = (sub_8044F3C(i) != 0) ? 7 : 2; - sprintfStatic(text, gUnknown_8106B50, colorId, sub_8044EC8(i)); - y = GetMenuEntryYCoord(&gDungeonMenu, i); - PrintStringOnWindow(8, y, text, 1, 0); - } - sub_80073E0(1); -} - -bool8 sub_805FD3C(struct UnkMenuBitsStruct *a0) -{ - u16 action = GetLeaderActionId(); - - a0->a0_8 = 0; - a0->a0_16 = 0; - a0->a0_24 = 0; - a0->a0_32 = 0; - if (action == 0xA) { - a0->a0_8 = 1; - a0->a0_32 = 1; - } - if (action == 0x3E) { - a0->a0_8 = 1; - a0->a0_16 = 0; - a0->a0_32 = 1; - } - return a0->a0_8; -} +extern MenuInputStruct gDungeonMenu; s32 sub_8060D64(s16 *a0, bool8 a1, bool8 a2, bool8 a3, Entity *a4); @@ -1768,9 +177,22 @@ void sub_8060890(DungeonPos *a0); bool8 sub_8060860(s32 a0); void sub_8060900(Entity *a0); s32 sub_8060800(WindowHeader *a0, s32 a1); -void sub_8060CE8(ActionContainer *a0); +void ChosenSubMenuToAction(ActionContainer *a0); Entity *DrawFieldGiveItemMenu(s32 *teamId, s32 a1); +// Could this be a start of a new file? +static UNUSED EWRAM_DATA u8 sUnused[4] = {0}; +static EWRAM_DATA ActionParameter sUnknownActionUnk4 = {0}; +static EWRAM_DATA s32 sUnknown_202F240 = 0; +static UNUSED EWRAM_DATA u8 sUnused2[4] = {0}; +static EWRAM_DATA s16 sUnknown_202F248[8] = {0}; +static EWRAM_DATA s32 sUnknown_202F258 = 0; +static UNUSED EWRAM_DATA u8 sUnused3[4] = {0}; +EWRAM_DATA s32 gTeamMenuChosenId = 0; +static UNUSED EWRAM_DATA u8 sUnused4[4] = {0}; + +static void PrintOnDungeonItemsMenu(s32 a0, Entity *a1, bool8 a2, bool8 a3, Windows *a4, WindowHeader *a5); + bool8 ShowDungeonItemsMenu(Entity * a0, struct UnkMenuBitsStruct *a1) { s32 i, i_r6; @@ -1990,9 +412,9 @@ bool8 ShowDungeonItemsMenu(Entity * a0, struct UnkMenuBitsStruct *a1) MoveMenuCursorUpWrapAround(&gDungeonMenu, TRUE); } if ((gRealInputs.pressed & A_BUTTON) || gDungeonMenu.unk28.a_button) { - if (sub_8044F3C(gDungeonMenu.menuIndex)) { + if (CanSubMenuItemBeChosen(gDungeonMenu.menuIndex)) { PlayDungeonConfirmationSE(); - sub_8060CE8(&a0Info->action); + ChosenSubMenuToAction(&a0Info->action); r9 = 0; break; } @@ -2271,7 +693,7 @@ void sub_8060900(Entity *a0) Item *item = sub_8044CC8(a0, &sUnknownActionUnk4, 0xA); EntityInfo *a0Info = GetEntInfo(a0); - gUnknown_202EE6C = 0; + gDungeonSubMenuItemsCount = 0; if (sUnknownActionUnk4.actionUseIndex < 144) { if (sUnknownActionUnk4.actionUseIndex == 128) { sub_8044F5C(9, item->id); @@ -2451,7 +873,7 @@ void sub_8060900(Entity *a0) sub_8045064(); } -void sub_8060CE8(ActionContainer *a0) +void ChosenSubMenuToAction(ActionContainer *a0) { SetMonsterActionFields(a0, gUnknown_202EE44[gDungeonMenu.menuIndex].unk0); a0->actionParameters[0] = sUnknownActionUnk4; @@ -2618,7 +1040,7 @@ bool8 ShowDungeonTeamMenu(Entity *a0) } sp.unk0 = gDungeonMenu.menuIndex; - sTeamMenuChosenId = gDungeonMenu.menuIndex; + gTeamMenuChosenId = gDungeonMenu.menuIndex; sub_806145C(&sp); if (r10) { EntityInfo *info = GetEntInfo(a0); @@ -2641,7 +1063,7 @@ bool8 ShowDungeonTeamMenu(Entity *a0) MoveMenuCursorUpWrapAround(&gDungeonMenu, TRUE); } if ((gRealInputs.pressed & A_BUTTON) || gDungeonMenu.unk28.a_button) { - if (sub_8044F3C(gDungeonMenu.menuIndex)) { + if (CanSubMenuItemBeChosen(gDungeonMenu.menuIndex)) { sub_80615B4(&GetEntInfo(a0)->action, &sp); PlayDungeonConfirmationSE(); r4 = FALSE; @@ -2705,18 +1127,18 @@ void PrintOnDungeonTeamMenu(struct UnkFieldTeamMenuStruct *a0, Windows *windows, a0->unk4[count] = i; monInfo = GetEntInfo(teamMon); a0->unk14[count] = monInfo->unk157; - if (pos.x == teamMon->pos.x && pos.y == teamMon->pos.y && sTeamMenuChosenId < 0) { - sTeamMenuChosenId = count; + if (pos.x == teamMon->pos.x && pos.y == teamMon->pos.y && gTeamMenuChosenId < 0) { + gTeamMenuChosenId = count; } count++; } } - if (sTeamMenuChosenId >= count) { - sTeamMenuChosenId = count - 1; + if (gTeamMenuChosenId >= count) { + gTeamMenuChosenId = count - 1; } - if (sTeamMenuChosenId < 0) { - sTeamMenuChosenId = 0; + if (gTeamMenuChosenId < 0) { + gTeamMenuChosenId = 0; } for (i = count; i < MAX_TEAM_MEMBERS; i++) { @@ -2727,7 +1149,7 @@ void PrintOnDungeonTeamMenu(struct UnkFieldTeamMenuStruct *a0, Windows *windows, gUnknown_202F270.f0 = 1; gUnknown_202F270.f1 = 0; gUnknown_202F270.f3 = 0; - gDungeonMenu.menuIndex = sTeamMenuChosenId; + gDungeonMenu.menuIndex = gTeamMenuChosenId; gDungeonMenu.unk1A = count; gDungeonMenu.unk1C = count; gDungeonMenu.unk1E = 0; @@ -2821,7 +1243,7 @@ void sub_806145C(struct UnkFieldTeamMenuStruct *a0) Entity *teamMon; EntityInfo *monInfo; - gUnknown_202EE6C = 0; + gDungeonSubMenuItemsCount = 0; teamMon = gDungeon->teamPokemon[a0->unk4[gDungeonMenu.menuIndex]]; monInfo = GetEntInfo(teamMon); sub_8044F5C(0x1B, 0); @@ -2994,7 +1416,7 @@ void ShowTacticsMenu(ActionContainer *a0) menuIndex = gDungeonMenu.menuIndex; sub_8062D68(); PlayDungeonConfirmationSE(); - gUnknown_202EE6C = 0; + gDungeonSubMenuItemsCount = 0; sub_8044F5C(0x2F, 0); sub_8044F5C(0xC, 0); if (CheckVariousStatuses2(teamMon, TRUE)) { @@ -3014,7 +1436,7 @@ void ShowTacticsMenu(ActionContainer *a0) MoveMenuCursorUpWrapAround(&gDungeonMenu, TRUE); } if ((gRealInputs.pressed & A_BUTTON) || gDungeonMenu.unk28.a_button) { - if (sub_8044F3C(gDungeonMenu.menuIndex)) { + if (CanSubMenuItemBeChosen(gDungeonMenu.menuIndex)) { changed = TRUE; break; } @@ -3452,7 +1874,7 @@ void sub_8061A38(ActionContainer *a0, bool8 a1) r8 = gDungeonMenu.menuIndex; sub_8062D68(); - gUnknown_202EE6C = 0; + gDungeonSubMenuItemsCount = 0; PlayDungeonConfirmationSE(); sub_8044F5C(0xC, 0); CreateDungeonMenuSubWindow(&windows.id[0], 0x16); @@ -3488,7 +1910,7 @@ void sub_8061A38(ActionContainer *a0, bool8 a1) r8 = gDungeonMenu.menuIndex; sub_8062D68(); - gUnknown_202EE6C = var_2C; + gDungeonSubMenuItemsCount = var_2C; PlayDungeonConfirmationSE(); sub_8044F5C(0x28, 0); sub_8044F5C(0xC, 0); @@ -3509,7 +1931,7 @@ void sub_8061A38(ActionContainer *a0, bool8 a1) } if ((gRealInputs.pressed & A_BUTTON) || gDungeonMenu.unk28.a_button) { - if (sub_8044F3C(gDungeonMenu.menuIndex)) { + if (CanSubMenuItemBeChosen(gDungeonMenu.menuIndex)) { PlayDungeonConfirmationSE(); aPress = TRUE; break; @@ -4295,9 +2717,9 @@ bool8 ShowDungeonMovesMenu(Entity * entity, u8 a1, u8 a2, s32 a3, s32 a4) sub_8063698(entity, a1, a2); if (r5 == 3) { s32 r6 = sub_8044FB4(0x20); - if (!sub_8044F3C(r6)) { + if (!CanSubMenuItemBeChosen(r6)) { r6 = sub_8044FB4(0x21); - if (sub_8044F3C(r6)) { + if (CanSubMenuItemBeChosen(r6)) { sub_80637BC(&leaderInfo->action, r6, GetTeamMemberEntityIndex(entity)); break; } @@ -4310,9 +2732,9 @@ bool8 ShowDungeonMovesMenu(Entity * entity, u8 a1, u8 a2, s32 a3, s32 a4) else if (r5 == 2) { if (entInfo->isTeamLeader) { s32 r6 = sub_8044FB4(0x1E); - if (!sub_8044F3C(r6)) { + if (!CanSubMenuItemBeChosen(r6)) { r6 = sub_8044FB4(0x33); - if (sub_8044F3C(r6)) { + if (CanSubMenuItemBeChosen(r6)) { sub_80637BC(&leaderInfo->action, r6, GetTeamMemberEntityIndex(entity)); break; } @@ -4324,7 +2746,7 @@ bool8 ShowDungeonMovesMenu(Entity * entity, u8 a1, u8 a2, s32 a3, s32 a4) } else { s32 r6 = sub_8044FB4(0x1F); - if (sub_8044F3C(r6)) { + if (CanSubMenuItemBeChosen(r6)) { sub_80637BC(&leaderInfo->action, r6, GetTeamMemberEntityIndex(entity)); break; } @@ -4346,7 +2768,7 @@ bool8 ShowDungeonMovesMenu(Entity * entity, u8 a1, u8 a2, s32 a3, s32 a4) } if ((gRealInputs.pressed & sub_8062D88()) || gDungeonMenu.unk28.a_button) { - if (sub_8044F3C(gDungeonMenu.menuIndex)) { + if (CanSubMenuItemBeChosen(gDungeonMenu.menuIndex)) { sub_80637A4(&leaderInfo->action, GetTeamMemberEntityIndex(entity)); if (leaderInfo->action.action != 20 && leaderInfo->action.action != 21) { PlayDungeonConfirmationSE(); @@ -4491,7 +2913,7 @@ void sub_8063698(Entity *entity, u8 a1, u8 a2) EntityInfo *entInfo = GetEntInfo(entity); Move *move = &entInfo->moves.moves[gUnknown_202F2D8]; - gUnknown_202EE6C = 0; + gDungeonSubMenuItemsCount = 0; if (entInfo->isTeamLeader) { if (a2) { sub_8044F5C(0x14, 0); @@ -4548,4 +2970,22 @@ void sub_80637A4(ActionContainer *a0, s32 a1) sub_80637BC(a0, gDungeonMenu.menuIndex, a1); } +void sub_80637BC(ActionContainer *a0, s32 a1, s32 a2) +{ + SetMonsterActionFields(a0, gUnknown_202EE44[a1].unk0); + a0->actionParameters[0].actionUseIndex = a2; + a0->actionParameters[1].actionUseIndex = gUnknown_202F2D8; +} + +void sub_8063834(Move *moves, s32 a1, s32 a2); + +void sub_80637E8(ActionContainer *a0) +{ + Entity *mon = gDungeon->teamPokemon[a0->actionParameters[0].actionUseIndex]; + EntityInfo *monInfo = GetEntInfo(mon); + + monInfo->moves.moves[a0->actionParameters[1].actionUseIndex].moveFlags2 |= 2; + sub_8063834(monInfo->moves.moves, a0->actionParameters[1].actionUseIndex, 4); +} + // diff --git a/src/code_8066D04.c b/src/code_8066D04.c index 020a8dcff..5f0810331 100644 --- a/src/code_8066D04.c +++ b/src/code_8066D04.c @@ -76,7 +76,7 @@ extern const u8 *const gMonCringing; extern const u8 *const gMonParalyzed; extern const u8 *const gUnknown_80FC690; -extern s32 gUnknown_202EE6C; +extern s32 gDungeonSubMenuItemsCount; extern u32 gUnknown_202F208; extern void sub_8071DA4(Entity *); @@ -901,7 +901,7 @@ extern void sub_80684C4(void); void sub_8045064(void); extern void PlayDungeonCursorSE(u8 param_1); extern void sub_8068344(void); -bool8 sub_8044F3C(s32 param_1); +bool8 CanSubMenuItemBeChosen(s32 param_1); void sub_8068310(s32 a0, PokemonStruct1 **a1); void sub_8067F00(u8 a0, PokemonStruct1 **a1, s32 a2, s32 a3, s32 a4); extern void DungeonShowWindows(Windows *a0, u8 a1); @@ -1124,7 +1124,7 @@ void sub_8067A80(u8 a0, s32 a1, s32 a2, PokemonStruct1 **a3) r10 = gDungeonMenu.menuIndex; arrId = gUnknown_202F30C + r10; - gUnknown_202EE6C = 0; + gDungeonSubMenuItemsCount = 0; sub_8044F5C(0x29, 0); sub_8044F5C(0x2A, 0); sub_8044F5C(0x40, 0); @@ -1158,7 +1158,7 @@ void sub_8067A80(u8 a0, s32 a1, s32 a2, PokemonStruct1 **a3) } if ((gRealInputs.pressed & A_BUTTON) || gDungeonMenu.unk28.a_button) { - if (sub_8044F3C(gDungeonMenu.menuIndex)) { + if (CanSubMenuItemBeChosen(gDungeonMenu.menuIndex)) { PlayDungeonConfirmationSE(); r7 = 1; break; diff --git a/src/dungeon_main.c b/src/dungeon_main.c new file mode 100644 index 000000000..c775ce053 --- /dev/null +++ b/src/dungeon_main.c @@ -0,0 +1,1748 @@ +#include "global.h" +#include "structs/str_dungeon.h" +#include "number_util.h" +#include "input.h" +#include "structs/map.h" +#include "dungeon_main.h" +#include "dungeon_message.h" +#include "dungeon_action.h" +#include "dungeon_ai_targeting.h" +#include "dungeon_pokemon_attributes.h" +#include "dungeon_random.h" +#include "dungeon_util.h" +#include "pokemon.h" +#include "moves.h" +#include "items.h" +#include "dungeon_music.h" +#include "dungeon_ai_movement.h" +#include "code_8045A00.h" +#include "string_format.h" +#include "code_803E46C.h" +#include "code_801602C.h" +#include "code_800D090.h" +#include "trap.h" +#include "charge_move.h" +#include "dungeon_map_access.h" +#include "status_checks_1.h" +#include "game_options.h" +#include "weather.h" +#include "dungeon_items.h" +#include "dungeon_leader.h" +#include "tile_types.h" +#include "dungeon_visibility.h" +#include "dungeon_movement.h" +#include "bg_control.h" +#include "menu_input.h" +#include "music.h" +#include "items.h" +#include "play_time.h" +#include "pokemon_3.h" +#include "text.h" +#include "code_806CD90.h" +#include "code_8044CC8.h" +#include "code_801B3C0.h" +#include "dungeon_capabilities.h" +#include "constants/dungeon.h" +#include "constants/status.h" +#include "constants/tactic.h" +#include "constants/iq_skill.h" +#include "constants/dungeon_action.h" +#include "structs/struct_sub80095e4.h" +#include "structs/str_text.h" + +struct UnkMenuBitsStruct { + u8 a0_8; + u8 a0_16; + u8 a0_24; + u8 a0_32; +}; + +extern void HandleSetItemAction(Entity *,bool8); +extern void HandleUnsetItemAction(Entity *,bool8); +extern bool8 sub_8048A68(Entity *param_1,Item *item); +extern bool8 sub_8048950(Entity *param_1,Item *item); +extern bool8 sub_8048B9C(Entity *param_1,Item *item); +extern Item *sub_8044D90(Entity *, s32, u32); +extern void PlayDungeonStartButtonSE(void); +extern void PlayDungeonCancelSE(void); +extern void PlayDungeonConfirmationSE(void); +extern void sub_806A6E8(Entity *); +extern bool8 sub_8047084(s32 itemFlag); +extern void HandleTrap(Entity *pokemon, DungeonPos *pos, int param_3, char param_4); +extern void sub_8045DB4(DungeonPos *, u32); +bool8 sub_807EF48(void); +void sub_806A2BC(Entity *a0, u8 a1); +bool8 sub_80701A4(Entity *a0); +void ShowDungeonStairsMenu(Entity *a0); +void sub_803E708(s32 a0, s32 a1); +void sub_8040A78(void); +void ShowDungeonOthersMenu(void); +void sub_8075680(u32); +void sub_8094C88(void); +void sub_8040A84(void); +void sub_8047158(void); +void sub_806A914(u8 a0, u8 a1, u8 a2); +void SetLeaderActionToNothing(u8 a0); +u16 GetLeaderActionId(void); +void sub_80978C8(s16 a0); +static void TryCreateModeArrows(Entity *leader); +bool8 sub_8094C48(void); +void sub_803E724(s32 a0); +void HandleTalkFieldAction(Entity *); +bool8 sub_8044B28(void); +bool8 IsNotAttacking(Entity *param_1, bool8 param_2); +s32 GetTeamMemberEntityIndex(Entity *pokemon); +bool8 sub_8070F80(Entity * pokemon, s32 direction); +bool8 ShowDungeonItemsMenu(Entity * a0, struct UnkMenuBitsStruct *a1); +void sub_8060D24(UNUSED ActionContainer *a0); +bool8 ShowDungeonTeamMenu(Entity *a0); +void sub_8062D8C(ActionContainer *a0); +void sub_80637E8(ActionContainer *a0); +void sub_8063B54(ActionContainer *a0); +void sub_8063BB4(ActionContainer *a0); +void sub_806752C(ActionContainer *a0); +void sub_8061A38(ActionContainer *a0, bool8 a1); +void sub_8063A70(ActionContainer *a0, bool8 a1); +void sub_8063CF0(ActionContainer *a0, bool8 a1); +void sub_8067768(ActionContainer *a0); +void ShowTacticsMenu(ActionContainer *a0); +void ChangeDungeonCameraPos(DungeonPos *pos, s32 a1, u8 a2, u8 a3); +extern bool8 sub_8071A8C(Entity *pokemon); +extern void sub_80643AC(Entity *pokemon); +extern bool8 ShowDungeonMovesMenu(Entity * entity, u8 a1, u8 a2, s32 a3, s32 a4); + +extern u8 gUnknown_202EE00; +extern Entity *gLeaderPointer; + +extern const u8 *gUnknown_80F8A84; +extern const u8 *gUnknown_80F8A6C; +extern const u8 *gUnknown_80F8ADC; +extern const u8 *gUnknown_80F8AB0; +extern const u8 *gUnknown_80F8B0C; +extern const u8 *gUnknown_80FD4B0; +extern const u8 *gUnknown_80F8A4C; +extern const u8 *gUnknown_80F8A28; +extern const u8 *gUnknown_8100208; +extern const u8 *gUnknown_80F9BD8; +extern const u8 *gUnknown_80F9C08; +extern const u8 *gUnknown_80F9C2C; +extern const u8 *gUnknown_80F9BB0; +extern const u8 *gUnknown_80FDE18; +extern const u8 *gUnknown_80F8B24; +extern const u8 *gTeamToolboxAPtr; +extern const u8 *gTeamToolboxBPtr; +extern const u8 *gFieldItemMenuGroundTextPtr; +extern const u8 *gUnknown_80FE940; +extern const u8 *gWhichTextPtr1; + +extern const u8 *const gFieldMenuMovesPtr; +extern const u8 *const gFieldMenuItemsPtr; +extern const u8 *const gFieldMenuTeamPtr; +extern const u8 *const gFieldMenuOthersPtr; +extern const u8 *const gFieldMenuGroundPtr; +extern const u8 *const gUnknown_80F9174; +extern const u8 *const gUnknown_80F9190; +extern const u8 *const gUnknown_80F91C8; +extern const u8 *const gUnknown_80F91E0; +extern const u8 *const gUnknown_80F91A8; +extern const u8 *const gUnknown_80FE954; + +const u8 *GetCurrentDungeonName(void); +void GetWeatherName(u8 *dst, u8 weatherId); +extern u8 *GetDungeonSubMenuItemString(s32 param_1); +extern bool8 CanSubMenuItemBeChosen(s32 param_1); +extern s32 gDungeonSubMenuItemsCount; +extern const u8 gUnknown_8106B50[]; + +extern void DungeonShowWindows(Windows *a0, u8 a1); + +extern bool8 sub_8070F14(Entity * pokemon, s32 direction); +extern Entity *sub_80696A8(Entity *a0); +extern u8 sub_806A538(s32); +extern void sub_803EAF0(u32, u8 *); +extern void sub_803F508(Entity *); +extern void sub_8041AD0(Entity *pokemon); +extern void sub_8041AE0(Entity *pokemon); +extern void sub_807EC28(bool8); +extern void PlayDungeonCursorSE(u8 param_1); + +extern MenuInputStruct gDungeonMenu; +extern s32 gTeamMenuChosenId; + +static EWRAM_DATA bool8 sInDiagonalMode = 0; +static EWRAM_DATA bool8 sInRotateMode = 0; +// Frames counter for arrows in diagonal/rotate mode. +static EWRAM_DATA s16 sArrowsFrames = 0; +// If both of these are set to TRUE, there are 3 arrows visible instead of 1 in rotate mode +static EWRAM_DATA bool8 sShowThreeArrows1 = 0; +static EWRAM_DATA bool8 sShowThreeArrows2 = 0; + +static void sub_805E738(Entity *a0); +static bool8 sub_805E874(void); +static bool8 sub_805EC2C(Entity *a0, s32 x, s32 y); +static bool8 sub_805EC4C(Entity *a0, u8 a1); +static bool8 sub_805EF60(Entity *a0, EntityInfo *a1); +static void ShowMainMenu(bool8 fromBPress, bool8 a1); +static void PrintOnMainMenu(bool8 printAll); +static bool8 sub_805FD3C(struct UnkMenuBitsStruct *a0); + +void DungeonHandlePlayerInput(void) +{ + struct UnkMenuBitsStruct r6; + bool8 triggers[5]; // Always FALSE, if one of these is TRUE - they can open various menus or cause an item throw. Most likely used for debugging/testing. + s32 frames; + s32 var_38; + UnkDungeonGlobal_unk181E8_sub *unkPtr; + + unkPtr = &gDungeon->unk181e8; + var_38 = 3; + gDungeon->unk12 = 0; + sub_806A2BC(GetLeader(), 1); + if (sub_80701A4(GetLeader())) { + sub_803E708(60, 16); + return; + } + + gDungeon->unk644.unk2F = 0; + sub_8040A78(); + if (gDungeon->unk1 != 0) { + gDungeon->unk1 = 0; + if (!ShouldMonsterRunAwayAndShowEffect(GetLeader(), TRUE)) { + SetLeaderActionToNothing(TRUE); + sub_805E804(); + ShowDungeonStairsMenu(GetLeader()); + ResetRepeatTimers(); + ResetUnusedInputStruct(); + if (GetLeaderActionId() != 0) { + return; + } + } + } + + sub_806A914(1, 1, 1); + while (1) { + Entity *leader = GetLeader(); + EntityInfo *leaderInfo = GetEntInfo(leader); + + sub_80978C8(leaderInfo->id); + if (gDungeon->unk644.unk28 != 0) { + if (sub_805E874()) { + leaderInfo->action.action = 2; + leaderInfo->action.actionParameters[0].actionUseIndex = 0; + break; + } + sub_805E804(); + } + sInRotateMode = FALSE; + sInDiagonalMode = FALSE; + if (gDungeon->unk5C0 >= 0) { + r6.a0_8 = 1; + r6.a0_16 = 0; + r6.a0_24 = 0; + } + else { + r6.a0_8 = 0; + r6.a0_16 = 0; + r6.a0_24 = 0; + } + + frames = 0; + sub_8044C50(ACTION_NOTHING); + sShowThreeArrows1 = FALSE; + sShowThreeArrows2 = FALSE; + + while (r6.a0_8 == 0) { + u32 dpadDiagonal, dpadSimple; + bool32 highlightTiles, tryItemThrow; + bool32 bPress, rPress, unkBool; // Always FALSE, might've been used as debug variables. + s32 directionNew; + + sArrowsFrames++; + if (unkPtr->unk1821A != 0) { + frames = 0; + } + else { + frames++; + } + + if (var_38 != 0 && --var_38 == 0) { + sub_8075680(0); + } + + TryCreateModeArrows(leader); + unkBool = FALSE; + { + s32 i; + for (i = 0; i < 5; i++) { + triggers[i] = FALSE; + } + } + + if (gRealInputs.held & A_BUTTON && gRealInputs.held & B_BUTTON && FixedPointToInt(leaderInfo->belly) != 0) { + sub_8044C50(ACTION_PASS_TURN); + gDungeon->unk644.unk2F = 1; + break; + } + + bPress = FALSE; + rPress = FALSE; + + if (gRealInputs.pressed & A_BUTTON) { + if (gRealInputs.held & B_BUTTON) { + if (FixedPointToInt(leaderInfo->belly) != 0) { + sub_8044C50(ACTION_PASS_TURN); + gDungeon->unk644.unk2F = 1; + break; + } + } + else if (ShouldMonsterRunAwayAndShowEffect(leader, TRUE)) { + LogMessageByIdWithPopupCheckUser(leader, gUnknown_80FD4B0); + sub_8044C50(ACTION_PASS_TURN); + gDungeon->unk644.unk2F = 1; + break; + } + else if (gRealInputs.held & L_BUTTON) { + bool32 canUseMove; + s32 i, j; + + for (i = 0; i < MAX_MON_MOVES; i++) { + if (MoveFlagExists(&leaderInfo->moves.moves[i]) && MoveFlagSet(&leaderInfo->moves.moves[i])) { + break; + } + } + if (i == MAX_MON_MOVES) { + LogMessageByIdWithPopupCheckUser(leader, gUnknown_80F8A28); + break; + } + + for (j = 0; j < MAX_MON_MOVES; j++) { + if (MoveFlagExists(&leaderInfo->moves.moves[j])) { + if (leaderInfo->moves.moves[j].PP != 0) + break; + } + } + if (j == MAX_MON_MOVES) { + SetMonsterActionFields(&leaderInfo->action, ACTION_STRUGGLE); + break; + } + + canUseMove = FALSE; + for (j = i; j < MAX_MON_MOVES; j++) { + if (j != i && !(leaderInfo->moves.moves[j].moveFlags & MOVE_FLAG_SUBSEQUENT_IN_LINK_CHAIN)) { + break; + } + if (leaderInfo->moves.moves[j].PP != 0) { + canUseMove = TRUE; + break; + } + } + if (!canUseMove) { + LogMessageByIdWithPopupCheckUser(leader, gUnknown_80F8A4C); + } + else { + SetMonsterActionFields(&leaderInfo->action, ACTION_USE_MOVE_PLAYER); + leaderInfo->action.actionParameters[0].actionUseIndex = GetTeamMemberEntityIndex(leader); + leaderInfo->action.actionParameters[1].actionUseIndex = i; + } + break; + } + else { + if (!sub_805EF60(leader, leaderInfo)) { + SetMonsterActionFields(&leaderInfo->action, ACTION_REGULAR_ATTACK); + } + break; + } + } + + if (gRealInputs.shortPress & B_BUTTON) { + r6.a0_8 = 1; + r6.a0_16 = 0; + r6.a0_24 = 0; + break; + } + else if (triggers[1]) { // Opens moves menu + gDungeon->unk5C0 = 0; + r6.a0_8 = 1; + r6.a0_16 = 0; + r6.a0_24 = 1; + break; + } + else if (triggers[2]) { // Opens item menu + gDungeon->unk5C0 = 1; + r6.a0_8 = 1; + r6.a0_16 = 0; + r6.a0_24 = 1; + break; + } + else if (triggers[3]) { // Opens pokemon menu + gDungeon->unk5C0 = 2; + r6.a0_8 = 1; + r6.a0_16 = 0; + r6.a0_24 = 1; + break; + } + else if (triggers[4]) { // Opens regular menu + r6.a0_8 = 1; + r6.a0_16 = 0; + r6.a0_24 = 1; + break; + } + else if (frames > 0x707) { // Opens simple menu when idling + r6.a0_8 = 1; + r6.a0_16 = 1; + r6.a0_24 = 0; + break; + } + + if (gGameOptionsRef->unk9 == 0 + && (gRealInputs.pressed & B_BUTTON || (!unkBool && bPress)) + && unkPtr->unk1821A != 0) + { + sub_804AA60(); + sInRotateMode = FALSE; + ResetRepeatTimers(); + ResetUnusedInputStruct(); + } + + if (gRealInputs.held & L_BUTTON) { + if (gRealInputs.pressed & B_BUTTON) { + DisplayMessageLog(); + ResetRepeatTimers(); + ResetUnusedInputStruct(); + } + } + + tryItemThrow = FALSE; + if (gRealInputs.held & R_BUTTON) { + if (!sInDiagonalMode) { + sArrowsFrames = 0; + } + sInDiagonalMode = TRUE; + } + else { + sInDiagonalMode = FALSE; + } + + highlightTiles = FALSE; + if (gGameOptionsRef->unk9 == 0) { + if (gRealInputs.shortPress & R_BUTTON || rPress || gRealInputs.pressed & START_BUTTON) { + highlightTiles = TRUE; + } + } + if (highlightTiles) { + sub_805E738(leader); + sInRotateMode = TRUE; + unkPtr->unk1821B = leaderInfo->action.direction; + unkPtr->unk1821C = 0xFF; + ResetRepeatTimers(); + } + + if ((gRealInputs.held & L_BUTTON) == L_BUTTON && (gRealInputs.pressed & R_BUTTON) == R_BUTTON) { + tryItemThrow = TRUE; + } + if (triggers[0]) { + tryItemThrow = TRUE; + } + if (tryItemThrow) { + s32 i; + for (i = 0; i < INVENTORY_SIZE; i++) { + if (ItemExists(&gTeamInventoryRef->teamItems[i]) && ItemSet(&gTeamInventoryRef->teamItems[i])) { + sub_8044C50(ACTION_THROW_ITEM_PLAYER); + leaderInfo->action.actionParameters[0].actionUseIndex = i +1; + leaderInfo->action.actionParameters[0].itemPos.x = 0; + leaderInfo->action.actionParameters[0].itemPos.y = 0; + break; + } + } + if (leaderInfo->action.action != 0) { + break; + } + } + + // SELECT button + if (!gDungeon->unk181e8.blinded && gGameOptionsRef->mapOption != 6 && gRealInputs.pressed & SELECT_BUTTON) { + s32 prevMapOption = gGameOptionsRef->mapOption; + gUnknown_202EE00 = 1; + gDungeon->unk181e8.unk18214 = 1; + if (!sub_8094C48()) { + sub_8094C88(); + } + sub_8052210(1); + sub_8040A84(); + SetBGOBJEnableFlags(0x1E); + sub_803E708(0xA, 0x2F); + while (1) { + DungeonRunFrameActions(0x2F); + if (gRealInputs.pressed & SELECT_BUTTON) + break; + if (gRealInputs.pressed & B_BUTTON) + break; + + if (gRealInputs.pressed & A_BUTTON) { + gUnknown_202EE00 = (gUnknown_202EE00 == 0) ? 1 : 0; // Flip + sub_8040A84(); + } + } + gDungeon->unk181e8.unk18214 = 0; + gGameOptionsRef->mapOption = prevMapOption; + gUnknown_202EE00 = 1; + sub_8040A84(); + SetBGOBJEnableFlags(0); + DungeonRunFrameActions(0x2F); + DungeonRunFrameActions(0x2F); + } + + if (gDungeon->unk644.unk29 != 0 && !sInDiagonalMode) { + dpadDiagonal = dpadSimple = gRealInputs.pressed; + } + else { + dpadDiagonal = gRealInputs.held; + dpadSimple = (unkPtr->unk1821A == 0) ? gRealInputs.held : gRealInputs.pressed; + } + + dpadDiagonal &= DPAD_ANY; + dpadSimple &= DPAD_ANY; + directionNew = -1; + if (dpadDiagonal == (DPAD_UP | DPAD_RIGHT)) + directionNew = DIRECTION_NORTHEAST; + if (dpadDiagonal == (DPAD_UP | DPAD_LEFT)) + directionNew = DIRECTION_NORTHWEST; + if (dpadDiagonal == (DPAD_DOWN | DPAD_RIGHT)) + directionNew = DIRECTION_SOUTHEAST; + if (dpadDiagonal == (DPAD_DOWN | DPAD_LEFT)) + directionNew = DIRECTION_SOUTHWEST; + + if (dpadSimple == DPAD_UP) + directionNew = DIRECTION_NORTH; + if (dpadSimple == DPAD_DOWN) + directionNew = DIRECTION_SOUTH; + if (dpadSimple == DPAD_RIGHT) + directionNew = DIRECTION_EAST; + if (dpadSimple == DPAD_LEFT) + directionNew = DIRECTION_WEST; + + if (directionNew >= 0 && (!sInDiagonalMode || (directionNew & 1))) { + bool32 directionChanged = (leaderInfo->action.direction != directionNew); + leaderInfo->action.direction = directionNew & DIRECTION_MASK; + if (sInRotateMode) { + unkPtr->unk1821B = directionNew; + sub_806CDD4(leader, sub_806CEBC(leader), directionNew); + } + else { + u8 canMoveFlags = 0; + const u8 *immobilizedMsg = NULL; + + if (sub_805EC4C(leader, 1)) + break; + + if (leaderInfo->frozenClassStatus.status == STATUS_SHADOW_HOLD) { + immobilizedMsg = gUnknown_80F8A84, canMoveFlags |= 1; + } + else if (leaderInfo->frozenClassStatus.status == STATUS_CONSTRICTION) { + immobilizedMsg = gUnknown_80F8A6C, canMoveFlags |= 1; + } + else if (leaderInfo->frozenClassStatus.status == STATUS_INGRAIN) { + immobilizedMsg = gUnknown_80F8AB0, canMoveFlags |= 1; + } + else if (leaderInfo->frozenClassStatus.status == STATUS_WRAP) { + immobilizedMsg = gUnknown_80F8ADC, canMoveFlags |= 1; + } + else if (leaderInfo->frozenClassStatus.status == STATUS_WRAPPED) { + immobilizedMsg = gUnknown_80F8B0C, canMoveFlags |= 1; + } + + if (!CanMoveInDirection(leader, directionNew)) + canMoveFlags |= 2; + + if (directionChanged) { + sub_806CDD4(leader, sub_806CEBC(leader), directionNew); + } + + if (!(canMoveFlags & 2)) { + if (canMoveFlags & 1) { + if (immobilizedMsg != NULL) { + LogMessageByIdWithPopupCheckUser(leader, immobilizedMsg); + } + sub_8044C50(ACTION_PASS_TURN); + gDungeon->unk644.unk2F = 1; + } + else { + sub_8044C50(ACTION_WALK); + if ((gRealInputs.held & B_BUTTON || bPress) && FixedPointToInt(leaderInfo->belly) != 0) { + if (GetEntInfo(leader)->cringeClassStatus.status != STATUS_CONFUSED) { + gDungeon->unk644.unk28 = 1; + } + leaderInfo->action.actionParameters[0].actionUseIndex = 0; + } + else { + leaderInfo->action.actionParameters[0].actionUseIndex = 1; + } + } + break; + } + else if (canMoveFlags & 1) { + sub_803E724(0x23); + } + + } + } + DungeonRunFrameActions(0xF); + } + + if (unkPtr->unk1821A != 0) { + sub_804AA60(); + } + + if (leaderInfo->action.action == 0x2D || leaderInfo->action.action == 0x13) { + HandleTalkFieldAction(leader); + if (sub_8044B28()) + break; + sub_8044C50(ACTION_NOTHING); + } + else if ((r6.a0_8) == 0) { + gDungeon->unk644.unk29 = 0; + if (leaderInfo->action.action != 0) { + if (!IsNotAttacking(leader, FALSE)) { + DungeonRunFrameActions(0xF); + } + break; + } + DungeonRunFrameActions(0xF); + } + else { + DungeonRunFrameActions(0xF); + sub_8047158(); + ShowMainMenu((r6.a0_16 == 0), r6.a0_24); + ResetRepeatTimers(); + ResetUnusedInputStruct(); + sInRotateMode = FALSE; + unkPtr->unk1821A = 0; + sub_804AA60(); + if (sub_8044B28()) + break; + if (leaderInfo->action.action != 0) { + if (leaderInfo->action.action == 0x2B) { + gDungeon->unk4 = 1; + gDungeon->unk3 = 1; + } + if (leaderInfo->action.action == 0x2E) { + gDungeon->unk4 = 1; + gDungeon->unk3 = 0; + } + break; + } + DungeonRunFrameActions(0xF); + if (gDungeon->unk4 != 0) + break; + } + } +} + +struct UnkStruct_8106AC8 +{ + s16 unk0; + s16 unk2; + u8 unk4; + u8 unk5; +}; + +extern const struct UnkStruct_8106AC8 gUnknown_8106AC8[]; + +struct UnkStruct_8106AE8 +{ + s16 unk0; + s16 unk2; + u32 unk4; + u8 unk8; + u8 unk9; + u8 unkA; +}; + +extern const struct UnkStruct_8106AE8 gUnknown_8106AE8[]; + +// Creates arrow sprites which are used when in rotate or diagonal modes. +static void TryCreateModeArrows(Entity *leader) +{ + UnkDungeonGlobal_unk181E8_sub *unkPtr = &gDungeon->unk181e8; + + if (sInDiagonalMode) { + s32 i; + SpriteOAM sprite; + + for (i = 0; i < 4; i++) { + u32 matrixNum; + s32 x, xMul, x2; + s32 y, yMul, y2; + + SpriteSetAffine1(&sprite, 0); + SpriteSetAffine2(&sprite, 0); + SpriteSetObjMode(&sprite, 1); + SpriteSetMosaic(&sprite, 0); + SpriteSetBpp(&sprite, 0); + SpriteSetShape(&sprite, 0); + + matrixNum = (gUnknown_8106AC8[i].unk4 != 0) ? 8 : 0; + + if (gUnknown_8106AC8[i].unk5) + matrixNum += 16; + + SpriteSetMatrixNum_UseLocalVar(&sprite, matrixNum); + SpriteSetSize(&sprite, 0); + + SpriteSetTileNum(&sprite, 0x213); + SpriteSetPriority(&sprite, 2); + SpriteSetPalNum(&sprite, 0); + + SpriteSetUnk6_0(&sprite, 0); + SpriteSetUnk6_1(&sprite, 0); + + xMul = gUnknown_8106AC8[i].unk0 * 10; + x2 = (sArrowsFrames / 2) & 7; + x = (x2 * gUnknown_8106AC8[i].unk0) + xMul + 116; + SpriteSetX(&sprite, x); + + yMul = gUnknown_8106AC8[i].unk2 * 10; + y2 = (sArrowsFrames / 2) & 7; + y = (y2 * gUnknown_8106AC8[i].unk2) + yMul + 82; + SpriteSetY(&sprite, y); + + AddSprite(&sprite, 0x100, NULL, NULL); + } + } + + else if (unkPtr->unk1821A) { + s32 i; + SpriteOAM sprite; + s32 var_2C = unkPtr->unk1821B; + + if (unkPtr->unk1821B < 8) { + s32 x, xMul, x2; + s32 y, yMul, y2; + s32 to = (sShowThreeArrows2 != FALSE && sShowThreeArrows1 != FALSE) ? 3 : 1; + + xMul = gUnknown_8106AE8[var_2C].unk0 * 10; + x2 = (sArrowsFrames / 2) & 7; + x = (gUnknown_8106AE8[var_2C].unk0 * x2) + xMul + 116; + + yMul = gUnknown_8106AE8[var_2C].unk2 * 10; + y2 = (sArrowsFrames / 2) & 7; + y = (y2 * gUnknown_8106AE8[var_2C].unk2) + yMul + 82; + for (i = 0; i < to; i++) { + u32 matrixNum; + + SpriteSetAffine1(&sprite, 0); + SpriteSetAffine2(&sprite, 0); + SpriteSetObjMode(&sprite, 1); + SpriteSetMosaic(&sprite, 0); + SpriteSetBpp(&sprite, 0); + SpriteSetShape(&sprite, 0); + + matrixNum = (gUnknown_8106AE8[var_2C].unk8 != 0) ? 8 : 0; + + if (gUnknown_8106AE8[var_2C].unk9) + matrixNum += 16; + + SpriteSetMatrixNum_UseLocalVar(&sprite, matrixNum); + SpriteSetSize(&sprite, 0); + + SpriteSetTileNum(&sprite, gUnknown_8106AE8[var_2C].unk4); + SpriteSetPriority(&sprite, 2); + SpriteSetPalNum(&sprite, 0); + + SpriteSetUnk6_0(&sprite, 0); + SpriteSetUnk6_1(&sprite, 0); + + SpriteSetX(&sprite, x); + SpriteSetY(&sprite, y); + + AddSprite(&sprite, 0x100, NULL, NULL); + x += gUnknown_8106AE8[var_2C].unk0 * 4; + y += gUnknown_8106AE8[var_2C].unk2 * 4; + } + } + } + + if (sInRotateMode && unkPtr->unk1821C != unkPtr->unk1821B) { + unkPtr->unk1821C = unkPtr->unk1821B; + ChangeDungeonCameraPos(&leader->pos, unkPtr->unk1821B, 0, sInRotateMode); + } +} + +static void sub_805E738(Entity *a0) +{ + const Tile *tile; + s32 i, j; + EntityInfo *entityInfo = GetEntInfo(a0); + if (entityInfo->blinkerClassStatus.status != 1 && entityInfo->blinkerClassStatus.status != 2) { + // What??? + for (i = 0; i < 1; i++) { + bool8 r9 = FALSE; + u32 direction = entityInfo->action.direction; + direction++; + for (j = 1; j < 8; j++, direction++) { + direction &= DIRECTION_MASK; + tile = GetTile(a0->pos.x + gAdjacentTileOffsets[direction].x, a0->pos.y + gAdjacentTileOffsets[direction].y); + if (tile->monster != NULL && GetEntityType(tile->monster) == ENTITY_MONSTER) { + EntityInfo *tileMonsterInfo = GetEntInfo(tile->monster); + if (CanSeeTarget(a0, tile->monster)) { + if (i != 0 || tileMonsterInfo->isNotTeamMember) { + r9 = TRUE; + break; + } + } + } + } + if (r9) { + GetEntInfo(a0)->action.direction = direction & DIRECTION_MASK; + sub_806CDD4(a0, sub_806CEBC(a0), direction); + break; + } + } + } +} + +void sub_805E804(void) +{ + gDungeon->unk644.unk29 |= gDungeon->unk644.unk28; + gDungeon->unk644.unk28 = 0; + while (gDungeon->unk644.unk29 != 0 && gRealInputs.held & R_BUTTON) { + DungeonRunFrameActions(0x54); + } +} + +static bool8 sub_805E874(void) +{ + u8 r7, r8, r0; + s32 i, j, k; + s32 xArray[3]; + s32 yArray[3]; + Dungeon *dungeon = gDungeon; + Entity *leader = GetLeader(); + s32 direction = GetEntInfo(leader)->action.direction; + s32 x = leader->pos.x; + s32 y = leader->pos.y; + const Tile *leaderTile = GetTile(x, y); + s32 xAdjacent = x + gAdjacentTileOffsets[direction].x; + s32 yAdjacent = y + gAdjacentTileOffsets[direction].y; + s32 room; + + if (dungeon->unk644.unk28 == 0) + return FALSE; + if (leaderTile->object != NULL) + return FALSE; + if (sub_805EC2C(leader, x, y)) + return FALSE; + if (!sub_8070F14(leader, direction)) + return FALSE; + + room = leaderTile->room; + if (room == 0xFF) { + if (GetTile(xAdjacent, yAdjacent)->room != 0xFF) + return FALSE; + } + else { + if (leaderTile->terrainType & TERRAIN_TYPE_NATURAL_JUNCTION) + return FALSE; + } + + for (j = -1; j < 2; j++) { + const Tile *tile = GetTile(x + gAdjacentTileOffsets[(direction + j) & 7].x, y + gAdjacentTileOffsets[(direction + j) & 7].y); + if (tile->monster != NULL) + return FALSE; + if (tile->terrainType & TERRAIN_TYPE_STAIRS) + return FALSE; + } + + xArray[0] = x + gAdjacentTileOffsets[(direction + 3) & 7].x; + xArray[1] = x + gAdjacentTileOffsets[(direction + 4) & 7].x; + xArray[2] = x + gAdjacentTileOffsets[(direction + 5) & 7].x; + + yArray[0] = y + gAdjacentTileOffsets[(direction + 3) & 7].y; + yArray[1] = y + gAdjacentTileOffsets[(direction + 4) & 7].y; + yArray[2] = y + gAdjacentTileOffsets[(direction + 5) & 7].y; + + for (i = -1; i < 2; i++) { + for (j = -1; j < 2; j++) { + const Tile *tile = GetTile(x + i, y + j); + if (tile->object != NULL) { + for (k = 0; k < 3; k++) { + if (x + i == xArray[k] && y + j == yArray[k]) + break; + } + if (k == 3 && GetEntityType(tile->object) == ENTITY_ITEM) + return FALSE; + } + + if (direction & 1) { + // This doesn't really have to be called two times... + if (tile->object != NULL && GetEntityType(tile->object) == ENTITY_TRAP && GetEntityType(tile->object) == ENTITY_TRAP) { + if (tile->object->isVisible) + return FALSE; + if (gDungeon->unk181e8.unk1820F) + return FALSE; + } + } + else if (i == 0 || j == 0) { + if (tile->object != NULL && GetEntityType(tile->object) == ENTITY_TRAP) { + if (tile->object->isVisible) + return FALSE; + if (gDungeon->unk181e8.unk1820F) + return FALSE; + } + } + + if (i != 0 && j != 0) continue; + if (i == 0 && j == 0) continue; + + if ((xArray[1] != x + i || yArray[1] != y + j) && !sub_805EC2C(leader, x + i, y + j) && room != 0xFF && room != tile->room) + return FALSE; + } + } + + if (!(direction & 1)) { + if (direction == 0 || direction == 4) { + r8 = sub_805EC2C(leader, x - 1, y - 1); + r7 = sub_805EC2C(leader, x - 1, y); + r0 = sub_805EC2C(leader, x - 1, y + 1); + if (r7 == 0) { + if (r8 != 0 || r7 != r0) + return FALSE; + } + + r8 = sub_805EC2C(leader, x + 1, y - 1); + r7 = sub_805EC2C(leader, x + 1, y); + r0 = sub_805EC2C(leader, x + 1, y + 1); + if (r7 == 0) { + if (r8 != 0 || r7 != r0) + return FALSE; + } + } + else { + r8 = sub_805EC2C(leader, x - 1, y - 1); + r7 = sub_805EC2C(leader, x, y - 1); + r0 = sub_805EC2C(leader, x + 1, y - 1); + if (r7 == 0) { + if (r8 != 0 || r7 != r0) + return FALSE; + } + + r8 = sub_805EC2C(leader, x - 1, y + 1); + r7 = sub_805EC2C(leader, x, y + 1); + r0 = sub_805EC2C(leader, x + 1, y + 1); + if (r7 == 0) { + if (r8 != 0 || r7 != r0) + return FALSE; + } + } + } + + return TRUE; +} + +static bool8 sub_805EC2C(Entity *a0, s32 x, s32 y) +{ + DungeonPos pos = {.x = x, .y = y}; + return sub_8070564(a0, &pos); +} + +static bool8 sub_805EC4C(Entity *a0, u8 a1) +{ + DungeonPos pos; + const Tile *tile; + EntityInfo *tileMonsterInfo; + Entity *tileMonster; + EntityInfo *entityInfo = GetEntInfo(a0); + + pos.x = a0->pos.x + gAdjacentTileOffsets[entityInfo->action.direction].x; + pos.y = a0->pos.y + gAdjacentTileOffsets[entityInfo->action.direction].y; + tile = GetTile(pos.x, pos.y); + tileMonster = tile->monster; + + if (tileMonster == NULL) return FALSE; + if (GetEntityType(tileMonster) != ENTITY_MONSTER) return FALSE; + + tileMonsterInfo = GetEntInfo(tileMonster); + if (tileMonsterInfo->isNotTeamMember + && (tileMonsterInfo->shopkeeper != 1 && tileMonsterInfo->shopkeeper != 2) + && !IsExperienceLocked(tileMonsterInfo->joinedAt.id) + && tileMonsterInfo->monsterBehavior != BEHAVIOR_RESCUE_TARGET) { + return FALSE; + } + + if (entityInfo->frozenClassStatus.status == STATUS_SHADOW_HOLD) return FALSE; + if (entityInfo->frozenClassStatus.status == STATUS_FROZEN) return FALSE; + if (entityInfo->frozenClassStatus.status == STATUS_CONSTRICTION) return FALSE; + if (entityInfo->frozenClassStatus.status == STATUS_INGRAIN) return FALSE; + if (entityInfo->frozenClassStatus.status == STATUS_WRAP) return FALSE; + if (entityInfo->frozenClassStatus.status == STATUS_WRAPPED) return FALSE; + + if (tileMonsterInfo->frozenClassStatus.status == STATUS_SHADOW_HOLD) return FALSE; + if (tileMonsterInfo->frozenClassStatus.status == STATUS_FROZEN) return FALSE; + if (tileMonsterInfo->frozenClassStatus.status == STATUS_CONSTRICTION) return FALSE; + if (tileMonsterInfo->frozenClassStatus.status == STATUS_INGRAIN) return FALSE; + if (tileMonsterInfo->frozenClassStatus.status == STATUS_WRAP) return FALSE; + if (tileMonsterInfo->frozenClassStatus.status == STATUS_WRAPPED) return FALSE; + + if (entityInfo->cringeClassStatus.status == STATUS_CONFUSED) return FALSE; + if (tileMonsterInfo->cringeClassStatus.status == STATUS_CONFUSED) return FALSE; + + if (tileMonsterInfo->sleepClassStatus.status != STATUS_NONE && tileMonsterInfo->sleepClassStatus.status != STATUS_SLEEPLESS && tileMonsterInfo->sleepClassStatus.status != STATUS_YAWNING) return FALSE; + if (entityInfo->sleepClassStatus.status != STATUS_NONE && entityInfo->sleepClassStatus.status != STATUS_SLEEPLESS && entityInfo->sleepClassStatus.status != STATUS_YAWNING) return FALSE; + + if (IsChargingAnyTwoTurnMove(tileMonster, FALSE)) return FALSE; + if (!sub_8070F80(a0, entityInfo->action.direction)) return FALSE; + + if (a1 != 0 && sub_807049C(tileMonster, &a0->pos) && !DisplayDungeonYesNoMessage(0, gUnknown_8100208, 0)) return FALSE; + + SetMonsterActionFields(&entityInfo->action, ACTION_WALK); + if (gRealInputs.held & B_BUTTON) { + entityInfo->action.actionParameters[0].actionUseIndex = 0; + } + else { + entityInfo->action.actionParameters[0].actionUseIndex = 1; + } + entityInfo->flags |= 0x8000; + + SetMonsterActionFields(&tileMonsterInfo->action, ACTION_WALK); + tileMonsterInfo->action.actionParameters[0].actionUseIndex = 0; + tileMonsterInfo->action.direction = (entityInfo->action.direction + 4) & 7; + tileMonsterInfo->flags |= 0x8000; + tileMonsterInfo->targetPos.x = tileMonster->pos.x; + tileMonsterInfo->targetPos.y = tileMonster->pos.y; + gDungeon->unkE = 1; + return TRUE; +} + +void sub_805EE30(void) +{ + Entity *tileObject; + Tile *tile; + Entity *leader = GetLeader(); + if (leader == NULL) + return; + if (sub_8044B28()) + return; + + tile = GetTileAtEntitySafe(leader); + if (IQSkillIsEnabled(leader, IQ_SUPER_MOBILE) && GetEntInfo(leader)->invisibleClassStatus.status != STATUS_MOBILE && !HasHeldItem(leader, ITEM_MOBILE_SCARF)) + sub_804AE84(&leader->pos); + if (tile->terrainType & TERRAIN_TYPE_STAIRS) + gDungeon->unk1 = 1; + + tileObject = tile->object; + if (tileObject == NULL) + return; + switch (GetEntityType(tileObject)) + { + case ENTITY_TRAP: { + Trap *trap = GetTrapData(tileObject); + bool32 r8 = FALSE; + bool32 r7 = FALSE; + if (IQSkillIsEnabled(leader, IQ_TRAP_SEER) && !tileObject->isVisible) { + tileObject->isVisible = TRUE; + sub_8049ED4(); + r7 = TRUE; + } + if (trap->unk1 != 0) { + if (trap->unk1 == 1) + break; + if (trap->unk1 == 2) + r8 = TRUE; + if (r8 == FALSE) + break; + } + if (!r7) { + HandleTrap(leader, &leader->pos, 0, 1); + } + } + break; + case ENTITY_ITEM: { + Item *item = GetItemData(tileObject); + if (!(item->flags & ITEM_FLAG_IN_SHOP)) { + sub_8045DB4(&leader->pos, 1); + } + else { + gDungeon->unk5C0 = 4; + } + } + break; + case ENTITY_NOTHING: + case ENTITY_MONSTER: + case ENTITY_UNK_4: + case ENTITY_UNK_5: + default: + break; + } +} + +static bool8 sub_805EF60(Entity *a0, EntityInfo *a1) +{ + Entity *r4 = sub_80696A8(a0); + + if (r4 == NULL) + return FALSE; + if (GetEntityType(r4) != ENTITY_MONSTER) + return FALSE; + if (!sub_8070BC0(a0)) + return FALSE; + if (GetEntInfo(r4)->isNotTeamMember && GetEntInfo(r4)->monsterBehavior != BEHAVIOR_RESCUE_TARGET && GetEntInfo(r4)->shopkeeper != 1) + return FALSE; + + SetMonsterActionFields(&a1->action, ACTION_TALK_FIELD); + return TRUE; +} + +void sub_805EFB4(Entity *a0, bool8 a1) +{ + s32 i; + EntityInfo *leaderInfo = GetLeaderInfo(); + if (a1 && leaderInfo->cringeClassStatus.status == STATUS_COWERING) { + leaderInfo->action.direction += 4; + leaderInfo->action.direction &= 7; + } + else if (leaderInfo->cringeClassStatus.status == STATUS_CONFUSED) { + s32 rnd = DungeonRandInt(8); + for (i = 0; i < 8; i++) { + if (a1 || CanMoveInDirection(a0, rnd)) { + leaderInfo->action.direction = rnd & 7; + return; + } + rnd = (rnd + 1) & 7; + } + } +} + +void sub_805F02C(void) +{ + s32 i; + Entity *r7 = gDungeon->unkBC; + Entity *leader = GetLeader(); + EntityInfo *r8 = GetEntInfo(r7); + EntityInfo *leaderInfo = GetEntInfo(leader); + + if (r8->isTeamLeader) { + DisplayDungeonLoggableMessageTrue(r7, gUnknown_80F9BD8); + } + else if (sub_8047084(ITEM_FLAG_IN_SHOP) || sub_807EF48()) { + DisplayDungeonLoggableMessageTrue(r7, gUnknown_80F9C08); + } + else if (gDungeon->unk644.unk2A) { + DisplayDungeonLoggableMessageTrue(r7, gUnknown_80F9C2C); + } + else { + gDungeon->unk644.unk35 = 0; + r8->isTeamLeader = TRUE; + leaderInfo->isTeamLeader = FALSE; + for (i = 0; i < 4; i++) { + PokemonStruct2 *mon = &gRecruitedPokemonRef->pokemon2[i]; + PokemonStruct1 *r5 = NULL; + + if ((u8)mon->unk0 & 1) { + if (!sub_806A538(mon->unkA)) { + r5 = &gRecruitedPokemonRef->pokemon[mon->unkA]; + } + if (i == r8->teamIndex) { + mon->isTeamLeader = TRUE; + if (r5 != NULL) { + r5->isTeamLeader = TRUE; + } + } + else { + mon->isTeamLeader = FALSE; + if (r5 != NULL) { + r5->isTeamLeader = FALSE; + } + } + } + } + gLeaderPointer = NULL; + r8->action = leaderInfo->action; + sub_803F508(r7); + sub_8041AD0(leader); + sub_8041AE0(GetLeader()); + SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], r7, 0); + LogMessageByIdWithPopupCheckUser(r7, gUnknown_80F9BB0); + sub_807EC28(FALSE); + r8->unk64 = 0; + leaderInfo->unk64 = 0; + sub_806A6E8(leader); + sub_806A6E8(r7); + } +} + +ActionContainer *GetLeaderActionContainer(void) +{ + return &GetLeaderInfo()->action; +} + +u16 GetLeaderActionId(void) +{ + return GetLeaderInfo()->action.action; +} + +enum +{ + MAIN_MENU_MOVES, + MAIN_MENU_ITEMS, + MAIN_MENU_TEAM, + MAIN_MENU_OTHERS, + MAIN_MENU_GROUND, +}; + +static void ShowMainMenu(bool8 fromBPress, bool8 a1) +{ + Item *item; + s32 r10; + bool8 printAll = fromBPress; + s32 chosenOption; + s32 var_24; + struct UnkMenuBitsStruct var_30; + struct UnkMenuBitsStruct var_34; + + r10 = gDungeon->unk5C0; + chosenOption = 0; + var_24 = (gDungeon->unk5C0 > - 1); + gDungeon->unk5C0 = -1; + if (r10 >= 0) { + chosenOption = r10; + } + + if (a1) { + PlayFanfareSE(0x137, 0x100); + } + else { + PlayDungeonStartButtonSE(); + } + + while (1) { + if (r10 < 0) { + SetLeaderActionToNothing(1); + gTeamMenuChosenId = -1; + PrintOnMainMenu(printAll); + sub_806A2BC(GetLeader(), 0); + while (1) { + AddMenuCursorSprite(&gDungeonMenu); + DungeonRunFrameActions(0x1D); + if (gRealInputs.repeated & DPAD_DOWN) { + PlayDungeonCursorSE(1); + MoveMenuCursorDownWrapAround(&gDungeonMenu, TRUE); + } + if (gRealInputs.repeated & DPAD_UP) { + PlayDungeonCursorSE(1); + MoveMenuCursorUpWrapAround(&gDungeonMenu, TRUE); + } + if ((gRealInputs.pressed & A_BUTTON || gDungeonMenu.unk28.a_button)) { + if (gUnknown_202749A[gDungeonMenu.menuIndex + 1] == 7) { + PlayDungeonConfirmationSE(); + chosenOption = gDungeonMenu.menuIndex; + break; + } + PlayDungeonCancelSE(); + } + if ((gRealInputs.pressed & B_BUTTON) || gDungeonMenu.unk28.b_button) { + PlayDungeonCancelSE(); + chosenOption = -1; + break; + } + } + AddMenuCursorSprite(&gDungeonMenu); + DungeonRunFrameActions(0x1D); + printAll = TRUE; + } + + r10 = chosenOption; + if (chosenOption == MAIN_MENU_ITEMS) { + u16 action; + + SetLeaderActionToNothing(1); + var_34.a0_8 = 0; + var_34.a0_16 = 1; + var_34.a0_24 = 0; + var_34.a0_32 = 0; + if (ShowDungeonItemsMenu(GetLeader(), &var_34)) { + r10 = -1; + } + if (sub_805FD3C(&var_34) && ShowDungeonItemsMenu(GetLeader(), &var_34)) { + SetLeaderActionToNothing(1); + } + action = GetLeaderActionId(); + if (action == 12) { + sub_8044D90(GetLeader(), 0, 12)->flags |= ITEM_FLAG_UNPAID; + sub_8060D24(GetLeaderActionContainer()); + SetLeaderActionToNothing(1); + } + else if (action == 53) { + item = sub_8044D90(GetLeader(), 0, 13); + if (!sub_8048A68(GetLeader(), item)) { + SetLeaderActionToNothing(1); + } + } + else if (action == 16) { + item = sub_8044D90(GetLeader(), 0, 14); + if (!sub_8048950(GetLeader(), item)) { + SetLeaderActionToNothing(1); + } + } + else if (action == 44) { + item = sub_8044D90(GetLeader(), 0, 15); + if (!sub_8048B9C(GetLeader(), item)) { + SetLeaderActionToNothing(1); + } + } + else if (action == 60) { + HandleSetItemAction(GetLeader(), TRUE); + SetLeaderActionToNothing(1); + sub_803E708(0x50, 0x4D); + sub_8052210(0); + break; + } + else if (action == 61) { + HandleUnsetItemAction(GetLeader(), TRUE); + SetLeaderActionToNothing(1); + sub_803E708(0x50, 0x4D); + sub_8052210(0); + break; + } + + if (GetLeaderActionId() != 0) + break; + } + else if (chosenOption == MAIN_MENU_TEAM) { + SetLeaderActionToNothing(1); + if (ShowDungeonTeamMenu(GetLeader())) { + r10 = -1; + } + + if (GetLeaderActionId() == ACTION_CHECK_SUMMARY) { + sub_8061A38(GetLeaderActionContainer(), FALSE); + SetLeaderActionToNothing(1); + } + else if (GetLeaderActionId() == ACTION_TALK_MENU) { + sub_806752C(GetLeaderActionContainer()); + SetLeaderActionToNothing(1); + } + else if (GetLeaderActionId() == 0x34) { + sub_8067768(GetLeaderActionContainer()); + SetLeaderActionToNothing(1); + } + else if (GetLeaderActionId() == ACTION_CHANGE_TACTICS) { + ShowTacticsMenu(GetLeaderActionContainer()); + SetLeaderActionToNothing(1); + } + else if (GetLeaderActionId() == ACTION_VIEW_IQ) { + sub_8061A38(GetLeaderActionContainer(), TRUE); + SetLeaderActionToNothing(1); + } + else if (GetLeaderActionId() == ACTION_CHECK_MOVES) { + s32 i, count; + + sub_8062D8C(GetLeaderActionContainer()); + count = 0; + for (i = 0; i < MAX_TEAM_MEMBERS; i++) { + Entity *teamMon = gDungeon->teamPokemon[i]; + if (EntityIsValid(teamMon)) { + if (i == GetLeaderActionContainer()->actionParameters[0].actionUseIndex) { + gTeamMenuChosenId = count; + if (GetLeaderActionId() != 0) { + sub_806A2BC(teamMon, 0); + } + break; + } + count++; + } + } + } + + if (GetLeaderActionId() != 0) + break; + } + else if (chosenOption == MAIN_MENU_MOVES) { + s32 i, currMonId, teamMonsCount, r9; + Entity *currEntity; + + currMonId = 0; + SetLeaderActionToNothing(1); + for (i = 0; i < MAX_TEAM_MEMBERS; i++) { + Entity *teamMon = gDungeon->teamPokemon[i]; + if (EntityIsValid(teamMon)) { + if (GetEntInfo(teamMon)->isTeamLeader) { + currMonId = i; + break; + } + } + } + + + while (1) { + SetLeaderActionToNothing(0); + LOOP_START_NO_CALL: // Actions 6 and 7 don't call SetLeaderActionToNothing + currEntity = NULL; + r9 = 0; + teamMonsCount = 0; + for (i = 0; i < MAX_TEAM_MEMBERS; i++) { + Entity *teamMon = gDungeon->teamPokemon[i]; + if (sub_8071A8C(teamMon)) { + if (i == currMonId) { + r9 = teamMonsCount; + currEntity = teamMon; + } + teamMonsCount++; + } + } + if (currEntity == NULL) { + currEntity = GetLeader(); + } + + sub_806A2BC(currEntity, 0); + ChangeDungeonCameraPos(&currEntity->pos, 0, 1, 1); + GetLeaderInfo()->action.actionParameters[0].actionUseIndex = currMonId; + SetLeaderActionToNothing(FALSE); + if (ShowDungeonMovesMenu(currEntity, 0, 1, r9, teamMonsCount)) { + r10 = -1; + } + + if (GetLeaderActionId() == ACTION_MOVES_MENU_NEXT_MON) { + s32 prevMonId = currMonId; + for (i = 0; i < MAX_TEAM_MEMBERS; i++) { + if (++currMonId >= MAX_TEAM_MEMBERS) { + currMonId = 0; + } + currEntity = gDungeon->teamPokemon[currMonId]; + if (sub_8071A8C(currEntity)) + break; + } + GetLeaderInfo()->action.actionParameters[0].actionUseIndex = currMonId; + if (prevMonId != currMonId) { + PlayDungeonCursorSE(0); + } + goto LOOP_START_NO_CALL; + } + else if (GetLeaderActionId() == ACTION_MOVES_MENU_PREV_MON) { + s32 prevMonId = currMonId; + for (i = 0; i < MAX_TEAM_MEMBERS; i++) { + if (--currMonId < 0) { + currMonId = MAX_TEAM_MEMBERS - 1; + } + currEntity = gDungeon->teamPokemon[currMonId]; + if (sub_8071A8C(currEntity)) + break; + } + GetLeaderInfo()->action.actionParameters[0].actionUseIndex = currMonId; + if (prevMonId != currMonId) { + PlayDungeonCursorSE(0); + } + goto LOOP_START_NO_CALL; + } + else if (GetLeaderActionId() == ACTION_UNK1D) { + sub_80637E8(GetLeaderActionContainer()); + } + else if (GetLeaderActionId() == ACTION_SET_MOVE || GetLeaderActionId() == ACTION_UNSET_MOVE) { + sub_8063A70(GetLeaderActionContainer(), FALSE); + } + else if (GetLeaderActionId() == ACTION_UNK1F) { + sub_8063B54(GetLeaderActionContainer()); + } + else if (GetLeaderActionId() == ACTION_UNK20) { + sub_8063BB4(GetLeaderActionContainer()); + } + else if (GetLeaderActionId() == ACTION_UNK21) { + sub_8063CF0(GetLeaderActionContainer(), FALSE); + } + else { + break; + } + } + sub_806A2BC(GetLeader(), 0); + ChangeDungeonCameraPos(&GetLeader()->pos, 0, 1, 1); + if (GetLeaderActionId() != 0) + break; + } + else if (chosenOption == MAIN_MENU_GROUND) { + Entity *leader = GetLeader(); + const Tile *tile = GetTile(leader->pos.x, leader->pos.y); + Entity *tileObject = tile->object; + if (tileObject != NULL) { + if (GetEntityType(tileObject) == ENTITY_ITEM) { + u16 action; + + SetLeaderActionToNothing(1); + var_30.a0_8 = 0; + var_30.a0_16 = 1; + var_30.a0_24 = 1; + var_30.a0_32 = 1; + if (ShowDungeonItemsMenu(GetLeader(), &var_30)) { + // This actually doesn't do anything, it's just there to make the code match as the compiler does a `lsl r0, r0, #0x10, mov r0, r4` + ASM_MATCH_TRICK(leader); + } + if (sub_805FD3C(&var_30) && ShowDungeonItemsMenu(GetLeader(), &var_30)) { + SetLeaderActionToNothing(1); + } + + action = GetLeaderActionId(); + if (action == 0xC) { + sub_8044D90(GetLeader(), 0, 0x10)->flags |= ITEM_FLAG_UNPAID; + sub_8060D24(GetLeaderActionContainer()); + SetLeaderActionToNothing(1); + } + else if (action == 0x35) { + item = sub_8044D90(GetLeader(), 0, 0x11); + if (!sub_8048A68(GetLeader(), item)) { + SetLeaderActionToNothing(1); + } + } + else if (action == 0x10) { + item = sub_8044D90(GetLeader(), 0, 0x12); + if (!sub_8048950(GetLeader(), item)) { + SetLeaderActionToNothing(1); + } + } + else if (action == 0x2C) { + item = sub_8044D90(GetLeader(), 0, 0x13); + if (!sub_8048B9C(GetLeader(), item)) { + SetLeaderActionToNothing(1); + } + } + if (GetLeaderActionId() != 0) + break; + } + else if (GetEntityType(tileObject) == ENTITY_TRAP) { + SetLeaderActionToNothing(1); + sub_80643AC(GetLeader()); + if (GetLeaderActionId() != 0) + break; + } + } + else + { + if (tile->terrainType & TERRAIN_TYPE_STAIRS) { + SetLeaderActionToNothing(1); + ShowDungeonStairsMenu(GetLeader()); + if (GetLeaderActionId() != 0) + break; + } + else { + SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], GetLeader(), 0); + DisplayDungeonMessage(0, gUnknown_80FDE18, 1); + } + } + r10 = -1; + } + else if (chosenOption == MAIN_MENU_OTHERS) { + ShowDungeonOthersMenu(); + if (gDungeon->unk4) + break; + if (GetLeaderActionId() != 0) + break; + r10 = -1; + } + + // B button + if (chosenOption < 0) + break; + + if (var_24 == 0) { + ResetRepeatTimers(); + ResetUnusedInputStruct(); + } + else { + sub_806A2BC(GetLeader(), 0); + break; + } + } + + sub_803EAF0(0, NULL); + ResetRepeatTimers(); + ResetUnusedInputStruct(); +} + +static void PrintOnMainMenu(bool8 printAll) +{ + s32 i, x, y, yLoop; + + gDungeonMenu.menuIndex = 0; + gDungeonMenu.unk1A = 5; + gDungeonMenu.unk1C = 5; + gDungeonMenu.unk1E = 0; + gDungeonMenu.unk4 = 0; + gDungeonMenu.firstEntryY = 2; + gDungeonMenu.unkC = 0; + gDungeonMenu.unkE = 0; + gDungeonMenu.unk0 = 0; + gDungeonMenu.unk14.x = 0; + sub_801317C(&gDungeonMenu.unk28); + sub_80137B0(&gDungeonMenu, 0x38); + if (printAll) { + sub_803EAF0(7, NULL); + } + else { + sub_803EAF0(6, NULL); + } + + sub_80073B8(0); + if (ShouldMonsterRunAwayAndShowEffect(GetLeader(), TRUE)) { + gUnknown_202749A[1] = 2; + gUnknown_202749A[2] = 2; + gUnknown_202749A[3] = 2; + gUnknown_202749A[4] = 7; + gUnknown_202749A[5] = 2; + } + else + { + gUnknown_202749A[1] = 7; + gUnknown_202749A[2] = 7; + gUnknown_202749A[3] = 7; + gUnknown_202749A[4] = 7; + gUnknown_202749A[5] = 7; + } + + y = GetMenuEntryYCoord(&gDungeonMenu, 0); + PrintStringOnWindow(8, y, gFieldMenuMovesPtr, 0, 0); + + y = GetMenuEntryYCoord(&gDungeonMenu, 1); + PrintStringOnWindow(8, y, gFieldMenuItemsPtr, 0, 0); + + y = GetMenuEntryYCoord(&gDungeonMenu, 2); + PrintStringOnWindow(8, y, gFieldMenuTeamPtr, 0, 0); + + y = GetMenuEntryYCoord(&gDungeonMenu, 3); + PrintStringOnWindow(8, y, gFieldMenuOthersPtr, 0, 0); + + y = GetMenuEntryYCoord(&gDungeonMenu, 4); + PrintStringOnWindow(8, y, gFieldMenuGroundPtr, 0, 0); + + sub_80073E0(0); + if (printAll) { + u32 hours, minutes, seconds; + EntityInfo *leaderInfo = GetEntInfo(GetLeader()); + const u8 *dungeonName = GetCurrentDungeonName(); + + x = (136 - sub_8008ED0(dungeonName)) / 2; + sub_80073B8(1); + PrintStringOnWindow(x, 2, dungeonName, 1, 0); + sub_80073E0(1); + sub_80073B8(2); + DeconstructPlayTime(gPlayTimeRef, &hours, &minutes, &seconds); + + gFormatArgs[0] = FixedPointToInt(leaderInfo->belly); + gFormatArgs[1] = FixedPointToInt(leaderInfo->maxBelly); + PrintFormattedStringOnWindow(0x73, 0, gUnknown_80F9174, 2, 0); + + gFormatArgs[0] = gTeamInventoryRef->teamMoney; + PrintFormattedStringOnWindow(0x73, 12, gUnknown_80F9190, 2, 0); + + GetWeatherName(gFormatBuffer_Monsters[0], GetApparentWeather(NULL)); + PrintFormattedStringOnWindow(0x73, 24, gUnknown_80F91A8, 2, 0); + + gFormatArgs[0] = hours; + gFormatArgs[1] = minutes; + gFormatArgs[2] = seconds; + PrintFormattedStringOnWindow(0x73, 36, gUnknown_80F91C8, 2, 0); + for (yLoop = 0, i = 0; i < MAX_TEAM_MEMBERS; i++) { + Entity *teamMon = gDungeon->teamPokemon[i]; + if (EntityIsValid(teamMon)) { + EntityInfo *monInfo = GetEntInfo(teamMon); + SubstitutePlaceholderStringTags(gFormatBuffer_Monsters[0], teamMon, 0); + gFormatArgs[0] = monInfo->HP; + gFormatArgs[1] = monInfo->maxHPStat; + PrintFormattedStringOnWindow(4, yLoop, gUnknown_80F91E0, 2, 0); + yLoop += 12; + if (yLoop >= 12 * MAX_TEAM_MEMBERS) + break; + } + } + sub_80073E0(2); + } +} + +bool8 sub_805FBE8(u8 *a0) +{ + s32 r4; + sub_803EAF0(8, a0); + do + { + DungeonRunFrameActions(0xE); + DrawDialogueBoxString(); + r4 = sub_8016080(); + } while (r4 == 0); + CleanConfirmNameMenu(); + DungeonRunFrameActions(0xE); + sub_803EAF0(0, NULL); + if (r4 == 3 && *a0 != 0) + return TRUE; + + return FALSE; +} + +void CreateDungeonMenuSubWindow(Window *mainWindow, s32 subWindowX) +{ + s32 i; + Windows windows = { + .id = { + [0] = WINDOW_DUMMY, + [1] = { + .type = WINDOW_TYPE_NORMAL, + .pos = {22, 4}, + .width = 6, + .height = 4, + .unk10 = 4, + }, + [2] = WINDOW_DUMMY, + [3] = WINDOW_DUMMY, + } + }; + + windows.id[0] = *mainWindow; + windows.id[0].unk0 = 0x80; + + gDungeonMenu.menuIndex = 0; + gDungeonMenu.unk1C = gDungeonSubMenuItemsCount; + gDungeonMenu.unk1A = gDungeonSubMenuItemsCount; + gDungeonMenu.unk1E = 0; + gDungeonMenu.unk20 = 0; + gDungeonMenu.unk4 = 0; + gDungeonMenu.firstEntryY = 0; + gDungeonMenu.unk0 = 1; + gDungeonMenu.unkC = 0; + gDungeonMenu.unkE = 0; + gDungeonMenu.unk14 = gDungeonMenu.unk8; + + sub_801317C(&gDungeonMenu.unk28); + + windows.id[1].pos.x = subWindowX; + windows.id[1].width = 28 - subWindowX; + windows.id[1].height = windows.id[1].unk10 = sub_80095E4(gDungeonMenu.unk1C, 0); + DungeonShowWindows(&windows, FALSE); + sub_80137B0(&gDungeonMenu, windows.id[1].height * 8); + sub_80073B8(1); + + for (i = 0; i < gDungeonSubMenuItemsCount; i++) { + s32 colorId, y; + u8 text[20]; + + colorId = (CanSubMenuItemBeChosen(i) != FALSE) ? 7 : 2; + sprintfStatic(text, gUnknown_8106B50, colorId, GetDungeonSubMenuItemString(i)); + y = GetMenuEntryYCoord(&gDungeonMenu, i); + PrintStringOnWindow(8, y, text, 1, 0); + } + sub_80073E0(1); +} + +static bool8 sub_805FD3C(struct UnkMenuBitsStruct *a0) +{ + u16 action = GetLeaderActionId(); + + a0->a0_8 = 0; + a0->a0_16 = 0; + a0->a0_24 = 0; + a0->a0_32 = 0; + if (action == 0xA) { + a0->a0_8 = 1; + a0->a0_32 = 1; + } + if (action == 0x3E) { + a0->a0_8 = 1; + a0->a0_16 = 0; + a0->a0_32 = 1; + } + return a0->a0_8; +} diff --git a/sym_ewram.txt b/sym_ewram.txt index 03fbfb149..18bb55d20 100644 --- a/sym_ewram.txt +++ b/sym_ewram.txt @@ -136,7 +136,7 @@ gUnknown_202EE3A: /* 202EE3A (sub_8060E38 - sub_8065DBC) */ gUnknown_202EE44: /* 202EE44 (sub_8044EC8 - sub_80647F0) */ .space 0x28 -gUnknown_202EE6C: /* 202EE6C (sub_8044F5C - sub_8067A80) */ +gDungeonSubMenuItemsCount: /* 202EE6C (sub_8044F5C - sub_8067A80) */ .space 0x4 gUnknown_202EE70: /* 202EE70 (sub_804513C - sub_80828E0) */ @@ -148,7 +148,8 @@ gUnknown_202EE76: /* 202EE76 (sub_804513C - sub_8082A08) */ .include "src/dungeon_generation.o" .include "src/dungeon_message.o" .include "src/dungeon_move.o" - .include "src/code_805D8C8_1.o" + .include "src/dungeon_main.o" + .include "src/code_805D8C8_2.o" gUnknown_202F268: /* 202F268 (sub_8062500) */ .space 0x8 diff --git a/sym_ewram_init.txt b/sym_ewram_init.txt index 39685f199..4881ca4e9 100644 --- a/sym_ewram_init.txt +++ b/sym_ewram_init.txt @@ -114,7 +114,8 @@ .include "src/dungeon_map_access.o" .include "src/dungeon_message.o" .include "src/dungeon_move.o" -.include "src/code_805D8C8_1.o" +.include "src/dungeon_main.o" +.include "src/code_805D8C8_2.o" .include "src/dungeon_ai_items.o" .include "src/code_807CD9C.o" .include "src/dungeon_leader.o"