mirror of
https://github.com/pret/pmd-red.git
synced 2026-04-26 00:15:48 -05:00
569 lines
18 KiB
C
569 lines
18 KiB
C
#include "global.h"
|
|
#include "globaldata.h"
|
|
#include "constants/dungeon.h"
|
|
#include "constants/item.h"
|
|
#include "constants/move_id.h"
|
|
#include "dungeon_vram.h"
|
|
#include "dungeon_tilemap.h"
|
|
#include "code_8041AD0.h"
|
|
#include "dungeon_action.h"
|
|
#include "code_8066D04.h"
|
|
#include "code_806CD90.h"
|
|
#include "code_8077274_1.h"
|
|
#include "run_dungeon.h"
|
|
#include "dungeon_items.h"
|
|
#include "dungeon_range.h"
|
|
#include "dungeon_map_access.h"
|
|
#include "dungeon_message.h"
|
|
#include "dungeon_misc.h"
|
|
#include "dungeon_move.h"
|
|
#include "dungeon_move_util.h"
|
|
#include "dungeon_logic.h"
|
|
#include "dungeon_music.h"
|
|
#include "dungeon_random.h"
|
|
#include "dungeon_strings.h"
|
|
#include "dungeon_util.h"
|
|
#include "friend_area.h"
|
|
#include "input.h"
|
|
#include "items.h"
|
|
#include "menu_input.h"
|
|
#include "moves.h"
|
|
#include "pokemon.h"
|
|
#include "pokemon_3.h"
|
|
#include "position_util.h"
|
|
#include "sprite.h"
|
|
#include "string_format.h"
|
|
#include "text_1.h"
|
|
#include "trap.h"
|
|
#include "dungeon_submenu.h"
|
|
#include "dungeon_engine.h"
|
|
|
|
extern void sub_80684C4(void);
|
|
extern void sub_8068344(void);
|
|
void sub_8068310(s32 n, Pokemon **monPtrs);
|
|
void sub_8067F00(u8 a0, Pokemon **a1, s32 a2, s32 a3, s32 a4);
|
|
void sub_806806C(Pokemon *a0);
|
|
|
|
|
|
static EWRAM_DATA WindowHeader gUnknown_202F308 = {0};
|
|
static EWRAM_DATA s32 gUnknown_202F30C = 0;
|
|
static EWRAM_DATA s32 gUnknown_202F310 = 0;
|
|
|
|
// It's likely a struct only used in Blue version. Touchpad maybe?
|
|
static const u8 sTouchScreenArrowPressData[] = {
|
|
0x01, 0, 0x38, 0, 0, 0, 0x18, 0, 0x18, 0, 0, 0, 0x02, 0, 0x38, 0, 0x68, 0, 0x18, 0, 0x18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
|
|
static const WindowTemplates gUnknown_8106DC8 = {
|
|
.id = {
|
|
[0] =
|
|
{
|
|
.unk0 = 0,
|
|
.type = WINDOW_TYPE_WITH_HEADER,
|
|
.pos = {0x02, 0x02},
|
|
.width = 0x11,
|
|
.height = 0x0E,
|
|
.unk10 = 0x12,
|
|
.unk12 = 0x02,
|
|
.header = &gUnknown_202F308
|
|
},
|
|
[1] =
|
|
{
|
|
.unk0 = 0,
|
|
.type = WINDOW_TYPE_NORMAL,
|
|
.pos = {0x15, 0x04},
|
|
.width = 0x07,
|
|
.height = 0x04,
|
|
.unk10 = 0x04,
|
|
.unk12 = 0,
|
|
.header = NULL
|
|
},
|
|
[2] = WIN_TEMPLATE_DUMMY,
|
|
[3] = WIN_TEMPLATE_DUMMY,
|
|
}
|
|
};
|
|
|
|
void sub_8067A80(u8 a0, s32 a1, s32 a2, Pokemon **a3)
|
|
{
|
|
s32 i;
|
|
s32 r10;
|
|
WindowTemplates spTxtStruct = gUnknown_8106DC8;
|
|
|
|
gUnknown_202F30C = 0;
|
|
r10 = 0;
|
|
for (i = 0; i < a2; i++) {
|
|
a3[i]->flags &= ~(POKEMON_FLAG_x8000);
|
|
}
|
|
|
|
while (1) {
|
|
sub_8068310(a2, a3);
|
|
if (gUnknown_202F310 >= a1)
|
|
break;
|
|
while (1) {
|
|
s32 r7 = 0, r5 = 0;
|
|
|
|
gUnknown_202F308.count = 1;
|
|
gUnknown_202F308.currId = 0;
|
|
gUnknown_202F308.width = 0xE;
|
|
gUnknown_202F308.f3 = 0;
|
|
|
|
ASM_MATCH_TRICK(r7);
|
|
|
|
DungeonShowWindows(&spTxtStruct, 1);
|
|
sub_8067F00(a0, a3, gUnknown_202F30C, a2, a1);
|
|
gDungeonMenu.currPageEntries = min(a2, 8);
|
|
gDungeonMenu.menuIndex = r10;
|
|
gDungeonMenu.entriesPerPage = 8;
|
|
gDungeonMenu.currPage = 0;
|
|
gDungeonMenu.pagesCount = 0;
|
|
gDungeonMenu.unk4 = 0;
|
|
gDungeonMenu.firstEntryY = 18;
|
|
gDungeonMenu.leftRightArrowsPos.x = 0;
|
|
gDungeonMenu.leftRightArrowsPos.y = 0;
|
|
gDungeonMenu.unk14.x = 0;
|
|
gDungeonMenu.windowId = 0;
|
|
ResetTouchScreenMenuInput(&gDungeonMenu.touchScreen);
|
|
sub_80137B0(&gDungeonMenu, 0);
|
|
while (1) {
|
|
s32 touchScreenArrow;
|
|
|
|
AddMenuCursorSprite(&gDungeonMenu);
|
|
r5 = 0;
|
|
r7 = 0;
|
|
if (a2 - gUnknown_202F30C > 8) {
|
|
r5 = 1;
|
|
sub_80684C4();
|
|
}
|
|
if (gUnknown_202F30C != 0) {
|
|
r7 = 1;
|
|
sub_8068344();
|
|
}
|
|
|
|
touchScreenArrow = GetTouchScreenArrowPress(0, sTouchScreenArrowPressData);
|
|
DungeonRunFrameActions(0x37);
|
|
if (touchScreenArrow == TOUCH_SCREEN_ARROW_DOWN_PRESS && r5) {
|
|
if (a2 - gUnknown_202F30C > 8) {
|
|
s32 i;
|
|
for (i = 0; i < 6; i++) {
|
|
ScrollDownWindowFunc(0);
|
|
DungeonRunFrameActions(0x37);
|
|
}
|
|
gUnknown_202F30C++;
|
|
}
|
|
r7 = 0;
|
|
r10 = 7;
|
|
break;
|
|
}
|
|
if (gRealInputs.repeated & DPAD_DOWN) {
|
|
PlayDungeonCursorSE(1);
|
|
if (gDungeonMenu.menuIndex == 7) {
|
|
if (a2 - gUnknown_202F30C > 8) {
|
|
s32 i;
|
|
for (i = 0; i < 6; i++) {
|
|
ScrollDownWindowFunc(0);
|
|
DungeonRunFrameActions(0x37);
|
|
}
|
|
gUnknown_202F30C++;
|
|
}
|
|
r7 = 0;
|
|
r10 = 7;
|
|
break;
|
|
}
|
|
MoveMenuCursorDownWrapAround(&gDungeonMenu, 0);
|
|
}
|
|
|
|
if (touchScreenArrow == TOUCH_SCREEN_ARROW_UP_PRESS && r7 != 0) {
|
|
if (gUnknown_202F30C != 0) {
|
|
s32 i;
|
|
for (i = 0; i < 6; i++) {
|
|
ScrollUpWindowFunc(0);
|
|
DungeonRunFrameActions(0x37);
|
|
}
|
|
gUnknown_202F30C--;
|
|
}
|
|
r7 = 0;
|
|
r10 = 0;
|
|
break;
|
|
}
|
|
if (gRealInputs.repeated & DPAD_UP) {
|
|
PlayDungeonCursorSE(1);
|
|
if (gDungeonMenu.menuIndex == 0) {
|
|
if (gUnknown_202F30C != 0) {
|
|
s32 i;
|
|
for (i = 0; i < 6; i++) {
|
|
ScrollUpWindowFunc(0);
|
|
DungeonRunFrameActions(0x37);
|
|
}
|
|
gUnknown_202F30C--;
|
|
}
|
|
r7 = 0;
|
|
r10 = 0;
|
|
break;
|
|
}
|
|
MoveMenuCursorUpWrapAround(&gDungeonMenu, 0);
|
|
}
|
|
|
|
if (sub_80048C8()) {
|
|
continue;
|
|
}
|
|
|
|
if (gRealInputs.pressed & START_BUTTON) {
|
|
sub_8083D1C();
|
|
r7 = 3;
|
|
break;
|
|
}
|
|
if ((gRealInputs.pressed & A_BUTTON) || gDungeonMenu.touchScreen.a_button) {
|
|
PlayDungeonConfirmationSE();
|
|
r7 = 1;
|
|
break;
|
|
}
|
|
if ((gRealInputs.pressed & B_BUTTON) || gDungeonMenu.touchScreen.b_button) {
|
|
PlayDungeonCancelSE();
|
|
r7 = 2;
|
|
break;
|
|
}
|
|
}
|
|
|
|
AddMenuCursorSprite(&gDungeonMenu);
|
|
DungeonRunFrameActions(0x37);
|
|
if (r7 == 0) {
|
|
continue;
|
|
}
|
|
else if (r7 == 2) {
|
|
r10 = gDungeonMenu.menuIndex;
|
|
if (gUnknown_202F310 < a1) {
|
|
continue;
|
|
}
|
|
|
|
if (DisplayDungeonYesNoMessage(NULL, gUnknown_80FDFB8, TRUE) == 1) {
|
|
break;
|
|
}
|
|
else {
|
|
continue;
|
|
}
|
|
}
|
|
else if (r7 == 3) {
|
|
r10 = gDungeonMenu.menuIndex;
|
|
sub_806806C(a3[gUnknown_202F30C + r10]);
|
|
continue;
|
|
}
|
|
else {
|
|
s32 arrId;
|
|
u8 locIdIsPartner;
|
|
|
|
r10 = gDungeonMenu.menuIndex;
|
|
arrId = gUnknown_202F30C + r10;
|
|
gDungeonSubMenuItemsCount = 0;
|
|
AddActionToDungeonSubMenu(0x29, 0);
|
|
AddActionToDungeonSubMenu(0x2A, 0);
|
|
AddActionToDungeonSubMenu(0x40, 0);
|
|
if (a3[arrId]->flags & POKEMON_FLAG_x8000) {
|
|
SetActionUnusableInDungeonSubMenu(0x29);
|
|
}
|
|
else {
|
|
SetActionUnusableInDungeonSubMenu(0x2A);
|
|
}
|
|
|
|
// This unnecessary variable is required to match.
|
|
locIdIsPartner = DUNGEON_JOIN_LOCATION_PARTNER;
|
|
if (a3[arrId]->isTeamLeader || (a3[arrId]->dungeonLocation.id == DUNGEON_JOIN_LOCATION_LEADER || a3[arrId]->dungeonLocation.id == locIdIsPartner)) {
|
|
SetActionUnusableInDungeonSubMenu(0x29);
|
|
}
|
|
|
|
sub_8045064();
|
|
CreateDungeonMenuSubWindow(&spTxtStruct.id[0], 0x15);
|
|
|
|
while (1) {
|
|
AddMenuCursorSprite(&gDungeonMenu);
|
|
DungeonRunFrameActions(0x37);
|
|
|
|
if (gRealInputs.repeated & DPAD_DOWN) {
|
|
PlayDungeonCursorSE(1);
|
|
MoveMenuCursorDownWrapAround(&gDungeonMenu, 1);
|
|
}
|
|
if (gRealInputs.repeated & DPAD_UP) {
|
|
PlayDungeonCursorSE(1);
|
|
MoveMenuCursorUpWrapAround(&gDungeonMenu, 1);
|
|
}
|
|
|
|
if ((gRealInputs.pressed & A_BUTTON) || gDungeonMenu.touchScreen.a_button) {
|
|
if (CanSubMenuItemBeChosen(gDungeonMenu.menuIndex)) {
|
|
PlayDungeonConfirmationSE();
|
|
r7 = 1;
|
|
break;
|
|
}
|
|
PlayDungeonCancelSE();
|
|
}
|
|
if ((gRealInputs.pressed & B_BUTTON) || gDungeonMenu.touchScreen.b_button) {
|
|
PlayDungeonCancelSE();
|
|
r7 = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
AddMenuCursorSprite(&gDungeonMenu);
|
|
DungeonRunFrameActions(0x37);
|
|
if (r7 != 0) {
|
|
if (gDungeonMenu.menuIndex == 0) {
|
|
a3[arrId]->flags |= POKEMON_FLAG_x8000;
|
|
sub_8068310(a2, a3);
|
|
}
|
|
else if (gDungeonMenu.menuIndex == 1) {
|
|
a3[arrId]->flags &= ~(POKEMON_FLAG_x8000);
|
|
sub_8068310(a2, a3);
|
|
}
|
|
else {
|
|
sub_806806C(a3[arrId]);
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_8067F00(u8 a0, Pokemon **a1, s32 a2_, s32 a3, s32 a4)
|
|
{
|
|
s32 i, y;
|
|
s32 a2;
|
|
|
|
a2 = a2_ - 1;
|
|
y = 0x16;
|
|
|
|
sub_80073B8(0);
|
|
WriteFriendAreaName(gFormatBuffer_Monsters[0], a0, FALSE);
|
|
PrintFormattedStringOnWindow(12, 0, _("{POKEMON_0}"), 0, '\0');
|
|
i = 0;
|
|
while (i < 10) {
|
|
if (a2 >= 0) {
|
|
if (a2 >= a3) {
|
|
break;
|
|
}
|
|
|
|
PrintColoredPokeNameToBuffer(gFormatBuffer_Monsters[0], a1[a2], 0);
|
|
sub_808D930(gFormatBuffer_Monsters[1], a1[a2]->speciesNum);
|
|
gFormatArgs[0] = a2 + 1;
|
|
if (a1[a2]->flags & POKEMON_FLAG_x8000) {
|
|
InlineStrcpy(gFormatBuffer_Items[0], _("{STAR_BULLET}"));
|
|
}
|
|
else {
|
|
InlineStrcpy(gFormatBuffer_Items[0], _("{ICON_BLANK}"));
|
|
}
|
|
|
|
if (a1[a2]->flags & POKEMON_FLAG_x4000) {
|
|
PrintFormattedStringOnWindow(7, y, _("{MOVE_ITEM_0}{color CYAN}$v02:{POKEMON_0}{reset}"), 0, '\0');
|
|
}
|
|
else {
|
|
PrintFormattedStringOnWindow(7, y, _("{MOVE_ITEM_0}{color YELLOW}$v02:{POKEMON_0}{reset}"), 0, '\0');
|
|
}
|
|
}
|
|
|
|
i++;
|
|
y += 12;
|
|
a2++;
|
|
}
|
|
|
|
sub_80073E0(0);
|
|
sub_80073B8(1);
|
|
if (gUnknown_202F310 >= a4) {
|
|
PrintFormattedStringOnWindow(8, 2, _("Press {B_BUTTON}\nif OK."), 1, '\0');
|
|
}
|
|
else {
|
|
gFormatArgs[0] = a4 - gUnknown_202F310;
|
|
PrintFormattedStringOnWindow(8, 2, _("Say bye to\n{VALUE_0} more"), 1, '\0');
|
|
}
|
|
|
|
sub_80073E0(1);
|
|
}
|
|
|
|
void sub_806806C(Pokemon *a0)
|
|
{
|
|
struct MonSummaryInfo unkStruct;
|
|
struct UnkInfoTabStruct var_C8;
|
|
WindowTemplates spTxtStruct = {0};
|
|
s32 r7;
|
|
|
|
spTxtStruct.id[0].type = WINDOW_TYPE_WITH_HEADER;
|
|
spTxtStruct.id[0].pos.x = 2;
|
|
spTxtStruct.id[0].pos.y = 2;
|
|
spTxtStruct.id[0].width = 0x12;
|
|
spTxtStruct.id[0].height = 0xE;
|
|
spTxtStruct.id[0].unk10 = 0x12;
|
|
spTxtStruct.id[0].unk12 = 2;
|
|
spTxtStruct.id[0].header = &gUnknown_202F308;
|
|
spTxtStruct.id[1].type = WINDOW_TYPE_NORMAL;
|
|
spTxtStruct.id[2].type = WINDOW_TYPE_NORMAL;
|
|
spTxtStruct.id[3].type = WINDOW_TYPE_NORMAL;
|
|
|
|
r7 = 0;
|
|
unkStruct.unk40 = 0;
|
|
unkStruct.unk56 = 0;
|
|
gDungeonMenu.menuIndex = 0;
|
|
|
|
while (1) {
|
|
bool32 loopBreak = FALSE;
|
|
s32 spF8[4] = {2, 3, 4, 5};
|
|
|
|
gUnknown_202F308.count = 4;
|
|
gUnknown_202F308.currId = r7;
|
|
gUnknown_202F308.width = 10;
|
|
gUnknown_202F308.f3 = 0;
|
|
|
|
gDungeonMenu.currPage = r7;
|
|
gDungeonMenu.pagesCount = 4;
|
|
gDungeonMenu.currPageEntries = 0;
|
|
gDungeonMenu.menuIndex = 0;
|
|
gDungeonMenu.entriesPerPage = 0;
|
|
gDungeonMenu.unk4 = 0;
|
|
gDungeonMenu.firstEntryY = 16;
|
|
gDungeonMenu.unk14.x = 0;
|
|
gDungeonMenu.windowId = 0;
|
|
|
|
ResetTouchScreenMenuInput(&gDungeonMenu.touchScreen);
|
|
DungeonShowWindows(&spTxtStruct, 1);
|
|
SetMonSummaryInfo(&unkStruct, a0, gDungeon->unk644.unk16);
|
|
ShowPokemonSummaryWindow(spF8[r7], r7, &unkStruct, &var_C8, 0);
|
|
|
|
gDungeonMenu.leftRightArrowsPos.x = (gWindows[0].x + 15) * 8;
|
|
gDungeonMenu.leftRightArrowsPos.y = ((gWindows[0].y + 1) * 8) - 2;
|
|
|
|
while (1) {
|
|
s32 r5;
|
|
|
|
AddMenuCursorSprite(&gDungeonMenu);
|
|
if (spF8[r7] == 4) {
|
|
if (var_C8.unk0[8] != 0) {
|
|
sub_80684C4();
|
|
}
|
|
if (unkStruct.unk40 != 0) {
|
|
sub_8068344();
|
|
}
|
|
}
|
|
|
|
r5 = GetTouchScreenArrowPress(0, sTouchScreenArrowPressData);
|
|
DungeonRunFrameActions(0x1C);
|
|
if ((gRealInputs.pressed & DPAD_RIGHT) || gDungeonMenu.touchScreen.dpad_right) {
|
|
PlayDungeonCursorSE(0);
|
|
if (++r7 == 4) {
|
|
r7 = 0;
|
|
}
|
|
break;
|
|
}
|
|
if ((gRealInputs.pressed & DPAD_LEFT) || gDungeonMenu.touchScreen.dpad_left) {
|
|
PlayDungeonCursorSE(0);
|
|
if (--r7 == -1) {
|
|
r7 = 3;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (spF8[r7] == 4) {
|
|
if (((gRealInputs.repeated & DPAD_DOWN) || r5 == 2) && var_C8.unk0[8] != 0) {
|
|
s32 i;
|
|
|
|
PlayDungeonCursorSE(0);
|
|
for (i = 0; i < 6; i++) {
|
|
ScrollDownWindowFunc(0);
|
|
DungeonRunFrameActions(0x1C);
|
|
}
|
|
unkStruct.unk40++;
|
|
break;
|
|
}
|
|
if (((gRealInputs.repeated & DPAD_UP) || r5 == 1) && unkStruct.unk40 != 0) {
|
|
s32 i;
|
|
|
|
PlayDungeonCursorSE(0);
|
|
for (i = 0; i < 6; i++) {
|
|
ScrollUpWindowFunc(0);
|
|
DungeonRunFrameActions(0x1C);
|
|
}
|
|
unkStruct.unk40--;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (sub_80048C8()) {
|
|
continue;
|
|
}
|
|
|
|
if ((gRealInputs.pressed & A_BUTTON) || gDungeonMenu.touchScreen.a_button) {
|
|
PlayDungeonConfirmationSE();
|
|
loopBreak = TRUE;
|
|
break;
|
|
}
|
|
if ((gRealInputs.pressed & B_BUTTON) || gDungeonMenu.touchScreen.b_button) {
|
|
PlayDungeonCancelSE();
|
|
loopBreak = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
DungeonRunFrameActions(0x37);
|
|
if (loopBreak) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
sub_803EAF0(0, NULL);
|
|
}
|
|
|
|
void sub_8068310(s32 n, Pokemon **monPtrs)
|
|
{
|
|
s32 i;
|
|
s32 counter = 0;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
if ((monPtrs[i]->flags & POKEMON_FLAG_x8000) != 0) {
|
|
counter++;
|
|
}
|
|
}
|
|
gUnknown_202F310 = counter;
|
|
}
|
|
|
|
void sub_8068344(void)
|
|
{
|
|
if ((gDungeonFramesCounter & 8) != 0) {
|
|
Window *window = &gWindows[0];
|
|
SpriteOAM sprite = {0};
|
|
|
|
SpriteSetAffine1(&sprite, 0);
|
|
SpriteSetAffine2(&sprite, 0);
|
|
SpriteSetObjMode(&sprite, 0);
|
|
SpriteSetMosaic(&sprite, 0);
|
|
SpriteSetBpp(&sprite, 0);
|
|
SpriteSetShape(&sprite, 1);
|
|
SpriteSetMatrixNum(&sprite, 16);
|
|
SpriteSetSize(&sprite, 0);
|
|
SpriteSetTileNum(&sprite, 0x3F0);
|
|
SpriteSetPriority(&sprite, 0);
|
|
SpriteSetPalNum(&sprite, 15);
|
|
SpriteSetY(&sprite, (window->y * 8) + 0x8);
|
|
SpriteSetX(&sprite, (window->x * 8) + 0x40);
|
|
AddSprite(&sprite,0x100,NULL,NULL);
|
|
}
|
|
}
|
|
|
|
// The same as sub_80623B0
|
|
void sub_80684C4(void)
|
|
{
|
|
if ((gDungeonFramesCounter & 8) != 0) {
|
|
Window *window = &gWindows[0];
|
|
SpriteOAM sprite = {0};
|
|
|
|
SpriteSetAffine1(&sprite, 0);
|
|
SpriteSetAffine2(&sprite, 0);
|
|
SpriteSetObjMode(&sprite, 0);
|
|
SpriteSetMosaic(&sprite, 0);
|
|
SpriteSetBpp(&sprite, 0);
|
|
SpriteSetShape(&sprite, 1);
|
|
SpriteSetMatrixNum(&sprite, 0);
|
|
SpriteSetSize(&sprite, 0);
|
|
SpriteSetTileNum(&sprite, 0x3F0);
|
|
SpriteSetPriority(&sprite, 0);
|
|
SpriteSetPalNum(&sprite, 15);
|
|
SpriteSetY(&sprite, (window->y * 8) + 0x70);
|
|
SpriteSetX(&sprite, (window->x * 8) + 0x40);
|
|
AddSprite(&sprite,0x100,NULL,NULL);
|
|
}
|
|
}
|