From 5fa8ca55b07dd5e5fb0f8cdbc111c36087eade3f Mon Sep 17 00:00:00 2001 From: GriffinR Date: Tue, 17 May 2022 17:12:45 -0400 Subject: [PATCH 01/69] Clean up some additional unknowns --- data/battle_ai_scripts.s | 9 ++++++--- graphics_file_rules.mk | 3 --- src/item.c | 6 ------ 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/data/battle_ai_scripts.s b/data/battle_ai_scripts.s index d856b926a..c211c4dd2 100644 --- a/data/battle_ai_scripts.s +++ b/data/battle_ai_scripts.s @@ -1099,15 +1099,18 @@ AI_CV_AttackDown3: score -2 AI_CV_AttackDown4: get_target_type1 - if_in_bytes AI_CV_AttackDown_UnknownTypeList, AI_CV_AttackDown_End + if_in_bytes AI_CV_AttackDown_PhysicalTypeList, AI_CV_AttackDown_End get_target_type2 - if_in_bytes AI_CV_AttackDown_UnknownTypeList, AI_CV_AttackDown_End + if_in_bytes AI_CV_AttackDown_PhysicalTypeList, AI_CV_AttackDown_End if_random_less_than 50, AI_CV_AttackDown_End score -2 AI_CV_AttackDown_End: end -AI_CV_AttackDown_UnknownTypeList: +@ If the target is not of any type in this list then using the move may be discouraged. +@ It seems likely this was meant to be "discourage reducing the target's attack if they're +@ not a physical type", but they've left out Flying, Poison, and Ghost. +AI_CV_AttackDown_PhysicalTypeList: .byte TYPE_NORMAL .byte TYPE_FIGHTING .byte TYPE_GROUND diff --git a/graphics_file_rules.mk b/graphics_file_rules.mk index 9e5c19193..704943126 100644 --- a/graphics_file_rules.mk +++ b/graphics_file_rules.mk @@ -665,9 +665,6 @@ $(WALLPAPERGFXDIR)/ludicolo/tiles.4bpp: $(WALLPAPERGFXDIR)/friends_frame2.4bpp $ $(WALLPAPERGFXDIR)/whiscash/tiles.4bpp: $(WALLPAPERGFXDIR)/friends_frame2.4bpp $(WALLPAPERGFXDIR)/whiscash/bg.4bpp @cat $^ >$@ -$(OBJEVENTGFXDIR)/pics/effects/unknown_4F6D38/0.4bpp: %.4bpp: %.png - $(GFX) $< $@ -num_tiles 11 - $(INTERFACEGFXDIR)/selector_outline.4bpp: %.4bpp: %.png $(GFX) $< $@ -num_tiles 8 diff --git a/src/item.c b/src/item.c index 63287693a..8d0f45fed 100644 --- a/src/item.c +++ b/src/item.c @@ -15,20 +15,14 @@ #include "constants/items.h" #include "constants/hold_effects.h" -extern u16 gUnknown_0203CF30[]; - -// this file's functions static bool8 CheckPyramidBagHasItem(u16 itemId, u16 count); static bool8 CheckPyramidBagHasSpace(u16 itemId, u16 count); -// EWRAM variables EWRAM_DATA struct BagPocket gBagPockets[POCKETS_COUNT] = {0}; -// rodata #include "data/text/item_descriptions.h" #include "data/items.h" -// code static u16 GetBagItemQuantity(u16 *quantity) { return gSaveBlock2Ptr->encryptionKey ^ *quantity; From f254df9a1a09163e4408470032220526dcbc0b98 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 11:28:27 -0400 Subject: [PATCH 02/69] Use window constants in berry_tag_screen --- src/berry_tag_screen.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/berry_tag_screen.c b/src/berry_tag_screen.c index f683c73f4..41fb8afba 100644 --- a/src/berry_tag_screen.c +++ b/src/berry_tag_screen.c @@ -102,7 +102,7 @@ static const u8 sTextColors[2][3] = static const struct WindowTemplate sWindowTemplates[] = { - { // WIN_BERRY_NAME + [WIN_BERRY_NAME] = { .bg = 1, .tilemapLeft = 11, .tilemapTop = 4, @@ -111,7 +111,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 15, .baseBlock = 69, }, - { // WIN_SIZE_FIRM + [WIN_SIZE_FIRM] = { .bg = 1, .tilemapLeft = 11, .tilemapTop = 7, @@ -120,7 +120,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 15, .baseBlock = 85, }, - { // WIN_DESC + [WIN_DESC] = { .bg = 1, .tilemapLeft = 4, .tilemapTop = 14, @@ -129,7 +129,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 15, .baseBlock = 157, }, - { // WIN_BERRY_TAG + [WIN_BERRY_TAG] = { .bg = 0, .tilemapLeft = 2, .tilemapTop = 0, From 16be1e8447d3e3cdb66cd6fdf83b428204ffeb50 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 11:57:30 -0400 Subject: [PATCH 03/69] Use window constants for move relearner --- include/menu_specialized.h | 13 +++++- src/menu_specialized.c | 93 +++++++++++++++++++------------------- src/move_relearner.c | 60 ++++++++---------------- 3 files changed, 76 insertions(+), 90 deletions(-) diff --git a/include/menu_specialized.h b/include/menu_specialized.h index 10a211046..06a188b8a 100644 --- a/include/menu_specialized.h +++ b/include/menu_specialized.h @@ -15,6 +15,15 @@ enum { MAILBOXWIN_COUNT }; +// Window IDs for the move relearner +enum { + RELEARNERWIN_DESC_BATTLE, + RELEARNERWIN_DESC_CONTEST, + RELEARNERWIN_MOVE_LIST, + RELEARNERWIN_MSG, + RELEARNERWIN_YESNO, +}; + enum { TAG_CONDITION_MON = 100, TAG_CONDITION_BALL, @@ -117,11 +126,11 @@ void DestroyConditionSparkleSprites(struct Sprite **sprites); void FreeConditionSparkles(struct Sprite **sprites); // Move relearner -void MoveRelearnerPrintText(u8 *str); +void MoveRelearnerPrintMessage(u8 *str); bool16 MoveRelearnerRunTextPrinters(void); void MoveRelearnerCreateYesNoMenu(void); u8 LoadMoveRelearnerMovesList(const struct ListMenuItem *items, u16 numChoices); -void InitMoveRelearnerWindows(bool8 useContextWindow); +void InitMoveRelearnerWindows(bool8 useContestWindow); // Level up window void DrawLevelUpWindowPg1(u16 windowId, u16 *statsBefore, u16 *statsAfter, u8 bgClr, u8 fgClr, u8 shadowClr); diff --git a/src/menu_specialized.c b/src/menu_specialized.c index 42c80b5ee..717190700 100644 --- a/src/menu_specialized.c +++ b/src/menu_specialized.c @@ -105,10 +105,9 @@ static const u8 sConditionToLineLength[MAX_CONDITION + 1] = 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35 }; - static const struct WindowTemplate sMoveRelearnerWindowTemplates[] = { - { + [RELEARNERWIN_DESC_BATTLE] = { .bg = 1, .tilemapLeft = 1, .tilemapTop = 1, @@ -117,7 +116,7 @@ static const struct WindowTemplate sMoveRelearnerWindowTemplates[] = .paletteNum = 0xF, .baseBlock = 0xA }, - { + [RELEARNERWIN_DESC_CONTEST] = { .bg = 1, .tilemapLeft = 1, .tilemapTop = 1, @@ -126,7 +125,7 @@ static const struct WindowTemplate sMoveRelearnerWindowTemplates[] = .paletteNum = 0xF, .baseBlock = 0xCA }, - { + [RELEARNERWIN_MOVE_LIST] = { .bg = 1, .tilemapLeft = 19, .tilemapTop = 1, @@ -135,7 +134,7 @@ static const struct WindowTemplate sMoveRelearnerWindowTemplates[] = .paletteNum = 0xF, .baseBlock = 0x18A }, - { + [RELEARNERWIN_MSG] = { .bg = 1, .tilemapLeft = 4, .tilemapTop = 15, @@ -144,7 +143,8 @@ static const struct WindowTemplate sMoveRelearnerWindowTemplates[] = .paletteNum = 0xF, .baseBlock = 0x202 }, - { + // Unused. Identical to sMoveRelearnerYesNoMenuTemplate + [RELEARNERWIN_YESNO] = { .bg = 0, .tilemapLeft = 22, .tilemapTop = 8, @@ -175,7 +175,7 @@ static const struct ListMenuTemplate sMoveRelearnerMovesListTemplate = .itemPrintFunc = NULL, .totalItems = 0, .maxShowed = 0, - .windowId = 2, + .windowId = RELEARNERWIN_MOVE_LIST, .header_X = 0, .item_X = 8, .cursor_X = 0, @@ -701,7 +701,7 @@ void ConditionGraph_CalcPositions(u8 *conditions, struct UCoords16 *positions) // Move relearner //---------------- -void InitMoveRelearnerWindows(bool8 useContextWindow) +void InitMoveRelearnerWindows(bool8 useContestWindow) { u8 i; @@ -713,20 +713,20 @@ void InitMoveRelearnerWindows(bool8 useContextWindow) for (i = 0; i < ARRAY_COUNT(sMoveRelearnerWindowTemplates) - 1; i++) FillWindowPixelBuffer(i, PIXEL_FILL(1)); - if (!useContextWindow) + if (!useContestWindow) { - PutWindowTilemap(0); - DrawStdFrameWithCustomTileAndPalette(0, FALSE, 0x1, 0xE); + PutWindowTilemap(RELEARNERWIN_DESC_BATTLE); + DrawStdFrameWithCustomTileAndPalette(RELEARNERWIN_DESC_BATTLE, FALSE, 0x1, 0xE); } else { - PutWindowTilemap(1); - DrawStdFrameWithCustomTileAndPalette(1, FALSE, 1, 0xE); + PutWindowTilemap(RELEARNERWIN_DESC_CONTEST); + DrawStdFrameWithCustomTileAndPalette(RELEARNERWIN_DESC_CONTEST, FALSE, 1, 0xE); } - PutWindowTilemap(2); - PutWindowTilemap(3); - DrawStdFrameWithCustomTileAndPalette(2, FALSE, 1, 0xE); - DrawStdFrameWithCustomTileAndPalette(3, FALSE, 1, 0xE); + PutWindowTilemap(RELEARNERWIN_MOVE_LIST); + PutWindowTilemap(RELEARNERWIN_MSG); + DrawStdFrameWithCustomTileAndPalette(RELEARNERWIN_MOVE_LIST, FALSE, 1, 0xE); + DrawStdFrameWithCustomTileAndPalette(RELEARNERWIN_MSG, FALSE, 1, 0xE); MoveRelearnerDummy(); ScheduleBgCopyTilemapToVram(1); } @@ -757,33 +757,34 @@ static void MoveRelearnerLoadBattleMoveDescription(u32 chosenMove) u8 buffer[32]; const u8 *str; - FillWindowPixelBuffer(0, PIXEL_FILL(1)); + FillWindowPixelBuffer(RELEARNERWIN_DESC_BATTLE, PIXEL_FILL(1)); str = gText_MoveRelearnerBattleMoves; - x = GetStringCenterAlignXOffset(FONT_NORMAL, str, 0x80); - AddTextPrinterParameterized(0, FONT_NORMAL, str, x, 1, TEXT_SKIP_DRAW, NULL); + x = GetStringCenterAlignXOffset(FONT_NORMAL, str, 128); + AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, str, x, 1, TEXT_SKIP_DRAW, NULL); str = gText_MoveRelearnerPP; - AddTextPrinterParameterized(0, FONT_NORMAL, str, 4, 0x29, TEXT_SKIP_DRAW, NULL); + AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, str, 4, 41, TEXT_SKIP_DRAW, NULL); str = gText_MoveRelearnerPower; - x = GetStringRightAlignXOffset(FONT_NORMAL, str, 0x6A); - AddTextPrinterParameterized(0, FONT_NORMAL, str, x, 0x19, TEXT_SKIP_DRAW, NULL); + x = GetStringRightAlignXOffset(FONT_NORMAL, str, 106); + AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, str, x, 25, TEXT_SKIP_DRAW, NULL); str = gText_MoveRelearnerAccuracy; - x = GetStringRightAlignXOffset(FONT_NORMAL, str, 0x6A); - AddTextPrinterParameterized(0, FONT_NORMAL, str, x, 0x29, TEXT_SKIP_DRAW, NULL); + x = GetStringRightAlignXOffset(FONT_NORMAL, str, 106); + AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, str, x, 41, TEXT_SKIP_DRAW, NULL); if (chosenMove == LIST_CANCEL) { - CopyWindowToVram(0, COPYWIN_GFX); + // On "Cancel", skip printing move data + CopyWindowToVram(RELEARNERWIN_DESC_BATTLE, COPYWIN_GFX); return; } move = &gBattleMoves[chosenMove]; str = gTypeNames[move->type]; - AddTextPrinterParameterized(0, FONT_NORMAL, str, 4, 0x19, TEXT_SKIP_DRAW, NULL); + AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, str, 4, 25, TEXT_SKIP_DRAW, NULL); x = 4 + GetStringWidth(FONT_NORMAL, gText_MoveRelearnerPP, 0); ConvertIntToDecimalStringN(buffer, move->pp, STR_CONV_MODE_LEFT_ALIGN, 2); - AddTextPrinterParameterized(0, FONT_NORMAL, buffer, x, 0x29, TEXT_SKIP_DRAW, NULL); + AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, buffer, x, 41, TEXT_SKIP_DRAW, NULL); if (move->power < 2) { @@ -794,7 +795,7 @@ static void MoveRelearnerLoadBattleMoveDescription(u32 chosenMove) ConvertIntToDecimalStringN(buffer, move->power, STR_CONV_MODE_LEFT_ALIGN, 3); str = buffer; } - AddTextPrinterParameterized(0, FONT_NORMAL, str, 0x6A, 0x19, TEXT_SKIP_DRAW, NULL); + AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, str, 106, 25, TEXT_SKIP_DRAW, NULL); if (move->accuracy == 0) { @@ -805,10 +806,10 @@ static void MoveRelearnerLoadBattleMoveDescription(u32 chosenMove) ConvertIntToDecimalStringN(buffer, move->accuracy, STR_CONV_MODE_LEFT_ALIGN, 3); str = buffer; } - AddTextPrinterParameterized(0, FONT_NORMAL, str, 0x6A, 0x29, TEXT_SKIP_DRAW, NULL); + AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NORMAL, str, 106, 41, TEXT_SKIP_DRAW, NULL); str = gMoveDescriptionPointers[chosenMove - 1]; - AddTextPrinterParameterized(0, FONT_NARROW, str, 0, 0x41, 0, NULL); + AddTextPrinterParameterized(RELEARNERWIN_DESC_BATTLE, FONT_NARROW, str, 0, 65, 0, NULL); } static void MoveRelearnerMenuLoadContestMoveDescription(u32 chosenMove) @@ -818,33 +819,33 @@ static void MoveRelearnerMenuLoadContestMoveDescription(u32 chosenMove) const struct ContestMove *move; MoveRelearnerShowHideHearts(chosenMove); - FillWindowPixelBuffer(1, PIXEL_FILL(1)); + FillWindowPixelBuffer(RELEARNERWIN_DESC_CONTEST, PIXEL_FILL(1)); str = gText_MoveRelearnerContestMovesTitle; - x = GetStringCenterAlignXOffset(FONT_NORMAL, str, 0x80); - AddTextPrinterParameterized(1, FONT_NORMAL, str, x, 1, TEXT_SKIP_DRAW, NULL); + x = GetStringCenterAlignXOffset(FONT_NORMAL, str, 128); + AddTextPrinterParameterized(RELEARNERWIN_DESC_CONTEST, FONT_NORMAL, str, x, 1, TEXT_SKIP_DRAW, NULL); str = gText_MoveRelearnerAppeal; - x = GetStringRightAlignXOffset(FONT_NORMAL, str, 0x5C); - AddTextPrinterParameterized(1, FONT_NORMAL, str, x, 0x19, TEXT_SKIP_DRAW, NULL); + x = GetStringRightAlignXOffset(FONT_NORMAL, str, 92); + AddTextPrinterParameterized(RELEARNERWIN_DESC_CONTEST, FONT_NORMAL, str, x, 25, TEXT_SKIP_DRAW, NULL); str = gText_MoveRelearnerJam; - x = GetStringRightAlignXOffset(FONT_NORMAL, str, 0x5C); - AddTextPrinterParameterized(1, FONT_NORMAL, str, x, 0x29, TEXT_SKIP_DRAW, NULL); + x = GetStringRightAlignXOffset(FONT_NORMAL, str, 92); + AddTextPrinterParameterized(RELEARNERWIN_DESC_CONTEST, FONT_NORMAL, str, x, 41, TEXT_SKIP_DRAW, NULL); if (chosenMove == MENU_NOTHING_CHOSEN) { - CopyWindowToVram(1, COPYWIN_GFX); + CopyWindowToVram(RELEARNERWIN_DESC_CONTEST, COPYWIN_GFX); return; } move = &gContestMoves[chosenMove]; str = gContestMoveTypeTextPointers[move->contestCategory]; - AddTextPrinterParameterized(1, FONT_NORMAL, str, 4, 0x19, TEXT_SKIP_DRAW, NULL); + AddTextPrinterParameterized(RELEARNERWIN_DESC_CONTEST, FONT_NORMAL, str, 4, 25, TEXT_SKIP_DRAW, NULL); str = gContestEffectDescriptionPointers[move->effect]; - AddTextPrinterParameterized(1, FONT_NARROW, str, 0, 0x41, TEXT_SKIP_DRAW, NULL); + AddTextPrinterParameterized(RELEARNERWIN_DESC_CONTEST, FONT_NARROW, str, 0, 65, TEXT_SKIP_DRAW, NULL); - CopyWindowToVram(1, COPYWIN_GFX); + CopyWindowToVram(RELEARNERWIN_DESC_CONTEST, COPYWIN_GFX); } static void MoveRelearnerCursorCallback(s32 itemIndex, bool8 onInit, struct ListMenu *list) @@ -855,20 +856,20 @@ static void MoveRelearnerCursorCallback(s32 itemIndex, bool8 onInit, struct List MoveRelearnerMenuLoadContestMoveDescription(itemIndex); } -void MoveRelearnerPrintText(u8 *str) +void MoveRelearnerPrintMessage(u8 *str) { u8 speed; - FillWindowPixelBuffer(3, PIXEL_FILL(1)); + FillWindowPixelBuffer(RELEARNERWIN_MSG, PIXEL_FILL(1)); gTextFlags.canABSpeedUpPrint = TRUE; speed = GetPlayerTextSpeedDelay(); - AddTextPrinterParameterized2(3, FONT_NORMAL, str, speed, NULL, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_WHITE, 3); + AddTextPrinterParameterized2(RELEARNERWIN_MSG, FONT_NORMAL, str, speed, NULL, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_WHITE, 3); } bool16 MoveRelearnerRunTextPrinters(void) { RunTextPrinters(); - return IsTextPrinterActive(3); + return IsTextPrinterActive(RELEARNERWIN_MSG); } void MoveRelearnerCreateYesNoMenu(void) diff --git a/src/move_relearner.c b/src/move_relearner.c index d9c943b57..bf2e7b5c2 100644 --- a/src/move_relearner.c +++ b/src/move_relearner.c @@ -458,10 +458,10 @@ static void CB2_MoveRelearnerMain(void) UpdatePaletteFade(); } -static void FormatAndPrintText(const u8 *src) +static void PrintMessageWithPlaceholders(const u8 *src) { StringExpandPlaceholders(gStringVar4, src); - MoveRelearnerPrintText(gStringVar4); + MoveRelearnerPrintMessage(gStringVar4); } // See the state machine doc at the top of the file. @@ -515,7 +515,7 @@ static void DoMoveRelearnerMain(void) { if (GiveMoveToMon(&gPlayerParty[sMoveRelearnerStruct->partyMon], GetCurrentSelectedMove()) != MON_HAS_MAX_MOVES) { - FormatAndPrintText(gText_MoveRelearnerPkmnLearnedMove); + PrintMessageWithPlaceholders(gText_MoveRelearnerPkmnLearnedMove); gSpecialVar_0x8004 = TRUE; sMoveRelearnerStruct->state = MENU_STATE_PRINT_TEXT_THEN_FANFARE; } @@ -567,7 +567,7 @@ static void DoMoveRelearnerMain(void) } break; case MENU_STATE_PRINT_TRYING_TO_LEARN_PROMPT: - FormatAndPrintText(gText_MoveRelearnerPkmnTryingToLearnMove); + PrintMessageWithPlaceholders(gText_MoveRelearnerPkmnTryingToLearnMove); sMoveRelearnerStruct->state++; break; case MENU_STATE_WAIT_FOR_TRYING_TO_LEARN: @@ -583,7 +583,7 @@ static void DoMoveRelearnerMain(void) if (var == 0) { - FormatAndPrintText(gText_MoveRelearnerWhichMoveToForget); + PrintMessageWithPlaceholders(gText_MoveRelearnerWhichMoveToForget); sMoveRelearnerStruct->state = MENU_STATE_PRINT_WHICH_MOVE_PROMPT; } else if (var == -1 || var == 1) @@ -594,7 +594,7 @@ static void DoMoveRelearnerMain(void) break; case MENU_STATE_PRINT_STOP_TEACHING: StringCopy(gStringVar2, gMoveNames[GetCurrentSelectedMove()]); - FormatAndPrintText(gText_MoveRelearnerStopTryingToTeachMove); + PrintMessageWithPlaceholders(gText_MoveRelearnerStopTryingToTeachMove); sMoveRelearnerStruct->state++; break; case MENU_STATE_WAIT_FOR_STOP_TEACHING: @@ -630,7 +630,7 @@ static void DoMoveRelearnerMain(void) case MENU_STATE_CHOOSE_SETUP_STATE: if (!MoveRelearnerRunTextPrinters()) { - FillWindowPixelBuffer(3, 0x11); + FillWindowPixelBuffer(RELEARNERWIN_MSG, 0x11); if (sMoveRelearnerMenuSate.showContestInfo == FALSE) { sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE; @@ -687,7 +687,7 @@ static void DoMoveRelearnerMain(void) ShowTeachMoveText(TRUE); } RemoveScrollArrows(); - CopyWindowToVram(3, COPYWIN_GFX); + CopyWindowToVram(RELEARNERWIN_MSG, COPYWIN_GFX); break; case MENU_STATE_TRY_OVERWRITE_MOVE: if (!gPaletteFade.active) @@ -704,7 +704,7 @@ static void DoMoveRelearnerMain(void) RemoveMonPPBonus(&gPlayerParty[sMoveRelearnerStruct->partyMon], sMoveRelearnerStruct->moveSlot); SetMonMoveSlot(&gPlayerParty[sMoveRelearnerStruct->partyMon], GetCurrentSelectedMove(), sMoveRelearnerStruct->moveSlot); StringCopy(gStringVar2, gMoveNames[GetCurrentSelectedMove()]); - FormatAndPrintText(gText_MoveRelearnerAndPoof); + PrintMessageWithPlaceholders(gText_MoveRelearnerAndPoof); sMoveRelearnerStruct->state = MENU_STATE_DOUBLE_FANFARE_FORGOT_MOVE; gSpecialVar_0x8004 = TRUE; } @@ -713,7 +713,7 @@ static void DoMoveRelearnerMain(void) case MENU_STATE_DOUBLE_FANFARE_FORGOT_MOVE: if (!MoveRelearnerRunTextPrinters()) { - FormatAndPrintText(gText_MoveRelearnerPkmnForgotMoveAndLearnedNew); + PrintMessageWithPlaceholders(gText_MoveRelearnerPkmnForgotMoveAndLearnedNew); sMoveRelearnerStruct->state = MENU_STATE_PRINT_TEXT_THEN_FANFARE; PlayFanfare(MUS_LEVEL_UP); } @@ -758,15 +758,13 @@ static void HideHeartSpritesAndShowTeachMoveText(bool8 onlyHideSprites) s32 i; for (i = 0; i < 16; i++) - { gSprites[sMoveRelearnerStruct->heartSpriteIds[i]].invisible = TRUE; - } if (!onlyHideSprites) { StringExpandPlaceholders(gStringVar4, gText_TeachWhichMoveToPkmn); - FillWindowPixelBuffer(3, 0x11); - AddTextPrinterParameterized(3, FONT_NORMAL, gStringVar4, 0, 1, 0, NULL); + FillWindowPixelBuffer(RELEARNERWIN_MSG, 0x11); + AddTextPrinterParameterized(RELEARNERWIN_MSG, FONT_NORMAL, gStringVar4, 0, 1, 0, NULL); } } @@ -779,21 +777,19 @@ static void HandleInput(bool8 showContest) { case LIST_NOTHING_CHOSEN: if (!(JOY_NEW(DPAD_LEFT | DPAD_RIGHT)) && !GetLRKeysPressed()) - { break; - } PlaySE(SE_SELECT); if (showContest == FALSE) { - PutWindowTilemap(1); + PutWindowTilemap(RELEARNERWIN_DESC_CONTEST); sMoveRelearnerStruct->state = MENU_STATE_SETUP_CONTEST_MODE; sMoveRelearnerMenuSate.showContestInfo = TRUE; } else { - PutWindowTilemap(0); + PutWindowTilemap(RELEARNERWIN_DESC_BATTLE); sMoveRelearnerStruct->state = MENU_STATE_SETUP_BATTLE_MODE; sMoveRelearnerMenuSate.showContestInfo = FALSE; } @@ -806,7 +802,7 @@ static void HandleInput(bool8 showContest) RemoveScrollArrows(); sMoveRelearnerStruct->state = MENU_STATE_PRINT_GIVE_UP_PROMPT; StringExpandPlaceholders(gStringVar4, gText_MoveRelearnerGiveUp); - MoveRelearnerPrintText(gStringVar4); + MoveRelearnerPrintMessage(gStringVar4); break; default: PlaySE(SE_SELECT); @@ -814,7 +810,7 @@ static void HandleInput(bool8 showContest) sMoveRelearnerStruct->state = MENU_STATE_PRINT_TEACH_MOVE_PROMPT; StringCopy(gStringVar2, gMoveNames[itemId]); StringExpandPlaceholders(gStringVar4, gText_MoveRelearnerTeachMoveConfirm); - MoveRelearnerPrintText(gStringVar4); + MoveRelearnerPrintMessage(gStringVar4); break; } } @@ -835,8 +831,8 @@ static void ShowTeachMoveText(bool8 shouldDoNothingInstead) if (shouldDoNothingInstead == FALSE) { StringExpandPlaceholders(gStringVar4, gText_TeachWhichMoveToPkmn); - FillWindowPixelBuffer(3, 0x11); - AddTextPrinterParameterized(3, FONT_NORMAL, gStringVar4, 0, 1, 0, NULL); + FillWindowPixelBuffer(RELEARNERWIN_MSG, 0x11); + AddTextPrinterParameterized(RELEARNERWIN_MSG, FONT_NORMAL, gStringVar4, 0, 1, 0, NULL); } } @@ -850,9 +846,7 @@ static void CreateUISprites(void) // These are the appeal hearts. for (i = 0; i < 8; i++) - { sMoveRelearnerStruct->heartSpriteIds[i] = CreateSprite(&sConstestMoveHeartSprite, (i - (i / 4) * 4) * 8 + 104, (i / 4) * 8 + 36, 0); - } // These are the jam harts. // The animation is used to toggle between full/empty heart sprites. @@ -863,17 +857,13 @@ static void CreateUISprites(void) } for (i = 0; i < 16; i++) - { gSprites[sMoveRelearnerStruct->heartSpriteIds[i]].invisible = TRUE; - } } static void AddScrollArrows(void) { if (sMoveRelearnerStruct->moveDisplayArrowTask == TASK_NONE) - { sMoveRelearnerStruct->moveDisplayArrowTask = AddScrollIndicatorArrowPair(&sDisplayModeArrowsTemplate, &sMoveRelearnerStruct->scrollOffset); - } if (sMoveRelearnerStruct->moveListScrollArrowTask == TASK_NONE) { @@ -927,49 +917,35 @@ void MoveRelearnerShowHideHearts(s32 moveId) if (!sMoveRelearnerMenuSate.showContestInfo || moveId == LIST_CANCEL) { for (i = 0; i < 16; i++) - { gSprites[sMoveRelearnerStruct->heartSpriteIds[i]].invisible = TRUE; - } } else { numHearts = (u8)(gContestEffects[gContestMoves[moveId].effect].appeal / 10); if (numHearts == 0xFF) - { numHearts = 0; - } for (i = 0; i < 8; i++) { if (i < numHearts) - { StartSpriteAnim(&gSprites[sMoveRelearnerStruct->heartSpriteIds[i]], 1); - } else - { StartSpriteAnim(&gSprites[sMoveRelearnerStruct->heartSpriteIds[i]], 0); - } gSprites[sMoveRelearnerStruct->heartSpriteIds[i]].invisible = FALSE; } numHearts = (u8)(gContestEffects[gContestMoves[moveId].effect].jam / 10); if (numHearts == 0xFF) - { numHearts = 0; - } for (i = 0; i < 8; i++) { if (i < numHearts) - { StartSpriteAnim(&gSprites[sMoveRelearnerStruct->heartSpriteIds[i + 8]], 3); - } else - { StartSpriteAnim(&gSprites[sMoveRelearnerStruct->heartSpriteIds[i + 8]], 2); - } gSprites[sMoveRelearnerStruct->heartSpriteIds[i + 8]].invisible = FALSE; } } From dd5daa3208484c0f13c9dcbfe7594e9251a5d74e Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 12:15:17 -0400 Subject: [PATCH 04/69] Use window constants in berry_blender --- src/berry_blender.c | 87 ++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/src/berry_blender.c b/src/berry_blender.c index d099a14ba..975ad7ea1 100644 --- a/src/berry_blender.c +++ b/src/berry_blender.c @@ -106,6 +106,13 @@ enum { // Last berry that an NPC can put in #define NUM_NPC_BERRIES ITEM_TO_BERRY(ITEM_ASPEAR_BERRY) +enum { + // Windows 0-3 are used implicitly in several loops over BLENDER_MAX_PLAYERS + // i.e. window 0 is for player 1, window 1 for player 2, etc. + WIN_MSG = BLENDER_MAX_PLAYERS, + WIN_RESULTS, +}; + struct BlenderBerry { u16 itemId; @@ -200,7 +207,7 @@ static void SpriteCB_ScoreSymbolBest(struct Sprite *); static void InitLocalPlayers(u8); static void CB2_LoadBerryBlender(void); static void UpdateBlenderCenter(void); -static bool32 Blender_PrintText(s16 *, const u8 *, s32 ); +static bool32 PrintMessage(s16 *, const u8 *, s32 ); static void StartBlender(void); static void CB2_StartBlenderLink(void); static void CB2_StartBlenderLocal(void); @@ -332,7 +339,7 @@ static const struct BgTemplate sBgTemplates[3] = static const struct WindowTemplate sWindowTemplates[] = { - { + { // Player 1 .bg = 0, .tilemapLeft = 1, .tilemapTop = 6, @@ -341,7 +348,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 14, .baseBlock = 0x28, }, - { + { // Player 2 .bg = 0, .tilemapLeft = 22, .tilemapTop = 6, @@ -350,7 +357,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 14, .baseBlock = 0x36, }, - { + { // Player 3 .bg = 0, .tilemapLeft = 1, .tilemapTop = 12, @@ -359,7 +366,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 14, .baseBlock = 0x44, }, - { + { // Player 4 .bg = 0, .tilemapLeft = 22, .tilemapTop = 12, @@ -368,7 +375,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 14, .baseBlock = 0x52, }, - { + [WIN_MSG] = { .bg = 0, .tilemapLeft = 2, .tilemapTop = 15, @@ -377,7 +384,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 14, .baseBlock = 0x60, }, - { + [WIN_RESULTS] = { .bg = 0, .tilemapLeft = 5, .tilemapTop = 3, @@ -1107,7 +1114,7 @@ static void CB2_LoadBerryBlender(void) sBerryBlender->mainState++; break; case 4: - if (Blender_PrintText(&sBerryBlender->textState, sText_BerryBlenderStart, GetPlayerTextSpeedDelay())) + if (PrintMessage(&sBerryBlender->textState, sText_BerryBlenderStart, GetPlayerTextSpeedDelay())) sBerryBlender->mainState++; break; case 5: @@ -1337,7 +1344,7 @@ static void CB2_StartBlenderLink(void) } break; case 5: - Blender_PrintText(&sBerryBlender->textState, sText_CommunicationStandby, 0); + PrintMessage(&sBerryBlender->textState, sText_CommunicationStandby, 0); sBerryBlender->mainState = 8; sBerryBlender->framesToWait = 0; break; @@ -1363,7 +1370,7 @@ static void CB2_StartBlenderLink(void) if (++sBerryBlender->framesToWait > 20) { // Wait for partners' berries - ClearDialogWindowAndFrameToTransparent(4, TRUE); + ClearDialogWindowAndFrameToTransparent(WIN_MSG, TRUE); if (GetBlockReceivedStatus() == GetLinkPlayerCountAsBitFlags()) { for (i = 0; i < GetLinkPlayerCount(); i++) @@ -2664,7 +2671,7 @@ static void CB2_EndBlenderGame(void) } break; case 7: - if (Blender_PrintText(&sBerryBlender->textState, sText_WouldLikeToBlendAnotherBerry, GetPlayerTextSpeedDelay())) + if (PrintMessage(&sBerryBlender->textState, sText_WouldLikeToBlendAnotherBerry, GetPlayerTextSpeedDelay())) sBerryBlender->gameEndState++; break; case 9: @@ -2748,7 +2755,7 @@ static void CB2_EndBlenderGame(void) sBerryBlender->gameEndState++; break; case 13: - if (Blender_PrintText(&sBerryBlender->textState, sText_CommunicationStandby, GetPlayerTextSpeedDelay())) + if (PrintMessage(&sBerryBlender->textState, sText_CommunicationStandby, GetPlayerTextSpeedDelay())) { SetMainCallback2(CB2_CheckPlayAgainLink); sBerryBlender->gameEndState = 0; @@ -2858,7 +2865,7 @@ static void CB2_CheckPlayAgainLink(void) StringAppend(gStringVar4, sText_HasNoBerriesToPut); break; case 3: - if (Blender_PrintText(&sBerryBlender->textState, gStringVar4, GetPlayerTextSpeedDelay())) + if (PrintMessage(&sBerryBlender->textState, gStringVar4, GetPlayerTextSpeedDelay())) { sBerryBlender->framesToWait = 0; sBerryBlender->gameEndState++; @@ -2869,7 +2876,7 @@ static void CB2_CheckPlayAgainLink(void) sBerryBlender->gameEndState = 5; break; case 5: - Blender_PrintText(&sBerryBlender->textState, gText_SavingDontTurnOff2, 0); + PrintMessage(&sBerryBlender->textState, gText_SavingDontTurnOff2, 0); SetLinkStandbyCallback(); sBerryBlender->gameEndState++; break; @@ -2965,7 +2972,7 @@ static void CB2_CheckPlayAgainLocal(void) StringCopy(gStringVar4, sText_RunOutOfBerriesForBlending); break; case 3: - if (Blender_PrintText(&sBerryBlender->textState, gStringVar4, GetPlayerTextSpeedDelay())) + if (PrintMessage(&sBerryBlender->textState, gStringVar4, GetPlayerTextSpeedDelay())) sBerryBlender->gameEndState = 9; break; case 9: @@ -3495,7 +3502,7 @@ static bool8 PrintBlendingResults(void) u8 *txtPtr; xPos = GetStringCenterAlignXOffset(FONT_NORMAL, sText_BlendingResults, 0xA8); - Blender_AddTextPrinter(5, sText_BlendingResults, xPos, 1, TEXT_SKIP_DRAW, 0); + Blender_AddTextPrinter(WIN_RESULTS, sText_BlendingResults, xPos, 1, TEXT_SKIP_DRAW, 0); if (sBerryBlender->numPlayers == BLENDER_MAX_PLAYERS) yPos = 17; @@ -3510,15 +3517,15 @@ static bool8 PrintBlendingResults(void) StringAppend(sBerryBlender->stringVar, sText_Dot); StringAppend(sBerryBlender->stringVar, gText_Space); StringAppend(sBerryBlender->stringVar, gLinkPlayers[place].name); - Blender_AddTextPrinter(5, sBerryBlender->stringVar, 8, yPos, TEXT_SKIP_DRAW, 3); + Blender_AddTextPrinter(WIN_RESULTS, sBerryBlender->stringVar, 8, yPos, TEXT_SKIP_DRAW, 3); StringCopy(sBerryBlender->stringVar, sBerryBlender->blendedBerries[place].name); ConvertInternationalString(sBerryBlender->stringVar, gLinkPlayers[place].language); StringAppend(sBerryBlender->stringVar, sText_SpaceBerry); - Blender_AddTextPrinter(5, sBerryBlender->stringVar, 0x54, yPos, TEXT_SKIP_DRAW, 3); + Blender_AddTextPrinter(WIN_RESULTS, sBerryBlender->stringVar, 0x54, yPos, TEXT_SKIP_DRAW, 3); } - Blender_AddTextPrinter(5, sText_MaximumSpeed, 0, 0x51, TEXT_SKIP_DRAW, 3); + Blender_AddTextPrinter(WIN_RESULTS, sText_MaximumSpeed, 0, 0x51, TEXT_SKIP_DRAW, 3); ConvertIntToDecimalStringN(sBerryBlender->stringVar, sBerryBlender->maxRPM / 100, STR_CONV_MODE_RIGHT_ALIGN, 3); StringAppend(sBerryBlender->stringVar, sText_Dot); @@ -3527,8 +3534,8 @@ static bool8 PrintBlendingResults(void) StringAppend(sBerryBlender->stringVar, sText_RPM); xPos = GetStringRightAlignXOffset(FONT_NORMAL, sBerryBlender->stringVar, 0xA8); - Blender_AddTextPrinter(5, sBerryBlender->stringVar, xPos, 0x51, TEXT_SKIP_DRAW, 3); - Blender_AddTextPrinter(5, sText_Time, 0, 0x61, TEXT_SKIP_DRAW, 3); + Blender_AddTextPrinter(WIN_RESULTS, sBerryBlender->stringVar, xPos, 0x51, TEXT_SKIP_DRAW, 3); + Blender_AddTextPrinter(WIN_RESULTS, sText_Time, 0, 0x61, TEXT_SKIP_DRAW, 3); seconds = (sBerryBlender->gameFrameTime / 60) % 60; minutes = (sBerryBlender->gameFrameTime / (60 * 60)); @@ -3540,12 +3547,12 @@ static bool8 PrintBlendingResults(void) StringAppend(sBerryBlender->stringVar, sText_Sec); xPos = GetStringRightAlignXOffset(FONT_NORMAL, sBerryBlender->stringVar, 0xA8); - Blender_AddTextPrinter(5, sBerryBlender->stringVar, xPos, 0x61, TEXT_SKIP_DRAW, 3); + Blender_AddTextPrinter(WIN_RESULTS, sBerryBlender->stringVar, xPos, 0x61, TEXT_SKIP_DRAW, 3); sBerryBlender->framesToWait = 0; sBerryBlender->mainState++; - CopyWindowToVram(5, COPYWIN_GFX); + CopyWindowToVram(WIN_RESULTS, COPYWIN_GFX); } break; case 4: @@ -3553,7 +3560,7 @@ static bool8 PrintBlendingResults(void) sBerryBlender->mainState++; break; case 5: - ClearStdWindowAndFrameToTransparent(5, TRUE); + ClearStdWindowAndFrameToTransparent(WIN_RESULTS, TRUE); for (i = 0; i < BLENDER_MAX_PLAYERS; i++) { @@ -3581,7 +3588,7 @@ static bool8 PrintBlendingResults(void) sBerryBlender->mainState++; break; case 6: - if (Blender_PrintText(&sBerryBlender->textState, sBerryBlender->stringVar, GetPlayerTextSpeedDelay())) + if (PrintMessage(&sBerryBlender->textState, sBerryBlender->stringVar, GetPlayerTextSpeedDelay())) { TryUpdateBerryBlenderRecord(); return TRUE; @@ -3692,9 +3699,9 @@ static bool8 PrintBlendingRanking(void) } break; case 3: - DrawStdFrameWithCustomTileAndPalette(5, FALSE, 1, 0xD); + DrawStdFrameWithCustomTileAndPalette(WIN_RESULTS, FALSE, 1, 0xD); xPos = GetStringCenterAlignXOffset(FONT_NORMAL, sText_Ranking, 168); - Blender_AddTextPrinter(5, sText_Ranking, xPos, 1, TEXT_SKIP_DRAW, 0); + Blender_AddTextPrinter(WIN_RESULTS, sText_Ranking, xPos, 1, TEXT_SKIP_DRAW, 0); sBerryBlender->scoreIconIds[SCORE_BEST] = CreateSprite(&sSpriteTemplate_ScoreSymbols, 128, 52, 0); StartSpriteAnim(&gSprites[sBerryBlender->scoreIconIds[SCORE_BEST]], SCOREANIM_BEST_STATIC); @@ -3718,20 +3725,20 @@ static bool8 PrintBlendingRanking(void) StringAppend(sBerryBlender->stringVar, sText_Dot); StringAppend(sBerryBlender->stringVar, gText_Space); StringAppend(sBerryBlender->stringVar, gLinkPlayers[place].name); - Blender_AddTextPrinter(5, sBerryBlender->stringVar, 0, yPos, TEXT_SKIP_DRAW, 3); + Blender_AddTextPrinter(WIN_RESULTS, sBerryBlender->stringVar, 0, yPos, TEXT_SKIP_DRAW, 3); ConvertIntToDecimalStringN(sBerryBlender->stringVar, sBerryBlender->scores[place][SCORE_BEST], STR_CONV_MODE_RIGHT_ALIGN, 3); - Blender_AddTextPrinter(5, sBerryBlender->stringVar, 78, yPos, TEXT_SKIP_DRAW, 3); + Blender_AddTextPrinter(WIN_RESULTS, sBerryBlender->stringVar, 78, yPos, TEXT_SKIP_DRAW, 3); ConvertIntToDecimalStringN(sBerryBlender->stringVar, sBerryBlender->scores[place][SCORE_GOOD], STR_CONV_MODE_RIGHT_ALIGN, 3); - Blender_AddTextPrinter(5, sBerryBlender->stringVar, 78 + 32, yPos, TEXT_SKIP_DRAW, 3); + Blender_AddTextPrinter(WIN_RESULTS, sBerryBlender->stringVar, 78 + 32, yPos, TEXT_SKIP_DRAW, 3); ConvertIntToDecimalStringN(sBerryBlender->stringVar, sBerryBlender->scores[place][SCORE_MISS], STR_CONV_MODE_RIGHT_ALIGN, 3); - Blender_AddTextPrinter(5, sBerryBlender->stringVar, 78 + 64, yPos, TEXT_SKIP_DRAW, 3); + Blender_AddTextPrinter(WIN_RESULTS, sBerryBlender->stringVar, 78 + 64, yPos, TEXT_SKIP_DRAW, 3); } - PutWindowTilemap(5); - CopyWindowToVram(5, COPYWIN_FULL); + PutWindowTilemap(WIN_RESULTS); + CopyWindowToVram(WIN_RESULTS, COPYWIN_FULL); sBerryBlender->framesToWait = 0; sBerryBlender->mainState++; @@ -3875,26 +3882,24 @@ static void Blender_AddTextPrinter(u8 windowId, const u8 *string, u8 x, u8 y, s3 } if (caseId != 3) - { FillWindowPixelBuffer(windowId, PIXEL_FILL(txtColor[0])); - } AddTextPrinterParameterized4(windowId, FONT_NORMAL, x, y, letterSpacing, 1, txtColor, speed, string); } -static bool32 Blender_PrintText(s16 *textState, const u8 *string, s32 textSpeed) +static bool32 PrintMessage(s16 *textState, const u8 *string, s32 textSpeed) { switch (*textState) { case 0: - DrawDialogFrameWithCustomTileAndPalette(4, FALSE, 0x14, 0xF); - Blender_AddTextPrinter(4, string, 0, 1, textSpeed, 0); - PutWindowTilemap(4); - CopyWindowToVram(4, COPYWIN_FULL); + DrawDialogFrameWithCustomTileAndPalette(WIN_MSG, FALSE, 0x14, 0xF); + Blender_AddTextPrinter(WIN_MSG, string, 0, 1, textSpeed, 0); + PutWindowTilemap(WIN_MSG); + CopyWindowToVram(WIN_MSG, COPYWIN_FULL); (*textState)++; break; case 1: - if (!IsTextPrinterActive(4)) + if (!IsTextPrinterActive(WIN_MSG)) { *textState = 0; return TRUE; From 9f5704b05a783a43914c51f869a399aac4337bc8 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 12:30:10 -0400 Subject: [PATCH 05/69] Use window constants in trainer_card --- src/trainer_card.c | 90 ++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 42 deletions(-) diff --git a/src/trainer_card.c b/src/trainer_card.c index 04b8f686a..ceda0e570 100755 --- a/src/trainer_card.c +++ b/src/trainer_card.c @@ -33,6 +33,12 @@ #include "constants/trainers.h" #include "constants/union_room.h" +enum { + WIN_MSG, + WIN_CARD_TEXT, + WIN_TRAINER_PIC, +}; + struct TrainerCardData { u8 mainState; @@ -226,7 +232,7 @@ static const struct BgTemplate sTrainerCardBgTemplates[4] = static const struct WindowTemplate sTrainerCardWindowTemplates[] = { - { + [WIN_MSG] = { .bg = 1, .tilemapLeft = 2, .tilemapTop = 15, @@ -235,7 +241,7 @@ static const struct WindowTemplate sTrainerCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 0x253, }, - { + [WIN_CARD_TEXT] = { .bg = 1, .tilemapLeft = 1, .tilemapTop = 1, @@ -244,7 +250,7 @@ static const struct WindowTemplate sTrainerCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 0x1, }, - { + [WIN_TRAINER_PIC] = { .bg = 3, .tilemapLeft = 19, .tilemapTop = 5, @@ -376,7 +382,7 @@ static void Task_TrainerCard(u8 taskId) case 0: if (!IsDma3ManagerBusyWithBgCopy()) { - FillWindowPixelBuffer(1, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_CARD_TEXT, PIXEL_FILL(0)); sData->mainState++; } break; @@ -385,13 +391,13 @@ static void Task_TrainerCard(u8 taskId) sData->mainState++; break; case 2: - DrawTrainerCardWindow(1); + DrawTrainerCardWindow(WIN_CARD_TEXT); sData->mainState++; break; case 3: - FillWindowPixelBuffer(2, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_TRAINER_PIC, PIXEL_FILL(0)); CreateTrainerCardTrainerPic(); - DrawTrainerCardWindow(2); + DrawTrainerCardWindow(WIN_TRAINER_PIC); sData->mainState++; break; case 4: @@ -411,7 +417,7 @@ static void Task_TrainerCard(u8 taskId) if (gWirelessCommType == 1 && gReceivedRemoteLinkPlayers == TRUE) { LoadWirelessStatusIndicatorSpriteGfx(); - CreateWirelessStatusIndicatorSprite(230, 150); + CreateWirelessStatusIndicatorSprite(DISPLAY_WIDTH - 10, DISPLAY_HEIGHT - 10); } BlendPalettes(PALETTES_ALL, 16, sData->blendColor); BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, sData->blendColor); @@ -434,7 +440,7 @@ static void Task_TrainerCard(u8 taskId) if (!gReceivedRemoteLinkPlayers && sData->timeColonNeedDraw) { PrintTimeOnCard(); - DrawTrainerCardWindow(1); + DrawTrainerCardWindow(WIN_CARD_TEXT); sData->timeColonNeedDraw = FALSE; } if (JOY_NEW(A_BUTTON)) @@ -497,9 +503,9 @@ static void Task_TrainerCard(u8 taskId) break; case STATE_WAIT_LINK_PARTNER: SetCloseLinkCallback(); - DrawDialogueFrame(0, TRUE); - AddTextPrinterParameterized(0, FONT_NORMAL, gText_WaitingTrainerFinishReading, 0, 1, 255, 0); - CopyWindowToVram(0, COPYWIN_FULL); + DrawDialogueFrame(WIN_MSG, TRUE); + AddTextPrinterParameterized(WIN_MSG, FONT_NORMAL, gText_WaitingTrainerFinishReading, 0, 1, 255, 0); + CopyWindowToVram(WIN_MSG, COPYWIN_FULL); sData->mainState = STATE_CLOSE_CARD_LINK; break; case STATE_CLOSE_CARD_LINK: @@ -1002,9 +1008,9 @@ static void PrintNameOnCardFront(void) StringCopy(txtPtr, sData->trainerCard.playerName); ConvertInternationalString(txtPtr, sData->language); if (sData->cardType == CARD_TYPE_FRLG) - AddTextPrinterParameterized3(1, FONT_NORMAL, 20, 28, sTrainerCardTextColors, TEXT_SKIP_DRAW, buffer); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, 20, 28, sTrainerCardTextColors, TEXT_SKIP_DRAW, buffer); else - AddTextPrinterParameterized3(1, FONT_NORMAL, 16, 33, sTrainerCardTextColors, TEXT_SKIP_DRAW, buffer); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, 16, 33, sTrainerCardTextColors, TEXT_SKIP_DRAW, buffer); } static void PrintIdOnCard(void) @@ -1026,7 +1032,7 @@ static void PrintIdOnCard(void) top = 9; } - AddTextPrinterParameterized3(1, FONT_NORMAL, xPos, top, sTrainerCardTextColors, TEXT_SKIP_DRAW, buffer); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, xPos, top, sTrainerCardTextColors, TEXT_SKIP_DRAW, buffer); } static void PrintMoneyOnCard(void) @@ -1035,9 +1041,9 @@ static void PrintMoneyOnCard(void) u8 top; if (!sData->isHoenn) - AddTextPrinterParameterized3(1, FONT_NORMAL, 20, 56, sTrainerCardTextColors, TEXT_SKIP_DRAW, gText_TrainerCardMoney); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, 20, 56, sTrainerCardTextColors, TEXT_SKIP_DRAW, gText_TrainerCardMoney); else - AddTextPrinterParameterized3(1, FONT_NORMAL, 16, 57, sTrainerCardTextColors, TEXT_SKIP_DRAW, gText_TrainerCardMoney); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, 16, 57, sTrainerCardTextColors, TEXT_SKIP_DRAW, gText_TrainerCardMoney); ConvertIntToDecimalStringN(gStringVar1, sData->trainerCard.money, STR_CONV_MODE_LEFT_ALIGN, 6); StringExpandPlaceholders(gStringVar4, gText_PokedollarVar1); @@ -1051,7 +1057,7 @@ static void PrintMoneyOnCard(void) xOffset = GetStringRightAlignXOffset(FONT_NORMAL, gStringVar4, 128); top = 57; } - AddTextPrinterParameterized3(1, FONT_NORMAL, xOffset, top, sTrainerCardTextColors, TEXT_SKIP_DRAW, gStringVar4); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, xOffset, top, sTrainerCardTextColors, TEXT_SKIP_DRAW, gStringVar4); } static u16 GetCaughtMonsCount(void) @@ -1069,9 +1075,9 @@ static void PrintPokedexOnCard(void) if (FlagGet(FLAG_SYS_POKEDEX_GET)) { if (!sData->isHoenn) - AddTextPrinterParameterized3(1, FONT_NORMAL, 20, 72, sTrainerCardTextColors, TEXT_SKIP_DRAW, gText_TrainerCardPokedex); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, 20, 72, sTrainerCardTextColors, TEXT_SKIP_DRAW, gText_TrainerCardPokedex); else - AddTextPrinterParameterized3(1, FONT_NORMAL, 16, 73, sTrainerCardTextColors, TEXT_SKIP_DRAW, gText_TrainerCardPokedex); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, 16, 73, sTrainerCardTextColors, TEXT_SKIP_DRAW, gText_TrainerCardPokedex); StringCopy(ConvertIntToDecimalStringN(gStringVar4, sData->trainerCard.caughtMonsCount, STR_CONV_MODE_LEFT_ALIGN, 3), gText_EmptyString6); if (!sData->isHoenn) { @@ -1083,7 +1089,7 @@ static void PrintPokedexOnCard(void) xOffset = GetStringRightAlignXOffset(FONT_NORMAL, gStringVar4, 128); top = 73; } - AddTextPrinterParameterized3(1, FONT_NORMAL, xOffset, top, sTrainerCardTextColors, TEXT_SKIP_DRAW, gStringVar4); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, xOffset, top, sTrainerCardTextColors, TEXT_SKIP_DRAW, gStringVar4); } } @@ -1097,9 +1103,9 @@ static void PrintTimeOnCard(void) u32 x, y, totalWidth; if (!sData->isHoenn) - AddTextPrinterParameterized3(1, FONT_NORMAL, 20, 88, sTrainerCardTextColors, TEXT_SKIP_DRAW, gText_TrainerCardTime); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, 20, 88, sTrainerCardTextColors, TEXT_SKIP_DRAW, gText_TrainerCardTime); else - AddTextPrinterParameterized3(1, FONT_NORMAL, 16, 89, sTrainerCardTextColors, TEXT_SKIP_DRAW, gText_TrainerCardTime); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, 16, 89, sTrainerCardTextColors, TEXT_SKIP_DRAW, gText_TrainerCardTime); if (sData->isLink) { @@ -1131,14 +1137,14 @@ static void PrintTimeOnCard(void) totalWidth = width + 30; x -= totalWidth; - FillWindowPixelRect(1, PIXEL_FILL(0), x, y, totalWidth, 15); + FillWindowPixelRect(WIN_CARD_TEXT, PIXEL_FILL(0), x, y, totalWidth, 15); ConvertIntToDecimalStringN(gStringVar4, hours, STR_CONV_MODE_RIGHT_ALIGN, 3); - AddTextPrinterParameterized3(1, FONT_NORMAL, x, y, sTrainerCardTextColors, TEXT_SKIP_DRAW, gStringVar4); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, x, y, sTrainerCardTextColors, TEXT_SKIP_DRAW, gStringVar4); x += 18; - AddTextPrinterParameterized3(1, FONT_NORMAL, x, y, sTimeColonTextColors[sData->timeColonInvisible], TEXT_SKIP_DRAW, gText_Colon2); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, x, y, sTimeColonTextColors[sData->timeColonInvisible], TEXT_SKIP_DRAW, gText_Colon2); x += width; ConvertIntToDecimalStringN(gStringVar4, minutes, STR_CONV_MODE_LEADING_ZEROS, 2); - AddTextPrinterParameterized3(1, FONT_NORMAL, x, y, sTrainerCardTextColors, TEXT_SKIP_DRAW, gStringVar4); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, x, y, sTrainerCardTextColors, TEXT_SKIP_DRAW, gStringVar4); } static void PrintProfilePhraseOnCard(void) @@ -1148,10 +1154,10 @@ static void PrintProfilePhraseOnCard(void) if (sData->isLink) { - AddTextPrinterParameterized3(1, FONT_NORMAL, 8, yOffsetsLine1[sData->isHoenn], sTrainerCardTextColors, TEXT_SKIP_DRAW, sData->easyChatProfile[0]); - AddTextPrinterParameterized3(1, FONT_NORMAL, GetStringWidth(FONT_NORMAL, sData->easyChatProfile[0], 0) + 14, yOffsetsLine1[sData->isHoenn], sTrainerCardTextColors, TEXT_SKIP_DRAW, sData->easyChatProfile[1]); - AddTextPrinterParameterized3(1, FONT_NORMAL, 8, yOffsetsLine2[sData->isHoenn], sTrainerCardTextColors, TEXT_SKIP_DRAW, sData->easyChatProfile[2]); - AddTextPrinterParameterized3(1, FONT_NORMAL, GetStringWidth(FONT_NORMAL, sData->easyChatProfile[2], 0) + 14, yOffsetsLine2[sData->isHoenn], sTrainerCardTextColors, TEXT_SKIP_DRAW, sData->easyChatProfile[3]); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, 8, yOffsetsLine1[sData->isHoenn], sTrainerCardTextColors, TEXT_SKIP_DRAW, sData->easyChatProfile[0]); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, GetStringWidth(FONT_NORMAL, sData->easyChatProfile[0], 0) + 14, yOffsetsLine1[sData->isHoenn], sTrainerCardTextColors, TEXT_SKIP_DRAW, sData->easyChatProfile[1]); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, 8, yOffsetsLine2[sData->isHoenn], sTrainerCardTextColors, TEXT_SKIP_DRAW, sData->easyChatProfile[2]); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, GetStringWidth(FONT_NORMAL, sData->easyChatProfile[2], 0) + 14, yOffsetsLine2[sData->isHoenn], sTrainerCardTextColors, TEXT_SKIP_DRAW, sData->easyChatProfile[3]); } } @@ -1169,9 +1175,9 @@ static void BufferNameForCardBack(void) static void PrintNameOnCardBack(void) { if (!sData->isHoenn) - AddTextPrinterParameterized3(1, FONT_NORMAL, 136, 9, sTrainerCardTextColors, TEXT_SKIP_DRAW, sData->textPlayersCard); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, 136, 9, sTrainerCardTextColors, TEXT_SKIP_DRAW, sData->textPlayersCard); else - AddTextPrinterParameterized3(1, FONT_NORMAL, GetStringRightAlignXOffset(FONT_NORMAL, sData->textPlayersCard, 216), 9, sTrainerCardTextColors, TEXT_SKIP_DRAW, sData->textPlayersCard); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, GetStringRightAlignXOffset(FONT_NORMAL, sData->textPlayersCard, 216), 9, sTrainerCardTextColors, TEXT_SKIP_DRAW, sData->textPlayersCard); } static const u8 sText_HofTime[] = _("{STR_VAR_1}:{STR_VAR_2}:{STR_VAR_3}"); @@ -1192,8 +1198,8 @@ static void PrintStatOnBackOfCard(u8 top, const u8 *statName, u8 *stat, const u8 static const u8 xOffsets[] = {8, 16}; static const u8 widths[] = {216, 216}; - AddTextPrinterParameterized3(1, FONT_NORMAL, xOffsets[sData->isHoenn], top * 16 + 33, sTrainerCardTextColors, TEXT_SKIP_DRAW, statName); - AddTextPrinterParameterized3(1, FONT_NORMAL, GetStringRightAlignXOffset(FONT_NORMAL, stat, widths[sData->isHoenn]), top * 16 + 33, color, TEXT_SKIP_DRAW, stat); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, xOffsets[sData->isHoenn], top * 16 + 33, sTrainerCardTextColors, TEXT_SKIP_DRAW, statName); + AddTextPrinterParameterized3(WIN_CARD_TEXT, FONT_NORMAL, GetStringRightAlignXOffset(FONT_NORMAL, stat, widths[sData->isHoenn]), top * 16 + 33, color, TEXT_SKIP_DRAW, stat); } static void PrintHofDebutTimeOnCard(void) @@ -1672,7 +1678,7 @@ static bool8 Task_DrawFlippedCardSide(struct Task *task) switch (sData->flipDrawState) { case 0: - FillWindowPixelBuffer(1, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_CARD_TEXT, PIXEL_FILL(0)); FillBgTilemapBufferRect_Palette0(3, 0, 0, 0, 0x20, 0x20); break; case 1: @@ -1691,13 +1697,13 @@ static bool8 Task_DrawFlippedCardSide(struct Task *task) if (!sData->onBack) DrawCardFrontOrBack(sData->backTilemap); else - DrawTrainerCardWindow(1); + DrawTrainerCardWindow(WIN_CARD_TEXT); break; case 3: if (!sData->onBack) DrawCardBackStats(); else - FillWindowPixelBuffer(2, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_TRAINER_PIC, PIXEL_FILL(0)); break; case 4: if (sData->onBack) @@ -1722,12 +1728,12 @@ static bool8 Task_SetCardFlipped(struct Task *task) // If on back of card, draw front of card because its being flipped if (sData->onBack) { - DrawTrainerCardWindow(2); + DrawTrainerCardWindow(WIN_TRAINER_PIC); DrawCardScreenBackground(sData->bgTilemap); DrawCardFrontOrBack(sData->frontTilemap); DrawStarsAndBadgesOnCard(); } - DrawTrainerCardWindow(1); + DrawTrainerCardWindow(WIN_CARD_TEXT); sData->onBack ^= 1; task->tFlipState++; sData->allowDMACopy = TRUE; @@ -1882,7 +1888,7 @@ static void CreateTrainerCardTrainerPic(void) sTrainerPicOffset[sData->isHoenn][sData->trainerCard.gender][0], sTrainerPicOffset[sData->isHoenn][sData->trainerCard.gender][1], 8, - 2); + WIN_TRAINER_PIC); } else { @@ -1891,6 +1897,6 @@ static void CreateTrainerCardTrainerPic(void) sTrainerPicOffset[sData->isHoenn][sData->trainerCard.gender][0], sTrainerPicOffset[sData->isHoenn][sData->trainerCard.gender][1], 8, - 2); + WIN_TRAINER_PIC); } } From 1f225286d5641fef8c1b7f657d7fa0bdbb0ff0df Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 12:55:31 -0400 Subject: [PATCH 06/69] Use window constants in party_menu --- src/data/party_menu.h | 54 +++++++++++++++++++++---------------------- src/party_menu.c | 28 ++++++++++++---------- 2 files changed, 43 insertions(+), 39 deletions(-) diff --git a/src/data/party_menu.h b/src/data/party_menu.h index b29449830..7a9efce0b 100644 --- a/src/data/party_menu.h +++ b/src/data/party_menu.h @@ -122,7 +122,7 @@ static const u8 sFontColorTable[][3] = static const struct WindowTemplate sSinglePartyMenuWindowTemplate[] = { - { + { // Party mon 1 .bg = 0, .tilemapLeft = 1, .tilemapTop = 3, @@ -131,7 +131,7 @@ static const struct WindowTemplate sSinglePartyMenuWindowTemplate[] = .paletteNum = 3, .baseBlock = 0x63, }, - { + { // Party mon 2 .bg = 0, .tilemapLeft = 12, .tilemapTop = 1, @@ -140,7 +140,7 @@ static const struct WindowTemplate sSinglePartyMenuWindowTemplate[] = .paletteNum = 4, .baseBlock = 0xA9, }, - { + { // Party mon 3 .bg = 0, .tilemapLeft = 12, .tilemapTop = 4, @@ -149,7 +149,7 @@ static const struct WindowTemplate sSinglePartyMenuWindowTemplate[] = .paletteNum = 5, .baseBlock = 0xDF, }, - { + { // Party mon 4 .bg = 0, .tilemapLeft = 12, .tilemapTop = 7, @@ -158,7 +158,7 @@ static const struct WindowTemplate sSinglePartyMenuWindowTemplate[] = .paletteNum = 6, .baseBlock = 0x115, }, - { + { // Party mon 5 .bg = 0, .tilemapLeft = 12, .tilemapTop = 10, @@ -167,7 +167,7 @@ static const struct WindowTemplate sSinglePartyMenuWindowTemplate[] = .paletteNum = 7, .baseBlock = 0x14B, }, - { + { // Party mon 6 .bg = 0, .tilemapLeft = 12, .tilemapTop = 13, @@ -176,7 +176,7 @@ static const struct WindowTemplate sSinglePartyMenuWindowTemplate[] = .paletteNum = 8, .baseBlock = 0x181, }, - { + [WIN_MSG] = { .bg = 2, .tilemapLeft = 1, .tilemapTop = 15, @@ -190,7 +190,7 @@ static const struct WindowTemplate sSinglePartyMenuWindowTemplate[] = static const struct WindowTemplate sDoublePartyMenuWindowTemplate[] = { - { + { // Party mon 1 .bg = 0, .tilemapLeft = 1, .tilemapTop = 1, @@ -199,7 +199,7 @@ static const struct WindowTemplate sDoublePartyMenuWindowTemplate[] = .paletteNum = 3, .baseBlock = 0x63, }, - { + { // Party mon 2 .bg = 0, .tilemapLeft = 1, .tilemapTop = 8, @@ -208,7 +208,7 @@ static const struct WindowTemplate sDoublePartyMenuWindowTemplate[] = .paletteNum = 4, .baseBlock = 0xA9, }, - { + { // Party mon 3 .bg = 0, .tilemapLeft = 12, .tilemapTop = 1, @@ -217,7 +217,7 @@ static const struct WindowTemplate sDoublePartyMenuWindowTemplate[] = .paletteNum = 5, .baseBlock = 0xEF, }, - { + { // Party mon 4 .bg = 0, .tilemapLeft = 12, .tilemapTop = 5, @@ -226,7 +226,7 @@ static const struct WindowTemplate sDoublePartyMenuWindowTemplate[] = .paletteNum = 6, .baseBlock = 0x125, }, - { + { // Party mon 5 .bg = 0, .tilemapLeft = 12, .tilemapTop = 9, @@ -235,7 +235,7 @@ static const struct WindowTemplate sDoublePartyMenuWindowTemplate[] = .paletteNum = 7, .baseBlock = 0x15B, }, - { + { // Party mon 6 .bg = 0, .tilemapLeft = 12, .tilemapTop = 13, @@ -244,7 +244,7 @@ static const struct WindowTemplate sDoublePartyMenuWindowTemplate[] = .paletteNum = 8, .baseBlock = 0x191, }, - { + [WIN_MSG] = { .bg = 2, .tilemapLeft = 1, .tilemapTop = 15, @@ -258,7 +258,7 @@ static const struct WindowTemplate sDoublePartyMenuWindowTemplate[] = static const struct WindowTemplate sMultiPartyMenuWindowTemplate[] = { - { + { // Party mon 1 .bg = 0, .tilemapLeft = 1, .tilemapTop = 1, @@ -267,7 +267,7 @@ static const struct WindowTemplate sMultiPartyMenuWindowTemplate[] = .paletteNum = 3, .baseBlock = 0x63, }, - { + { // Party mon 2 .bg = 0, .tilemapLeft = 1, .tilemapTop = 8, @@ -276,7 +276,7 @@ static const struct WindowTemplate sMultiPartyMenuWindowTemplate[] = .paletteNum = 4, .baseBlock = 0xA9, }, - { + { // Party mon 3 .bg = 0, .tilemapLeft = 12, .tilemapTop = 2, @@ -285,7 +285,7 @@ static const struct WindowTemplate sMultiPartyMenuWindowTemplate[] = .paletteNum = 5, .baseBlock = 0xEF, }, - { + { // Party mon 4 .bg = 0, .tilemapLeft = 12, .tilemapTop = 5, @@ -294,7 +294,7 @@ static const struct WindowTemplate sMultiPartyMenuWindowTemplate[] = .paletteNum = 6, .baseBlock = 0x125, }, - { + { // Party mon 5 .bg = 0, .tilemapLeft = 12, .tilemapTop = 9, @@ -303,7 +303,7 @@ static const struct WindowTemplate sMultiPartyMenuWindowTemplate[] = .paletteNum = 7, .baseBlock = 0x15B, }, - { + { // Party mon 6 .bg = 0, .tilemapLeft = 12, .tilemapTop = 12, @@ -312,7 +312,7 @@ static const struct WindowTemplate sMultiPartyMenuWindowTemplate[] = .paletteNum = 8, .baseBlock = 0x191, }, - { + [WIN_MSG] = { .bg = 2, .tilemapLeft = 1, .tilemapTop = 15, @@ -326,7 +326,7 @@ static const struct WindowTemplate sMultiPartyMenuWindowTemplate[] = static const struct WindowTemplate sShowcaseMultiPartyMenuWindowTemplate[] = { - { + { // Party mon 1 .bg = 0, .tilemapLeft = 1, .tilemapTop = 2, @@ -335,7 +335,7 @@ static const struct WindowTemplate sShowcaseMultiPartyMenuWindowTemplate[] = .paletteNum = 3, .baseBlock = 0x63, }, - { + { // Party mon 2 .bg = 0, .tilemapLeft = 12, .tilemapTop = 3, @@ -344,7 +344,7 @@ static const struct WindowTemplate sShowcaseMultiPartyMenuWindowTemplate[] = .paletteNum = 5, .baseBlock = 0xA9, }, - { + { // Party mon 3 .bg = 0, .tilemapLeft = 12, .tilemapTop = 6, @@ -353,7 +353,7 @@ static const struct WindowTemplate sShowcaseMultiPartyMenuWindowTemplate[] = .paletteNum = 6, .baseBlock = 0xDF, }, - { + { // Party mon 4 .bg = 2, .tilemapLeft = 1, .tilemapTop = 11, @@ -362,7 +362,7 @@ static const struct WindowTemplate sShowcaseMultiPartyMenuWindowTemplate[] = .paletteNum = 4, .baseBlock = 0x115, }, - { + { // Party mon 5 .bg = 2, .tilemapLeft = 12, .tilemapTop = 12, @@ -371,7 +371,7 @@ static const struct WindowTemplate sShowcaseMultiPartyMenuWindowTemplate[] = .paletteNum = 7, .baseBlock = 0x16B, }, - { + { // Party mon 6 .bg = 2, .tilemapLeft = 12, .tilemapTop = 15, diff --git a/src/party_menu.c b/src/party_menu.c index 8c9b09f52..153e389b2 100755 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -161,14 +161,18 @@ enum { #define MENU_DIR_RIGHT 2 #define MENU_DIR_LEFT -2 -enum -{ +enum { CAN_LEARN_MOVE, CANNOT_LEARN_MOVE, ALREADY_KNOWS_MOVE, CANNOT_LEARN_MOVE_IS_EGG }; +enum { + // Window ids 0-5 are implicitly assigned to each party pokemon in InitPartyMenuBoxes + WIN_MSG = PARTY_SIZE, +}; + struct PartyMenuBoxInfoRects { void (*blitFunc)(u8, u8, u8, u8, u8, bool8); @@ -320,7 +324,7 @@ static void UpdateCurrentPartySelection(s8 *, s8); static void UpdatePartySelectionSingleLayout(s8 *, s8); static void UpdatePartySelectionDoubleLayout(s8 *, s8); static s8 GetNewSlotDoubleLayout(s8, s8); -static void PartyMenuPrintText(const u8 *); +static void PrintMessage(const u8 *); static void Task_PrintAndWaitForText(u8); static bool16 IsMonAllowedInPokemonJump(struct Pokemon *); static bool16 IsMonAllowedInDodrioBerryPicking(struct Pokemon *); @@ -1703,7 +1707,7 @@ u8 DisplayPartyMenuMessage(const u8 *str, bool8 keepOpen) { u8 taskId; - PartyMenuPrintText(str); + PrintMessage(str); taskId = CreateTask(Task_PrintAndWaitForText, 1); gTasks[taskId].tKeepOpen = keepOpen; return taskId; @@ -1711,12 +1715,12 @@ u8 DisplayPartyMenuMessage(const u8 *str, bool8 keepOpen) static void Task_PrintAndWaitForText(u8 taskId) { - if (RunTextPrintersRetIsActive(6) != TRUE) + if (RunTextPrintersRetIsActive(WIN_MSG) != TRUE) { if (gTasks[taskId].tKeepOpen == FALSE) { - ClearStdWindowAndFrameToTransparent(6, FALSE); - ClearWindowTilemap(6); + ClearStdWindowAndFrameToTransparent(WIN_MSG, FALSE); + ClearWindowTilemap(WIN_MSG); } DestroyTask(taskId); } @@ -1742,8 +1746,8 @@ static void Task_ReturnToChooseMonAfterText(u8 taskId) { if (IsPartyMenuTextPrinterActive() != TRUE) { - ClearStdWindowAndFrameToTransparent(6, FALSE); - ClearWindowTilemap(6); + ClearStdWindowAndFrameToTransparent(WIN_MSG, FALSE); + ClearWindowTilemap(WIN_MSG); if (MenuHelpers_IsLinkActive() == TRUE) { gTasks[taskId].func = Task_WaitForLinkAndReturnToChooseMon; @@ -2559,11 +2563,11 @@ static u8 DisplaySelectionWindow(u8 windowType) return sPartyMenuInternal->windowId[0]; } -static void PartyMenuPrintText(const u8 *text) +static void PrintMessage(const u8 *text) { - DrawStdFrameWithCustomTileAndPalette(6, FALSE, 0x4F, 13); + DrawStdFrameWithCustomTileAndPalette(WIN_MSG, FALSE, 0x4F, 13); gTextFlags.canABSpeedUpPrint = TRUE; - AddTextPrinterParameterized2(6, FONT_NORMAL, text, GetPlayerTextSpeedDelay(), 0, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_WHITE, TEXT_COLOR_LIGHT_GRAY); + AddTextPrinterParameterized2(WIN_MSG, FONT_NORMAL, text, GetPlayerTextSpeedDelay(), 0, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_WHITE, TEXT_COLOR_LIGHT_GRAY); } static void PartyMenuDisplayYesNoMenu(void) From 4af1044439d46afdd5da98f7e4b41fafc4b246f8 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 13:11:38 -0400 Subject: [PATCH 07/69] Use window constants in region_map --- include/region_map.h | 3 ++- src/region_map.c | 47 ++++++++++++++++++++++++-------------------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/include/region_map.h b/include/region_map.h index 85793badc..9f0b110a6 100644 --- a/include/region_map.h +++ b/include/region_map.h @@ -21,7 +21,8 @@ enum { MAPSECTYPE_ROUTE, MAPSECTYPE_CITY_CANFLY, MAPSECTYPE_CITY_CANTFLY, - MAPSECTYPE_BATTLE_FRONTIER + MAPSECTYPE_BATTLE_FRONTIER, + NUM_MAPSEC_TYPES }; struct RegionMap { diff --git a/src/region_map.c b/src/region_map.c index 8157f8a4e..ba7dcf106 100644 --- a/src/region_map.c +++ b/src/region_map.c @@ -53,7 +53,12 @@ enum { TAG_FLY_ICON, }; -// Static type declarations +// Window IDs for the fly map +enum { + WIN_MAPSEC_NAME, + WIN_MAPSEC_NAME_TALL, // For fly destinations with subtitles (just Ever Grande) + WIN_FLY_TO_WHERE, +}; struct MultiNameFlyDest { @@ -386,7 +391,7 @@ static const struct BgTemplate sFlyMapBgTemplates[] = static const struct WindowTemplate sFlyMapWindowTemplates[] = { - { + [WIN_MAPSEC_NAME] = { .bg = 0, .tilemapLeft = 17, .tilemapTop = 17, @@ -395,7 +400,7 @@ static const struct WindowTemplate sFlyMapWindowTemplates[] = .paletteNum = 15, .baseBlock = 0x01 }, - { + [WIN_MAPSEC_NAME_TALL] = { .bg = 0, .tilemapLeft = 17, .tilemapTop = 15, @@ -404,7 +409,7 @@ static const struct WindowTemplate sFlyMapWindowTemplates[] = .paletteNum = 15, .baseBlock = 0x19 }, - { + [WIN_FLY_TO_WHERE] = { .bg = 0, .tilemapLeft = 1, .tilemapTop = 18, @@ -1404,7 +1409,7 @@ void CreateRegionMapCursor(u16 tileTag, u16 paletteTag) } LoadSpriteSheet(&sheet); LoadSpritePalette(&palette); - spriteId = CreateSprite(&template, 0x38, 0x48, 0); + spriteId = CreateSprite(&template, 56, 72, 0); if (spriteId != MAX_SPRITES) { sRegionMap->cursorSprite = &gSprites[spriteId]; @@ -1713,9 +1718,9 @@ void CB2_OpenFlyMap(void) break; case 7: LoadPalette(sRegionMapFramePal, 0x10, sizeof(sRegionMapFramePal)); - PutWindowTilemap(2); - FillWindowPixelBuffer(2, PIXEL_FILL(0)); - AddTextPrinterParameterized(2, FONT_NORMAL, gText_FlyToWhere, 0, 1, 0, NULL); + PutWindowTilemap(WIN_FLY_TO_WHERE); + FillWindowPixelBuffer(WIN_FLY_TO_WHERE, PIXEL_FILL(0)); + AddTextPrinterParameterized(WIN_FLY_TO_WHERE, FONT_NORMAL, gText_FlyToWhere, 0, 1, 0, NULL); ScheduleBgCopyTilemapToVram(0); gMain.state++; break; @@ -1768,7 +1773,7 @@ static void DrawFlyDestTextWindow(void) bool32 namePrinted; const u8 *name; - if (sFlyMap->regionMap.mapSecType > MAPSECTYPE_NONE && sFlyMap->regionMap.mapSecType <= MAPSECTYPE_BATTLE_FRONTIER) + if (sFlyMap->regionMap.mapSecType > MAPSECTYPE_NONE && sFlyMap->regionMap.mapSecType < NUM_MAPSEC_TYPES) { namePrinted = FALSE; for (i = 0; i < ARRAY_COUNT(sMultiNameFlyDestinations); i++) @@ -1779,11 +1784,11 @@ static void DrawFlyDestTextWindow(void) { StringLength(sMultiNameFlyDestinations[i].name[sFlyMap->regionMap.posWithinMapSec]); namePrinted = TRUE; - ClearStdWindowAndFrameToTransparent(0, FALSE); - DrawStdFrameWithCustomTileAndPalette(1, FALSE, 101, 13); - AddTextPrinterParameterized(1, FONT_NORMAL, sFlyMap->regionMap.mapSecName, 0, 1, 0, NULL); + ClearStdWindowAndFrameToTransparent(WIN_MAPSEC_NAME, FALSE); + DrawStdFrameWithCustomTileAndPalette(WIN_MAPSEC_NAME_TALL, FALSE, 101, 13); + AddTextPrinterParameterized(WIN_MAPSEC_NAME_TALL, FONT_NORMAL, sFlyMap->regionMap.mapSecName, 0, 1, 0, NULL); name = sMultiNameFlyDestinations[i].name[sFlyMap->regionMap.posWithinMapSec]; - AddTextPrinterParameterized(1, FONT_NORMAL, name, GetStringRightAlignXOffset(FONT_NORMAL, name, 96), 17, 0, NULL); + AddTextPrinterParameterized(WIN_MAPSEC_NAME_TALL, FONT_NORMAL, name, GetStringRightAlignXOffset(FONT_NORMAL, name, 96), 17, 0, NULL); ScheduleBgCopyTilemapToVram(0); sDrawFlyDestTextWindow = TRUE; } @@ -1794,15 +1799,15 @@ static void DrawFlyDestTextWindow(void) { if (sDrawFlyDestTextWindow == TRUE) { - ClearStdWindowAndFrameToTransparent(1, FALSE); - DrawStdFrameWithCustomTileAndPalette(0, FALSE, 101, 13); + ClearStdWindowAndFrameToTransparent(WIN_MAPSEC_NAME_TALL, FALSE); + DrawStdFrameWithCustomTileAndPalette(WIN_MAPSEC_NAME, FALSE, 101, 13); } else { // Window is already drawn, just empty it - FillWindowPixelBuffer(0, PIXEL_FILL(1)); + FillWindowPixelBuffer(WIN_MAPSEC_NAME, PIXEL_FILL(1)); } - AddTextPrinterParameterized(0, FONT_NORMAL, sFlyMap->regionMap.mapSecName, 0, 1, 0, NULL); + AddTextPrinterParameterized(WIN_MAPSEC_NAME, FONT_NORMAL, sFlyMap->regionMap.mapSecName, 0, 1, 0, NULL); ScheduleBgCopyTilemapToVram(0); sDrawFlyDestTextWindow = FALSE; } @@ -1812,11 +1817,11 @@ static void DrawFlyDestTextWindow(void) // Selection is on MAPSECTYPE_NONE, draw empty fly destination text window if (sDrawFlyDestTextWindow == TRUE) { - ClearStdWindowAndFrameToTransparent(1, FALSE); - DrawStdFrameWithCustomTileAndPalette(0, FALSE, 101, 13); + ClearStdWindowAndFrameToTransparent(WIN_MAPSEC_NAME_TALL, FALSE); + DrawStdFrameWithCustomTileAndPalette(WIN_MAPSEC_NAME, FALSE, 101, 13); } - FillWindowPixelBuffer(0, PIXEL_FILL(1)); - CopyWindowToVram(0, COPYWIN_GFX); + FillWindowPixelBuffer(WIN_MAPSEC_NAME, PIXEL_FILL(1)); + CopyWindowToVram(WIN_MAPSEC_NAME, COPYWIN_GFX); ScheduleBgCopyTilemapToVram(0); sDrawFlyDestTextWindow = FALSE; } From 81defb5986dc76951f593a403c5d78ba500c652e Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 13:20:35 -0400 Subject: [PATCH 08/69] Use window constants in union_room_chat --- src/union_room_chat.c | 94 ++++++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/src/union_room_chat.c b/src/union_room_chat.c index e1ca7c0b0..36bdbe07b 100755 --- a/src/union_room_chat.c +++ b/src/union_room_chat.c @@ -116,6 +116,13 @@ enum { // Shared by all above #define PALTAG_INTERFACE 0 +enum { + WIN_CHAT_HISTORY, + WIN_TEXT_ENTRY, + WIN_KEYBOARD, + WIN_SWAP_MENU, +}; + struct UnionRoomChat { u32 filler1; @@ -560,7 +567,7 @@ static const struct BgTemplate sBgTemplates[] = { }; static const struct WindowTemplate sWinTemplates[] = { - { + [WIN_CHAT_HISTORY] = { .bg = 3, .tilemapLeft = 8, .tilemapTop = 1, @@ -568,7 +575,8 @@ static const struct WindowTemplate sWinTemplates[] = { .height = 19, .paletteNum = 15, .baseBlock = 0x0001, - }, { + }, + [WIN_TEXT_ENTRY] = { .bg = 1, .tilemapLeft = 9, .tilemapTop = 18, @@ -576,7 +584,8 @@ static const struct WindowTemplate sWinTemplates[] = { .height = 2, .paletteNum = 12, .baseBlock = 0x007a, - }, { + }, + [WIN_KEYBOARD] = { .bg = 1, .tilemapLeft = 0, .tilemapTop = 2, @@ -584,7 +593,8 @@ static const struct WindowTemplate sWinTemplates[] = { .height = 15, .paletteNum = 7, .baseBlock = 0x0020, - }, { + }, + [WIN_SWAP_MENU] = { .bg = 0, .tilemapLeft = 1, .tilemapTop = 2, @@ -2280,7 +2290,7 @@ static bool32 Display_ShowKeyboardSwapMenu(u8 *state) { case 0: ShowKeyboardSwapMenu(); - CopyWindowToVram(3, COPYWIN_FULL); + CopyWindowToVram(WIN_SWAP_MENU, COPYWIN_FULL); break; case 1: return IsDma3ManagerBusyWithBgCopy(); @@ -2296,7 +2306,7 @@ static bool32 Display_HideKeyboardSwapMenu(u8 *state) { case 0: HideKeyboardSwapMenu(); - CopyWindowToVram(3, COPYWIN_FULL); + CopyWindowToVram(WIN_SWAP_MENU, COPYWIN_FULL); break; case 1: return IsDma3ManagerBusyWithBgCopy(); @@ -2316,7 +2326,7 @@ static bool32 Display_SwitchPages(u8 *state) return TRUE; PrintCurrentKeyboardPage(); - CopyWindowToVram(2, COPYWIN_GFX); + CopyWindowToVram(WIN_KEYBOARD, COPYWIN_GFX); break; case 1: if (IsDma3ManagerBusyWithBgCopy()) @@ -2393,7 +2403,7 @@ static bool32 Display_UpdateMessageBuffer(u8 *state) FillTextEntryWindow(x, width, 0); str = GetMessageEntryBuffer(); DrawTextEntryMessage(0, str, 3, 1, 2); - CopyWindowToVram(1, COPYWIN_GFX); + CopyWindowToVram(WIN_TEXT_ENTRY, COPYWIN_GFX); break; case 1: if (!IsDma3ManagerBusyWithBgCopy()) @@ -2422,7 +2432,7 @@ static bool32 Display_AskRegisterText(u8 *state) length = StringLength_Multibyte(str); FillTextEntryWindow(x, length, PIXEL_FILL(6)); DrawTextEntryMessage(x, str, 0, 4, 5); - CopyWindowToVram(1, COPYWIN_GFX); + CopyWindowToVram(WIN_TEXT_ENTRY, COPYWIN_GFX); break; case 1: if (!IsDma3ManagerBusyWithBgCopy()) @@ -2463,7 +2473,7 @@ static bool32 Display_CancelRegister(u8 *state) length = StringLength_Multibyte(str); FillTextEntryWindow(x, length, PIXEL_FILL(0)); DrawTextEntryMessage(x, str, 3, 1, 2); - CopyWindowToVram(1, COPYWIN_GFX); + CopyWindowToVram(WIN_TEXT_ENTRY, COPYWIN_GFX); break; case 1: if (!IsDma3ManagerBusyWithBgCopy()) @@ -2501,7 +2511,7 @@ static bool32 Display_ReturnToKeyboard(u8 *state) { case 0: PrintCurrentKeyboardPage(); - CopyWindowToVram(2, COPYWIN_GFX); + CopyWindowToVram(WIN_KEYBOARD, COPYWIN_GFX); (*state)++; break; case 1: @@ -2527,7 +2537,7 @@ static bool32 Display_ScrollChat(u8 *state) str = GetLastReceivedMessage(); colorIdx = GetReceivedPlayerIndex(); PrintChatMessage(row, str, colorIdx); - CopyWindowToVram(0, COPYWIN_GFX); + CopyWindowToVram(WIN_CHAT_HISTORY, COPYWIN_GFX); break; case 1: if (IsDma3ManagerBusyWithBgCopy()) @@ -2546,8 +2556,8 @@ static bool32 Display_ScrollChat(u8 *state) } // fall through case 2: - ScrollWindow(0, 0, 5, PIXEL_FILL(1)); - CopyWindowToVram(0, COPYWIN_GFX); + ScrollWindow(WIN_CHAT_HISTORY, 0, 5, PIXEL_FILL(1)); + CopyWindowToVram(WIN_CHAT_HISTORY, COPYWIN_GFX); sDisplay->scrollCount++; (*state)++; // fall through @@ -2864,7 +2874,7 @@ static void DestroyStdMessageWindow(void) static void FillTextEntryWindow(u16 x, u16 width, u8 fillValue) { - FillWindowPixelRect(1, fillValue, x * 8, 1, width * 8, 14); + FillWindowPixelRect(WIN_TEXT_ENTRY, fillValue, x * 8, 1, width * 8, 14); } static void DrawTextEntryMessage(u16 x, u8 *str, u8 bgColor, u8 fgColor, u8 shadowColor) @@ -2881,7 +2891,7 @@ static void DrawTextEntryMessage(u16 x, u8 *str, u8 bgColor, u8 fgColor, u8 shad strBuffer[1] = EXT_CTRL_CODE_MIN_LETTER_SPACING; strBuffer[2] = 8; StringCopy(&strBuffer[3], str); - AddTextPrinterParameterized3(1, FONT_SHORT, x * 8, 1, color, TEXT_SKIP_DRAW, strBuffer); + AddTextPrinterParameterized3(WIN_TEXT_ENTRY, FONT_SHORT, x * 8, 1, color, TEXT_SKIP_DRAW, strBuffer); } static void PrintCurrentKeyboardPage(void) @@ -2894,7 +2904,7 @@ static void PrintCurrentKeyboardPage(void) u8 str[45]; u8 *str2; - FillWindowPixelBuffer(2, PIXEL_FILL(15)); + FillWindowPixelBuffer(WIN_KEYBOARD, PIXEL_FILL(15)); page = GetCurrentKeyboardPage(); color[0] = TEXT_COLOR_TRANSPARENT; color[1] = TEXT_DYNAMIC_COLOR_5; @@ -2916,7 +2926,7 @@ static void PrintCurrentKeyboardPage(void) return; StringCopy(&str[3], sUnionRoomKeyboardText[page][i]); - AddTextPrinterParameterized3(2, FONT_SMALL, left, top, color, TEXT_SKIP_DRAW, str); + AddTextPrinterParameterized3(WIN_KEYBOARD, FONT_SMALL, left, top, color, TEXT_SKIP_DRAW, str); } } else @@ -2927,7 +2937,7 @@ static void PrintCurrentKeyboardPage(void) str2 = GetRegisteredTextByRow(i); if (GetStringWidth(FONT_SMALL, str2, 0) <= 40) { - AddTextPrinterParameterized3(2, FONT_SMALL, left, top, color, TEXT_SKIP_DRAW, str2); + AddTextPrinterParameterized3(WIN_KEYBOARD, FONT_SMALL, left, top, color, TEXT_SKIP_DRAW, str2); } else { @@ -2938,8 +2948,8 @@ static void PrintCurrentKeyboardPage(void) StringCopyN_Multibyte(str, str2, length); } while (GetStringWidth(FONT_SMALL, str, 0) > 35); - AddTextPrinterParameterized3(2, FONT_SMALL, left, top, color, TEXT_SKIP_DRAW, str); - AddTextPrinterParameterized3(2, FONT_SMALL, left + 35, top, color, TEXT_SKIP_DRAW, sText_Ellipsis); + AddTextPrinterParameterized3(WIN_KEYBOARD, FONT_SMALL, left, top, color, TEXT_SKIP_DRAW, str); + AddTextPrinterParameterized3(WIN_KEYBOARD, FONT_SMALL, left + 35, top, color, TEXT_SKIP_DRAW, sText_Ellipsis); } } } @@ -2989,17 +2999,17 @@ static bool32 SlideKeyboardPageIn(void) static void ShowKeyboardSwapMenu(void) { - FillWindowPixelBuffer(3, PIXEL_FILL(1)); - DrawTextBorderOuter(3, 1, 13); - PrintMenuActionTextsAtPos(3, FONT_SHORT, 8, 1, 14, ARRAY_COUNT(sKeyboardPageTitleTexts), sKeyboardPageTitleTexts); - InitMenuNormal(3, FONT_SHORT, 0, 1, 14, 5, GetCurrentKeyboardPage()); - PutWindowTilemap(3); + FillWindowPixelBuffer(WIN_SWAP_MENU, PIXEL_FILL(1)); + DrawTextBorderOuter(WIN_SWAP_MENU, 1, 13); + PrintMenuActionTextsAtPos(WIN_SWAP_MENU, FONT_SHORT, 8, 1, 14, ARRAY_COUNT(sKeyboardPageTitleTexts), sKeyboardPageTitleTexts); + InitMenuNormal(WIN_SWAP_MENU, FONT_SHORT, 0, 1, 14, 5, GetCurrentKeyboardPage()); + PutWindowTilemap(WIN_SWAP_MENU); } static void HideKeyboardSwapMenu(void) { - ClearStdWindowAndFrameToTransparent(3, FALSE); - ClearWindowTilemap(3); + ClearStdWindowAndFrameToTransparent(WIN_SWAP_MENU, FALSE); + ClearWindowTilemap(WIN_SWAP_MENU); } static void PrintChatMessage(u16 row, u8 *str, u8 colorIdx) @@ -3009,8 +3019,8 @@ static void PrintChatMessage(u16 row, u8 *str, u8 colorIdx) color[0] = TEXT_COLOR_WHITE; color[1] = colorIdx * 2 + 2; color[2] = colorIdx * 2 + 3; - FillWindowPixelRect(0, PIXEL_FILL(1), 0, row * 15, 168, 15); - AddTextPrinterParameterized3(0, FONT_SHORT, 0, row * 15 + 1, color, TEXT_SKIP_DRAW, str); + FillWindowPixelRect(WIN_CHAT_HISTORY, PIXEL_FILL(1), 0, row * 15, 168, 15); + AddTextPrinterParameterized3(WIN_CHAT_HISTORY, FONT_SHORT, 0, row * 15 + 1, color, TEXT_SKIP_DRAW, str); } static void ResetGpuBgState(void) @@ -3087,16 +3097,16 @@ static void LoadChatUnkPalette(void) static void LoadChatMessagesWindow(void) { LoadPalette(sUnk_Palette2, 0xF0, sizeof(sUnk_Palette2)); - PutWindowTilemap(0); - FillWindowPixelBuffer(0, PIXEL_FILL(1)); - CopyWindowToVram(0, COPYWIN_FULL); + PutWindowTilemap(WIN_CHAT_HISTORY); + FillWindowPixelBuffer(WIN_CHAT_HISTORY, PIXEL_FILL(1)); + CopyWindowToVram(WIN_CHAT_HISTORY, COPYWIN_FULL); } static void LoadKeyboardWindow(void) { - PutWindowTilemap(2); + PutWindowTilemap(WIN_KEYBOARD); PrintCurrentKeyboardPage(); - CopyWindowToVram(2, COPYWIN_FULL); + CopyWindowToVram(WIN_KEYBOARD, COPYWIN_FULL); } static void LoadTextEntryWindow(void) @@ -3107,18 +3117,18 @@ static void LoadTextEntryWindow(void) unused[1] = 0xFF; for (i = 0; i < MAX_MESSAGE_LENGTH; i++) - BlitBitmapToWindow(1, sDisplay->unk2128, i * 8, 0, 8, 16); + BlitBitmapToWindow(WIN_TEXT_ENTRY, sDisplay->unk2128, i * 8, 0, 8, 16); - FillWindowPixelBuffer(1, PIXEL_FILL(0)); - PutWindowTilemap(1); - CopyWindowToVram(1, COPYWIN_FULL); + FillWindowPixelBuffer(WIN_TEXT_ENTRY, PIXEL_FILL(0)); + PutWindowTilemap(WIN_TEXT_ENTRY); + CopyWindowToVram(WIN_TEXT_ENTRY, COPYWIN_FULL); } static void LoadKeyboardSwapWindow(void) { - FillWindowPixelBuffer(3, PIXEL_FILL(1)); - LoadUserWindowBorderGfx(3, 1, 0xD0); - LoadUserWindowBorderGfx_(3, 0xA, 0x20); + FillWindowPixelBuffer(WIN_SWAP_MENU, PIXEL_FILL(1)); + LoadUserWindowBorderGfx(WIN_SWAP_MENU, 1, 0xD0); + LoadUserWindowBorderGfx_(WIN_SWAP_MENU, 0xA, 0x20); LoadPalette(gStandardMenuPalette, 0xE0, 0x20); } From 2cd07d80b8e60cc0b2660dea3df7d2f4295b69c8 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 13:31:01 -0400 Subject: [PATCH 09/69] Use window constants in wireless_communication_status_screen --- src/wireless_communication_status_screen.c | 62 ++++++++++++---------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/src/wireless_communication_status_screen.c b/src/wireless_communication_status_screen.c index 1fbd83fcd..5d40aefb7 100644 --- a/src/wireless_communication_status_screen.c +++ b/src/wireless_communication_status_screen.c @@ -27,12 +27,20 @@ enum { COLORMODE_WHITE_DGRAY, }; -#define GROUPTYPE_TRADE 0 -#define GROUPTYPE_BATTLE 1 -#define GROUPTYPE_UNION 2 -#define GROUPTYPE_TOTAL 3 -#define GROUPTYPE_NONE -1 -#define NUM_GROUPTYPES 4 +enum { + WIN_TITLE, + WIN_GROUP_NAMES, + WIN_GROUP_COUNTS, +}; + +enum { + GROUPTYPE_NONE = -1, + GROUPTYPE_TRADE, + GROUPTYPE_BATTLE, + GROUPTYPE_UNION, + GROUPTYPE_TOTAL, + NUM_GROUPTYPES +}; struct WirelessCommunicationStatusScreen { @@ -70,7 +78,7 @@ static const struct BgTemplate sBgTemplates[] = { }; static const struct WindowTemplate sWindowTemplates[] = { - { + [WIN_TITLE] = { .bg = 0, .tilemapLeft = 3, .tilemapTop = 0, @@ -78,7 +86,8 @@ static const struct WindowTemplate sWindowTemplates[] = { .height = 3, .paletteNum = 15, .baseBlock = 0x0001 - }, { + }, + [WIN_GROUP_NAMES] = { .bg = 0, .tilemapLeft = 3, .tilemapTop = 4, @@ -86,7 +95,8 @@ static const struct WindowTemplate sWindowTemplates[] = { .height = 15, .paletteNum = 15, .baseBlock = 0x0049 - }, { + }, + [WIN_GROUP_COUNTS] = { .bg = 0, .tilemapLeft = 24, .tilemapTop = 4, @@ -233,19 +243,17 @@ static void WCSS_CyclePalette(s16 * counter, s16 * palIdx) static void PrintHeaderTexts(void) { s32 i; - FillWindowPixelBuffer(0, PIXEL_FILL(0)); - FillWindowPixelBuffer(1, PIXEL_FILL(0)); - FillWindowPixelBuffer(2, PIXEL_FILL(0)); - WCSS_AddTextPrinterParameterized(0, FONT_NORMAL, sHeaderTexts[0], GetStringCenterAlignXOffset(FONT_NORMAL, sHeaderTexts[0], 0xC0), 6, COLORMODE_GREEN); + FillWindowPixelBuffer(WIN_TITLE, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_GROUP_NAMES, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_GROUP_COUNTS, PIXEL_FILL(0)); + WCSS_AddTextPrinterParameterized(WIN_TITLE, FONT_NORMAL, sHeaderTexts[0], GetStringCenterAlignXOffset(FONT_NORMAL, sHeaderTexts[0], 0xC0), 6, COLORMODE_GREEN); for (i = 0; i < (int)ARRAY_COUNT(*sHeaderTexts) - 1; i++) - { - WCSS_AddTextPrinterParameterized(1, FONT_NORMAL, sHeaderTexts[i + 1], 0, 30 * i + 8, COLORMODE_WHITE_LGRAY); - } - WCSS_AddTextPrinterParameterized(1, FONT_NORMAL, sHeaderTexts[i + 1], 0, 30 * i + 8, COLORMODE_RED); - PutWindowTilemap(0); - CopyWindowToVram(0, COPYWIN_GFX); - PutWindowTilemap(1); - CopyWindowToVram(1, COPYWIN_GFX); + WCSS_AddTextPrinterParameterized(WIN_GROUP_NAMES, FONT_NORMAL, sHeaderTexts[i + 1], 0, 30 * i + 8, COLORMODE_WHITE_LGRAY); + WCSS_AddTextPrinterParameterized(WIN_GROUP_NAMES, FONT_NORMAL, sHeaderTexts[i + 1], 0, 30 * i + 8, COLORMODE_RED); + PutWindowTilemap(WIN_TITLE); + CopyWindowToVram(WIN_TITLE, COPYWIN_GFX); + PutWindowTilemap(WIN_GROUP_NAMES); + CopyWindowToVram(WIN_GROUP_NAMES, COPYWIN_GFX); } #define tState data[0] @@ -268,24 +276,22 @@ static void Task_WirelessCommunicationScreen(u8 taskId) break; case 2: if (!gPaletteFade.active) - { gTasks[taskId].tState++; - } break; case 3: if (UpdateCommunicationCounts(sStatusScreen->groupCounts, sStatusScreen->prevGroupCounts, sStatusScreen->activities, sStatusScreen->rfuTaskId)) { - FillWindowPixelBuffer(2, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_GROUP_COUNTS, PIXEL_FILL(0)); for (i = 0; i < NUM_GROUPTYPES; i++) { ConvertIntToDecimalStringN(gStringVar4, sStatusScreen->groupCounts[i], STR_CONV_MODE_RIGHT_ALIGN, 2); if (i != GROUPTYPE_TOTAL) - WCSS_AddTextPrinterParameterized(2, FONT_NORMAL, gStringVar4, 12, 30 * i + 8, COLORMODE_WHITE_LGRAY); + WCSS_AddTextPrinterParameterized(WIN_GROUP_COUNTS, FONT_NORMAL, gStringVar4, 12, 30 * i + 8, COLORMODE_WHITE_LGRAY); else - WCSS_AddTextPrinterParameterized(2, FONT_NORMAL, gStringVar4, 12, 98, COLORMODE_RED); + WCSS_AddTextPrinterParameterized(WIN_GROUP_COUNTS, FONT_NORMAL, gStringVar4, 12, 98, COLORMODE_RED); } - PutWindowTilemap(2); - CopyWindowToVram(2, COPYWIN_FULL); + PutWindowTilemap(WIN_GROUP_COUNTS); + CopyWindowToVram(WIN_GROUP_COUNTS, COPYWIN_FULL); } if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON)) { From 9ae918bb3564065d056c75fe80a86061b1962f77 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 13:37:32 -0400 Subject: [PATCH 10/69] Use window constants in field_region_map --- src/field_region_map.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/field_region_map.c b/src/field_region_map.c index 43055174f..365b1622a 100644 --- a/src/field_region_map.c +++ b/src/field_region_map.c @@ -23,9 +23,15 @@ * For the fly map, and utility functions all of the maps use, see region_map.c */ -// Static type declarations +enum { + WIN_MAPSEC_NAME, + WIN_TITLE, +}; -// Static RAM declarations +enum { + TAG_PLAYER_ICON, + TAG_CURSOR, +}; static EWRAM_DATA struct { MainCallback callback; @@ -34,16 +40,12 @@ static EWRAM_DATA struct { u16 state; } *sFieldRegionMapHandler = NULL; -// Static ROM declarations - static void MCB2_InitRegionMapRegisters(void); static void VBCB_FieldUpdateRegionMap(void); static void MCB2_FieldUpdateRegionMap(void); static void FieldUpdateRegionMap(void); static void PrintRegionMapSecName(void); -// .rodata - static const struct BgTemplate sFieldRegionMapBgTemplates[] = { { .bg = 0, @@ -66,7 +68,7 @@ static const struct BgTemplate sFieldRegionMapBgTemplates[] = { static const struct WindowTemplate sFieldRegionMapWindowTemplates[] = { - { + [WIN_MAPSEC_NAME] = { .bg = 0, .tilemapLeft = 17, .tilemapTop = 17, @@ -75,7 +77,7 @@ static const struct WindowTemplate sFieldRegionMapWindowTemplates[] = .paletteNum = 15, .baseBlock = 1 }, - { + [WIN_TITLE] = { .bg = 0, .tilemapLeft = 22, .tilemapTop = 1, @@ -87,8 +89,6 @@ static const struct WindowTemplate sFieldRegionMapWindowTemplates[] = DUMMY_WIN_TEMPLATE }; -// .text - void FieldInitRegionMap(MainCallback callback) { SetVBlankCallback(NULL); @@ -145,16 +145,16 @@ static void FieldUpdateRegionMap(void) { case 0: InitRegionMap(&sFieldRegionMapHandler->regionMap, FALSE); - CreateRegionMapPlayerIcon(0, 0); - CreateRegionMapCursor(1, 1); + CreateRegionMapPlayerIcon(TAG_PLAYER_ICON, TAG_PLAYER_ICON); + CreateRegionMapCursor(TAG_CURSOR, TAG_CURSOR); sFieldRegionMapHandler->state++; break; case 1: - DrawStdFrameWithCustomTileAndPalette(1, FALSE, 0x27, 0xd); + DrawStdFrameWithCustomTileAndPalette(WIN_TITLE, FALSE, 0x27, 0xd); offset = GetStringCenterAlignXOffset(FONT_NORMAL, gText_Hoenn, 0x38); - AddTextPrinterParameterized(1, FONT_NORMAL, gText_Hoenn, offset, 1, 0, NULL); + AddTextPrinterParameterized(WIN_TITLE, FONT_NORMAL, gText_Hoenn, offset, 1, 0, NULL); ScheduleBgCopyTilemapToVram(0); - DrawStdFrameWithCustomTileAndPalette(0, FALSE, 0x27, 0xd); + DrawStdFrameWithCustomTileAndPalette(WIN_MAPSEC_NAME, FALSE, 0x27, 0xd); PrintRegionMapSecName(); BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK); sFieldRegionMapHandler->state++; @@ -203,13 +203,13 @@ static void PrintRegionMapSecName(void) { if (sFieldRegionMapHandler->regionMap.mapSecType != MAPSECTYPE_NONE) { - FillWindowPixelBuffer(0, PIXEL_FILL(1)); - AddTextPrinterParameterized(0, FONT_NORMAL, sFieldRegionMapHandler->regionMap.mapSecName, 0, 1, 0, NULL); - ScheduleBgCopyTilemapToVram(0); + FillWindowPixelBuffer(WIN_MAPSEC_NAME, PIXEL_FILL(1)); + AddTextPrinterParameterized(WIN_MAPSEC_NAME, FONT_NORMAL, sFieldRegionMapHandler->regionMap.mapSecName, 0, 1, 0, NULL); + ScheduleBgCopyTilemapToVram(WIN_MAPSEC_NAME); } else { - FillWindowPixelBuffer(0, PIXEL_FILL(1)); - CopyWindowToVram(0, COPYWIN_FULL); + FillWindowPixelBuffer(WIN_MAPSEC_NAME, PIXEL_FILL(1)); + CopyWindowToVram(WIN_MAPSEC_NAME, COPYWIN_FULL); } } From c719d5d9b1a6af7e1afe6966dfd8b07edc09437b Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 14:50:51 -0400 Subject: [PATCH 11/69] Use window constants in link --- src/link.c | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/link.c b/src/link.c index b01be9d89..3d36755fc 100644 --- a/src/link.c +++ b/src/link.c @@ -28,6 +28,13 @@ #include "constants/rgb.h" #include "constants/trade.h" +// Window IDs for the link error screens +enum { + WIN_LINK_ERROR_TOP, + WIN_LINK_ERROR_MID, + WIN_LINK_ERROR_BOTTOM, +}; + struct BlockTransfer { u16 pos; @@ -193,8 +200,9 @@ static const struct BgTemplate sLinkErrorBgTemplates[] = { .priority = 1 } }; + static const struct WindowTemplate sLinkErrorWindowTemplates[] = { - { + [WIN_LINK_ERROR_TOP] = { .bg = 0, .tilemapLeft = 0, .tilemapTop = 0, @@ -202,7 +210,8 @@ static const struct WindowTemplate sLinkErrorWindowTemplates[] = { .height = 5, .paletteNum = 15, .baseBlock = 0x002 - }, { + }, + [WIN_LINK_ERROR_MID] = { .bg = 0, .tilemapLeft = 0, .tilemapTop = 6, @@ -210,7 +219,8 @@ static const struct WindowTemplate sLinkErrorWindowTemplates[] = { .height = 7, .paletteNum = 15, .baseBlock = 0x098 - }, { + }, + [WIN_LINK_ERROR_BOTTOM] = { .bg = 0, .tilemapLeft = 0, .tilemapTop = 13, @@ -1641,26 +1651,26 @@ static void ErrorMsg_MoveCloserToPartner(void) CopyToBgTilemapBuffer(1, sWirelessLinkDisplayTilemap, 0, 0); CopyBgTilemapBufferToVram(1); LoadPalette(sWirelessLinkDisplayPal, 0, 0x20); - FillWindowPixelBuffer(0, PIXEL_FILL(0)); - FillWindowPixelBuffer(2, PIXEL_FILL(0)); - AddTextPrinterParameterized3(0, FONT_SHORT_COPY_1, 2, 6, sTextColors, 0, gText_CommErrorEllipsis); - AddTextPrinterParameterized3(2, FONT_SHORT_COPY_1, 2, 1, sTextColors, 0, gText_MoveCloserToLinkPartner); - PutWindowTilemap(0); - PutWindowTilemap(2); - CopyWindowToVram(0, COPYWIN_NONE); // Does nothing - CopyWindowToVram(2, COPYWIN_FULL); + FillWindowPixelBuffer(WIN_LINK_ERROR_TOP, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_LINK_ERROR_BOTTOM, PIXEL_FILL(0)); + AddTextPrinterParameterized3(WIN_LINK_ERROR_TOP, FONT_SHORT_COPY_1, 2, 6, sTextColors, 0, gText_CommErrorEllipsis); + AddTextPrinterParameterized3(WIN_LINK_ERROR_BOTTOM, FONT_SHORT_COPY_1, 2, 1, sTextColors, 0, gText_MoveCloserToLinkPartner); + PutWindowTilemap(WIN_LINK_ERROR_TOP); + PutWindowTilemap(WIN_LINK_ERROR_BOTTOM); + CopyWindowToVram(WIN_LINK_ERROR_TOP, COPYWIN_NONE); // Does nothing + CopyWindowToVram(WIN_LINK_ERROR_BOTTOM, COPYWIN_FULL); } static void ErrorMsg_CheckConnections(void) { LoadBgTiles(0, sCommErrorBg_Gfx, 0x20, 0); - FillWindowPixelBuffer(1, PIXEL_FILL(0)); - FillWindowPixelBuffer(2, PIXEL_FILL(0)); - AddTextPrinterParameterized3(1, FONT_SHORT_COPY_1, 2, 0, sTextColors, 0, gText_CommErrorCheckConnections); - PutWindowTilemap(1); - PutWindowTilemap(2); - CopyWindowToVram(1, COPYWIN_NONE); // Does nothing - CopyWindowToVram(2, COPYWIN_FULL); + FillWindowPixelBuffer(WIN_LINK_ERROR_MID, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_LINK_ERROR_BOTTOM, PIXEL_FILL(0)); + AddTextPrinterParameterized3(WIN_LINK_ERROR_MID, FONT_SHORT_COPY_1, 2, 0, sTextColors, 0, gText_CommErrorCheckConnections); + PutWindowTilemap(WIN_LINK_ERROR_MID); + PutWindowTilemap(WIN_LINK_ERROR_BOTTOM); + CopyWindowToVram(WIN_LINK_ERROR_MID, COPYWIN_NONE); // Does nothing + CopyWindowToVram(WIN_LINK_ERROR_BOTTOM, COPYWIN_FULL); } static void CB2_PrintErrorMessage(void) @@ -1691,9 +1701,9 @@ static void CB2_PrintErrorMessage(void) break; case 130: if (gWirelessCommType == 2) - AddTextPrinterParameterized3(0, FONT_SHORT_COPY_1, 2, 20, sTextColors, 0, gText_ABtnTitleScreen); + AddTextPrinterParameterized3(WIN_LINK_ERROR_TOP, FONT_SHORT_COPY_1, 2, 20, sTextColors, 0, gText_ABtnTitleScreen); else if (gWirelessCommType == 1) - AddTextPrinterParameterized3(0, FONT_SHORT_COPY_1, 2, 20, sTextColors, 0, gText_ABtnRegistrationCounter); + AddTextPrinterParameterized3(WIN_LINK_ERROR_TOP, FONT_SHORT_COPY_1, 2, 20, sTextColors, 0, gText_ABtnRegistrationCounter); break; } if (gMain.state == 160) From 6bc1955c992458891538267193eaa18549d9cf66 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 15:03:44 -0400 Subject: [PATCH 12/69] Use window constants in easy_chat --- src/easy_chat.c | 88 ++++++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 38 deletions(-) diff --git a/src/easy_chat.c b/src/easy_chat.c index 054c65c0f..8a2bae7d5 100644 --- a/src/easy_chat.c +++ b/src/easy_chat.c @@ -226,18 +226,23 @@ static void DoQuizQuestionEasyChatScreen(void); static void DoQuizSetAnswerEasyChatScreen(void); static void DoQuizSetQuestionEasyChatScreen(void); -#define PALTAG_TRIANGLE_CURSOR 0 -#define PALTAG_RECTANGLE_CURSOR 1 -#define PALTAG_MISC_UI 2 -#define PALTAG_RS_INTERVIEW_FRAME 3 +enum { + PALTAG_TRIANGLE_CURSOR, + PALTAG_RECTANGLE_CURSOR, + PALTAG_MISC_UI, + PALTAG_RS_INTERVIEW_FRAME, +}; + +enum { + GFXTAG_TRIANGLE_CURSOR, + GFXTAG_RECTANGLE_CURSOR, + GFXTAG_SCROLL_INDICATOR, + GFXTAG_START_SELECT_BUTTONS, + GFXTAG_MODE_WINDOW, + GFXTAG_RS_INTERVIEW_FRAME, + GFXTAG_BUTTON_WINDOW, +}; -#define GFXTAG_TRIANGLE_CURSOR 0 -#define GFXTAG_RECTANGLE_CURSOR 1 -#define GFXTAG_SCROLL_INDICATOR 2 -#define GFXTAG_START_SELECT_BUTTONS 3 -#define GFXTAG_MODE_WINDOW 4 -#define GFXTAG_RS_INTERVIEW_FRAME 5 -#define GFXTAG_BUTTON_WINDOW 6 // State values for sEasyChatScreen->inputState // Control which input handler to use in HandleEasyChatInput @@ -376,6 +381,13 @@ enum { WINANIM_KEYBOARD_SWITCH_IN, }; +// Window IDs +enum { + WIN_TITLE, + WIN_MSG, + WIN_INPUT_SELECT, // Word groups, word list, and keyboard +}; + // Values for text frame tilemap #define FRAME_OFFSET_ORANGE 0x1000 // Orange frame, for phrase text #define FRAME_OFFSET_GREEN 0x4000 // Green frame, for keyboard/word select @@ -814,7 +826,7 @@ static const struct BgTemplate sEasyChatBgTemplates[] = { }; static const struct WindowTemplate sEasyChatWindowTemplates[] = { - { + [WIN_TITLE] = { .bg = 1, .tilemapLeft = 6, .tilemapTop = 0, @@ -823,7 +835,7 @@ static const struct WindowTemplate sEasyChatWindowTemplates[] = { .paletteNum = 10, .baseBlock = 0x10, }, - { + [WIN_MSG] = { .bg = 0, .tilemapLeft = 3, .tilemapTop = 15, @@ -832,7 +844,7 @@ static const struct WindowTemplate sEasyChatWindowTemplates[] = { .paletteNum = 15, .baseBlock = 0xA, }, - { + [WIN_INPUT_SELECT] = { .bg = 2, .tilemapLeft = 1, .tilemapTop = 0, @@ -3934,10 +3946,10 @@ static void PrintTitle(void) return; xOffset = GetStringCenterAlignXOffset(FONT_NORMAL, titleText, 144); - FillWindowPixelBuffer(0, PIXEL_FILL(0)); - PrintEasyChatTextWithColors(0, FONT_NORMAL, titleText, xOffset, 1, TEXT_SKIP_DRAW, TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY); - PutWindowTilemap(0); - CopyWindowToVram(0, COPYWIN_FULL); + FillWindowPixelBuffer(WIN_TITLE, PIXEL_FILL(0)); + PrintEasyChatTextWithColors(WIN_TITLE, FONT_NORMAL, titleText, xOffset, 1, TEXT_SKIP_DRAW, TEXT_COLOR_TRANSPARENT, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY); + PutWindowTilemap(WIN_TITLE); + CopyWindowToVram(WIN_TITLE, COPYWIN_FULL); } static void PrintEasyChatText(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 speed, void (*callback)(struct TextPrinterTemplate *, u16)) @@ -3957,10 +3969,10 @@ static void PrintEasyChatTextWithColors(u8 windowId, u8 fontId, const u8 *str, u static void PrintInitialInstructions(void) { FillBgTilemapBufferRect(0, 0, 0, 0, 32, 20, 17); - LoadUserWindowBorderGfx(1, 1, 0xE0); - DrawTextBorderOuter(1, 1, 14); + LoadUserWindowBorderGfx(WIN_MSG, 1, 0xE0); + DrawTextBorderOuter(WIN_MSG, 1, 14); PrintEasyChatStdMessage(MSG_INSTRUCTIONS); - PutWindowTilemap(1); + PutWindowTilemap(WIN_MSG); CopyBgTilemapBufferToVram(0); } @@ -4004,14 +4016,14 @@ static void PrintEasyChatStdMessage(u8 msgId) break; } - FillWindowPixelBuffer(1, PIXEL_FILL(1)); + FillWindowPixelBuffer(WIN_MSG, PIXEL_FILL(1)); if (text1) - PrintEasyChatText(1, FONT_NORMAL, text1, 0, 1, TEXT_SKIP_DRAW, 0); + PrintEasyChatText(WIN_MSG, FONT_NORMAL, text1, 0, 1, TEXT_SKIP_DRAW, 0); if (text2) - PrintEasyChatText(1, FONT_NORMAL, text2, 0, 17, TEXT_SKIP_DRAW, 0); + PrintEasyChatText(WIN_MSG, FONT_NORMAL, text2, 0, 17, TEXT_SKIP_DRAW, 0); - CopyWindowToVram(1, COPYWIN_FULL); + CopyWindowToVram(WIN_MSG, COPYWIN_FULL); } static void CreateEasyChatYesNoMenu(u8 initialCursorPos) @@ -4198,14 +4210,14 @@ static void AdjustBgTilemapForFooter(void) static void DrawLowerWindow(void) { - PutWindowTilemap(2); - CopyBgTilemapBufferToVram(2); + PutWindowTilemap(WIN_INPUT_SELECT); + CopyBgTilemapBufferToVram(WIN_INPUT_SELECT); } static void InitLowerWindowText(u32 whichText) { ResetLowerWindowScroll(); - FillWindowPixelBuffer(2, PIXEL_FILL(1)); + FillWindowPixelBuffer(WIN_INPUT_SELECT, PIXEL_FILL(1)); switch (whichText) { case TEXT_GROUPS: @@ -4219,7 +4231,7 @@ static void InitLowerWindowText(u32 whichText) break; } - CopyWindowToVram(2, COPYWIN_GFX); + CopyWindowToVram(WIN_INPUT_SELECT, COPYWIN_GFX); } static void PrintKeyboardText(void) @@ -4248,7 +4260,7 @@ static void PrintKeyboardGroupNames(void) return; } - PrintEasyChatText(2, FONT_NORMAL, GetEasyChatWordGroupName(groupId), x * 84 + 10, y, TEXT_SKIP_DRAW, NULL); + PrintEasyChatText(WIN_INPUT_SELECT, FONT_NORMAL, GetEasyChatWordGroupName(groupId), x * 84 + 10, y, TEXT_SKIP_DRAW, NULL); } y += 16; @@ -4260,7 +4272,7 @@ static void PrintKeyboardAlphabet(void) u32 i; for (i = 0; i < ARRAY_COUNT(sEasyChatKeyboardAlphabet); i++) - PrintEasyChatText(2, FONT_NORMAL, sEasyChatKeyboardAlphabet[i], 10, 97 + i * 16, TEXT_SKIP_DRAW, NULL); + PrintEasyChatText(WIN_INPUT_SELECT, FONT_NORMAL, sEasyChatKeyboardAlphabet[i], 10, 97 + i * 16, TEXT_SKIP_DRAW, NULL); } static void PrintInitialWordSelectText(void) @@ -4331,16 +4343,16 @@ static void PrintWordSelectText(u8 scrollOffset, u8 numRows) { CopyEasyChatWordPadded(sScreenControl->wordSelectPrintBuffer, easyChatWord, 0); if (!DummyWordCheck(easyChatWord)) - PrintEasyChatText(2, FONT_NORMAL, sScreenControl->wordSelectPrintBuffer, (j * 13 + 3) * 8, y, TEXT_SKIP_DRAW, NULL); + PrintEasyChatText(WIN_INPUT_SELECT, FONT_NORMAL, sScreenControl->wordSelectPrintBuffer, (j * 13 + 3) * 8, y, TEXT_SKIP_DRAW, NULL); else // Never reached - PrintEasyChatTextWithColors(2, FONT_NORMAL, sScreenControl->wordSelectPrintBuffer, (j * 13 + 3) * 8, y, TEXT_SKIP_DRAW, TEXT_COLOR_WHITE, TEXT_COLOR_LIGHT_RED, TEXT_COLOR_LIGHT_GRAY); + PrintEasyChatTextWithColors(WIN_INPUT_SELECT, FONT_NORMAL, sScreenControl->wordSelectPrintBuffer, (j * 13 + 3) * 8, y, TEXT_SKIP_DRAW, TEXT_COLOR_WHITE, TEXT_COLOR_LIGHT_RED, TEXT_COLOR_LIGHT_GRAY); } } y += 16; } - CopyWindowToVram(2, COPYWIN_GFX); + CopyWindowToVram(WIN_INPUT_SELECT, COPYWIN_GFX); } static void EraseWordSelectRows(u8 scrollOffset, u8 numRows) @@ -4364,15 +4376,15 @@ static void EraseWordSelectRows(u8 scrollOffset, u8 numRows) var1 = 0; } - FillWindowPixelRect(2, PIXEL_FILL(1), 0, y, 224, var2); + FillWindowPixelRect(WIN_INPUT_SELECT, PIXEL_FILL(1), 0, y, 224, var2); if (var1) - FillWindowPixelRect(2, PIXEL_FILL(1), 0, 0, 224, var1); + FillWindowPixelRect(WIN_INPUT_SELECT, PIXEL_FILL(1), 0, 0, 224, var1); } static void ClearWordSelectWindow(void) { - FillWindowPixelBuffer(2, PIXEL_FILL(1)); - CopyWindowToVram(2, COPYWIN_GFX); + FillWindowPixelBuffer(WIN_INPUT_SELECT, PIXEL_FILL(1)); + CopyWindowToVram(WIN_INPUT_SELECT, COPYWIN_GFX); } static void InitLowerWindowAnim(int winAnimType) From 5af7355fbd8a04e4d24a7e5e791f2ca5c6d68935 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 15:10:32 -0400 Subject: [PATCH 13/69] Clarify window ID usage in contest_util --- src/contest_util.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/contest_util.c b/src/contest_util.c index d44b47373..654a0c399 100644 --- a/src/contest_util.c +++ b/src/contest_util.c @@ -319,9 +319,10 @@ static const struct BgTemplate sBgTemplates[] = } }; -static const struct WindowTemplate sWindowTemplates[] = +// Window IDs are implicitly shared with contestant IDs in LoadContestMonName +static const struct WindowTemplate sWindowTemplates[CONTESTANT_COUNT + 1] = { - { + { // Contestant 1 .bg = 1, .tilemapLeft = 7, .tilemapTop = 4, @@ -330,7 +331,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 15, .baseBlock = 770 }, - { + { // Contestant 2 .bg = 1, .tilemapLeft = 7, .tilemapTop = 7, @@ -339,7 +340,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 15, .baseBlock = 794 }, - { + { // Contestant 3 .bg = 1, .tilemapLeft = 7, .tilemapTop = 10, @@ -348,7 +349,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 15, .baseBlock = 818 }, - { + { // Contestant 4 .bg = 1, .tilemapLeft = 7, .tilemapTop = 13, @@ -357,7 +358,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 15, .baseBlock = 842 }, - DUMMY_WIN_TEMPLATE, + DUMMY_WIN_TEMPLATE }; static const struct OamData sOamData_WirelessIndicatorWindow = From fb87616e9d147de21fe2eba278f0f74737ebfc32 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 15:48:19 -0400 Subject: [PATCH 14/69] Use window constants in mystery_gift_menu --- include/mystery_gift_menu.h | 4 +- src/ereader_screen.c | 14 ++-- src/mystery_gift_menu.c | 133 +++++++++++++++++++----------------- src/mystery_gift_view.c | 4 +- src/union_room.c | 18 ++--- 5 files changed, 91 insertions(+), 82 deletions(-) diff --git a/include/mystery_gift_menu.h b/include/mystery_gift_menu.h index dc30d3051..665c4596e 100644 --- a/include/mystery_gift_menu.h +++ b/include/mystery_gift_menu.h @@ -5,11 +5,11 @@ extern bool8 gGiftIsFromEReader; u16 GetMysteryGiftBaseBlock(void); void CB2_MysteryGiftEReader(void); -void PrintMysteryGiftOrEReaderTopMenu(bool8 isJapanese, bool32 usePickOkCancel); +void PrintMysteryGiftOrEReaderHeader(bool8 isJapanese, bool32 usePickOkCancel); void MG_DrawCheckerboardPattern(u32 bg); void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void); bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str); -void AddTextPrinterToWindow1(const u8 *src); +void MG_AddMessageTextPrinter(const u8 *src); void CB2_InitEReader(void); void CB2_InitMysteryGift(void); void MG_DrawTextBorder(u8 windowId); diff --git a/src/ereader_screen.c b/src/ereader_screen.c index b6bf7133a..8079c9900 100755 --- a/src/ereader_screen.c +++ b/src/ereader_screen.c @@ -342,7 +342,7 @@ static void Task_EReader(u8 taskId) case ER_STATE_MSG_SELECT_CONNECT: if (PrintMysteryGiftMenuMessage(&data->textState, gJPText_SelectConnectFromEReaderMenu)) { - AddTextPrinterToWindow1(gJPText_SelectConnectWithGBA); + MG_AddMessageTextPrinter(gJPText_SelectConnectWithGBA); ResetTimer(&data->timer); data->state = ER_STATE_MSG_SELECT_CONNECT_WAIT; } @@ -396,7 +396,7 @@ static void Task_EReader(u8 taskId) data->state = ER_STATE_MSG_SELECT_CONNECT; break; case ER_STATE_CONNECTING: - AddTextPrinterToWindow1(gJPText_Connecting); + MG_AddMessageTextPrinter(gJPText_Connecting); // XXX: This (u32 *) cast is discarding the const qualifier from gMultiBootProgram_EReader_Start EReader_Load(&gEReaderData, gMultiBootProgram_EReader_End - gMultiBootProgram_EReader_Start, (u32 *)gMultiBootProgram_EReader_Start); data->state = ER_STATE_TRANSFER; @@ -415,7 +415,7 @@ static void Task_EReader(u8 taskId) else if (data->status == TRANSFER_SUCCESS) { ResetTimer(&data->timer); - AddTextPrinterToWindow1(gJPText_PleaseWaitAMoment); + MG_AddMessageTextPrinter(gJPText_PleaseWaitAMoment); data->state = ER_STATE_TRANSFER_SUCCESS; } else // TRANSFER_CANCELED @@ -429,7 +429,7 @@ static void Task_EReader(u8 taskId) break; case ER_STATE_LOAD_CARD_START: OpenEReaderLink(); - AddTextPrinterToWindow1(gJPText_AllowEReaderToLoadCard); + MG_AddMessageTextPrinter(gJPText_AllowEReaderToLoadCard); data->state = ER_STATE_LOAD_CARD; break; case ER_STATE_LOAD_CARD: @@ -438,7 +438,7 @@ static void Task_EReader(u8 taskId) case RECV_ACTIVE: break; case RECV_SUCCESS: - AddTextPrinterToWindow1(gJPText_Connecting); + MG_AddMessageTextPrinter(gJPText_Connecting); data->state = ER_STATE_WAIT_RECV_CARD; break; case RECV_CANCELED: @@ -486,7 +486,7 @@ static void Task_EReader(u8 taskId) case ER_STATE_SAVE: if (TryWriteTrainerHill((struct EReaderTrainerHillSet *)&gDecompressionBuffer)) { - AddTextPrinterToWindow1(gJPText_ConnectionComplete); + MG_AddMessageTextPrinter(gJPText_ConnectionComplete); ResetTimer(&data->timer); data->state = ER_STATE_SUCCESS_MSG; } @@ -498,7 +498,7 @@ static void Task_EReader(u8 taskId) case ER_STATE_SUCCESS_MSG: if (UpdateTimer(&data->timer, 120)) { - AddTextPrinterToWindow1(gJPText_NewTrainerHasComeToHoenn); + MG_AddMessageTextPrinter(gJPText_NewTrainerHasComeToHoenn); PlayFanfare(MUS_OBTAIN_ITEM); data->state = ER_STATE_SUCCESS_END; } diff --git a/src/mystery_gift_menu.c b/src/mystery_gift_menu.c index 9e4796bb2..9c8aea4d6 100644 --- a/src/mystery_gift_menu.c +++ b/src/mystery_gift_menu.c @@ -32,6 +32,12 @@ #include "wonder_news.h" #include "constants/cable_club.h" +enum { + WIN_HEADER, + WIN_MSG, + WIN_UNK, // Cleared, but nothing is ever apparently rendered on it +}; + #define LIST_MENU_TILE_NUM 10 #define LIST_MENU_PAL_NUM 224 @@ -98,7 +104,7 @@ static const struct BgTemplate sBGTemplates[] = { }; static const struct WindowTemplate sMainWindows[] = { - { + [WIN_HEADER] = { .bg = 0, .tilemapLeft = 0, .tilemapTop = 0, @@ -106,7 +112,8 @@ static const struct WindowTemplate sMainWindows[] = { .height = 2, .paletteNum = 12, .baseBlock = 0x0013 - }, { + }, + [WIN_MSG] = { .bg = 0, .tilemapLeft = 1, .tilemapTop = 15, @@ -114,7 +121,8 @@ static const struct WindowTemplate sMainWindows[] = { .height = 4, .paletteNum = 12, .baseBlock = 0x004f - }, { + }, + [WIN_UNK] = { .bg = 0, .tilemapLeft = 0, .tilemapTop = 15, @@ -224,7 +232,7 @@ static const struct ListMenuTemplate sListMenuTemplate_ThreeOptions = { .itemPrintFunc = NULL, .totalItems = 3, .maxShowed = 3, - .windowId = 0, + .windowId = 0, // Overwritten by DoMysteryGiftListMenu .header_X = 0, .item_X = 8, .cursor_X = 0, @@ -269,7 +277,7 @@ static const struct ListMenuTemplate sListMenu_ReceiveSendToss = { .itemPrintFunc = NULL, .totalItems = 4, .maxShowed = 4, - .windowId = 0, + .windowId = 0, // Overwritten by DoMysteryGiftListMenu .header_X = 0, .item_X = 8, .cursor_X = 0, @@ -290,7 +298,7 @@ static const struct ListMenuTemplate sListMenu_ReceiveToss = { .itemPrintFunc = NULL, .totalItems = 3, .maxShowed = 3, - .windowId = 0, + .windowId = 0, // Overwritten by DoMysteryGiftListMenu .header_X = 0, .item_X = 8, .cursor_X = 0, @@ -311,7 +319,7 @@ static const struct ListMenuTemplate sListMenu_ReceiveSend = { .itemPrintFunc = NULL, .totalItems = 3, .maxShowed = 3, - .windowId = 0, + .windowId = 0, // Overwritten by DoMysteryGiftListMenu .header_X = 0, .item_X = 8, .cursor_X = 0, @@ -332,7 +340,7 @@ static const struct ListMenuTemplate sListMenu_Receive = { .itemPrintFunc = NULL, .totalItems = 2, .maxShowed = 2, - .windowId = 0, + .windowId = 0, // Overwritten by DoMysteryGiftListMenu .header_X = 0, .item_X = 8, .cursor_X = 0, @@ -354,9 +362,9 @@ static const u8 *const sUnusedMenuTexts[] = { gText_ReturnToTitle }; -ALIGNED(2) static const u8 sTextColors_TopMenu[] = { TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY }; -ALIGNED(2) static const u8 sTextColors_TopMenu_Copy[] = { TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY }; -ALIGNED(2) static const u8 sMG_Ereader_TextColor_2[] = { TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY }; +ALIGNED(2) static const u8 sTextColors_Header[] = { TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY }; +ALIGNED(2) static const u8 sTextColors_Header_Copy[] = { TEXT_COLOR_TRANSPARENT, TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY }; +ALIGNED(2) static const u8 sMG_Ereader_TextColor_2[] = { TEXT_COLOR_WHITE, TEXT_COLOR_DARK_GRAY, TEXT_COLOR_LIGHT_GRAY }; static void VBlankCB_MysteryGiftEReader(void) { @@ -420,7 +428,7 @@ static bool32 HandleMysteryGiftOrEReaderSetup(s32 isEReader) FillBgTilemapBufferRect(1, 0x000, 0, 0, 32, 32, 0x11); FillBgTilemapBufferRect(2, 0x000, 0, 0, 32, 32, 0x11); MG_DrawCheckerboardPattern(3); - PrintMysteryGiftOrEReaderTopMenu(isEReader, FALSE); + PrintMysteryGiftOrEReaderHeader(isEReader, FALSE); gMain.state++; break; case 2: @@ -474,26 +482,27 @@ void MainCB_FreeAllBuffersAndReturnToInitTitleScreen(void) SetMainCallback2(CB2_InitTitleScreen); } -void PrintMysteryGiftOrEReaderTopMenu(bool8 isEReader, bool32 useCancel) +// Print the text window at the top of the screen with the title and control instructions +void PrintMysteryGiftOrEReaderHeader(bool8 isEReader, bool32 useCancel) { - const u8 * header; + const u8 * title; const u8 * options; - FillWindowPixelBuffer(0, 0); + FillWindowPixelBuffer(WIN_HEADER, 0); if (!isEReader) { - header = gText_MysteryGift; + title = gText_MysteryGift; options = !useCancel ? gText_PickOKExit : gText_PickOKCancel; } else { - header = gJPText_MysteryGift; + title = gJPText_MysteryGift; options = gJPText_DecideStop; } - AddTextPrinterParameterized4(0, FONT_NORMAL, 4, 1, 0, 0, sTextColors_TopMenu, TEXT_SKIP_DRAW, header); - AddTextPrinterParameterized4(0, FONT_SMALL, GetStringRightAlignXOffset(FONT_SMALL, options, 0xDE), 1, 0, 0, sTextColors_TopMenu, TEXT_SKIP_DRAW, options); - CopyWindowToVram(0, COPYWIN_GFX); - PutWindowTilemap(0); + AddTextPrinterParameterized4(WIN_HEADER, FONT_NORMAL, 4, 1, 0, 0, sTextColors_Header, TEXT_SKIP_DRAW, title); + AddTextPrinterParameterized4(WIN_HEADER, FONT_SMALL, GetStringRightAlignXOffset(FONT_SMALL, options, 0xDE), 1, 0, 0, sTextColors_Header, TEXT_SKIP_DRAW, options); + CopyWindowToVram(WIN_HEADER, COPYWIN_GFX); + PutWindowTilemap(WIN_HEADER); } void MG_DrawTextBorder(u8 windowId) @@ -533,21 +542,21 @@ static void ClearScreenInBg0(bool32 ignoreTopTwoRows) CopyBgTilemapBufferToVram(0); } -void AddTextPrinterToWindow1(const u8 *str) +void MG_AddMessageTextPrinter(const u8 *str) { StringExpandPlaceholders(gStringVar4, str); - FillWindowPixelBuffer(1, 0x11); - AddTextPrinterParameterized4(1, FONT_NORMAL, 0, 1, 0, 0, sMG_Ereader_TextColor_2, 0, gStringVar4); - DrawTextBorderOuter(1, 0x001, 0xF); - PutWindowTilemap(1); - CopyWindowToVram(1, COPYWIN_FULL); + FillWindowPixelBuffer(WIN_MSG, 0x11); + AddTextPrinterParameterized4(WIN_MSG, FONT_NORMAL, 0, 1, 0, 0, sMG_Ereader_TextColor_2, 0, gStringVar4); + DrawTextBorderOuter(WIN_MSG, 0x001, 0xF); + PutWindowTilemap(WIN_MSG); + CopyWindowToVram(WIN_MSG, COPYWIN_FULL); } -static void ClearTextWindow(void) +static void ClearMessage(void) { - rbox_fill_rectangle(1); - ClearWindowTilemap(1); - CopyWindowToVram(1, COPYWIN_MAP); + rbox_fill_rectangle(WIN_MSG); + ClearWindowTilemap(WIN_MSG); + CopyWindowToVram(WIN_MSG, COPYWIN_MAP); } #define DOWN_ARROW_X 208 @@ -558,18 +567,18 @@ bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str) switch (*textState) { case 0: - AddTextPrinterToWindow1(str); + MG_AddMessageTextPrinter(str); (*textState)++; break; case 1: - DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); - if (({JOY_NEW(A_BUTTON | B_BUTTON);})) + DrawDownArrow(WIN_MSG, DOWN_ARROW_X, DOWN_ARROW_Y, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); + if (JOY_NEW(A_BUTTON | B_BUTTON)) (*textState)++; break; case 2: - DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); + DrawDownArrow(WIN_MSG, DOWN_ARROW_X, DOWN_ARROW_Y, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); *textState = 0; - ClearTextWindow(); + ClearMessage(); return TRUE; case 0xFF: *textState = 2; @@ -580,12 +589,12 @@ bool32 PrintMysteryGiftMenuMessage(u8 *textState, const u8 *str) static void HideDownArrow(void) { - DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); + DrawDownArrow(WIN_MSG, DOWN_ARROW_X, DOWN_ARROW_Y, 1, FALSE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); } static void ShowDownArrow(void) { - DrawDownArrow(1, DOWN_ARROW_X, DOWN_ARROW_Y, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); + DrawDownArrow(WIN_MSG, DOWN_ARROW_X, DOWN_ARROW_Y, 1, TRUE, &sDownArrowCounterAndYCoordIdx[0], &sDownArrowCounterAndYCoordIdx[1]); } // Unused @@ -609,12 +618,12 @@ static bool32 HideDownArrowAndWaitButton(u8 * textState) static bool32 PrintStringAndWait2Seconds(u8 * counter, const u8 * str) { if (*counter == 0) - AddTextPrinterToWindow1(str); + MG_AddMessageTextPrinter(str); if (++(*counter) > 120) { *counter = 0; - ClearTextWindow(); + ClearMessage(); return TRUE; } else @@ -648,8 +657,8 @@ static u32 MysteryGift_HandleThreeOptionMenu(u8 * unused0, u16 * unused1, u8 whi response = DoMysteryGiftListMenu(&windowTemplate, &listMenuTemplate, 1, LIST_MENU_TILE_NUM, LIST_MENU_PAL_NUM); if (response != LIST_NOTHING_CHOSEN) { - ClearWindowTilemap(2); - CopyWindowToVram(2, COPYWIN_MAP); + ClearWindowTilemap(WIN_UNK); + CopyWindowToVram(WIN_UNK, COPYWIN_MAP); } return response; } @@ -865,7 +874,7 @@ static bool32 SaveOnMysteryGiftMenu(u8 * state) switch (*state) { case 0: - AddTextPrinterToWindow1(gText_DataWillBeSaved); + MG_AddMessageTextPrinter(gText_DataWillBeSaved); (*state)++; break; case 1: @@ -873,7 +882,7 @@ static bool32 SaveOnMysteryGiftMenu(u8 * state) (*state)++; break; case 2: - AddTextPrinterToWindow1(gText_SaveCompletedPressA); + MG_AddMessageTextPrinter(gText_SaveCompletedPressA); (*state)++; break; case 3: @@ -882,7 +891,7 @@ static bool32 SaveOnMysteryGiftMenu(u8 * state) break; case 4: *state = 0; - ClearTextWindow(); + ClearMessage(); return TRUE; } @@ -967,7 +976,7 @@ static bool32 PrintSuccessMessage(u8 * state, const u8 * msg, u16 * timer) { case 0: if (msg != NULL) - AddTextPrinterToWindow1(msg); + MG_AddMessageTextPrinter(msg); PlayFanfare(MUS_OBTAIN_ITEM); *timer = 0; (*state)++; @@ -980,7 +989,7 @@ static bool32 PrintSuccessMessage(u8 * state, const u8 * msg, u16 * timer) if (IsFanfareTaskInactive()) { *state = 0; - ClearTextWindow(); + ClearMessage(); return TRUE; } break; @@ -1161,7 +1170,7 @@ static void Task_MysteryGift(u8 taskId) if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveCardNewOneInput)) { data->state = MG_STATE_SOURCE_PROMPT; - PrintMysteryGiftOrEReaderTopMenu(FALSE, TRUE); + PrintMysteryGiftOrEReaderHeader(FALSE, TRUE); } } else @@ -1169,16 +1178,16 @@ static void Task_MysteryGift(u8 taskId) if (PrintMysteryGiftMenuMessage(&data->textState, gText_DontHaveNewsNewOneInput)) { data->state = MG_STATE_SOURCE_PROMPT; - PrintMysteryGiftOrEReaderTopMenu(FALSE, TRUE); + PrintMysteryGiftOrEReaderHeader(FALSE, TRUE); } } break; } case MG_STATE_SOURCE_PROMPT: if (!data->isWonderNews) - AddTextPrinterToWindow1(gText_WhereShouldCardBeAccessed); + MG_AddMessageTextPrinter(gText_WhereShouldCardBeAccessed); else - AddTextPrinterToWindow1(gText_WhereShouldNewsBeAccessed); + MG_AddMessageTextPrinter(gText_WhereShouldNewsBeAccessed); data->state = MG_STATE_SOURCE_PROMPT_INPUT; break; case MG_STATE_SOURCE_PROMPT_INPUT: @@ -1186,17 +1195,17 @@ static void Task_MysteryGift(u8 taskId) switch (MysteryGift_HandleThreeOptionMenu(&data->textState, &data->var, TRUE)) { case 0: // "Wireless Communication" - ClearTextWindow(); + ClearMessage(); data->state = MG_STATE_CLIENT_LINK_START; data->sourceIsFriend = FALSE; break; case 1: // "Friend" - ClearTextWindow(); + ClearMessage(); data->state = MG_STATE_CLIENT_LINK_START; data->sourceIsFriend = TRUE; break; case LIST_CANCEL: - ClearTextWindow(); + ClearMessage(); if (ValidateCardOrNews(data->isWonderNews)) { data->state = MG_STATE_LOAD_GIFT; @@ -1204,7 +1213,7 @@ static void Task_MysteryGift(u8 taskId) else { data->state = MG_STATE_TO_MAIN_MENU; - PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE); + PrintMysteryGiftOrEReaderHeader(FALSE, FALSE); } break; } @@ -1246,7 +1255,7 @@ static void Task_MysteryGift(u8 taskId) } break; case MG_STATE_CLIENT_COMMUNICATING: - AddTextPrinterToWindow1(gText_Communicating); + MG_AddMessageTextPrinter(gText_Communicating); data->state = MG_STATE_CLIENT_LINK; break; case MG_STATE_CLIENT_LINK: @@ -1379,7 +1388,7 @@ static void Task_MysteryGift(u8 taskId) { // Did not receive card/news, return to main menu data->state = MG_STATE_TO_MAIN_MENU; - PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE); + PrintMysteryGiftOrEReaderHeader(FALSE, FALSE); } else { @@ -1500,7 +1509,7 @@ static void Task_MysteryGift(u8 taskId) if (PrintThrownAway(&data->textState, data->isWonderNews)) { data->state = MG_STATE_TO_MAIN_MENU; - PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE); + PrintMysteryGiftOrEReaderHeader(FALSE, FALSE); } break; case MG_STATE_GIFT_INPUT_EXIT: @@ -1546,12 +1555,12 @@ static void Task_MysteryGift(u8 taskId) if (!data->isWonderNews) { - AddTextPrinterToWindow1(gText_SendingWonderCard); + MG_AddMessageTextPrinter(gText_SendingWonderCard); MysterGiftServer_CreateForCard(); } else { - AddTextPrinterToWindow1(gText_SendingWonderNews); + MG_AddMessageTextPrinter(gText_SendingWonderNews); MysterGiftServer_CreateForNews(); } data->state = MG_STATE_SERVER_LINK; @@ -1586,7 +1595,7 @@ static void Task_MysteryGift(u8 taskId) else { data->state = MG_STATE_TO_MAIN_MENU; - PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE); + PrintMysteryGiftOrEReaderHeader(FALSE, FALSE); } } break; @@ -1595,7 +1604,7 @@ static void Task_MysteryGift(u8 taskId) if (PrintMysteryGiftMenuMessage(&data->textState, gText_CommunicationError)) { data->state = MG_STATE_TO_MAIN_MENU; - PrintMysteryGiftOrEReaderTopMenu(FALSE, FALSE); + PrintMysteryGiftOrEReaderHeader(FALSE, FALSE); } break; case MG_STATE_EXIT: diff --git a/src/mystery_gift_view.c b/src/mystery_gift_view.c index b059b183c..a1e294f23 100644 --- a/src/mystery_gift_view.c +++ b/src/mystery_gift_view.c @@ -310,7 +310,7 @@ s32 WonderCard_Exit(bool32 useCancel) FreeMonIconPalettes(); break; case 5: - PrintMysteryGiftOrEReaderTopMenu(gGiftIsFromEReader, useCancel); + PrintMysteryGiftOrEReaderHeader(gGiftIsFromEReader, useCancel); CopyBgTilemapBufferToVram(0); BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK); break; @@ -785,7 +785,7 @@ s32 WonderNews_Exit(bool32 useCancel) } break; case 5: - PrintMysteryGiftOrEReaderTopMenu(gGiftIsFromEReader, useCancel); + PrintMysteryGiftOrEReaderHeader(gGiftIsFromEReader, useCancel); MG_DrawCheckerboardPattern(3); CopyBgTilemapBufferToVram(0); CopyBgTilemapBufferToVram(3); diff --git a/src/union_room.c b/src/union_room.c index b47ddb41c..1396aa224 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -1927,7 +1927,7 @@ static void Task_SendMysteryGift(u8 taskId) data->state = 3; break; case 3: - AddTextPrinterToWindow1(gStringVar4); + MG_AddMessageTextPrinter(gStringVar4); data->state = 4; break; case 4: @@ -2001,7 +2001,7 @@ static void Task_SendMysteryGift(u8 taskId) } break; case 9: - AddTextPrinterToWindow1(gStringVar4); + MG_AddMessageTextPrinter(gStringVar4); data->state = 10; break; case 10: @@ -2104,7 +2104,7 @@ static void Task_CardOrNewsWithFriend(u8 taskId) data->state = 1; break; case 1: - AddTextPrinterToWindow1(sText_ChooseTrainer); + MG_AddMessageTextPrinter(sText_ChooseTrainer); data->state = 2; break; case 2: @@ -2177,7 +2177,7 @@ static void Task_CardOrNewsWithFriend(u8 taskId) } break; case 4: - AddTextPrinterToWindow1(sText_AwaitingPlayersResponse); + MG_AddMessageTextPrinter(sText_AwaitingPlayersResponse); CopyAndTranslatePlayerName(gStringVar1, &data->playerList->players[data->leaderId]); data->state = 5; break; @@ -2196,7 +2196,7 @@ static void Task_CardOrNewsWithFriend(u8 taskId) data->state = 8; break; case RFU_STATUS_JOIN_GROUP_OK: - AddTextPrinterToWindow1(sText_PlayerSentBackOK); + MG_AddMessageTextPrinter(sText_PlayerSentBackOK); RfuSetStatus(RFU_STATUS_OK, 0); break; } @@ -2224,7 +2224,7 @@ static void Task_CardOrNewsWithFriend(u8 taskId) break; case 7: DestroyWirelessStatusIndicatorSprite(); - AddTextPrinterToWindow1(sText_PleaseStartOver); + MG_AddMessageTextPrinter(sText_PleaseStartOver); DestroyTask(taskId); LinkRfu_Shutdown(); gSpecialVar_Result = LINKUP_FAILED; @@ -2273,7 +2273,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId) data->state = 1; break; case 1: - AddTextPrinterToWindow1(sText_SearchingForWirelessSystemWait); + MG_AddMessageTextPrinter(sText_SearchingForWirelessSystemWait); data->state = 2; break; case 2: @@ -2342,7 +2342,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId) } break; case 4: - AddTextPrinterToWindow1(sText_AwaitingResponseFromWirelessSystem); + MG_AddMessageTextPrinter(sText_AwaitingResponseFromWirelessSystem); CopyAndTranslatePlayerName(gStringVar1, &data->playerList->players[data->leaderId]); data->state = 5; break; @@ -2361,7 +2361,7 @@ static void Task_CardOrNewsOverWireless(u8 taskId) data->state = 8; break; case RFU_STATUS_JOIN_GROUP_OK: - AddTextPrinterToWindow1(sText_WirelessLinkEstablished); + MG_AddMessageTextPrinter(sText_WirelessLinkEstablished); RfuSetStatus(RFU_STATUS_OK, 0); break; } From 7d4fddd56b1c91089d166f2d4ec033d43fe69c11 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 15:55:26 -0400 Subject: [PATCH 15/69] Use window constants in mystery_event_menu --- src/mystery_event_menu.c | 53 ++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/src/mystery_event_menu.c b/src/mystery_event_menu.c index b6610a640..826055b24 100644 --- a/src/mystery_event_menu.c +++ b/src/mystery_event_menu.c @@ -20,6 +20,11 @@ #include "decompress.h" #include "constants/rgb.h" +enum { + WIN_MSG, + WIN_LOADING, +}; + static void CB2_MysteryEventMenu(void); static void PrintMysteryMenuText(u8 windowId, const u8 *text, u8 x, u8 y, s32 speed); @@ -40,7 +45,7 @@ static const struct BgTemplate sBgTemplates[] = static const struct WindowTemplate sWindowTemplates[] = { - { + [WIN_MSG] = { .bg = 0, .tilemapLeft = 4, .tilemapTop = 15, @@ -49,7 +54,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 14, .baseBlock = 20 }, - { + [WIN_LOADING] = { .bg = 0, .tilemapLeft = 7, .tilemapTop = 6, @@ -87,7 +92,7 @@ void CB2_InitMysteryEventMenu(void) s32 i; DeactivateAllTextPrinters(); - for (i = 0; i < 2; i++) + for (i = 0; i < (int)ARRAY_COUNT(sWindowTemplates) - 1; i++) FillWindowPixelBuffer(i, PIXEL_FILL(0)); FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 0x1E, 0x14); @@ -131,9 +136,9 @@ static void CB2_MysteryEventMenu(void) switch (gMain.state) { case 0: - DrawStdFrameWithCustomTileAndPalette(0, TRUE, 1, 0xD); - PutWindowTilemap(0); - CopyWindowToVram(0, COPYWIN_FULL); + DrawStdFrameWithCustomTileAndPalette(WIN_MSG, TRUE, 1, 0xD); + PutWindowTilemap(WIN_MSG); + CopyWindowToVram(WIN_MSG, COPYWIN_FULL); ShowBg(0); BeginNormalPaletteFade(PALETTES_ALL, 0, 0x10, 0, RGB_BLACK); gMain.state++; @@ -141,12 +146,12 @@ static void CB2_MysteryEventMenu(void) case 1: if (!gPaletteFade.active) { - PrintMysteryMenuText(0, gText_LinkStandby2, 1, 2, 1); + PrintMysteryMenuText(WIN_MSG, gText_LinkStandby2, 1, 2, 1); gMain.state++; } break; case 2: - if (!IsTextPrinterActive(0)) + if (!IsTextPrinterActive(WIN_MSG)) { gMain.state++; gLinkType = LINKTYPE_MYSTERY_EVENT; @@ -154,10 +159,10 @@ static void CB2_MysteryEventMenu(void) } break; case 3: - if ((gLinkStatus & 0x20) && (gLinkStatus & 0x1C) > 4) + if ((gLinkStatus & LINK_STAT_MASTER) && (gLinkStatus & LINK_STAT_PLAYER_COUNT) > 4) { PlaySE(SE_PIN); - PrintMysteryMenuText(0, gText_PressAToLoadEvent, 1, 2, 1); + PrintMysteryMenuText(WIN_MSG, gText_PressAToLoadEvent, 1, 2, 1); gMain.state++; } if (JOY_NEW(B_BUTTON)) @@ -168,7 +173,7 @@ static void CB2_MysteryEventMenu(void) } break; case 4: - if (!IsTextPrinterActive(0)) + if (!IsTextPrinterActive(WIN_MSG)) gMain.state++; break; case 5: @@ -178,10 +183,10 @@ static void CB2_MysteryEventMenu(void) { PlaySE(SE_SELECT); CheckShouldAdvanceLinkState(); - DrawStdFrameWithCustomTileAndPalette(1, TRUE, 1, 0xD); - PrintMysteryMenuText(1, gText_LoadingEvent, 1, 2, 0); - PutWindowTilemap(1); - CopyWindowToVram(1, COPYWIN_FULL); + DrawStdFrameWithCustomTileAndPalette(WIN_LOADING, TRUE, 1, 0xD); + PrintMysteryMenuText(WIN_LOADING, gText_LoadingEvent, 1, 2, 0); + PutWindowTilemap(WIN_LOADING); + CopyWindowToVram(WIN_LOADING, COPYWIN_FULL); gMain.state++; } else if (JOY_NEW(B_BUTTON)) @@ -194,7 +199,7 @@ static void CB2_MysteryEventMenu(void) else { GetEventLoadMessage(gStringVar4, MEVENT_STATUS_LOAD_ERROR); - PrintMysteryMenuText(0, gStringVar4, 1, 2, 1); + PrintMysteryMenuText(WIN_MSG, gStringVar4, 1, 2, 1); gMain.state = 13; } break; @@ -207,19 +212,19 @@ static void CB2_MysteryEventMenu(void) { SetCloseLinkCallback(); GetEventLoadMessage(gStringVar4, MEVENT_STATUS_LOAD_ERROR); - PrintMysteryMenuText(0, gStringVar4, 1, 2, 1); + PrintMysteryMenuText(WIN_MSG, gStringVar4, 1, 2, 1); gMain.state = 13; } else if (CheckLanguageMatch()) { - PrintMysteryMenuText(0, gText_DontRemoveCableTurnOff, 1, 2, 1); + PrintMysteryMenuText(WIN_MSG, gText_DontRemoveCableTurnOff, 1, 2, 1); gMain.state++; } else { CloseLink(); GetEventLoadMessage(gStringVar4, MEVENT_STATUS_LOAD_ERROR); - PrintMysteryMenuText(0, gStringVar4, 1, 2, 1); + PrintMysteryMenuText(WIN_MSG, gStringVar4, 1, 2, 1); gMain.state = 13; } } @@ -232,7 +237,7 @@ static void CB2_MysteryEventMenu(void) } break; case 7: - if (!IsTextPrinterActive(0)) + if (!IsTextPrinterActive(WIN_MSG)) gMain.state++; break; case 8: @@ -260,11 +265,11 @@ static void CB2_MysteryEventMenu(void) } break; case 12: - PrintMysteryMenuText(0, gStringVar4, 1, 2, 1); + PrintMysteryMenuText(WIN_MSG, gStringVar4, 1, 2, 1); gMain.state++; break; case 13: - if (!IsTextPrinterActive(0)) + if (!IsTextPrinterActive(WIN_MSG)) { gMain.state++; sUnused = 0; @@ -287,11 +292,11 @@ static void CB2_MysteryEventMenu(void) break; } - if (gLinkStatus & 0x40 && !IsLinkMaster()) + if (gLinkStatus & LINK_STAT_CONN_ESTABLISHED && !IsLinkMaster()) { CloseLink(); GetEventLoadMessage(gStringVar4, MEVENT_STATUS_LOAD_ERROR); - PrintMysteryMenuText(0, gStringVar4, 1, 2, 1); + PrintMysteryMenuText(WIN_MSG, gStringVar4, 1, 2, 1); gMain.state = 13; } From 77c3163cf00b12b1568c69571d135888e3b25946 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 18:29:20 -0400 Subject: [PATCH 16/69] Use window constants in reset_rtc_screen --- src/reset_rtc_screen.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/reset_rtc_screen.c b/src/reset_rtc_screen.c index 0a9ec4911..8f8ff6c16 100644 --- a/src/reset_rtc_screen.c +++ b/src/reset_rtc_screen.c @@ -49,6 +49,11 @@ enum { SELECTION_NONE }; +enum { + WIN_TIME, + WIN_MSG, +}; + struct ResetRtcInputMap { /*0x0*/ u8 dataIndex; @@ -79,7 +84,7 @@ static const struct BgTemplate sBgTemplates[] = static const struct WindowTemplate sWindowTemplates[] = { - { + [WIN_TIME] = { .bg = 0, .tilemapLeft = 1, .tilemapTop = 1, @@ -88,7 +93,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 15, .baseBlock = 0x155 }, - { + [WIN_MSG] = { .bg = 0, .tilemapLeft = 2, .tilemapTop = 15, @@ -562,8 +567,8 @@ static void VBlankCB(void) static void ShowMessage(const u8 *str) { - DrawDialogFrameWithCustomTileAndPalette(1, FALSE, 0x200, 0xF); - AddTextPrinterParameterized(1, FONT_NORMAL, str, 0, 1, 0, NULL); + DrawDialogFrameWithCustomTileAndPalette(WIN_MSG, FALSE, 0x200, 0xF); + AddTextPrinterParameterized(WIN_MSG, FONT_NORMAL, str, 0, 1, 0, NULL); ScheduleBgCopyTilemapToVram(0); } @@ -576,11 +581,11 @@ static void Task_ShowResetRtcPrompt(u8 taskId) switch (tState) { case 0: - DrawStdFrameWithCustomTileAndPalette(0, FALSE, 0x214, 0xE); + DrawStdFrameWithCustomTileAndPalette(WIN_TIME, FALSE, 0x214, 0xE); - AddTextPrinterParameterized(0, FONT_NORMAL, gText_PresentTime, 0, 1, TEXT_SKIP_DRAW, 0); + AddTextPrinterParameterized(WIN_TIME, FONT_NORMAL, gText_PresentTime, 0, 1, TEXT_SKIP_DRAW, 0); PrintTime( - 0, + WIN_TIME, 0, 17, gLocalTime.days, @@ -588,9 +593,9 @@ static void Task_ShowResetRtcPrompt(u8 taskId) gLocalTime.minutes, gLocalTime.seconds); - AddTextPrinterParameterized(0, FONT_NORMAL, gText_PreviousTime, 0, 33, TEXT_SKIP_DRAW, 0); + AddTextPrinterParameterized(WIN_TIME, FONT_NORMAL, gText_PreviousTime, 0, 33, TEXT_SKIP_DRAW, 0); PrintTime( - 0, + WIN_TIME, 0, 49, gSaveBlock2Ptr->lastBerryTreeUpdate.days, @@ -599,7 +604,7 @@ static void Task_ShowResetRtcPrompt(u8 taskId) gSaveBlock2Ptr->lastBerryTreeUpdate.seconds); ShowMessage(gText_ResetRTCConfirmCancel); - CopyWindowToVram(0, COPYWIN_GFX); + CopyWindowToVram(WIN_TIME, COPYWIN_GFX); ScheduleBgCopyTilemapToVram(0); tState++; case 1: @@ -666,7 +671,7 @@ static void Task_ResetRtcScreen(u8 taskId) // Wait for A or B press on prompt first if (gTasks[tSubTaskId].isActive != TRUE) { - ClearStdWindowAndFrameToTransparent(0, FALSE); + ClearStdWindowAndFrameToTransparent(WIN_TIME, FALSE); ShowMessage(gText_PleaseResetTime); gLocalTime = gSaveBlock2Ptr->lastBerryTreeUpdate; tSubTaskId = CreateTask(Task_ResetRtc_Init, 80); From 744952542872b6a5b9e37a0f03028a0e18674a94 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 18:56:34 -0400 Subject: [PATCH 17/69] Use window constants in wallclock --- src/wallclock.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/wallclock.c b/src/wallclock.c index 5e0fae3a1..105bd350d 100644 --- a/src/wallclock.c +++ b/src/wallclock.c @@ -55,25 +55,28 @@ static void SpriteCB_AMIndicator(struct Sprite *sprite); #define PALTAG_WALL_CLOCK_MALE 0x1000 #define PALTAG_WALL_CLOCK_FEMALE 0x1001 -enum -{ +enum { PERIOD_AM, PERIOD_PM, }; -enum -{ +enum { MOVE_NONE, MOVE_BACKWARD, MOVE_FORWARD, }; +enum { + WIN_MSG, + WIN_BUTTON_LABEL, +}; + static const u32 sHand_Gfx[] = INCBIN_U32("graphics/wallclock/hand.4bpp.lz"); static const u16 sTextPrompt_Pal[] = INCBIN_U16("graphics/wallclock/text_prompt.gbapal"); // for "Cancel" or "Confirm" static const struct WindowTemplate sWindowTemplates[] = { - { + [WIN_MSG] = { .bg = 0, .tilemapLeft = 3, .tilemapTop = 17, @@ -82,7 +85,7 @@ static const struct WindowTemplate sWindowTemplates[] = .paletteNum = 14, .baseBlock = 512 }, - { + [WIN_BUTTON_LABEL] = { .bg = 2, .tilemapLeft = 24, .tilemapTop = 16, @@ -717,8 +720,8 @@ void CB2_StartWallClock(void) WallClockInit(); - AddTextPrinterParameterized(1, FONT_NORMAL, gText_Confirm3, 0, 1, 0, NULL); - PutWindowTilemap(1); + AddTextPrinterParameterized(WIN_BUTTON_LABEL, FONT_NORMAL, gText_Confirm3, 0, 1, 0, NULL); + PutWindowTilemap(WIN_BUTTON_LABEL); ScheduleBgCopyTilemapToVram(2); } @@ -765,8 +768,8 @@ void CB2_ViewWallClock(void) WallClockInit(); - AddTextPrinterParameterized(1, FONT_NORMAL, gText_Cancel4, 0, 1, 0, NULL); - PutWindowTilemap(1); + AddTextPrinterParameterized(WIN_BUTTON_LABEL, FONT_NORMAL, gText_Cancel4, 0, 1, 0, NULL); + PutWindowTilemap(WIN_BUTTON_LABEL); ScheduleBgCopyTilemapToVram(2); } @@ -829,9 +832,9 @@ static void Task_SetClock_HandleInput(u8 taskId) static void Task_SetClock_AskConfirm(u8 taskId) { - DrawStdFrameWithCustomTileAndPalette(0, FALSE, 0x250, 0x0d); - AddTextPrinterParameterized(0, FONT_NORMAL, gText_IsThisTheCorrectTime, 0, 1, 0, NULL); - PutWindowTilemap(0); + DrawStdFrameWithCustomTileAndPalette(WIN_MSG, FALSE, 0x250, 0x0d); + AddTextPrinterParameterized(WIN_MSG, FONT_NORMAL, gText_IsThisTheCorrectTime, 0, 1, 0, NULL); + PutWindowTilemap(WIN_MSG); ScheduleBgCopyTilemapToVram(0); CreateYesNoMenu(&sWindowTemplate_ConfirmYesNo, 0x250, 0x0d, 1); gTasks[taskId].func = Task_SetClock_HandleConfirmInput; @@ -848,8 +851,8 @@ static void Task_SetClock_HandleConfirmInput(u8 taskId) case 1: // NO case MENU_B_PRESSED: PlaySE(SE_SELECT); - ClearStdWindowAndFrameToTransparent(0, FALSE); - ClearWindowTilemap(0); + ClearStdWindowAndFrameToTransparent(WIN_MSG, FALSE); + ClearWindowTilemap(WIN_MSG); gTasks[taskId].func = Task_SetClock_HandleInput; break; } From 7587963d24f74b2d8bf20e051861de0e0739ea66 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 19:09:50 -0400 Subject: [PATCH 18/69] Use window constants in berry_fix_program --- src/berry_fix_program.c | 53 +++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/src/berry_fix_program.c b/src/berry_fix_program.c index e8c4bc7e6..af21bb929 100644 --- a/src/berry_fix_program.c +++ b/src/berry_fix_program.c @@ -14,6 +14,13 @@ #include "m4a.h" #include "constants/rgb.h" +enum { + WIN_TITLE, // "Berry Program Update" header on the first screen + WIN_MSG_BODY, + WIN_GAME_NAMES, // The labels under the GBA graphics on the link screen + WIN_TURN_OFF_TITLE, // "Ruby/Sapphire" at the top of the "turn off the power" screen +}; + struct { u8 state; u8 curScene; @@ -71,7 +78,7 @@ static const struct BgTemplate sBerryFixBgTemplates[] = { }; static const struct WindowTemplate sBerryFixWindowTemplates[] = { - { + [WIN_TITLE] = { .bg = 0, .tilemapLeft = 2, .tilemapTop = 4, @@ -80,7 +87,7 @@ static const struct WindowTemplate sBerryFixWindowTemplates[] = { .paletteNum = 15, .baseBlock = 1 }, - { + [WIN_MSG_BODY] = { .bg = 0, .tilemapLeft = 1, .tilemapTop = 11, @@ -89,7 +96,7 @@ static const struct WindowTemplate sBerryFixWindowTemplates[] = { .paletteNum = 15, .baseBlock = 53 }, - { + [WIN_GAME_NAMES] = { .bg = 0, .tilemapLeft = 0, .tilemapTop = 8, @@ -98,7 +105,7 @@ static const struct WindowTemplate sBerryFixWindowTemplates[] = { .paletteNum = 15, .baseBlock = 277 }, - { + [WIN_TURN_OFF_TITLE] = { .bg = 0, .tilemapLeft = 8, .tilemapTop = 0, @@ -217,11 +224,11 @@ static void BerryFix_Main(void) sBerryFix->state = MAINSTATE_BEGIN; break; case MAINSTATE_BEGIN: - if (TryScene(SCENE_BEGIN) && (JOY_NEW(A_BUTTON))) + if (TryScene(SCENE_BEGIN) && JOY_NEW(A_BUTTON)) sBerryFix->state = MAINSTATE_CONNECT; break; case MAINSTATE_CONNECT: - if (TryScene(SCENE_ENSURE_CONNECT) && (JOY_NEW(A_BUTTON))) + if (TryScene(SCENE_ENSURE_CONNECT) && JOY_NEW(A_BUTTON)) sBerryFix->state = MAINSTATE_INIT_MULTIBOOT; break; case MAINSTATE_INIT_MULTIBOOT: @@ -299,29 +306,29 @@ static void BerryFix_GpuSet(void) DmaCopy32(3, sBerryFixPalColors, BG_PLTT + 0x1E0, sizeof(sBerryFixPalColors)); SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP); - FillWindowPixelBuffer(2, PIXEL_FILL(0)); - FillWindowPixelBuffer(3, PIXEL_FILL(0)); - FillWindowPixelBuffer(0, PIXEL_FILL(10)); + FillWindowPixelBuffer(WIN_GAME_NAMES, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_TURN_OFF_TITLE, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_TITLE, PIXEL_FILL(10)); width = GetStringWidth(FONT_SMALL, sText_Emerald, 0); left = (120 - width) / 2; - AddTextPrinterParameterized3(2, FONT_SMALL, left, 3, sGameTitleTextColors, TEXT_SKIP_DRAW, sText_Emerald); + AddTextPrinterParameterized3(WIN_GAME_NAMES, FONT_SMALL, left, 3, sGameTitleTextColors, TEXT_SKIP_DRAW, sText_Emerald); width = GetStringWidth(FONT_SMALL, sText_RubySapphire, 0); left = (120 - width) / 2 + 120; - AddTextPrinterParameterized3(2, FONT_SMALL, left, 3, sGameTitleTextColors, TEXT_SKIP_DRAW, sText_RubySapphire); + AddTextPrinterParameterized3(WIN_GAME_NAMES, FONT_SMALL, left, 3, sGameTitleTextColors, TEXT_SKIP_DRAW, sText_RubySapphire); width = GetStringWidth(FONT_SMALL, sText_RubySapphire, 0); left = (112 - width) / 2; - AddTextPrinterParameterized3(3, FONT_SMALL, left, 0, sGameTitleTextColors, TEXT_SKIP_DRAW, sText_RubySapphire); + AddTextPrinterParameterized3(WIN_TURN_OFF_TITLE, FONT_SMALL, left, 0, sGameTitleTextColors, TEXT_SKIP_DRAW, sText_RubySapphire); width = GetStringWidth(FONT_NORMAL, sText_BerryProgramUpdate, 0); left = (208 - width) / 2; - AddTextPrinterParameterized3(0, FONT_NORMAL, left, 2, sBerryProgramTextColors, TEXT_SKIP_DRAW, sText_BerryProgramUpdate); + AddTextPrinterParameterized3(WIN_TITLE, FONT_NORMAL, left, 2, sBerryProgramTextColors, TEXT_SKIP_DRAW, sText_BerryProgramUpdate); - CopyWindowToVram(2, COPYWIN_GFX); - CopyWindowToVram(3, COPYWIN_GFX); - CopyWindowToVram(0, COPYWIN_GFX); + CopyWindowToVram(WIN_GAME_NAMES, COPYWIN_GFX); + CopyWindowToVram(WIN_TURN_OFF_TITLE, COPYWIN_GFX); + CopyWindowToVram(WIN_TITLE, COPYWIN_GFX); } static int BerryFix_TrySetScene(int scene) @@ -345,23 +352,23 @@ static int BerryFix_TrySetScene(int scene) static void BerryFix_SetScene(int scene) { FillBgTilemapBufferRect_Palette0(0, 0, 0, 0, 32, 32); - FillWindowPixelBuffer(1, PIXEL_FILL(10)); - AddTextPrinterParameterized3(1, FONT_NORMAL, 0, 0, sBerryProgramTextColors, TEXT_SKIP_DRAW, sBerryProgramTexts[scene]); - PutWindowTilemap(1); - CopyWindowToVram(1, COPYWIN_GFX); + FillWindowPixelBuffer(WIN_MSG_BODY, PIXEL_FILL(10)); + AddTextPrinterParameterized3(WIN_MSG_BODY, FONT_NORMAL, 0, 0, sBerryProgramTextColors, TEXT_SKIP_DRAW, sBerryProgramTexts[scene]); + PutWindowTilemap(WIN_MSG_BODY); + CopyWindowToVram(WIN_MSG_BODY, COPYWIN_GFX); switch (scene) { case SCENE_ENSURE_CONNECT: case SCENE_TRANSMITTING: case SCENE_FOLLOW_INSTRUCT: case SCENE_TRANSMIT_FAILED: - PutWindowTilemap(2); + PutWindowTilemap(WIN_GAME_NAMES); break; case SCENE_TURN_OFF_POWER: - PutWindowTilemap(3); + PutWindowTilemap(WIN_TURN_OFF_TITLE); break; case SCENE_BEGIN: - PutWindowTilemap(0); + PutWindowTilemap(WIN_TITLE); break; } CopyBgTilemapBufferToVram(0); From e989879f71d39a798108559cbb0b6c7b58da9e65 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 29 Sep 2022 21:24:50 -0400 Subject: [PATCH 19/69] Use window constants in battle_dome --- src/battle_dome.c | 177 ++++++++++++++++++++++++++-------------------- 1 file changed, 102 insertions(+), 75 deletions(-) diff --git a/src/battle_dome.c b/src/battle_dome.c index d30739ca5..224ef1b84 100644 --- a/src/battle_dome.c +++ b/src/battle_dome.c @@ -73,9 +73,33 @@ struct TourneyTreeLineSection #define tMode data[2] #define tPrevTaskId data[3] -#define EFFECTIVENESS_MODE_GOOD 0 -#define EFFECTIVENESS_MODE_BAD 1 -#define EFFECTIVENESS_MODE_AI_VS_AI 2 +enum { + EFFECTIVENESS_MODE_GOOD, + EFFECTIVENESS_MODE_BAD, + EFFECTIVENESS_MODE_AI_VS_AI, +}; + +// Window IDs for the tourney tree +enum { + TOURNEYWIN_NAMES_LEFT, + TOURNEYWIN_NAMES_RIGHT, + TOURNEYWIN_TITLE, +}; + +// Window IDs for the trainer (WIN_TRAINER_*) and match (WIN_MATCH_*) info cards. +// All 9 have a duplicate window at WIN + NUM_INFO_CARD_WINDOWS used by the alternate info card +enum { + WIN_TRAINER_NAME, + WIN_TRAINER_MON1_NAME, + WIN_TRAINER_MON2_NAME, // Used implicitly + WIN_TRAINER_MON3_NAME, // Used implicitly + WIN_TRAINER_FLAVOR_TEXT = WIN_TRAINER_MON1_NAME + FRONTIER_PARTY_SIZE, // Trainer's potential, battle style, and stat texts + WIN_MATCH_NUMBER, + WIN_MATCH_TRAINER_NAME_LEFT, + WIN_MATCH_TRAINER_NAME_RIGHT, + WIN_MATCH_WIN_TEXT, + NUM_INFO_CARD_WINDOWS +}; static u8 GetDomeTrainerMonIvs(u16); static void SwapDomeTrainers(int, int, u16 *); @@ -670,7 +694,7 @@ static const struct BgTemplate sInfoCardBgTemplates[4] = static const struct WindowTemplate sTourneyTreeWindowTemplates[] = { - { + [TOURNEYWIN_NAMES_LEFT] = { .bg = 0, .tilemapLeft = 0, .tilemapTop = 3, @@ -679,7 +703,7 @@ static const struct WindowTemplate sTourneyTreeWindowTemplates[] = .paletteNum = 15, .baseBlock = 16, }, - { + [TOURNEYWIN_NAMES_RIGHT] = { .bg = 0, .tilemapLeft = 22, .tilemapTop = 3, @@ -688,7 +712,7 @@ static const struct WindowTemplate sTourneyTreeWindowTemplates[] = .paletteNum = 15, .baseBlock = 144, }, - { + [TOURNEYWIN_TITLE] = { .bg = 0, .tilemapLeft = 8, .tilemapTop = 1, @@ -702,7 +726,7 @@ static const struct WindowTemplate sTourneyTreeWindowTemplates[] = static const struct WindowTemplate sInfoCardWindowTemplates[] = { - { + [WIN_TRAINER_NAME] = { .bg = 0, .tilemapLeft = 2, .tilemapTop = 2, @@ -711,7 +735,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 1, }, - { + [WIN_TRAINER_MON1_NAME] = { .bg = 0, .tilemapLeft = 16, .tilemapTop = 5, @@ -720,7 +744,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 53, }, - { + [WIN_TRAINER_MON2_NAME] = { .bg = 0, .tilemapLeft = 19, .tilemapTop = 7, @@ -729,7 +753,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 69, }, - { + [WIN_TRAINER_MON3_NAME] = { .bg = 0, .tilemapLeft = 16, .tilemapTop = 10, @@ -738,7 +762,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 96, }, - { + [WIN_TRAINER_FLAVOR_TEXT] = { .bg = 0, .tilemapLeft = 2, .tilemapTop = 12, @@ -747,7 +771,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 112, }, - { + [WIN_MATCH_NUMBER] = { .bg = 0, .tilemapLeft = 5, .tilemapTop = 2, @@ -756,7 +780,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 294, }, - { + [WIN_MATCH_TRAINER_NAME_LEFT] = { .bg = 0, .tilemapLeft = 2, .tilemapTop = 5, @@ -765,7 +789,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 340, }, - { + [WIN_MATCH_TRAINER_NAME_RIGHT] = { .bg = 0, .tilemapLeft = 20, .tilemapTop = 5, @@ -774,7 +798,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 356, }, - { + [WIN_MATCH_WIN_TEXT] = { .bg = 0, .tilemapLeft = 2, .tilemapTop = 16, @@ -783,7 +807,9 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 372, }, - { + // Duplicate windows used by the alternate info card + // Same as above but on bg 1 instead of bg 0 + [WIN_TRAINER_NAME + NUM_INFO_CARD_WINDOWS] = { .bg = 1, .tilemapLeft = 2, .tilemapTop = 2, @@ -792,7 +818,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 1, }, - { + [WIN_TRAINER_MON1_NAME + NUM_INFO_CARD_WINDOWS] = { .bg = 1, .tilemapLeft = 16, .tilemapTop = 5, @@ -801,7 +827,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 53, }, - { + [WIN_TRAINER_MON2_NAME + NUM_INFO_CARD_WINDOWS] = { .bg = 1, .tilemapLeft = 19, .tilemapTop = 7, @@ -810,7 +836,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 69, }, - { + [WIN_TRAINER_MON3_NAME + NUM_INFO_CARD_WINDOWS] = { .bg = 1, .tilemapLeft = 16, .tilemapTop = 10, @@ -819,7 +845,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 96, }, - { + [WIN_TRAINER_FLAVOR_TEXT + NUM_INFO_CARD_WINDOWS] = { .bg = 1, .tilemapLeft = 2, .tilemapTop = 12, @@ -828,7 +854,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 112, }, - { + [WIN_MATCH_NUMBER + NUM_INFO_CARD_WINDOWS] = { .bg = 1, .tilemapLeft = 5, .tilemapTop = 2, @@ -837,7 +863,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 294, }, - { + [WIN_MATCH_TRAINER_NAME_LEFT + NUM_INFO_CARD_WINDOWS] = { .bg = 1, .tilemapLeft = 2, .tilemapTop = 5, @@ -846,7 +872,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 340, }, - { + [WIN_MATCH_TRAINER_NAME_RIGHT + NUM_INFO_CARD_WINDOWS] = { .bg = 1, .tilemapLeft = 20, .tilemapTop = 5, @@ -855,7 +881,7 @@ static const struct WindowTemplate sInfoCardWindowTemplates[] = .paletteNum = 15, .baseBlock = 356, }, - { + [WIN_MATCH_WIN_TEXT + NUM_INFO_CARD_WINDOWS] = { .bg = 1, .tilemapLeft = 2, .tilemapTop = 16, @@ -1397,26 +1423,27 @@ static const u8 sCompetitorRangeByMatch[DOME_TOURNAMENT_MATCHES_COUNT][3] = { NUM_POSSIBLE_MATCH_TRAINERS(DOME_FINAL) * 0, NUM_POSSIBLE_MATCH_TRAINERS(DOME_FINAL), DOME_FINAL}, }; -// 1st value is the windowId (0 for left column, 1 for right column) -// 2nd value is the y coord +#define NAME_ROW_HEIGHT 16 + +// 1st value is the windowId, 2nd value is the y coord static const u8 sTrainerNamePositions[DOME_TOURNAMENT_TRAINERS_COUNT][2] = { - { 0, 0}, - { 1, 112}, - { 1, 0}, - { 0, 112}, - { 0, 48}, - { 1, 64}, - { 1, 48}, - { 0, 64}, - { 0, 16}, - { 1, 96}, - { 1, 16}, - { 0, 96}, - { 0, 32}, - { 1, 80}, - { 1, 32}, - { 0, 80}, + { TOURNEYWIN_NAMES_LEFT, 0 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_RIGHT, 7 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_RIGHT, 0 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_LEFT, 7 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_LEFT, 3 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_RIGHT, 4 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_RIGHT, 3 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_LEFT, 4 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_LEFT, 1 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_RIGHT, 6 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_RIGHT, 1 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_LEFT, 6 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_LEFT, 2 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_RIGHT, 5 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_RIGHT, 2 * NAME_ROW_HEIGHT}, + { TOURNEYWIN_NAMES_LEFT, 5 * NAME_ROW_HEIGHT}, }; // Coords for the pokeballs on the tourney tree that act as buttons to view trainer/match info @@ -2427,7 +2454,7 @@ static void InitDomeTrainers(void) break; } - if (sTrainerNamePositions[i][0] != 0) + if (sTrainerNamePositions[i][0] != TOURNEYWIN_NAMES_LEFT) { j = 0; DOME_TRAINERS[j].trainerId = TRAINER_FRONTIER_BRAIN; @@ -3437,11 +3464,11 @@ static void Task_HandleInfoCardInput(u8 taskId) case MATCHCARD_INPUT_UP ... MATCHCARD_INPUT_RIGHT: gTasks[taskId].data[5] = i; if (gTasks[taskId].tUsingAlternateSlot) - windowId = 9; + windowId = NUM_INFO_CARD_WINDOWS; else windowId = 0; - for (i = windowId; i < windowId + 9; i++) + for (i = windowId; i < windowId + NUM_INFO_CARD_WINDOWS; i++) { CopyWindowToVram(i, COPYWIN_GFX); FillWindowPixelBuffer(i, PIXEL_FILL(0)); @@ -4263,14 +4290,14 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId) int trainerId = 0; u8 nature = 0; int arrId = 0; - int windowId = 0; + int windowId = WIN_TRAINER_NAME; int x = 0, y = 0; u8 palSlot = 0; s16 *allocatedArray = AllocZeroed(sizeof(s16) * ALLOC_ARRAY_SIZE); trainerId = DOME_TRAINERS[trainerTourneyId].trainerId; if (flags & CARD_ALTERNATE_SLOT) - arrId = 2 * (FRONTIER_PARTY_SIZE + 1), windowId = 9, palSlot = 2; + arrId = 2 * (FRONTIER_PARTY_SIZE + 1), windowId = WIN_TRAINER_NAME + NUM_INFO_CARD_WINDOWS, palSlot = 2; if (flags & MOVE_CARD_RIGHT) x = DISPLAY_WIDTH + 16; if (flags & MOVE_CARD_DOWN) @@ -4388,19 +4415,19 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId) else textPrinter.currentChar = gSpeciesNames[gFacilityTrainerMons[DOME_MONS[trainerTourneyId][i]].species]; - textPrinter.windowId = 1 + i + windowId; + textPrinter.windowId = WIN_TRAINER_MON1_NAME + i + windowId; if (i == 1) textPrinter.currentX = 7; else textPrinter.currentX = 0; - PutWindowTilemap(1 + i + windowId); - CopyWindowToVram(1 + i + windowId, COPYWIN_FULL); + PutWindowTilemap(WIN_TRAINER_MON1_NAME + i + windowId); + CopyWindowToVram(WIN_TRAINER_MON1_NAME + i + windowId, COPYWIN_FULL); AddTextPrinter(&textPrinter, 0, NULL); } - PutWindowTilemap(windowId + 4); - CopyWindowToVram(windowId + 4, COPYWIN_FULL); + PutWindowTilemap(windowId + WIN_TRAINER_FLAVOR_TEXT); + CopyWindowToVram(windowId + WIN_TRAINER_FLAVOR_TEXT, COPYWIN_FULL); // Print text about trainers potential in the tourney if (trainerId == TRAINER_FRONTIER_BRAIN) @@ -4409,7 +4436,7 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId) textPrinter.currentChar = sBattleDomePotentialTexts[trainerTourneyId]; textPrinter.fontId = FONT_NORMAL; - textPrinter.windowId = windowId + 4; + textPrinter.windowId = windowId + WIN_TRAINER_FLAVOR_TEXT; textPrinter.currentX = 0; textPrinter.y = 4; textPrinter.currentY = 4; @@ -4731,7 +4758,7 @@ static void DisplayMatchInfoOnCard(u8 flags, u8 matchNo) u8 palSlot = 0; if (flags & CARD_ALTERNATE_SLOT) - arrId = 2 * (FRONTIER_PARTY_SIZE + 1), windowId = 9, palSlot = 2; + arrId = 2 * (FRONTIER_PARTY_SIZE + 1), windowId = NUM_INFO_CARD_WINDOWS, palSlot = 2; if (flags & MOVE_CARD_RIGHT) x = DISPLAY_WIDTH + 16; if (flags & MOVE_CARD_DOWN) @@ -4873,10 +4900,10 @@ static void DisplayMatchInfoOnCard(u8 flags, u8 matchNo) textPrinter.shadowColor = TEXT_DYNAMIC_COLOR_4; StringExpandPlaceholders(gStringVar4, sBattleDomeWinTexts[winStringId]); textPrinter.currentChar = gStringVar4; - textPrinter.windowId = windowId + 8; + textPrinter.windowId = windowId + WIN_MATCH_WIN_TEXT; textPrinter.fontId = FONT_NORMAL; - PutWindowTilemap(windowId + 8); - CopyWindowToVram(windowId + 8, COPYWIN_FULL); + PutWindowTilemap(windowId + WIN_MATCH_WIN_TEXT); + CopyWindowToVram(windowId + WIN_MATCH_WIN_TEXT, COPYWIN_FULL); textPrinter.currentX = 0; textPrinter.currentY = textPrinter.y = 0; AddTextPrinter(&textPrinter, 0, NULL); @@ -4892,11 +4919,11 @@ static void DisplayMatchInfoOnCard(u8 flags, u8 matchNo) textPrinter.fontId = FONT_SHORT; textPrinter.letterSpacing = 2; textPrinter.currentChar = gStringVar1; - textPrinter.windowId = windowId + 6; + textPrinter.windowId = windowId + WIN_MATCH_TRAINER_NAME_LEFT; textPrinter.currentX = GetStringCenterAlignXOffsetWithLetterSpacing(textPrinter.fontId, textPrinter.currentChar, 0x40, textPrinter.letterSpacing); textPrinter.currentY = textPrinter.y = 2; - PutWindowTilemap(windowId + 6); - CopyWindowToVram(windowId + 6, COPYWIN_FULL); + PutWindowTilemap(windowId + WIN_MATCH_TRAINER_NAME_LEFT); + CopyWindowToVram(windowId + WIN_MATCH_TRAINER_NAME_LEFT, COPYWIN_FULL); AddTextPrinter(&textPrinter, 0, NULL); // Print right trainer's name. @@ -4908,21 +4935,21 @@ static void DisplayMatchInfoOnCard(u8 flags, u8 matchNo) CopyDomeTrainerName(gStringVar1, trainerIds[1]); textPrinter.currentChar = gStringVar1; - textPrinter.windowId = windowId + 7; + textPrinter.windowId = windowId + WIN_MATCH_TRAINER_NAME_RIGHT; textPrinter.currentX = GetStringCenterAlignXOffsetWithLetterSpacing(textPrinter.fontId, textPrinter.currentChar, 0x40, textPrinter.letterSpacing); textPrinter.currentY = textPrinter.y = 2; - PutWindowTilemap(windowId + 7); - CopyWindowToVram(windowId + 7, COPYWIN_FULL); + PutWindowTilemap(windowId + WIN_MATCH_TRAINER_NAME_RIGHT); + CopyWindowToVram(windowId + WIN_MATCH_TRAINER_NAME_RIGHT, COPYWIN_FULL); AddTextPrinter(&textPrinter, 0, NULL); // Print match number. textPrinter.letterSpacing = 0; textPrinter.currentChar = sBattleDomeMatchNumberTexts[matchNo]; - textPrinter.windowId = windowId + 5; + textPrinter.windowId = windowId + WIN_MATCH_NUMBER; textPrinter.currentX = GetStringCenterAlignXOffsetWithLetterSpacing(textPrinter.fontId, textPrinter.currentChar, 0xA0, textPrinter.letterSpacing); textPrinter.currentY = textPrinter.y = 2; - PutWindowTilemap(windowId + 5); - CopyWindowToVram(windowId + 5, COPYWIN_FULL); + PutWindowTilemap(windowId + WIN_MATCH_NUMBER); + CopyWindowToVram(windowId + WIN_MATCH_NUMBER, COPYWIN_FULL); AddTextPrinter(&textPrinter, 0, NULL); } @@ -5356,7 +5383,7 @@ static void Task_ShowTourneyTree(u8 taskId) case 4: textPrinter.fontId = FONT_SHORT; textPrinter.currentChar = gText_BattleTourney; - textPrinter.windowId = 2; + textPrinter.windowId = TOURNEYWIN_TITLE; textPrinter.x = 0; textPrinter.y = 0; textPrinter.letterSpacing = 2; @@ -5442,7 +5469,7 @@ static void Task_ShowTourneyTree(u8 taskId) } } - if (sTrainerNamePositions[i][0] == 0) + if (sTrainerNamePositions[i][0] == TOURNEYWIN_NAMES_LEFT) textPrinter.currentX = GetStringWidthDifference(textPrinter.fontId, gDisplayedStringBattle, 0x3D, textPrinter.letterSpacing); else textPrinter.currentX = 3; @@ -5454,12 +5481,12 @@ static void Task_ShowTourneyTree(u8 taskId) gTasks[taskId].tState++; break; case 5: - PutWindowTilemap(0); - PutWindowTilemap(1); - PutWindowTilemap(2); - CopyWindowToVram(0, COPYWIN_FULL); - CopyWindowToVram(1, COPYWIN_FULL); - CopyWindowToVram(2, COPYWIN_FULL); + PutWindowTilemap(TOURNEYWIN_NAMES_LEFT); + PutWindowTilemap(TOURNEYWIN_NAMES_RIGHT); + PutWindowTilemap(TOURNEYWIN_TITLE); + CopyWindowToVram(TOURNEYWIN_NAMES_LEFT, COPYWIN_FULL); + CopyWindowToVram(TOURNEYWIN_NAMES_RIGHT, COPYWIN_FULL); + CopyWindowToVram(TOURNEYWIN_TITLE, COPYWIN_FULL); SetHBlankCallback(HblankCb_TourneyTree); SetVBlankCallback(VblankCb_TourneyTree); if (r4 == 2) @@ -5556,7 +5583,7 @@ static void Task_HandleStaticTourneyTreeInput(u8 taskId) if (DOME_TRAINERS[i].eliminatedAt == gSaveBlock2Ptr->frontier.curChallengeBattleNum - 1 && DOME_TRAINERS[i].isEliminated) { - if (sTrainerNamePositions[i][0] == 0) + if (sTrainerNamePositions[i][0] == TOURNEYWIN_NAMES_LEFT) textPrinter.currentX = GetStringWidthDifference(textPrinter.fontId, gDisplayedStringBattle, 0x3D, textPrinter.letterSpacing); else textPrinter.currentX = 3; From 347a02ace1f571a8aab355a9df2f3bf112d3cca7 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Fri, 9 Dec 2022 12:34:55 -0500 Subject: [PATCH 20/69] Sync trade --- include/battle_anim.h | 2 +- include/constants/trade.h | 77 +-- include/link_rfu.h | 2 +- src/battle_anim_mons.c | 2 +- src/battle_main.c | 27 +- src/data/trade.h | 173 +++-- src/link_rfu_3.c | 2 +- src/trade.c | 1319 +++++++++++++++++++------------------ src/trainer_see.c | 20 +- src/union_room.c | 2 +- 10 files changed, 813 insertions(+), 813 deletions(-) diff --git a/include/battle_anim.h b/include/battle_anim.h index 0fe0d1898..f99af9059 100644 --- a/include/battle_anim.h +++ b/include/battle_anim.h @@ -148,7 +148,7 @@ void AnimThrowProjectile(struct Sprite *sprite); void GetBgDataForTransform(struct BattleAnimBgData *dest, u8 battlerId); u8 CreateAdditionalMonSpriteForMoveAnim(u16 species, bool8 isBackpic, u8 id, s16 x, s16 y, u8 subpriority, u32 personality, u32 trainerId, u32 battlerId, bool32 ignoreDeoxysForm); void ResetSpriteRotScale_PreserveAffine(struct Sprite *sprite); -void TradeMenuBouncePartySprites(struct Sprite *sprite); +void Trade_MoveSelectedMonToTarget(struct Sprite *sprite); void DestroyAnimVisualTaskAndDisableBlend(u8 taskId); void DestroySpriteAndFreeResources_(struct Sprite *sprite); void SetBattlerSpriteYOffsetFromOtherYScale(u8 spriteId, u8 otherSpriteId); diff --git a/include/constants/trade.h b/include/constants/trade.h index fa42e6b43..0f205d6d2 100644 --- a/include/constants/trade.h +++ b/include/constants/trade.h @@ -12,21 +12,13 @@ #define INGAME_TRADE_HORSEA 2 #define INGAME_TRADE_MEOWTH 3 -// Flag IDs for sending link data -#define INITIATE_TRADE 1 -#define CANCEL_TRADE 2 -#define WANTS_TO_TRADE 1 -#define WANTS_TO_CANCEL 2 -#define READY_FINISH_TRADE 1 -#define FINISH_TRADE 2 - // Return values for CanTradeSelectedMon and CanSpinTradeMon -#define CAN_TRADE_MON 0 -#define CANT_TRADE_LAST_MON 1 -#define CANT_TRADE_NATIONAL 2 -#define CANT_TRADE_EGG_YET 3 -#define CANT_TRADE_INVALID_MON 4 -#define CANT_TRADE_EGG_YET2 5 +#define CAN_TRADE_MON 0 +#define CANT_TRADE_LAST_MON 1 +#define CANT_TRADE_NATIONAL 2 +#define CANT_TRADE_EGG_YET 3 +#define CANT_TRADE_INVALID_MON 4 +#define CANT_TRADE_PARTNER_EGG_YET 5 // Return values for CheckValidityOfTradeMons #define PLAYER_MON_INVALID 0 @@ -38,63 +30,6 @@ #define TRADE_PLAYER_NOT_READY 1 #define TRADE_PARTNER_NOT_READY 2 -// Indexes for sTradeActionTexts -#define TRADE_TEXT_CANCEL 0 -#define TRADE_TEXT_CHOOSE_MON 1 -#define TRADE_TEXT_SUMMARY 2 -#define TRADE_TEXT_TRADE 3 -#define TRADE_TEXT_CANCEL_TRADE 4 -#define TRADE_TEXT_JP_QUIT 5 - -// Checked to confirm DrawTradeMenuParty has reached final state -#define DRAW_PARTY_FINISH 5 - -// Message indexes for sTradeMessages -#define TRADE_MSG_STANDBY 0 -#define TRADE_MSG_CANCELED 1 -#define TRADE_MSG_ONLY_MON1 2 -#define TRADE_MSG_ONLY_MON2 3 -#define TRADE_MSG_WAITING_FOR_FRIEND 4 -#define TRADE_MSG_FRIEND_WANTS_TO_TRADE 5 -#define TRADE_MSG_MON_CANT_BE_TRADED 6 -#define TRADE_MSG_EGG_CANT_BE_TRADED 7 -#define TRADE_MSG_FRIENDS_MON_CANT_BE_TRADED 8 - -// IDs for QueueAction -#define QUEUE_SEND_DATA 0 -#define QUEUE_STANDBY 1 -#define QUEUE_ONLY_MON1 2 -#define QUEUE_ONLY_MON2 3 -#define QUEUE_UNUSED1 4 -#define QUEUE_UNUSED2 5 -#define QUEUE_MON_CANT_BE_TRADED 6 -#define QUEUE_EGG_CANT_BE_TRADED 7 -#define QUEUE_FRIENDS_MON_CANT_BE_TRADED 8 - -#define QUEUE_DELAY_MSG 3 -#define QUEUE_DELAY_DATA 5 - -// IDs for CallTradeMenuFunc -#define TRADEMENUFUNC_MAIN_MENU 0 -#define TRADEMENUFUNC_SELECTED_MON 1 -#define TRADEMENUFUNC_SHOW_MON_SUMMARY 2 -#define TRADEMENUFUNC_CONFIRM_OR_CANCEL_TRADE 3 -#define TRADEMENUFUNC_CANCEL_TRADE_PROMPT 4 -#define TRADEMENUFUNC_UNUSED_5 5 -#define TRADEMENUFUNC_BOTH_MONS_SELECTED 6 -#define TRADEMENUFUNC_CONFIRM_TRADE_PROMPT 7 -#define TRADEMENUFUNC_REDRAW_MAIN_MENU 8 -#define TRADEMENUFUNC_LINK_TRADE_FADE_OUT 9 -#define TRADEMENUFUNC_LINK_TRADE_WAIT_FADE 10 -#define TRADEMENUFUNC_CANCEL_TRADE_1 11 -#define TRADEMENUFUNC_CANCEL_TRADE_2 12 -#define TRADEMENUFUNC_START_LINK_TRADE 13 -#define TRADEMENUFUNC_DELAY_TRADE_CONFIRM 14 -#define TRADEMENUFUNC_UNUSED_15 15 -#define TRADEMENUFUNC_LINK_TRADE_WAIT_QUEUE 16 -#define TRADEMENUFUNC_PARTNER_MON_INVALID 17 -#define TRADEMENUFUNC_STANDBY 100 - // Message indexes for sUnionRoomTradeMessages #define UR_TRADE_MSG_NONE 0 #define UR_TRADE_MSG_NOT_MON_PARTNER_WANTS 1 diff --git a/include/link_rfu.h b/include/link_rfu.h index 1e434e830..4a3b8928c 100644 --- a/include/link_rfu.h +++ b/include/link_rfu.h @@ -83,7 +83,7 @@ struct RfuGameCompatibilityData u16 hasNews:1; u16 hasCard:1; u16 unknown:1; // Never read - u16 isChampion:1; + u16 canLinkNationally:1; u16 hasNationalDex:1; u16 gameClear:1; u16 version:4; diff --git a/src/battle_anim_mons.c b/src/battle_anim_mons.c index a5d4659a9..b1c3072fc 100644 --- a/src/battle_anim_mons.c +++ b/src/battle_anim_mons.c @@ -1047,7 +1047,7 @@ void UpdateAnimBg3ScreenSize(bool8 largeScreenSize) } } -void TradeMenuBouncePartySprites(struct Sprite *sprite) +void Trade_MoveSelectedMonToTarget(struct Sprite *sprite) { sprite->data[1] = sprite->x; sprite->data[3] = sprite->y; diff --git a/src/battle_main.c b/src/battle_main.c index fa85608d4..8492040ee 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -301,11 +301,28 @@ const struct OamData gOamData_BattleSpritePlayerSide = .affineParam = 0, }; -// Unknown and unused data. Feel free to remove. -static const u16 sUnused1[] = {0, 5, 0xfffe, 0}; -static const u16 *const sUnused1Ptr = sUnused1; -static const u16 sUnused2[] = {0xfff0, 0, 0x0400, 0, 0, 0, 0x3c00, 0, 0x7ffe, 1, 0, 0}; -static const u16 *const sUnused2Ptr = sUnused2; +static const union AnimCmd sAnim_Unused[] = +{ + ANIMCMD_FRAME(0, 5), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd *const sAnims_Unused[] = +{ + sAnim_Unused, +}; + +static const union AffineAnimCmd sAffineAnim_Unused[] = +{ + AFFINEANIMCMD_FRAME(-0x10, 0x0, 0, 4), + AFFINEANIMCMD_FRAME(0x0, 0x0, 0, 0x3C), + AFFINEANIMCMD_JUMP(1), +}; + +static const union AffineAnimCmd *const sAffineAnims_Unused[] = +{ + sAffineAnim_Unused, +}; static const s8 sCenterToCornerVecXs[8] ={-32, -16, -16, -32, -32}; diff --git a/src/data/trade.h b/src/data/trade.h index 80d17a49b..433e36247 100644 --- a/src/data/trade.h +++ b/src/data/trade.h @@ -55,7 +55,7 @@ static const u8 sText_OnlyPkmnForBattle[] = _("That's your only\nPOKéMON for ba static const u8 sText_WaitingForYourFriend[] = _("{COLOR DARK_GRAY}{HIGHLIGHT WHITE}{SHADOW LIGHT_GRAY}Waiting for your friend\nto finish…"); static const u8 sText_YourFriendWantsToTrade[] = _("Your friend wants\nto trade POKéMON."); -static const struct OamData sTradeOamData_32x16 = +static const struct OamData sOamData_MenuText = { .shape = SPRITE_SHAPE(32x16), .size = SPRITE_SIZE(32x16), @@ -167,17 +167,17 @@ static const struct SpriteTemplate sSpriteTemplate_MenuText = { .tileTag = GFXTAG_MENU_TEXT, .paletteTag = PALTAG_MENU_TEXT, - .oam = &sTradeOamData_32x16, + .oam = &sOamData_MenuText, .anims = sAnims_MenuText, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, .callback = SpriteCallbackDummy, }; -static const u16 sTradeScreenTextPalette[] = INCBIN_U16("graphics/trade/text.gbapal"); -static const struct SpritePalette sSpritePalette_TradeScreenText = +static const u16 sMenuText_Pal[] = INCBIN_U16("graphics/trade/text.gbapal"); +static const struct SpritePalette sSpritePalette_MenuText = { - .data = sTradeScreenTextPalette, + .data = sMenuText_Pal, .tag = PALTAG_MENU_TEXT }; @@ -193,7 +193,7 @@ static const struct SpritePalette sSpritePalette_TradeScreenText = // 1st array is the current positions // 2nd array is directions of input // 3rd array is the next positions to go to (unoccupied spaces are skipped over) -static const u8 sTradeNextSelectedMonTable[(PARTY_SIZE * 2) + 1][4][PARTY_SIZE] = +static const u8 sCursorMoveDestinations[(PARTY_SIZE * 2) + 1][4][PARTY_SIZE] = { { {4, 2, 12, 12, 0, 0}, // UP @@ -275,86 +275,67 @@ static const u8 sTradeNextSelectedMonTable[(PARTY_SIZE * 2) + 1][4][PARTY_SIZE] } }; +#define COL0_X 1 +#define COL1_X 8 +#define COL2_X 16 +#define COL3_X 23 +#define ROW0_Y 5 +#define ROW1_Y 10 +#define ROW2_Y 15 +#define ROW3_Y 18 + static const u8 sTradeMonSpriteCoords[(PARTY_SIZE * 2) + 1][2] = { - // Your party - {1, 5 }, - {8, 5 }, - {1, 10}, - {8, 10}, - {1, 15}, - {8, 15}, - - // Friend's party - {16, 5 }, - {23, 5 }, - {16, 10}, - {23, 10}, - {16, 15}, - {23, 15}, - - {23, 18} // CANCEL + // Player's party + {COL0_X, ROW0_Y }, + {COL1_X, ROW0_Y }, + {COL0_X, ROW1_Y}, + {COL1_X, ROW1_Y}, + {COL0_X, ROW2_Y}, + {COL1_X, ROW2_Y}, + // Partners's party + {COL2_X, ROW0_Y }, + {COL3_X, ROW0_Y }, + {COL2_X, ROW1_Y}, + {COL3_X, ROW1_Y}, + {COL2_X, ROW2_Y}, + {COL3_X, ROW2_Y}, + // Cancel + {COL3_X, ROW3_Y} }; -static const u8 sTradeMonLevelCoords[][2][2] = -{ - // Your party - { - {5, 4}, - {12, 4}, - }, - { - {5, 9}, - {12, 9}, - }, - { - {5, 14}, +static const u8 sTradeMonLevelCoords[PARTY_SIZE * 2][2] = { + [TRADE_PLAYER] = + { 5, 4}, + {12, 4}, + { 5, 9}, + {12, 9}, + { 5, 14}, {12, 14}, - }, - // Friend's party - { - - {20, 4}, - {27, 4}, - }, - { - {20, 9}, - {27, 9}, - }, - { + [TRADE_PARTNER * PARTY_SIZE] = + {20, 4}, + {27, 4}, + {20, 9}, + {27, 9}, {20, 14}, {27, 14}, - }, }; -static const u8 sTradeMonBoxCoords[][2][2] = -{ - // Your party - { - {1, 3}, - {8, 3}, - }, - { - {1, 8}, - {8, 8}, - }, - { - {1, 13}, - {8, 13}, - }, - // Friend's party - { - {16, 3}, - {23, 3}, - }, - { - {16, 8}, - {23, 8}, - }, - { +static const u8 sTradeMonBoxCoords[PARTY_SIZE * 2][2] = { + [TRADE_PLAYER] = + { 1, 3}, + { 8, 3}, + { 1, 8}, + { 8, 8}, + { 1, 13}, + { 8, 13}, + [TRADE_PARTNER * PARTY_SIZE] = + {16, 3}, + {23, 3}, + {16, 8}, + {23, 8}, {16, 13}, {23, 13}, - }, }; static const u8 sUnusedCoords[][2] = @@ -379,14 +360,14 @@ static const u8 sUnusedCoords[][2] = {23, 12} }; -static const u8 *const sTradeActionTexts[] = +static const u8 *const sActionTexts[] = { - [TRADE_TEXT_CANCEL] = sText_Cancel, - [TRADE_TEXT_CHOOSE_MON] = sText_ChooseAPkmn, - [TRADE_TEXT_SUMMARY] = sText_Summary, - [TRADE_TEXT_TRADE] = sText_Trade, - [TRADE_TEXT_CANCEL_TRADE] = sText_CancelTrade, - [TRADE_TEXT_JP_QUIT] = sJPText_PressBButtonToQuit + [TEXT_CANCEL] = sText_Cancel, + [TEXT_CHOOSE_MON] = sText_ChooseAPkmn, + [TEXT_SUMMARY] = sText_Summary, + [TEXT_TRADE] = sText_Trade, + [TEXT_CANCEL_TRADE] = sText_CancelTrade, + [TEXT_JP_QUIT] = sJPText_PressBButtonToQuit }; static const struct MenuAction sSelectTradeMonActions[] = @@ -395,17 +376,17 @@ static const struct MenuAction sSelectTradeMonActions[] = {sText_Trade2, Task_DrawSelectionTrade} }; -static const u8 *const sTradeMessages[] = +static const u8 *const sMessages[] = { - [TRADE_MSG_STANDBY] = sText_CommunicationStandby, - [TRADE_MSG_CANCELED] = sText_TheTradeHasBeenCanceled, - [TRADE_MSG_ONLY_MON1] = sText_OnlyPkmnForBattle, - [TRADE_MSG_ONLY_MON2] = gText_OnlyPkmnForBattle, //identical text to above - [TRADE_MSG_WAITING_FOR_FRIEND] = sText_WaitingForYourFriend, - [TRADE_MSG_FRIEND_WANTS_TO_TRADE] = sText_YourFriendWantsToTrade, - [TRADE_MSG_MON_CANT_BE_TRADED] = gText_PkmnCantBeTradedNow, - [TRADE_MSG_EGG_CANT_BE_TRADED] = gText_EggCantBeTradedNow, - [TRADE_MSG_FRIENDS_MON_CANT_BE_TRADED] = gText_OtherTrainersPkmnCantBeTraded + [MSG_STANDBY] = sText_CommunicationStandby, + [MSG_CANCELED] = sText_TheTradeHasBeenCanceled, + [MSG_ONLY_MON1] = sText_OnlyPkmnForBattle, + [MSG_ONLY_MON2] = gText_OnlyPkmnForBattle, //identical text to above + [MSG_WAITING_FOR_FRIEND] = sText_WaitingForYourFriend, + [MSG_FRIEND_WANTS_TO_TRADE] = sText_YourFriendWantsToTrade, + [MSG_MON_CANT_BE_TRADED] = gText_PkmnCantBeTradedNow, + [MSG_EGG_CANT_BE_TRADED] = gText_EggCantBeTradedNow, + [MSG_FRIENDS_MON_CANT_BE_TRADED] = gText_OtherTrainersPkmnCantBeTraded }; static const u8 sTradeTextColors[] = @@ -415,7 +396,7 @@ static const u8 sTradeTextColors[] = TEXT_COLOR_DARK_GRAY //shadow color }; -static const struct BgTemplate sTradeMenuBgTemplates[] = +static const struct BgTemplate sBgTemplates[] = { { .bg = 0, @@ -455,7 +436,7 @@ static const struct BgTemplate sTradeMenuBgTemplates[] = }, }; -static const struct WindowTemplate sTradeMenuWindowTemplates[] = +static const struct WindowTemplate sWindowTemplates[] = { { .bg = 0, @@ -633,8 +614,8 @@ static const struct WindowTemplate sTradeYesNoWindowTemplate = .baseBlock = 582 }; -static const u8 sJPText_Shedinja[] = _("ヌケニン"); -static const u8 sTradeMenuPartyMonBoxDimensions[3][2] = +static const u8 sText_ShedinjaJP[] = _("ヌケニン"); +static const u8 sSelectedMonLevelGenderCoords[3][2] = { [TRADE_PLAYER] = {4, 3}, [TRADE_PARTNER] = {19, 3} diff --git a/src/link_rfu_3.c b/src/link_rfu_3.c index 0d028cd48..6eee8435c 100644 --- a/src/link_rfu_3.c +++ b/src/link_rfu_3.c @@ -677,7 +677,7 @@ void InitHostRfuGameData(struct RfuGameData *data, u8 activity, bool32 startedAc data->compatibility.hasNews = FALSE; data->compatibility.hasCard = FALSE; data->compatibility.unknown = FALSE; - data->compatibility.isChampion = FlagGet(FLAG_IS_CHAMPION); + data->compatibility.canLinkNationally = FlagGet(FLAG_IS_CHAMPION); data->compatibility.hasNationalDex = IsNationalPokedexEnabled(); data->compatibility.gameClear = FlagGet(FLAG_SYS_GAME_CLEAR); } diff --git a/src/trade.c b/src/trade.c index 61ebaf4cc..1032d0d5d 100644 --- a/src/trade.c +++ b/src/trade.c @@ -51,6 +51,68 @@ #include "constants/songs.h" #include "constants/union_room.h" +// IDs for RunTradeMenuCallback +enum { + CB_MAIN_MENU, + CB_SELECTED_MON, + CB_SHOW_MON_SUMMARY, + CB_CONFIRM_TRADE_PROMPT, + CB_CANCEL_TRADE_PROMPT, + CB_READY_WAIT, // Unused in Emerald, equivalent to CB_IDLE + CB_SET_SELECTED_MONS, + CB_PRINT_IS_THIS_OKAY, + CB_HANDLE_TRADE_CANCELED, + CB_FADE_TO_START_TRADE, + CB_WAIT_TO_START_TRADE, + CB_INIT_EXIT_CANCELED_TRADE, + CB_EXIT_CANCELED_TRADE, + CB_START_LINK_TRADE, + CB_INIT_CONFIRM_TRADE_PROMPT, + CB_UNUSED_CLOSE_MSG, + CB_WAIT_TO_START_RFU_TRADE, + CB_PARTNER_MON_INVALID, + CB_IDLE = 100, +}; + +// Indexes for sActionTexts +enum { + TEXT_CANCEL, + TEXT_CHOOSE_MON, + TEXT_SUMMARY, + TEXT_TRADE, + TEXT_CANCEL_TRADE, + TEXT_JP_QUIT, +}; + +// Indexes for sMessages +enum { + MSG_STANDBY, + MSG_CANCELED, + MSG_ONLY_MON1, + MSG_ONLY_MON2, + MSG_WAITING_FOR_FRIEND, + MSG_FRIEND_WANTS_TO_TRADE, + MSG_MON_CANT_BE_TRADED, + MSG_EGG_CANT_BE_TRADED, + MSG_FRIENDS_MON_CANT_BE_TRADED, +}; + +// IDs for QueueAction +enum { + QUEUE_SEND_DATA, + QUEUE_STANDBY, + QUEUE_ONLY_MON1, + QUEUE_ONLY_MON2, + QUEUE_UNUSED1, // Presumably intended for MSG_WAITING_FOR_FRIEND + QUEUE_UNUSED2, // Presumably intended for MSG_FRIEND_WANTS_TO_TRADE + QUEUE_MON_CANT_BE_TRADED, + QUEUE_EGG_CANT_BE_TRADED, + QUEUE_FRIENDS_MON_CANT_BE_TRADED, +}; + +#define QUEUE_DELAY_MSG 3 +#define QUEUE_DELAY_DATA 5 + // The following tags are offsets from GFXTAG_MENU_TEXT // They're looped over in CB2_CreateTradeMenu and CB2_ReturnToTradeMenu // and used as indexes into sMenuTextTileBuffers @@ -69,11 +131,21 @@ enum { GFXTAG_CHOOSE_PKMN_EMPTY_1, // 6 sprites to cover the full bottom bar, but only first 3 are needed GFXTAG_CHOOSE_PKMN_EMPTY_2, GFXTAG_CHOOSE_PKMN_EMPTY_3, - GFXTAG_MENU_TEXT_COUNT + NUM_MENU_TEXT_SPRITES }; -#define GFXTAG_PLAYER_NAME (1 + GFXTAG_PLAYER_NAME_R - GFXTAG_PLAYER_NAME_L) -#define GFXTAG_PARTNER_NAME (1 + GFXTAG_PARTNER_NAME_R - GFXTAG_PARTNER_NAME_L) -#define GFXTAG_CHOOSE_PKMN (1 + GFXTAG_CHOOSE_PKMN_EMPTY_3 - GFXTAG_CHOOSE_PKMN_L) +#define NUM_PLAYER_NAME_SPRITES (1 + GFXTAG_PLAYER_NAME_R - GFXTAG_PLAYER_NAME_L) +#define NUM_PARTNER_NAME_SPRITES (1 + GFXTAG_PARTNER_NAME_R - GFXTAG_PARTNER_NAME_L) +#define NUM_CHOOSE_PKMN_SPRITES (1 + GFXTAG_CHOOSE_PKMN_EMPTY_3 - GFXTAG_CHOOSE_PKMN_L) + +// Values for signaling to/from the link partner +enum { + STATUS_NONE, + STATUS_READY, + STATUS_CANCEL, +}; + +// Checked to confirm DrawSelectedMonScreen has reached final state +#define DRAW_SELECTED_FINISH 5 struct InGameTrade { /*0x00*/ u8 nickname[POKEMON_NAME_LENGTH + 1]; @@ -91,56 +163,53 @@ struct InGameTrade { /*0x38*/ u16 requestedSpecies; }; -static EWRAM_DATA u8 *sMenuTextAllocBuffer = NULL; +static EWRAM_DATA u8 *sMenuTextTileBuffer = NULL; // Bytes 0-2 are used for the player's name text // Bytes 3-5 are used for the partner's name text // Bytes 6-7 are used for the Cancel text // Bytes 8-13 are used for the Choose a Pokemon text // See the corresponding GFXTAGs in src/data/trade.h -static EWRAM_DATA u8 *sMenuTextTileBuffers[GFXTAG_MENU_TEXT_COUNT] = {NULL}; +static EWRAM_DATA u8 *sMenuTextTileBuffers[NUM_MENU_TEXT_SPRITES] = {NULL}; EWRAM_DATA struct Mail gTradeMail[PARTY_SIZE] = {0}; EWRAM_DATA u8 gSelectedTradeMonPositions[2] = {0}; static EWRAM_DATA struct { - /*0x0000*/ u8 bg2hofs; - /*0x0001*/ u8 bg3hofs; - /*0x0002*/ u8 filler_2[38]; - /*0x0028*/ u8 partySpriteIds[2][PARTY_SIZE]; - /*0x0034*/ u8 cursorSpriteId; - /*0x0035*/ u8 cursorPosition; - /*0x0036*/ u8 partyCounts[2]; - /*0x0038*/ bool8 monPresent[PARTY_SIZE * 2]; - /*0x0044*/ bool8 neverRead_44; - /*0x0045*/ bool8 isLiveMon[2][PARTY_SIZE]; - /*0x0051*/ bool8 isEgg[2][PARTY_SIZE]; - /*0x005D*/ u8 hpBarLevels[2][PARTY_SIZE]; - /*0x0069*/ u8 bufferPartyState; - /*0x006A*/ u8 filler_6A[5]; - /*0x006F*/ u8 tradeMenuFunc; - /*0x0070*/ u8 neverRead_70; - /*0x0071*/ u8 filler_71; - /*0x0072*/ u16 bottomTextTileStart; - /*0x0074*/ u8 drawPartyState[2]; - /*0x0076*/ u8 selectedMonIdx[2]; - /*0x0078*/ u8 playerLinkFlagChoseAction; - /*0x0079*/ u8 partnerLinkFlagChoseAction; - /*0x007A*/ u8 playerLinkFlagStatus; - /*0x007B*/ u8 partnerLinkFlagStatus; - /*0x007C*/ u8 filler_7C[2]; - /*0x007E*/ u8 partnerCursorPosition; - /*0x007F*/ u8 unused_7F; - /*0x0080*/ u16 linkData[20]; - /*0x00A8*/ u8 timer; - /*0x00A9*/ u8 giftRibbons[GIFT_RIBBONS_COUNT]; - /*0x00B4*/ u8 filler_B4[0x81C]; - /*0x08D0*/ struct { - bool8 queued; - u16 queueDelay; + u8 bg2hofs; + u8 bg3hofs; + u8 filler_2[38]; + u8 partySpriteIds[2][PARTY_SIZE]; + u8 cursorSpriteId; + u8 cursorPosition; + u8 partyCounts[2]; + bool8 optionsActive[PARTY_SIZE * 2 + 1]; + bool8 isLiveMon[2][PARTY_SIZE]; + bool8 isEgg[2][PARTY_SIZE]; + u8 hpBarLevels[2][PARTY_SIZE]; + u8 bufferPartyState; + u8 filler_6A[5]; + u8 callbackId; + u8 neverRead_70; + u16 bottomTextTileStart; + u8 drawSelectedMonState[2]; + u8 selectedMonIdx[2]; + u8 playerSelectStatus; + u8 partnerSelectStatus; + u8 playerConfirmStatus; + u8 partnerConfirmStatus; + u8 filler_7C[2]; + u8 partnerCursorPosition; + u16 linkData[20]; + u8 timer; + u8 giftRibbons[GIFT_RIBBONS_COUNT]; + u8 filler_B4[0x81C]; + struct { + bool8 active; + u16 delay; u8 actionId; } queuedActions[4]; - /*0x08F0*/ u16 tilemapBuffer[0x400]; -} *sTradeMenuData = {NULL}; + u16 tilemapBuffer[BG_SCREEN_SIZE / 2]; +} *sTradeMenu = NULL; static EWRAM_DATA struct { /*0x00*/ struct Pokemon tempMon; // Used as a temp variable when swapping Pokémon @@ -193,29 +262,29 @@ static void CB2_CreateTradeMenu(void); static void VBlankCB_TradeMenu(void); static void CB2_TradeMenu(void); static void LoadTradeBgGfx(u8); -static void SetTradePartyMonsVisible(void); +static void SetActiveMenuOptions(void); static bool8 BufferTradeParties(void); -static void CB1_SendOrReactToLinkTradeData(void); -static void CallTradeMenuFunc(void); +static void CB1_UpdateLink(void); +static void RunTradeMenuCallback(void); static void SetSelectedMon(u8); -static void DrawTradeMenuParty(u8); +static void DrawSelectedMonScreen(u8); static u8 GetMonNicknameWidth(u8 *, u8, u8); -static void BufferTradeMonMoves(u8 *, u8, u8); -static void PrintPartyNicknamesForTradeMenu(u8); -static void DrawTradeMenuPartyMonInfo(u8, u8, u8, u8, u8, u8); -static void DrawTradeMenuPartyInfo(u8); -static void PrintNicknamesForTradeMenu(void); -static void RedrawTradeMenuParty(u8); +static void BufferMovesString(u8 *, u8, u8); +static void PrintPartyNicknames(u8); +static void PrintLevelAndGender(u8, u8, u8, u8, u8, u8); +static void PrintPartyLevelsAndGenders(u8); +static void PrintTradePartnerPartyNicknames(void); +static void RedrawPartyWindow(u8); static void Task_DrawSelectionSummary(u8); static void Task_DrawSelectionTrade(u8); static void QueueAction(u16, u8); static u32 GetNumQueuedActions(void); static void DoQueuedActions(void); static void PrintTradeMessage(u8); -static bool8 LoadTradeMenuSpriteSheetsAndPalettes(void); +static bool8 LoadUISpriteGfx(void); static void DrawBottomRowText(const u8 *, u8 *, u8); -static void SetTradePartyLiveStatuses(u8); -static void GetTradePartyHPBarLevels(u8); +static void ComputePartyTradeableFlags(u8); +static void ComputePartyHPBarLevels(u8); static void SetTradePartyHPBarSprites(void); static void SaveTradeGiftRibbons(void); static u32 CanTradeSelectedMon(struct Pokemon *, int, int); @@ -336,16 +405,16 @@ static void InitTradeMenu(void) LoadPalette(gStandardMenuPalette, 0xF0, 20); LoadPalette(gStandardMenuPalette, 0xD0, 20); ResetBgsAndClearDma3BusyFlags(0); - InitBgsFromTemplates(0, sTradeMenuBgTemplates, ARRAY_COUNT(sTradeMenuBgTemplates)); - SetBgTilemapBuffer(1, sTradeMenuData->tilemapBuffer); + InitBgsFromTemplates(0, sBgTemplates, ARRAY_COUNT(sBgTemplates)); + SetBgTilemapBuffer(1, sTradeMenu->tilemapBuffer); - if (InitWindows(sTradeMenuWindowTemplates)) + if (InitWindows(sWindowTemplates)) { u32 i; DeactivateAllTextPrinters(); - for (i = 0; i < 18; i++) + for (i = 0; i < ARRAY_COUNT(sWindowTemplates) - 1; i++) { ClearWindowTilemap(i); FillWindowPixelBuffer(i, PIXEL_FILL(0)); @@ -355,14 +424,14 @@ static void InitTradeMenu(void) LoadUserWindowBorderGfx_(0, 20, 0xC0); LoadUserWindowBorderGfx(2, 1, 0xE0); LoadMonIconPalettes(); - sTradeMenuData->bufferPartyState = 0; - sTradeMenuData->tradeMenuFunc = 0; - sTradeMenuData->neverRead_70 = 0; - sTradeMenuData->drawPartyState[TRADE_PLAYER] = 0; - sTradeMenuData->drawPartyState[TRADE_PARTNER] = 0; - sTradeMenuData->playerLinkFlagStatus = 0; - sTradeMenuData->partnerLinkFlagStatus = 0; - sTradeMenuData->timer = 0; + sTradeMenu->bufferPartyState = 0; + sTradeMenu->callbackId = CB_MAIN_MENU; + sTradeMenu->neverRead_70 = 0; + sTradeMenu->drawSelectedMonState[TRADE_PLAYER] = 0; + sTradeMenu->drawSelectedMonState[TRADE_PARTNER] = 0; + sTradeMenu->playerConfirmStatus = STATUS_NONE; + sTradeMenu->partnerConfirmStatus = STATUS_NONE; + sTradeMenu->timer = 0; } } @@ -383,12 +452,12 @@ static void CB2_CreateTradeMenu(void) switch (gMain.state) { case 0: - sTradeMenuData = AllocZeroed(sizeof(*sTradeMenuData)); + sTradeMenu = AllocZeroed(sizeof(*sTradeMenu)); InitTradeMenu(); - sMenuTextAllocBuffer = AllocZeroed(GFXTAG_MENU_TEXT_COUNT * 256); + sMenuTextTileBuffer = AllocZeroed(NUM_MENU_TEXT_SPRITES * 256); - for (i = 0; i < GFXTAG_MENU_TEXT_COUNT; i++) - sMenuTextTileBuffers[i] = &sMenuTextAllocBuffer[i * 256]; + for (i = 0; i < NUM_MENU_TEXT_SPRITES; i++) + sMenuTextTileBuffers[i] = &sMenuTextTileBuffer[i * 256]; gMain.state++; break; @@ -398,13 +467,13 @@ static void CB2_CreateTradeMenu(void) for (i = 0; i < PARTY_SIZE; i++) CreateMon(&gEnemyParty[i], SPECIES_NONE, 0, USE_RANDOM_IVS, FALSE, 0, OT_ID_PLAYER_ID, 0); - PrintTradeMessage(TRADE_MSG_STANDBY); + PrintTradeMessage(MSG_STANDBY); ShowBg(0); if (!gReceivedRemoteLinkPlayers) { gLinkType = LINKTYPE_TRADE_CONNECTING; - sTradeMenuData->timer = 0; + sTradeMenu->timer = 0; if (gWirelessCommType) { @@ -425,10 +494,10 @@ static void CB2_CreateTradeMenu(void) } break; case 2: - sTradeMenuData->timer++; - if (sTradeMenuData->timer > 11) + sTradeMenu->timer++; + if (sTradeMenu->timer > 11) { - sTradeMenuData->timer = 0; + sTradeMenu->timer = 0; gMain.state++; } break; @@ -437,7 +506,7 @@ static void CB2_CreateTradeMenu(void) { if (IsLinkMaster()) { - if (++sTradeMenuData->timer > 30) + if (++sTradeMenu->timer > 30) { CheckShouldAdvanceLinkState(); gMain.state++; @@ -455,7 +524,7 @@ static void CB2_CreateTradeMenu(void) DestroyTask_RfuIdle(); CalculatePlayerPartyCount(); gMain.state++; - sTradeMenuData->timer = 0; + sTradeMenu->timer = 0; if (gWirelessCommType) { Rfu_SetLinkRecovery(TRUE); @@ -489,13 +558,13 @@ static void CB2_CreateTradeMenu(void) CalculateEnemyPartyCount(); SetGpuReg(REG_OFFSET_DISPCNT, 0); SetGpuReg(REG_OFFSET_BLDCNT, 0); - sTradeMenuData->partyCounts[TRADE_PLAYER] = gPlayerPartyCount; - sTradeMenuData->partyCounts[TRADE_PARTNER] = gEnemyPartyCount; + sTradeMenu->partyCounts[TRADE_PLAYER] = gPlayerPartyCount; + sTradeMenu->partyCounts[TRADE_PARTNER] = gEnemyPartyCount; - for (i = 0; i < sTradeMenuData->partyCounts[TRADE_PLAYER]; i++) + for (i = 0; i < sTradeMenu->partyCounts[TRADE_PLAYER]; i++) { struct Pokemon *mon = &gPlayerParty[i]; - sTradeMenuData->partySpriteIds[TRADE_PLAYER][i] = CreateMonIcon(GetMonData(mon, MON_DATA_SPECIES2), + sTradeMenu->partySpriteIds[TRADE_PLAYER][i] = CreateMonIcon(GetMonData(mon, MON_DATA_SPECIES2), SpriteCB_MonIcon, (sTradeMonSpriteCoords[i][0] * 8) + 14, (sTradeMonSpriteCoords[i][1] * 8) - 12, @@ -504,10 +573,10 @@ static void CB2_CreateTradeMenu(void) TRUE); } - for (i = 0; i < sTradeMenuData->partyCounts[TRADE_PARTNER]; i++) + for (i = 0; i < sTradeMenu->partyCounts[TRADE_PARTNER]; i++) { struct Pokemon *mon = &gEnemyParty[i]; - sTradeMenuData->partySpriteIds[TRADE_PARTNER][i] = CreateMonIcon(GetMonData(mon, MON_DATA_SPECIES2, NULL), + sTradeMenu->partySpriteIds[TRADE_PARTNER][i] = CreateMonIcon(GetMonData(mon, MON_DATA_SPECIES2, NULL), SpriteCB_MonIcon, (sTradeMonSpriteCoords[i + PARTY_SIZE][0] * 8) + 14, (sTradeMonSpriteCoords[i + PARTY_SIZE][1] * 8) - 12, @@ -519,30 +588,30 @@ static void CB2_CreateTradeMenu(void) break; case 8: LoadHeldItemIcons(); - DrawHeldItemIconsForTrade(&sTradeMenuData->partyCounts[0], sTradeMenuData->partySpriteIds[0], TRADE_PLAYER); + DrawHeldItemIconsForTrade(&sTradeMenu->partyCounts[0], sTradeMenu->partySpriteIds[0], TRADE_PLAYER); gMain.state++; break; case 9: - DrawHeldItemIconsForTrade(&sTradeMenuData->partyCounts[0], sTradeMenuData->partySpriteIds[0], TRADE_PARTNER); + DrawHeldItemIconsForTrade(&sTradeMenu->partyCounts[0], sTradeMenu->partySpriteIds[0], TRADE_PARTNER); gMain.state++; break; case 10: DrawTextWindowAndBufferTiles(gSaveBlock2Ptr->playerName, sMenuTextTileBuffers[GFXTAG_PLAYER_NAME_L], 0, 0, 3); id = GetMultiplayerId(); DrawTextWindowAndBufferTiles(gLinkPlayers[id ^ 1].name, sMenuTextTileBuffers[GFXTAG_PARTNER_NAME_L], 0, 0, 3); - DrawTextWindowAndBufferTiles(sTradeActionTexts[TRADE_TEXT_CANCEL], sMenuTextTileBuffers[GFXTAG_CANCEL_L], 0, 0, 2); - DrawBottomRowText(sTradeActionTexts[TRADE_TEXT_CHOOSE_MON], sMenuTextTileBuffers[GFXTAG_CHOOSE_PKMN_L], 24); + DrawTextWindowAndBufferTiles(sActionTexts[TEXT_CANCEL], sMenuTextTileBuffers[GFXTAG_CANCEL_L], 0, 0, 2); + DrawBottomRowText(sActionTexts[TEXT_CHOOSE_MON], sMenuTextTileBuffers[GFXTAG_CHOOSE_PKMN_L], 24); gMain.state++; - sTradeMenuData->timer = 0; + sTradeMenu->timer = 0; break; case 11: - if (LoadTradeMenuSpriteSheetsAndPalettes()) + if (LoadUISpriteGfx()) gMain.state++; break; case 12: // Create player's name text sprites xPos = GetStringCenterAlignXOffset(FONT_NORMAL, gSaveBlock2Ptr->playerName, 120); - for (i = 0; i < GFXTAG_PLAYER_NAME; i++) + for (i = 0; i < NUM_PLAYER_NAME_SPRITES; i++) { temp = sSpriteTemplate_MenuText; temp.tileTag += i + GFXTAG_PLAYER_NAME_L; @@ -551,7 +620,7 @@ static void CB2_CreateTradeMenu(void) // Create partner's name text sprites xPos = GetStringCenterAlignXOffset(FONT_NORMAL, gLinkPlayers[GetMultiplayerId() ^ 1].name, 120); - for (i = 0; i < GFXTAG_PARTNER_NAME; i++) + for (i = 0; i < NUM_PARTNER_NAME_SPRITES; i++) { temp = sSpriteTemplate_MenuText; temp.tileTag += i + GFXTAG_PARTNER_NAME_L; @@ -566,33 +635,33 @@ static void CB2_CreateTradeMenu(void) CreateSprite(&temp, 215, 152, 1); temp = sSpriteTemplate_MenuText; temp.tileTag += GFXTAG_CANCEL_R; - CreateSprite(&temp, 247, 152, 1); + CreateSprite(&temp, 215 + 32, 152, 1); // Create Choose a Pokémon text sprites (only 3 are needed, other 3 are empty) - for (i = 0; i < GFXTAG_CHOOSE_PKMN; i++) + for (i = 0; i < NUM_CHOOSE_PKMN_SPRITES; i++) { temp = sSpriteTemplate_MenuText; temp.tileTag += i + GFXTAG_CHOOSE_PKMN_L; CreateSprite(&temp, (i * 32) + 24, 150, 1); } - sTradeMenuData->cursorSpriteId = CreateSprite(&sSpriteTemplate_Cursor, sTradeMonSpriteCoords[0][0] * 8 + 32, sTradeMonSpriteCoords[0][1] * 8, 2); - sTradeMenuData->cursorPosition = 0; + sTradeMenu->cursorSpriteId = CreateSprite(&sSpriteTemplate_Cursor, sTradeMonSpriteCoords[0][0] * 8 + 32, sTradeMonSpriteCoords[0][1] * 8, 2); + sTradeMenu->cursorPosition = 0; gMain.state++; rbox_fill_rectangle(0); break; case 14: - SetTradePartyLiveStatuses(TRADE_PLAYER); - PrintPartyNicknamesForTradeMenu(TRADE_PLAYER); - sTradeMenuData->bg2hofs = 0; - sTradeMenuData->bg3hofs = 0; - SetTradePartyMonsVisible(); + ComputePartyTradeableFlags(TRADE_PLAYER); + PrintPartyNicknames(TRADE_PLAYER); + sTradeMenu->bg2hofs = 0; + sTradeMenu->bg3hofs = 0; + SetActiveMenuOptions(); gMain.state++; PlayBGM(MUS_SCHOOL); break; case 15: - SetTradePartyLiveStatuses(TRADE_PARTNER); - PrintPartyNicknamesForTradeMenu(TRADE_PARTNER); + ComputePartyTradeableFlags(TRADE_PARTNER); + PrintPartyNicknames(TRADE_PARTNER); gMain.state++; // fallthrough case 16: @@ -613,18 +682,18 @@ static void CB2_CreateTradeMenu(void) gMain.state++; break; case 20: - GetTradePartyHPBarLevels(TRADE_PLAYER); + ComputePartyHPBarLevels(TRADE_PLAYER); gMain.state++; break; case 21: - GetTradePartyHPBarLevels(TRADE_PARTNER); + ComputePartyHPBarLevels(TRADE_PARTNER); SetTradePartyHPBarSprites(); gMain.state++; break; case 22: if (!gPaletteFade.active) { - gMain.callback1 = CB1_SendOrReactToLinkTradeData; + gMain.callback1 = CB1_UpdateLink; SetMainCallback2(CB2_TradeMenu); } break; @@ -652,7 +721,7 @@ static void CB2_ReturnToTradeMenu(void) break; case 1: gMain.state++; - sTradeMenuData->timer = 0; + sTradeMenu->timer = 0; break; case 2: gMain.state++; @@ -677,16 +746,16 @@ static void CB2_ReturnToTradeMenu(void) break; case 7: CalculateEnemyPartyCount(); - sTradeMenuData->partyCounts[TRADE_PLAYER] = gPlayerPartyCount; - sTradeMenuData->partyCounts[TRADE_PARTNER] = gEnemyPartyCount; + sTradeMenu->partyCounts[TRADE_PLAYER] = gPlayerPartyCount; + sTradeMenu->partyCounts[TRADE_PARTNER] = gEnemyPartyCount; ClearWindowTilemap(0); - PrintPartyNicknamesForTradeMenu(TRADE_PLAYER); - PrintPartyNicknamesForTradeMenu(TRADE_PARTNER); + PrintPartyNicknames(TRADE_PLAYER); + PrintPartyNicknames(TRADE_PARTNER); - for (i = 0; i < sTradeMenuData->partyCounts[TRADE_PLAYER]; i++) + for (i = 0; i < sTradeMenu->partyCounts[TRADE_PLAYER]; i++) { struct Pokemon *mon = &gPlayerParty[i]; - sTradeMenuData->partySpriteIds[TRADE_PLAYER][i] = CreateMonIcon(GetMonData(mon, MON_DATA_SPECIES2, NULL), + sTradeMenu->partySpriteIds[TRADE_PLAYER][i] = CreateMonIcon(GetMonData(mon, MON_DATA_SPECIES2, NULL), SpriteCB_MonIcon, (sTradeMonSpriteCoords[i][0] * 8) + 14, (sTradeMonSpriteCoords[i][1] * 8) - 12, @@ -695,10 +764,10 @@ static void CB2_ReturnToTradeMenu(void) TRUE); } - for (i = 0; i < sTradeMenuData->partyCounts[TRADE_PARTNER]; i++) + for (i = 0; i < sTradeMenu->partyCounts[TRADE_PARTNER]; i++) { struct Pokemon *mon = &gEnemyParty[i]; - sTradeMenuData->partySpriteIds[TRADE_PARTNER][i] = CreateMonIcon(GetMonData(mon, MON_DATA_SPECIES2, NULL), + sTradeMenu->partySpriteIds[TRADE_PARTNER][i] = CreateMonIcon(GetMonData(mon, MON_DATA_SPECIES2, NULL), SpriteCB_MonIcon, (sTradeMonSpriteCoords[i + PARTY_SIZE][0] * 8) + 14, (sTradeMonSpriteCoords[i + PARTY_SIZE][1] * 8) - 12, @@ -710,30 +779,30 @@ static void CB2_ReturnToTradeMenu(void) break; case 8: LoadHeldItemIcons(); - DrawHeldItemIconsForTrade(&sTradeMenuData->partyCounts[0], sTradeMenuData->partySpriteIds[0], TRADE_PLAYER); + DrawHeldItemIconsForTrade(&sTradeMenu->partyCounts[0], sTradeMenu->partySpriteIds[0], TRADE_PLAYER); gMain.state++; break; case 9: - DrawHeldItemIconsForTrade(&sTradeMenuData->partyCounts[0], sTradeMenuData->partySpriteIds[0], TRADE_PARTNER); + DrawHeldItemIconsForTrade(&sTradeMenu->partyCounts[0], sTradeMenu->partySpriteIds[0], TRADE_PARTNER); gMain.state++; break; case 10: DrawTextWindowAndBufferTiles(gSaveBlock2Ptr->playerName, sMenuTextTileBuffers[GFXTAG_PLAYER_NAME_L], 0, 0, 3); id = GetMultiplayerId(); DrawTextWindowAndBufferTiles(gLinkPlayers[id ^ 1].name, sMenuTextTileBuffers[GFXTAG_PARTNER_NAME_L], 0, 0, 3); - DrawTextWindowAndBufferTiles(sTradeActionTexts[TRADE_TEXT_CANCEL], sMenuTextTileBuffers[GFXTAG_CANCEL_L], 0, 0, 2); - DrawBottomRowText(sTradeActionTexts[TRADE_TEXT_CHOOSE_MON], sMenuTextTileBuffers[GFXTAG_CHOOSE_PKMN_L], 24); + DrawTextWindowAndBufferTiles(sActionTexts[TEXT_CANCEL], sMenuTextTileBuffers[GFXTAG_CANCEL_L], 0, 0, 2); + DrawBottomRowText(sActionTexts[TEXT_CHOOSE_MON], sMenuTextTileBuffers[GFXTAG_CHOOSE_PKMN_L], 24); gMain.state++; - sTradeMenuData->timer = 0; + sTradeMenu->timer = 0; break; case 11: - if (LoadTradeMenuSpriteSheetsAndPalettes()) + if (LoadUISpriteGfx()) gMain.state++; break; case 12: // Create player's name text sprites xPos = GetStringCenterAlignXOffset(FONT_NORMAL, gSaveBlock2Ptr->playerName, 120); - for (i = 0; i < GFXTAG_PLAYER_NAME; i++) + for (i = 0; i < NUM_PLAYER_NAME_SPRITES; i++) { temp = sSpriteTemplate_MenuText; temp.tileTag += i + GFXTAG_PLAYER_NAME_L; @@ -742,7 +811,7 @@ static void CB2_ReturnToTradeMenu(void) // Create partner's name text sprites xPos = GetStringCenterAlignXOffset(FONT_NORMAL, gLinkPlayers[GetMultiplayerId() ^ 1].name, 120); - for (i = 0; i < GFXTAG_PARTNER_NAME; i++) + for (i = 0; i < NUM_PARTNER_NAME_SPRITES; i++) { temp = sSpriteTemplate_MenuText; temp.tileTag += i + GFXTAG_PARTNER_NAME_L; @@ -757,24 +826,24 @@ static void CB2_ReturnToTradeMenu(void) CreateSprite(&temp, 215, 152, 1); temp = sSpriteTemplate_MenuText; temp.tileTag += GFXTAG_CANCEL_R; - CreateSprite(&temp, 247, 152, 1); + CreateSprite(&temp, 215 + 32, 152, 1); // Create Choose a Pokémon text sprites - for (i = 0; i < GFXTAG_CHOOSE_PKMN; i++) + for (i = 0; i < NUM_CHOOSE_PKMN_SPRITES; i++) { temp = sSpriteTemplate_MenuText; temp.tileTag += i + GFXTAG_CHOOSE_PKMN_L; CreateSprite(&temp, (i * 32) + 24, 150, 1); } - if (sTradeMenuData->cursorPosition < PARTY_SIZE) - sTradeMenuData->cursorPosition = gLastViewedMonIndex; + if (sTradeMenu->cursorPosition < PARTY_SIZE) + sTradeMenu->cursorPosition = gLastViewedMonIndex; else - sTradeMenuData->cursorPosition = gLastViewedMonIndex + PARTY_SIZE; + sTradeMenu->cursorPosition = gLastViewedMonIndex + PARTY_SIZE; - sTradeMenuData->cursorSpriteId = CreateSprite(&sSpriteTemplate_Cursor, - sTradeMonSpriteCoords[sTradeMenuData->cursorPosition][0] * 8 + 32, - sTradeMonSpriteCoords[sTradeMenuData->cursorPosition][1] * 8, 2); + sTradeMenu->cursorSpriteId = CreateSprite(&sSpriteTemplate_Cursor, + sTradeMonSpriteCoords[sTradeMenu->cursorPosition][0] * 8 + 32, + sTradeMonSpriteCoords[sTradeMenu->cursorPosition][1] * 8, 2); gMain.state = 16; break; case 16: @@ -783,9 +852,9 @@ static void CB2_ReturnToTradeMenu(void) break; case 17: LoadTradeBgGfx(1); - sTradeMenuData->bg2hofs = 0; - sTradeMenuData->bg3hofs = 0; - SetTradePartyMonsVisible(); + sTradeMenu->bg2hofs = 0; + sTradeMenu->bg3hofs = 0; + SetActiveMenuOptions(); gMain.state++; break; case 18: @@ -808,9 +877,7 @@ static void CB2_ReturnToTradeMenu(void) break; case 22: if (!gPaletteFade.active) - { SetMainCallback2(CB2_TradeMenu); - } break; } @@ -827,59 +894,59 @@ static void VBlankCB_TradeMenu(void) TransferPlttBuffer(); } -static void LinkTradeFadeOut(void) +static void CB_FadeToStartTrade(void) { - if (++sTradeMenuData->timer > 15) + if (++sTradeMenu->timer > 15) { BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_LINK_TRADE_WAIT_FADE; + sTradeMenu->callbackId = CB_WAIT_TO_START_TRADE; } } -static void LinkTradeWaitForFade(void) +static void CB_WaitToStartTrade(void) { if (!gPaletteFade.active) { - gSelectedTradeMonPositions[TRADE_PLAYER] = sTradeMenuData->cursorPosition; - gSelectedTradeMonPositions[TRADE_PARTNER] = sTradeMenuData->partnerCursorPosition; + gSelectedTradeMonPositions[TRADE_PLAYER] = sTradeMenu->cursorPosition; + gSelectedTradeMonPositions[TRADE_PARTNER] = sTradeMenu->partnerCursorPosition; if (gWirelessCommType) { - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_LINK_TRADE_WAIT_QUEUE; + sTradeMenu->callbackId = CB_WAIT_TO_START_RFU_TRADE; } else { SetCloseLinkCallbackAndType(32); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_START_LINK_TRADE; + sTradeMenu->callbackId = CB_START_LINK_TRADE; } } } -static void SetLinkTradeCallbacks(void) +static void CB_StartLinkTrade(void) { gMain.savedCallback = CB2_StartCreateTradeMenu; - // Wireless Link Trade if (gWirelessCommType) { + // Wireless Link Trade if (IsLinkRfuTaskFinished()) { - Free(sMenuTextAllocBuffer); + Free(sMenuTextTileBuffer); FreeAllWindowBuffers(); - Free(sTradeMenuData); + Free(sTradeMenu); gMain.callback1 = NULL; DestroyWirelessStatusIndicatorSprite(); SetMainCallback2(CB2_LinkTrade); } } - // Cable Link Trade else { + // Cable Link Trade if (!gReceivedRemoteLinkPlayers) { - Free(sMenuTextAllocBuffer); + Free(sMenuTextTileBuffer); FreeAllWindowBuffers(); - Free(sTradeMenuData); + Free(sTradeMenu); gMain.callback1 = NULL; SetMainCallback2(CB2_LinkTrade); } @@ -888,13 +955,15 @@ static void SetLinkTradeCallbacks(void) static void CB2_TradeMenu(void) { - CallTradeMenuFunc(); + RunTradeMenuCallback(); DoQueuedActions(); - DrawTradeMenuParty(TRADE_PLAYER); - DrawTradeMenuParty(TRADE_PARTNER); - SetGpuReg(REG_OFFSET_BG2HOFS, sTradeMenuData->bg2hofs++); - SetGpuReg(REG_OFFSET_BG3HOFS, sTradeMenuData->bg3hofs--); + // As long as drawSelectedMonState is 0, these do nothing + DrawSelectedMonScreen(TRADE_PLAYER); + DrawSelectedMonScreen(TRADE_PARTNER); + + SetGpuReg(REG_OFFSET_BG2HOFS, sTradeMenu->bg2hofs++); + SetGpuReg(REG_OFFSET_BG3HOFS, sTradeMenu->bg3hofs--); RunTextPrintersAndIsPrinter0Active(); RunTasks(); @@ -917,8 +986,8 @@ static void LoadTradeBgGfx(u8 state) break; case 1: LoadBgTilemap(3, sTradeStripesBG3Tilemap, 0x800, 0); - DrawTradeMenuPartyInfo(TRADE_PLAYER); - DrawTradeMenuPartyInfo(TRADE_PARTNER); + PrintPartyLevelsAndGenders(TRADE_PLAYER); + PrintPartyLevelsAndGenders(TRADE_PARTNER); CopyBgTilemapBufferToVram(1); break; case 2: @@ -932,47 +1001,50 @@ static void LoadTradeBgGfx(u8 state) } } -static void SetTradePartyMonsVisible(void) +// Determine (based on party counts) where the main menu cursor can go +static void SetActiveMenuOptions(void) { int i; for (i = 0; i < PARTY_SIZE; i++) { - if (i < sTradeMenuData->partyCounts[TRADE_PLAYER]) + if (i < sTradeMenu->partyCounts[TRADE_PLAYER]) { - gSprites[sTradeMenuData->partySpriteIds[TRADE_PLAYER][i]].invisible = FALSE; - sTradeMenuData->monPresent[i] = TRUE; + // Present player pokemon + gSprites[sTradeMenu->partySpriteIds[TRADE_PLAYER][i]].invisible = FALSE; + sTradeMenu->optionsActive[i] = TRUE; } else { - sTradeMenuData->monPresent[i] = FALSE; + // Absent player pokemon + sTradeMenu->optionsActive[i] = FALSE; } - if (i < sTradeMenuData->partyCounts[TRADE_PARTNER]) + if (i < sTradeMenu->partyCounts[TRADE_PARTNER]) { - gSprites[sTradeMenuData->partySpriteIds[TRADE_PARTNER][i]].invisible = FALSE; - sTradeMenuData->monPresent[i + PARTY_SIZE] = TRUE; + // Present partner pokemon + gSprites[sTradeMenu->partySpriteIds[TRADE_PARTNER][i]].invisible = FALSE; + sTradeMenu->optionsActive[i + PARTY_SIZE] = TRUE; } else { - sTradeMenuData->monPresent[i + PARTY_SIZE] = FALSE; + // Absent partner pokemno + sTradeMenu->optionsActive[i + PARTY_SIZE] = FALSE; } } - sTradeMenuData->neverRead_44 = TRUE; + // Cancel is always active + sTradeMenu->optionsActive[PARTY_SIZE * 2] = TRUE; } // why not just use memcpy? -static void Trade_Memcpy(void *dataDest, const void *dataSrc, u32 count) +static void Trade_Memcpy(void *dest, const void *src, u32 size) { - u8 *dest = dataDest; - const u8 *src = dataSrc; + u8 *_dest = dest; + const u8 *_src = src; u32 i; - - for (i = 0; i < count; i++) - { - dest[i] = src[i]; - } + for (i = 0; i < size; i++) + _dest[i] = _src[i]; } static bool8 BufferTradeParties(void) @@ -981,107 +1053,107 @@ static bool8 BufferTradeParties(void) int i; struct Pokemon *mon; - switch (sTradeMenuData->bufferPartyState) + switch (sTradeMenu->bufferPartyState) { case 0: // The parties are sent in pairs rather than all at once Trade_Memcpy(gBlockSendBuffer, &gPlayerParty[0], 2 * sizeof(struct Pokemon)); - sTradeMenuData->bufferPartyState++; - sTradeMenuData->timer = 0; + sTradeMenu->bufferPartyState++; + sTradeMenu->timer = 0; break; case 1: if (IsLinkTradeTaskFinished()) { if (_GetBlockReceivedStatus() == 0) { - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; } else { TradeResetReceivedFlags(); - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; } } break; case 3: if (id == 0) RequestLinkData(BLOCK_REQ_SIZE_200); - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; break; case 4: if (_GetBlockReceivedStatus() == 3) { Trade_Memcpy(&gEnemyParty[0], gBlockRecvBuffer[id ^ 1], 2 * sizeof(struct Pokemon)); TradeResetReceivedFlags(); - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; } break; case 5: Trade_Memcpy(gBlockSendBuffer, &gPlayerParty[2], 2 * sizeof(struct Pokemon)); - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; break; case 7: if (id == 0) RequestLinkData(BLOCK_REQ_SIZE_200); - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; break; case 8: if (_GetBlockReceivedStatus() == 3) { Trade_Memcpy(&gEnemyParty[2], gBlockRecvBuffer[id ^ 1], 2 * sizeof(struct Pokemon)); TradeResetReceivedFlags(); - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; } break; case 9: Trade_Memcpy(gBlockSendBuffer, &gPlayerParty[4], 2 * sizeof(struct Pokemon)); - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; break; case 11: if (id == 0) RequestLinkData(BLOCK_REQ_SIZE_200); - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; break; case 12: if (_GetBlockReceivedStatus() == 3) { Trade_Memcpy(&gEnemyParty[4], gBlockRecvBuffer[id ^ 1], 2 * sizeof(struct Pokemon)); TradeResetReceivedFlags(); - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; } break; case 13: Trade_Memcpy(gBlockSendBuffer, gSaveBlock1Ptr->mail, PARTY_SIZE * sizeof(struct Mail) + 4); - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; break; case 15: if (id == 0) RequestLinkData(BLOCK_REQ_SIZE_220); - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; break; case 16: if (_GetBlockReceivedStatus() == 3) { Trade_Memcpy(gTradeMail, gBlockRecvBuffer[id ^ 1], PARTY_SIZE * sizeof(struct Mail)); TradeResetReceivedFlags(); - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; } break; case 17: - Trade_Memcpy(gBlockSendBuffer, gSaveBlock1Ptr->giftRibbons, sizeof(sTradeMenuData->giftRibbons)); - sTradeMenuData->bufferPartyState++; + Trade_Memcpy(gBlockSendBuffer, gSaveBlock1Ptr->giftRibbons, sizeof(sTradeMenu->giftRibbons)); + sTradeMenu->bufferPartyState++; break; case 19: if (id == 0) RequestLinkData(BLOCK_REQ_SIZE_40); - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; break; case 20: if (_GetBlockReceivedStatus() == 3) { - Trade_Memcpy(sTradeMenuData->giftRibbons, gBlockRecvBuffer[id ^ 1], sizeof(sTradeMenuData->giftRibbons)); + Trade_Memcpy(sTradeMenu->giftRibbons, gBlockRecvBuffer[id ^ 1], sizeof(sTradeMenu->giftRibbons)); TradeResetReceivedFlags(); - sTradeMenuData->bufferPartyState++; + sTradeMenu->bufferPartyState++; } break; case 21: @@ -1096,10 +1168,8 @@ static bool8 BufferTradeParties(void) { GetMonData(mon, MON_DATA_NICKNAME, name); - if (!StringCompareWithoutExtCtrlCodes(name, sJPText_Shedinja)) - { + if (!StringCompareWithoutExtCtrlCodes(name, sText_ShedinjaJP)) SetMonData(mon, MON_DATA_NICKNAME, gSpeciesNames[SPECIES_SHEDINJA]); - } } } } @@ -1110,40 +1180,39 @@ static bool8 BufferTradeParties(void) case 10: case 14: case 18: - sTradeMenuData->timer++; - if (sTradeMenuData->timer > 10) + sTradeMenu->timer++; + if (sTradeMenu->timer > 10) { - sTradeMenuData->timer = 0; - sTradeMenuData->bufferPartyState++; + sTradeMenu->timer = 0; + sTradeMenu->bufferPartyState++; } break; } return FALSE; } -static void DrawIsThisTradeOkay(void) +static void PrintIsThisTradeOkay(void) { - DrawBottomRowText(sText_IsThisTradeOkay, (void *)(OBJ_VRAM0 + (sTradeMenuData->bottomTextTileStart * 32)), 24); + DrawBottomRowText(sText_IsThisTradeOkay, (void *)(OBJ_VRAM0 + (sTradeMenu->bottomTextTileStart * 32)), 24); } -// mpId is unused -static void UpdateLinkTradeFlags(u8 mpId, u8 status) +static void Leader_ReadLinkBuffer(u8 mpId, u8 status) { if (status & 1) { switch (gBlockRecvBuffer[0][0]) { case LINKCMD_REQUEST_CANCEL: - sTradeMenuData->playerLinkFlagChoseAction = WANTS_TO_CANCEL; + sTradeMenu->playerSelectStatus = STATUS_CANCEL; break; case LINKCMD_READY_TO_TRADE: - sTradeMenuData->playerLinkFlagChoseAction = WANTS_TO_TRADE; + sTradeMenu->playerSelectStatus = STATUS_READY; break; case LINKCMD_INIT_BLOCK: - sTradeMenuData->playerLinkFlagStatus = INITIATE_TRADE; + sTradeMenu->playerConfirmStatus = STATUS_READY; break; case LINKCMD_READY_CANCEL_TRADE: - sTradeMenuData->playerLinkFlagStatus = CANCEL_TRADE; + sTradeMenu->playerConfirmStatus = STATUS_CANCEL; break; } TradeResetReceivedFlag(0); @@ -1154,25 +1223,24 @@ static void UpdateLinkTradeFlags(u8 mpId, u8 status) switch (gBlockRecvBuffer[1][0]) { case LINKCMD_REQUEST_CANCEL: - sTradeMenuData->partnerLinkFlagChoseAction = WANTS_TO_CANCEL; + sTradeMenu->partnerSelectStatus = STATUS_CANCEL; break; case LINKCMD_READY_TO_TRADE: - sTradeMenuData->partnerCursorPosition = gBlockRecvBuffer[1][1] + 6; - sTradeMenuData->partnerLinkFlagChoseAction = WANTS_TO_TRADE; + sTradeMenu->partnerCursorPosition = gBlockRecvBuffer[1][1] + PARTY_SIZE; + sTradeMenu->partnerSelectStatus = STATUS_READY; break; case LINKCMD_INIT_BLOCK: - sTradeMenuData->partnerLinkFlagStatus = INITIATE_TRADE; + sTradeMenu->partnerConfirmStatus = STATUS_READY; break; case LINKCMD_READY_CANCEL_TRADE: - sTradeMenuData->partnerLinkFlagStatus = CANCEL_TRADE; + sTradeMenu->partnerConfirmStatus = STATUS_CANCEL; break; } TradeResetReceivedFlag(1); } } -// mpId is unused -static void ReactToLinkTradeData(u8 mpId, u8 status) +static void Follower_ReadLinkBuffer(u8 mpId, u8 status) { if (status & 1) { @@ -1180,27 +1248,27 @@ static void ReactToLinkTradeData(u8 mpId, u8 status) { case LINKCMD_BOTH_CANCEL_TRADE: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - PrintTradeMessage(TRADE_MSG_WAITING_FOR_FRIEND); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_CANCEL_TRADE_1; + PrintTradeMessage(MSG_WAITING_FOR_FRIEND); + sTradeMenu->callbackId = CB_INIT_EXIT_CANCELED_TRADE; break; case LINKCMD_PARTNER_CANCEL_TRADE: - PrintTradeMessage(TRADE_MSG_FRIEND_WANTS_TO_TRADE); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_REDRAW_MAIN_MENU; + PrintTradeMessage(MSG_FRIEND_WANTS_TO_TRADE); + sTradeMenu->callbackId = CB_HANDLE_TRADE_CANCELED; break; case LINKCMD_SET_MONS_TO_TRADE: - sTradeMenuData->partnerCursorPosition = gBlockRecvBuffer[0][1] + 6; + sTradeMenu->partnerCursorPosition = gBlockRecvBuffer[0][1] + PARTY_SIZE; rbox_fill_rectangle(0); - SetSelectedMon(sTradeMenuData->cursorPosition); - SetSelectedMon(sTradeMenuData->partnerCursorPosition); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_CONFIRM_TRADE_PROMPT; + SetSelectedMon(sTradeMenu->cursorPosition); + SetSelectedMon(sTradeMenu->partnerCursorPosition); + sTradeMenu->callbackId = CB_PRINT_IS_THIS_OKAY; break; case LINKCMD_START_TRADE: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_LINK_TRADE_WAIT_FADE; + sTradeMenu->callbackId = CB_WAIT_TO_START_TRADE; break; case LINKCMD_PLAYER_CANCEL_TRADE: - PrintTradeMessage(TRADE_MSG_CANCELED); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_REDRAW_MAIN_MENU; + PrintTradeMessage(MSG_CANCELED); + sTradeMenu->callbackId = CB_HANDLE_TRADE_CANCELED; } TradeResetReceivedFlag(0); } @@ -1209,76 +1277,87 @@ static void ReactToLinkTradeData(u8 mpId, u8 status) TradeResetReceivedFlag(1); } -static void QueueLinkTradeData(void) +static void Leader_HandleCommunication(void) { - if (sTradeMenuData->playerLinkFlagChoseAction && sTradeMenuData->partnerLinkFlagChoseAction) + if (sTradeMenu->playerSelectStatus != STATUS_NONE + && sTradeMenu->partnerSelectStatus != STATUS_NONE) { - if (sTradeMenuData->playerLinkFlagChoseAction == WANTS_TO_TRADE - && sTradeMenuData->partnerLinkFlagChoseAction == WANTS_TO_TRADE) + if (sTradeMenu->playerSelectStatus == STATUS_READY + && sTradeMenu->partnerSelectStatus == STATUS_READY) { - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_BOTH_MONS_SELECTED; - sTradeMenuData->linkData[0] = LINKCMD_SET_MONS_TO_TRADE; - sTradeMenuData->linkData[1] = sTradeMenuData->cursorPosition; + // Both players have selected a pokemon to trade + sTradeMenu->callbackId = CB_SET_SELECTED_MONS; + sTradeMenu->linkData[0] = LINKCMD_SET_MONS_TO_TRADE; + sTradeMenu->linkData[1] = sTradeMenu->cursorPosition; QueueAction(QUEUE_DELAY_DATA, QUEUE_SEND_DATA); - sTradeMenuData->playerLinkFlagChoseAction = sTradeMenuData->partnerLinkFlagChoseAction = 0; + sTradeMenu->playerSelectStatus = sTradeMenu->partnerSelectStatus = STATUS_NONE; } - else if (sTradeMenuData->playerLinkFlagChoseAction == WANTS_TO_TRADE - && sTradeMenuData->partnerLinkFlagChoseAction == WANTS_TO_CANCEL) + else if (sTradeMenu->playerSelectStatus == STATUS_READY + && sTradeMenu->partnerSelectStatus == STATUS_CANCEL) { - PrintTradeMessage(TRADE_MSG_CANCELED); - sTradeMenuData->linkData[0] = LINKCMD_PARTNER_CANCEL_TRADE; - sTradeMenuData->linkData[1] = 0; + // The player has selected a pokemon to trade, + // but the partner has selected Cancel + PrintTradeMessage(MSG_CANCELED); + sTradeMenu->linkData[0] = LINKCMD_PARTNER_CANCEL_TRADE; + sTradeMenu->linkData[1] = 0; QueueAction(QUEUE_DELAY_DATA, QUEUE_SEND_DATA); - sTradeMenuData->playerLinkFlagStatus = sTradeMenuData->partnerLinkFlagStatus = 0; - sTradeMenuData->playerLinkFlagChoseAction = sTradeMenuData->partnerLinkFlagChoseAction = 0; - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_REDRAW_MAIN_MENU; + sTradeMenu->playerConfirmStatus = sTradeMenu->partnerConfirmStatus = STATUS_NONE; + sTradeMenu->playerSelectStatus = sTradeMenu->partnerSelectStatus = STATUS_NONE; + sTradeMenu->callbackId = CB_HANDLE_TRADE_CANCELED; } - else if (sTradeMenuData->playerLinkFlagChoseAction == WANTS_TO_CANCEL - && sTradeMenuData->partnerLinkFlagChoseAction == WANTS_TO_TRADE) + else if (sTradeMenu->playerSelectStatus == STATUS_CANCEL + && sTradeMenu->partnerSelectStatus == STATUS_READY) { - PrintTradeMessage(TRADE_MSG_FRIEND_WANTS_TO_TRADE); - sTradeMenuData->linkData[0] = LINKCMD_PLAYER_CANCEL_TRADE; - sTradeMenuData->linkData[1] = 0; + // The partner has selected a pokemon to trade, + // but the player has selected cancel + PrintTradeMessage(MSG_FRIEND_WANTS_TO_TRADE); + sTradeMenu->linkData[0] = LINKCMD_PLAYER_CANCEL_TRADE; + sTradeMenu->linkData[1] = 0; QueueAction(QUEUE_DELAY_DATA, QUEUE_SEND_DATA); - sTradeMenuData->playerLinkFlagStatus = sTradeMenuData->partnerLinkFlagStatus = 0; - sTradeMenuData->playerLinkFlagChoseAction = sTradeMenuData->partnerLinkFlagChoseAction = 0; - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_REDRAW_MAIN_MENU; + sTradeMenu->playerConfirmStatus = sTradeMenu->partnerConfirmStatus = STATUS_NONE; + sTradeMenu->playerSelectStatus = sTradeMenu->partnerSelectStatus = STATUS_NONE; + sTradeMenu->callbackId = CB_HANDLE_TRADE_CANCELED; } - else if (sTradeMenuData->playerLinkFlagChoseAction == WANTS_TO_CANCEL - && sTradeMenuData->partnerLinkFlagChoseAction == WANTS_TO_CANCEL) + else if (sTradeMenu->playerSelectStatus == STATUS_CANCEL + && sTradeMenu->partnerSelectStatus == STATUS_CANCEL) { - sTradeMenuData->linkData[0] = LINKCMD_BOTH_CANCEL_TRADE; - sTradeMenuData->linkData[1] = 0; + // Both players have selected Cancel + sTradeMenu->linkData[0] = LINKCMD_BOTH_CANCEL_TRADE; + sTradeMenu->linkData[1] = 0; QueueAction(QUEUE_DELAY_DATA, QUEUE_SEND_DATA); BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeMenuData->playerLinkFlagChoseAction = sTradeMenuData->partnerLinkFlagChoseAction = 0; - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_CANCEL_TRADE_1; + sTradeMenu->playerSelectStatus = sTradeMenu->partnerSelectStatus = STATUS_NONE; + sTradeMenu->callbackId = CB_INIT_EXIT_CANCELED_TRADE; } } - if (sTradeMenuData->playerLinkFlagStatus && sTradeMenuData->partnerLinkFlagStatus) + if (sTradeMenu->playerConfirmStatus != STATUS_NONE + && sTradeMenu->partnerConfirmStatus != STATUS_NONE) { - if (sTradeMenuData->playerLinkFlagStatus == INITIATE_TRADE - && sTradeMenuData->partnerLinkFlagStatus == INITIATE_TRADE) + if (sTradeMenu->playerConfirmStatus == STATUS_READY + && sTradeMenu->partnerConfirmStatus == STATUS_READY) { - sTradeMenuData->linkData[0] = LINKCMD_START_TRADE; - sTradeMenuData->linkData[1] = 0; + // Both players have confirmed trade + sTradeMenu->linkData[0] = LINKCMD_START_TRADE; + sTradeMenu->linkData[1] = 0; QueueAction(QUEUE_DELAY_DATA, QUEUE_SEND_DATA); - sTradeMenuData->playerLinkFlagStatus = 0; - sTradeMenuData->partnerLinkFlagStatus = 0; - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_LINK_TRADE_FADE_OUT; + sTradeMenu->playerConfirmStatus = STATUS_NONE; + sTradeMenu->partnerConfirmStatus = STATUS_NONE; + sTradeMenu->callbackId = CB_FADE_TO_START_TRADE; } - if (sTradeMenuData->playerLinkFlagStatus == CANCEL_TRADE - || sTradeMenuData->partnerLinkFlagStatus == CANCEL_TRADE) + if (sTradeMenu->playerConfirmStatus == STATUS_CANCEL + || sTradeMenu->partnerConfirmStatus == STATUS_CANCEL) { - PrintTradeMessage(TRADE_MSG_CANCELED); - sTradeMenuData->linkData[0] = LINKCMD_PLAYER_CANCEL_TRADE; - sTradeMenuData->linkData[1] = 0; + // One of the players has decided not to confirm the trade, + // or the trade was not allowed. + PrintTradeMessage(MSG_CANCELED); + sTradeMenu->linkData[0] = LINKCMD_PLAYER_CANCEL_TRADE; + sTradeMenu->linkData[1] = 0; QueueAction(QUEUE_DELAY_DATA, QUEUE_SEND_DATA); - sTradeMenuData->playerLinkFlagStatus = 0; - sTradeMenuData->partnerLinkFlagStatus = 0; - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_REDRAW_MAIN_MENU; + sTradeMenu->playerConfirmStatus = STATUS_NONE; + sTradeMenu->partnerConfirmStatus = STATUS_NONE; + sTradeMenu->callbackId = CB_HANDLE_TRADE_CANCELED; } } } @@ -1292,10 +1371,10 @@ static void _SetLinkData(u16 *linkData, u16 linkCmd, u16 cursorPosition) static void SetLinkData(u16 linkCmd, u16 cursorPosition) { - _SetLinkData(sTradeMenuData->linkData, linkCmd, cursorPosition); + _SetLinkData(sTradeMenu->linkData, linkCmd, cursorPosition); } -static void CB1_SendOrReactToLinkTradeData(void) +static void CB1_UpdateLink(void) { u8 mpId = GetMultiplayerId(); u8 status; @@ -1303,25 +1382,25 @@ static void CB1_SendOrReactToLinkTradeData(void) if ((status = _GetBlockReceivedStatus())) { if (mpId == 0) - UpdateLinkTradeFlags(mpId, status); + Leader_ReadLinkBuffer(mpId, status); else - ReactToLinkTradeData(mpId, status); + Follower_ReadLinkBuffer(mpId, status); } if (mpId == 0) - QueueLinkTradeData(); + Leader_HandleCommunication(); } -static u8 GetNewTradeMenuPosition(u8 oldPosition, u8 direction) +static u8 GetNewCursorPosition(u8 oldPosition, u8 direction) { int i; u8 newPosition = 0; for (i = 0; i < PARTY_SIZE; i++) { - if (sTradeMenuData->monPresent[sTradeNextSelectedMonTable[oldPosition][direction][i]] == TRUE) + if (sTradeMenu->optionsActive[sCursorMoveDestinations[oldPosition][direction][i]] == TRUE) { - newPosition = sTradeNextSelectedMonTable[oldPosition][direction][i]; + newPosition = sCursorMoveDestinations[oldPosition][direction][i]; break; } } @@ -1331,157 +1410,151 @@ static u8 GetNewTradeMenuPosition(u8 oldPosition, u8 direction) static void TradeMenuMoveCursor(u8 *cursorPosition, u8 direction) { - u8 newPosition = GetNewTradeMenuPosition(*cursorPosition, direction); + u8 newPosition = GetNewCursorPosition(*cursorPosition, direction); if (newPosition == (PARTY_SIZE * 2)) // CANCEL { - StartSpriteAnim(&gSprites[sTradeMenuData->cursorSpriteId], CURSOR_ANIM_ON_CANCEL); - gSprites[sTradeMenuData->cursorSpriteId].x = DISPLAY_WIDTH - 16; - gSprites[sTradeMenuData->cursorSpriteId].y = DISPLAY_HEIGHT; + StartSpriteAnim(&gSprites[sTradeMenu->cursorSpriteId], CURSOR_ANIM_ON_CANCEL); + gSprites[sTradeMenu->cursorSpriteId].x = DISPLAY_WIDTH - 16; + gSprites[sTradeMenu->cursorSpriteId].y = DISPLAY_HEIGHT; } else { - StartSpriteAnim(&gSprites[sTradeMenuData->cursorSpriteId], CURSOR_ANIM_NORMAL); - gSprites[sTradeMenuData->cursorSpriteId].x = sTradeMonSpriteCoords[newPosition][0] * 8 + 32; - gSprites[sTradeMenuData->cursorSpriteId].y = sTradeMonSpriteCoords[newPosition][1] * 8; + StartSpriteAnim(&gSprites[sTradeMenu->cursorSpriteId], CURSOR_ANIM_NORMAL); + gSprites[sTradeMenu->cursorSpriteId].x = sTradeMonSpriteCoords[newPosition][0] * 8 + 32; + gSprites[sTradeMenu->cursorSpriteId].y = sTradeMonSpriteCoords[newPosition][1] * 8; } if (*cursorPosition != newPosition) - { PlaySE(SE_SELECT); - } *cursorPosition = newPosition; } static void SetReadyToTrade(void) { - PrintTradeMessage(TRADE_MSG_STANDBY); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_STANDBY; + PrintTradeMessage(MSG_STANDBY); + sTradeMenu->callbackId = CB_IDLE; if (GetMultiplayerId() == 1) - SetLinkData(LINKCMD_READY_TO_TRADE, sTradeMenuData->cursorPosition); + { + // Communicate to the link leader that we're ready to trade + SetLinkData(LINKCMD_READY_TO_TRADE, sTradeMenu->cursorPosition); + } else - sTradeMenuData->playerLinkFlagChoseAction = WANTS_TO_TRADE; + { + // We are the link leader, no communication necessary + sTradeMenu->playerSelectStatus = STATUS_READY; + } } -static void TradeMenuProcessInput(void) +static void CB_ProcessMenuInput(void) { if (JOY_REPEAT(DPAD_UP)) - { - TradeMenuMoveCursor(&sTradeMenuData->cursorPosition, 0); - } + TradeMenuMoveCursor(&sTradeMenu->cursorPosition, 0); else if (JOY_REPEAT(DPAD_DOWN)) - { - TradeMenuMoveCursor(&sTradeMenuData->cursorPosition, 1); - } + TradeMenuMoveCursor(&sTradeMenu->cursorPosition, 1); else if (JOY_REPEAT(DPAD_LEFT)) - { - TradeMenuMoveCursor(&sTradeMenuData->cursorPosition, 2); - } + TradeMenuMoveCursor(&sTradeMenu->cursorPosition, 2); else if (JOY_REPEAT(DPAD_RIGHT)) - { - TradeMenuMoveCursor(&sTradeMenuData->cursorPosition, 3); - } + TradeMenuMoveCursor(&sTradeMenu->cursorPosition, 3); if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); - // Cursor is in player's party - if (sTradeMenuData->cursorPosition < PARTY_SIZE) + if (sTradeMenu->cursorPosition < PARTY_SIZE) { + // Selected pokemon in player's party DrawTextBorderOuter(1, 1, 14); FillWindowPixelBuffer(1, PIXEL_FILL(1)); PrintMenuTable(1, ARRAY_COUNT(sSelectTradeMonActions), sSelectTradeMonActions); InitMenuInUpperLeftCornerNormal(1, ARRAY_COUNT(sSelectTradeMonActions), 0); PutWindowTilemap(1); CopyWindowToVram(1, COPYWIN_FULL); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_SELECTED_MON; + sTradeMenu->callbackId = CB_SELECTED_MON; } - // Cursor is in partner's party - else if (sTradeMenuData->cursorPosition < PARTY_SIZE * 2) + else if (sTradeMenu->cursorPosition < PARTY_SIZE * 2) { + // Selected pokemon in partner's party BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_SHOW_MON_SUMMARY; + sTradeMenu->callbackId = CB_SHOW_MON_SUMMARY; } - // Cursor is on Cancel - else if (sTradeMenuData->cursorPosition == PARTY_SIZE * 2) + else if (sTradeMenu->cursorPosition == PARTY_SIZE * 2) { + // Selected Cancel CreateYesNoMenu(&sTradeYesNoWindowTemplate, 1, 14, 0); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_CANCEL_TRADE_PROMPT; - DrawBottomRowText(sTradeActionTexts[TRADE_TEXT_CANCEL_TRADE], (void *)(OBJ_VRAM0 + sTradeMenuData->bottomTextTileStart * 32), 24); + sTradeMenu->callbackId = CB_CANCEL_TRADE_PROMPT; + DrawBottomRowText(sActionTexts[TEXT_CANCEL_TRADE], (void *)(OBJ_VRAM0 + sTradeMenu->bottomTextTileStart * 32), 24); } } } -static void TradeMenuChooseMon(void) +static void RedrawChooseAPokemonWindow(void) { - PrintNicknamesForTradeMenu(); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_MAIN_MENU; - gSprites[sTradeMenuData->cursorSpriteId].invisible = FALSE; - DrawBottomRowText(sTradeActionTexts[TRADE_TEXT_CHOOSE_MON], (void *)(OBJ_VRAM0 + sTradeMenuData->bottomTextTileStart * 32), 24); + PrintTradePartnerPartyNicknames(); + sTradeMenu->callbackId = CB_MAIN_MENU; + gSprites[sTradeMenu->cursorSpriteId].invisible = FALSE; + DrawBottomRowText(sActionTexts[TEXT_CHOOSE_MON], (void *)(OBJ_VRAM0 + sTradeMenu->bottomTextTileStart * 32), 24); } -static void TradeMenuProcessInput_SelectedMon(void) +static void CB_ProcessSelectedMonInput(void) { switch (Menu_ProcessInputNoWrap()) { case MENU_B_PRESSED: PlaySE(SE_SELECT); - TradeMenuChooseMon(); + RedrawChooseAPokemonWindow(); break; case MENU_NOTHING_CHOSEN: break; case 0: // Summary BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_SHOW_MON_SUMMARY; + sTradeMenu->callbackId = CB_SHOW_MON_SUMMARY; break; case 1: // Trade - switch (CanTradeSelectedMon(gPlayerParty, gPlayerPartyCount, sTradeMenuData->cursorPosition)) + switch (CanTradeSelectedMon(gPlayerParty, gPlayerPartyCount, sTradeMenu->cursorPosition)) { case CAN_TRADE_MON: SetReadyToTrade(); - gSprites[sTradeMenuData->cursorSpriteId].invisible = TRUE; + gSprites[sTradeMenu->cursorSpriteId].invisible = TRUE; break; case CANT_TRADE_LAST_MON: QueueAction(QUEUE_DELAY_MSG, QUEUE_ONLY_MON2); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_REDRAW_MAIN_MENU; + sTradeMenu->callbackId = CB_HANDLE_TRADE_CANCELED; break; case CANT_TRADE_NATIONAL: case CANT_TRADE_INVALID_MON: QueueAction(QUEUE_DELAY_MSG, QUEUE_MON_CANT_BE_TRADED); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_REDRAW_MAIN_MENU; + sTradeMenu->callbackId = CB_HANDLE_TRADE_CANCELED; break; case CANT_TRADE_EGG_YET: - case CANT_TRADE_EGG_YET2: + case CANT_TRADE_PARTNER_EGG_YET: QueueAction(QUEUE_DELAY_MSG, QUEUE_EGG_CANT_BE_TRADED); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_REDRAW_MAIN_MENU; + sTradeMenu->callbackId = CB_HANDLE_TRADE_CANCELED; break; } break; } } -static void ChooseMonAfterButtonPress(void) +static void CB_ChooseMonAfterButtonPress(void) { - if ((JOY_NEW(A_BUTTON)) || (JOY_NEW(B_BUTTON))) + if (JOY_NEW(A_BUTTON) || JOY_NEW(B_BUTTON)) { PlaySE(SE_SELECT); - TradeMenuChooseMon(); + RedrawChooseAPokemonWindow(); } } -static void TradeMenuShowMonSummaryScreen(void) +static void CB_ShowTradeMonSummaryScreen(void) { if (!gPaletteFade.active) { - // Player's party - if (sTradeMenuData->cursorPosition < PARTY_SIZE) - ShowPokemonSummaryScreen(SUMMARY_MODE_LOCK_MOVES, gPlayerParty, sTradeMenuData->cursorPosition, sTradeMenuData->partyCounts[TRADE_PLAYER] - 1, CB2_ReturnToTradeMenu); - // Partner's party + if (sTradeMenu->cursorPosition < PARTY_SIZE) + ShowPokemonSummaryScreen(SUMMARY_MODE_LOCK_MOVES, gPlayerParty, sTradeMenu->cursorPosition, sTradeMenu->partyCounts[TRADE_PLAYER] - 1, CB2_ReturnToTradeMenu); else - ShowPokemonSummaryScreen(SUMMARY_MODE_LOCK_MOVES, gEnemyParty, sTradeMenuData->cursorPosition - PARTY_SIZE, sTradeMenuData->partyCounts[TRADE_PARTNER] - 1, CB2_ReturnToTradeMenu); + ShowPokemonSummaryScreen(SUMMARY_MODE_LOCK_MOVES, gEnemyParty, sTradeMenu->cursorPosition - PARTY_SIZE, sTradeMenu->partyCounts[TRADE_PARTNER] - 1, CB2_ReturnToTradeMenu); FreeAllWindowBuffers(); } } @@ -1511,7 +1584,7 @@ static u8 CheckValidityOfTradeMons(u8 *aliveMons, u8 playerPartyCount, u8 player // Partner cant trade Egg or non-Hoenn mon if player doesn't have National Dex if (!IsNationalPokedexEnabled()) { - if (sTradeMenuData->isEgg[TRADE_PARTNER][partnerMonIdx] || !IsSpeciesInHoennDex(partnerSpecies)) + if (sTradeMenu->isEgg[TRADE_PARTNER][partnerMonIdx] || !IsSpeciesInHoennDex(partnerSpecies)) return PARTNER_MON_INVALID; } @@ -1527,14 +1600,12 @@ static bool32 CheckMonsBeforeTrade(void) int i; u8 aliveMons[PARTY_SIZE * 2]; - for (i = 0; i < sTradeMenuData->partyCounts[TRADE_PLAYER]; i++) - { - aliveMons[i] = sTradeMenuData->isLiveMon[TRADE_PLAYER][i]; - } + for (i = 0; i < sTradeMenu->partyCounts[TRADE_PLAYER]; i++) + aliveMons[i] = sTradeMenu->isLiveMon[TRADE_PLAYER][i]; - switch (CheckValidityOfTradeMons(aliveMons, sTradeMenuData->partyCounts[TRADE_PLAYER], - sTradeMenuData->cursorPosition, - sTradeMenuData->partnerCursorPosition)) + switch (CheckValidityOfTradeMons(aliveMons, sTradeMenu->partyCounts[TRADE_PLAYER], + sTradeMenu->cursorPosition, + sTradeMenu->partnerCursorPosition)) { case PLAYER_MON_INVALID: QueueAction(QUEUE_DELAY_MSG, QUEUE_ONLY_MON2); @@ -1552,24 +1623,24 @@ static bool32 CheckMonsBeforeTrade(void) return FALSE; } -static void ConfirmOrCancelTrade(void) +static void CB_ProcessConfirmTradeInput(void) { switch (Menu_ProcessInputNoWrapClearOnChoose()) { - case 0: // Confirm Trade + case 0: // YES, Confirm selection if (!CheckMonsBeforeTrade()) - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_STANDBY; + sTradeMenu->callbackId = CB_IDLE; else - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_PARTNER_MON_INVALID; + sTradeMenu->callbackId = CB_PARTNER_MON_INVALID; PutWindowTilemap(17); break; - case 1: // Cancel Trade + case 1: // NO, Cancel Trade case MENU_B_PRESSED: QueueAction(QUEUE_DELAY_MSG, QUEUE_STANDBY); if (IsLinkTradeTaskFinished()) SetLinkData(LINKCMD_READY_CANCEL_TRADE, 0); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_STANDBY; + sTradeMenu->callbackId = CB_IDLE; PutWindowTilemap(17); break; } @@ -1580,66 +1651,65 @@ static void RestoreNicknamesCoveredByYesNo(void) { int i; - for (i = 0; i < sTradeMenuData->partyCounts[1] - 4; i++) + for (i = 0; i < sTradeMenu->partyCounts[1] - 4; i++) { - PutWindowTilemap(i + 12); - CopyWindowToVram(i + 12, COPYWIN_MAP); + PutWindowTilemap(i + PARTY_SIZE * 2); + CopyWindowToVram(i + PARTY_SIZE * 2, COPYWIN_MAP); } } -static void CancelTradeYesNo(void) +static void CB_ProcessCancelTradeInput(void) { switch (Menu_ProcessInputNoWrapClearOnChoose()) { case 0: // YES, Cancel - PrintTradeMessage(TRADE_MSG_WAITING_FOR_FRIEND); + PrintTradeMessage(MSG_WAITING_FOR_FRIEND); SetLinkData(LINKCMD_REQUEST_CANCEL, 0); - gSprites[sTradeMenuData->cursorSpriteId].invisible = TRUE; - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_STANDBY; + gSprites[sTradeMenu->cursorSpriteId].invisible = TRUE; + sTradeMenu->callbackId = CB_IDLE; RestoreNicknamesCoveredByYesNo(); break; case 1: // NO, Continue case MENU_B_PRESSED: PlaySE(SE_SELECT); - TradeMenuChooseMon(); + RedrawChooseAPokemonWindow(); break; } } -static void SetBothSelectedMons(void) +static void CB_SetSelectedMons(void) { if (GetMultiplayerId() == 0) { rbox_fill_rectangle(0); - SetSelectedMon(sTradeMenuData->cursorPosition); - SetSelectedMon(sTradeMenuData->partnerCursorPosition); + SetSelectedMon(sTradeMenu->cursorPosition); + SetSelectedMon(sTradeMenu->partnerCursorPosition); } - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_CONFIRM_TRADE_PROMPT; + sTradeMenu->callbackId = CB_PRINT_IS_THIS_OKAY; } -static void ConfirmTradePrompt(void) +static void CB_PrintIsThisTradeOkay(void) { - if (sTradeMenuData->drawPartyState[TRADE_PLAYER] == DRAW_PARTY_FINISH - && sTradeMenuData->drawPartyState[TRADE_PARTNER] == DRAW_PARTY_FINISH) + if (sTradeMenu->drawSelectedMonState[TRADE_PLAYER] == DRAW_SELECTED_FINISH + && sTradeMenu->drawSelectedMonState[TRADE_PARTNER] == DRAW_SELECTED_FINISH) { - DrawIsThisTradeOkay(); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_DELAY_TRADE_CONFIRM; + PrintIsThisTradeOkay(); + sTradeMenu->callbackId = CB_INIT_CONFIRM_TRADE_PROMPT; } } -static void DelayTradeConfirmation(void) +static void CB_InitConfirmTradePrompt(void) { - sTradeMenuData->timer++; - - if (sTradeMenuData->timer > 120) + sTradeMenu->timer++; + if (sTradeMenu->timer > 120) { CreateYesNoMenu(&sTradeYesNoWindowTemplate, 1, 14, 0); - sTradeMenuData->timer = 0; - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_CONFIRM_OR_CANCEL_TRADE; + sTradeMenu->timer = 0; + sTradeMenu->callbackId = CB_CONFIRM_TRADE_PROMPT; } } -static void RedrawTradeMenuAfterPressA(void) +static void CB_HandleTradeCanceled(void) { int i; @@ -1655,38 +1725,34 @@ static void RedrawTradeMenuAfterPressA(void) rbox_fill_rectangle(i + 14); } - RedrawTradeMenuParty(TRADE_PLAYER); - RedrawTradeMenuParty(TRADE_PARTNER); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_MAIN_MENU; - gSprites[sTradeMenuData->cursorSpriteId].invisible = FALSE; + RedrawPartyWindow(TRADE_PLAYER); + RedrawPartyWindow(TRADE_PARTNER); + sTradeMenu->callbackId = CB_MAIN_MENU; + gSprites[sTradeMenu->cursorSpriteId].invisible = FALSE; } } -static void CancelTrade_1(void) +static void CB_InitExitCanceledTrade(void) { if (!gPaletteFade.active) { if (gWirelessCommType) - { SetLinkStandbyCallback(); - } else - { SetCloseLinkCallbackAndType(12); - } - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_CANCEL_TRADE_2; + sTradeMenu->callbackId = CB_EXIT_CANCELED_TRADE; } } -static void CancelTrade_2(void) +static void CB_ExitCanceledTrade(void) { if (gWirelessCommType) { if (IsLinkTradeTaskFinished() && GetNumQueuedActions() == 0) { - Free(sMenuTextAllocBuffer); - Free(sTradeMenuData); + Free(sMenuTextTileBuffer); + Free(sTradeMenu); FreeAllWindowBuffers(); DestroyWirelessStatusIndicatorSprite(); SetMainCallback2(CB2_ReturnToFieldFromMultiplayer); @@ -1696,88 +1762,88 @@ static void CancelTrade_2(void) { if (!gReceivedRemoteLinkPlayers) { - Free(sMenuTextAllocBuffer); - Free(sTradeMenuData); + Free(sMenuTextTileBuffer); + Free(sTradeMenu); FreeAllWindowBuffers(); SetMainCallback2(CB2_ReturnToFieldFromMultiplayer); } } } -static void LinkTradeWaitForQueue(void) +static void CB_WaitToStartRfuTrade(void) { if (!Rfu_SetLinkRecovery(FALSE) && GetNumQueuedActions() == 0) { SetLinkStandbyCallback(); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_START_LINK_TRADE; + sTradeMenu->callbackId = CB_START_LINK_TRADE; } } -static void PartnersMonWasInvalid(void) +static void CB_PartnersMonWasInvalid(void) { if (JOY_NEW(A_BUTTON)) { SetLinkData(LINKCMD_READY_CANCEL_TRADE, 0); - sTradeMenuData->tradeMenuFunc = TRADEMENUFUNC_STANDBY; + sTradeMenu->callbackId = CB_IDLE; } } -static void CallTradeMenuFunc(void) +static void RunTradeMenuCallback(void) { - switch (sTradeMenuData->tradeMenuFunc) + switch (sTradeMenu->callbackId) { - case TRADEMENUFUNC_MAIN_MENU: - TradeMenuProcessInput(); + case CB_MAIN_MENU: + CB_ProcessMenuInput(); break; - case TRADEMENUFUNC_SELECTED_MON: - TradeMenuProcessInput_SelectedMon(); + case CB_SELECTED_MON: + CB_ProcessSelectedMonInput(); break; - case TRADEMENUFUNC_SHOW_MON_SUMMARY: - TradeMenuShowMonSummaryScreen(); + case CB_SHOW_MON_SUMMARY: + CB_ShowTradeMonSummaryScreen(); break; - case TRADEMENUFUNC_CONFIRM_OR_CANCEL_TRADE: - ConfirmOrCancelTrade(); + case CB_CONFIRM_TRADE_PROMPT: + CB_ProcessConfirmTradeInput(); break; - case TRADEMENUFUNC_CANCEL_TRADE_PROMPT: - CancelTradeYesNo(); + case CB_CANCEL_TRADE_PROMPT: + CB_ProcessCancelTradeInput(); break; - case TRADEMENUFUNC_BOTH_MONS_SELECTED: - SetBothSelectedMons(); + case CB_SET_SELECTED_MONS: + CB_SetSelectedMons(); break; - case TRADEMENUFUNC_CONFIRM_TRADE_PROMPT: - ConfirmTradePrompt(); + case CB_PRINT_IS_THIS_OKAY: + CB_PrintIsThisTradeOkay(); break; - case TRADEMENUFUNC_REDRAW_MAIN_MENU: - RedrawTradeMenuAfterPressA(); + case CB_HANDLE_TRADE_CANCELED: + CB_HandleTradeCanceled(); break; - case TRADEMENUFUNC_LINK_TRADE_FADE_OUT: - LinkTradeFadeOut(); + case CB_FADE_TO_START_TRADE: + CB_FadeToStartTrade(); break; - case TRADEMENUFUNC_LINK_TRADE_WAIT_FADE: - LinkTradeWaitForFade(); + case CB_WAIT_TO_START_TRADE: + CB_WaitToStartTrade(); break; - case TRADEMENUFUNC_CANCEL_TRADE_1: - CancelTrade_1(); + case CB_INIT_EXIT_CANCELED_TRADE: + CB_InitExitCanceledTrade(); break; - case TRADEMENUFUNC_CANCEL_TRADE_2: - CancelTrade_2(); + case CB_EXIT_CANCELED_TRADE: + CB_ExitCanceledTrade(); break; - case TRADEMENUFUNC_START_LINK_TRADE: - SetLinkTradeCallbacks(); + case CB_START_LINK_TRADE: + CB_StartLinkTrade(); break; - case TRADEMENUFUNC_DELAY_TRADE_CONFIRM: - DelayTradeConfirmation(); + case CB_INIT_CONFIRM_TRADE_PROMPT: + CB_InitConfirmTradePrompt(); break; - case TRADEMENUFUNC_UNUSED_15: - ChooseMonAfterButtonPress(); + case CB_UNUSED_CLOSE_MSG: + CB_ChooseMonAfterButtonPress(); break; - case TRADEMENUFUNC_LINK_TRADE_WAIT_QUEUE: - LinkTradeWaitForQueue(); + case CB_WAIT_TO_START_RFU_TRADE: + CB_WaitToStartRfuTrade(); break; - case TRADEMENUFUNC_PARTNER_MON_INVALID: - PartnersMonWasInvalid(); + case CB_PARTNER_MON_INVALID: + CB_PartnersMonWasInvalid(); break; - //case TRADEMENUFUNC_STANDBY: is nop + //case CB_IDLE: is nop } } @@ -1786,14 +1852,16 @@ static void SetSelectedMon(u8 cursorPosition) //cursorPosition 0-5 are the player's mons, 6-11 are the partner's u8 whichParty = cursorPosition / PARTY_SIZE; - if (sTradeMenuData->drawPartyState[whichParty] == 0) + if (sTradeMenu->drawSelectedMonState[whichParty] == 0) { - sTradeMenuData->drawPartyState[whichParty] = 1; - sTradeMenuData->selectedMonIdx[whichParty] = cursorPosition; + // Start the animation to display just the selected + // pokemon in the middle of the screen + sTradeMenu->drawSelectedMonState[whichParty] = 1; + sTradeMenu->selectedMonIdx[whichParty] = cursorPosition; } } -static void DrawTradeMenuParty(u8 whichParty) +static void DrawSelectedMonScreen(u8 whichParty) { s8 nameStringWidth; u8 nickname[20]; @@ -1801,105 +1869,111 @@ static void DrawTradeMenuParty(u8 whichParty) u8 i; u8 partyIdx; u8 selectedMonParty; - u8 selectedMonIdx = sTradeMenuData->selectedMonIdx[whichParty]; + u8 selectedMonIdx = sTradeMenu->selectedMonIdx[whichParty]; selectedMonParty = TRADE_PARTNER; - if (sTradeMenuData->selectedMonIdx[whichParty] < PARTY_SIZE) + if (sTradeMenu->selectedMonIdx[whichParty] < PARTY_SIZE) selectedMonParty = TRADE_PLAYER; partyIdx = selectedMonIdx % PARTY_SIZE; nameStringWidth = 0; - switch (sTradeMenuData->drawPartyState[whichParty]) + switch (sTradeMenu->drawSelectedMonState[whichParty]) { + default: + // Idle while state is 0, and once it reaches the final state (DRAW_SELECTED_FINISH) + break; case 1: - for (i = 0; i < sTradeMenuData->partyCounts[whichParty]; i++) - { - gSprites[sTradeMenuData->partySpriteIds[0][i + (selectedMonParty * PARTY_SIZE)]].invisible = TRUE; - } - - for (i = 0; i < 6; i++) - { + // Erase the rest of the party + for (i = 0; i < sTradeMenu->partyCounts[whichParty]; i++) + gSprites[sTradeMenu->partySpriteIds[selectedMonParty][i]].invisible = TRUE; + for (i = 0; i < PARTY_SIZE; i++) ClearWindowTilemap(i + (whichParty * PARTY_SIZE + 2)); - } - gSprites[sTradeMenuData->partySpriteIds[0][partyIdx + (selectedMonParty * PARTY_SIZE)]].invisible = FALSE; - gSprites[sTradeMenuData->partySpriteIds[0][partyIdx + (selectedMonParty * PARTY_SIZE)]].data[0] = 20; - gSprites[sTradeMenuData->partySpriteIds[0][partyIdx + (selectedMonParty * PARTY_SIZE)]].data[2] = (sTradeMonSpriteCoords[selectedMonParty * PARTY_SIZE][0] - + sTradeMonSpriteCoords[selectedMonParty * PARTY_SIZE + 1][0]) / 2 * 8 + 14; - gSprites[sTradeMenuData->partySpriteIds[0][partyIdx + (selectedMonParty * PARTY_SIZE)]].data[4] = (sTradeMonSpriteCoords[selectedMonParty * PARTY_SIZE][1] * 8) - 12; - StoreSpriteCallbackInData6(&gSprites[sTradeMenuData->partySpriteIds[0][partyIdx + (selectedMonParty * PARTY_SIZE)]], SpriteCB_MonIcon); - sTradeMenuData->drawPartyState[whichParty]++; - TradeMenuBouncePartySprites(&gSprites[sTradeMenuData->partySpriteIds[0][partyIdx + (selectedMonParty * PARTY_SIZE)]]); + // Re-display the selected pokemon + gSprites[sTradeMenu->partySpriteIds[selectedMonParty][partyIdx]].invisible = FALSE; + + // Move the selected pokemon to the center + gSprites[sTradeMenu->partySpriteIds[selectedMonParty][partyIdx]].data[0] = 20; + gSprites[sTradeMenu->partySpriteIds[selectedMonParty][partyIdx]].data[2] = (sTradeMonSpriteCoords[selectedMonParty * PARTY_SIZE][0] + + sTradeMonSpriteCoords[selectedMonParty * PARTY_SIZE + 1][0]) / 2 * 8 + 14; + gSprites[sTradeMenu->partySpriteIds[selectedMonParty][partyIdx]].data[4] = (sTradeMonSpriteCoords[selectedMonParty * PARTY_SIZE][1] * 8) - 12; + StoreSpriteCallbackInData6(&gSprites[sTradeMenu->partySpriteIds[selectedMonParty][partyIdx]], SpriteCB_MonIcon); + sTradeMenu->drawSelectedMonState[whichParty]++; + Trade_MoveSelectedMonToTarget(&gSprites[sTradeMenu->partySpriteIds[selectedMonParty][partyIdx]]); + CopyToBgTilemapBufferRect_ChangePalette(1, sTradePartyBoxTilemap, whichParty * 15, 0, 15, 17, 0); CopyBgTilemapBufferToVram(1); CopyBgTilemapBufferToVram(0); if (selectedMonParty == TRADE_PLAYER) - PrintNicknamesForTradeMenu(); + PrintTradePartnerPartyNicknames(); break; case 2: - if (gSprites[sTradeMenuData->partySpriteIds[0][partyIdx + (selectedMonParty * PARTY_SIZE)]].callback == SpriteCB_MonIcon) - sTradeMenuData->drawPartyState[whichParty] = 3; + // Wait for the selected pokemon's sprite to move to the correct position + if (gSprites[sTradeMenu->partySpriteIds[selectedMonParty][partyIdx]].callback == SpriteCB_MonIcon) + sTradeMenu->drawSelectedMonState[whichParty] = 3; break; case 3: + // Redisplay the bg box CopyToBgTilemapBufferRect_ChangePalette(1, sTradeMovesBoxTilemap, selectedMonParty * 15, 0, 15, 17, 0); CopyBgTilemapBufferToVram(1); - gSprites[sTradeMenuData->partySpriteIds[0][partyIdx + (selectedMonParty * PARTY_SIZE)]].x = (sTradeMonSpriteCoords[selectedMonParty * PARTY_SIZE][0] - + sTradeMonSpriteCoords[selectedMonParty * PARTY_SIZE + 1][0]) / 2 * 8 + 14; - gSprites[sTradeMenuData->partySpriteIds[0][partyIdx + (selectedMonParty * PARTY_SIZE)]].y = (sTradeMonSpriteCoords[selectedMonParty * PARTY_SIZE][1] * 8) - 12; - gSprites[sTradeMenuData->partySpriteIds[0][partyIdx + (selectedMonParty * PARTY_SIZE)]].x2 = 0; - gSprites[sTradeMenuData->partySpriteIds[0][partyIdx + (selectedMonParty * PARTY_SIZE)]].y2 = 0; + + // Finalize the selected pokemon's position + gSprites[sTradeMenu->partySpriteIds[selectedMonParty][partyIdx]].x = (sTradeMonSpriteCoords[selectedMonParty * PARTY_SIZE][0] + + sTradeMonSpriteCoords[selectedMonParty * PARTY_SIZE + 1][0]) / 2 * 8 + 14; + gSprites[sTradeMenu->partySpriteIds[selectedMonParty][partyIdx]].y = (sTradeMonSpriteCoords[selectedMonParty * PARTY_SIZE][1] * 8) - 12; + gSprites[sTradeMenu->partySpriteIds[selectedMonParty][partyIdx]].x2 = 0; + gSprites[sTradeMenu->partySpriteIds[selectedMonParty][partyIdx]].y2 = 0; + + // Print selected pokemon's name and moves nameStringWidth = GetMonNicknameWidth(nickname, selectedMonParty, partyIdx); AddTextPrinterParameterized3((whichParty * 2) + 14, FONT_SMALL, (80 - nameStringWidth) / 2, 4, sTradeTextColors, 0, nickname); - BufferTradeMonMoves(movesString, selectedMonParty, partyIdx); + BufferMovesString(movesString, selectedMonParty, partyIdx); AddTextPrinterParameterized4((whichParty * 2) + 15, FONT_NORMAL, 0, 0, 0, 0, sTradeTextColors, 0, movesString); PutWindowTilemap((whichParty * 2) + 14); CopyWindowToVram((whichParty * 2) + 14, COPYWIN_FULL); PutWindowTilemap((whichParty * 2) + 15); CopyWindowToVram((whichParty * 2) + 15, COPYWIN_FULL); - sTradeMenuData->drawPartyState[whichParty]++; + + sTradeMenu->drawSelectedMonState[whichParty]++; break; case 4: - DrawTradeMenuPartyMonInfo(whichParty, partyIdx, - sTradeMenuPartyMonBoxDimensions[whichParty][0] + 4, - sTradeMenuPartyMonBoxDimensions[whichParty][1] + 1, - sTradeMenuPartyMonBoxDimensions[whichParty][0], - sTradeMenuPartyMonBoxDimensions[whichParty][1]); - sTradeMenuData->drawPartyState[whichParty]++; + PrintLevelAndGender(whichParty, partyIdx, + sSelectedMonLevelGenderCoords[whichParty][0] + 4, + sSelectedMonLevelGenderCoords[whichParty][1] + 1, + sSelectedMonLevelGenderCoords[whichParty][0], + sSelectedMonLevelGenderCoords[whichParty][1]); + sTradeMenu->drawSelectedMonState[whichParty]++; break; } } -static u8 GetMonNicknameWidth(u8 *str, u8 whichParty, u8 monIdx) +static u8 GetMonNicknameWidth(u8 *str, u8 whichParty, u8 partyIdx) { - u8 nickname[12]; + u8 nickname[POKEMON_NAME_LENGTH]; if (whichParty == TRADE_PLAYER) - GetMonData(&gPlayerParty[monIdx], MON_DATA_NICKNAME, nickname); + GetMonData(&gPlayerParty[partyIdx], MON_DATA_NICKNAME, nickname); else - GetMonData(&gEnemyParty[monIdx], MON_DATA_NICKNAME, nickname); + GetMonData(&gEnemyParty[partyIdx], MON_DATA_NICKNAME, nickname); StringCopy_Nickname(str, nickname); return GetStringWidth(FONT_SMALL, str, GetFontAttribute(FONT_SMALL, FONTATTR_LETTER_SPACING)); } -static void BufferTradeMonMoves(u8 *str, u8 whichParty, u8 partyIdx) +static void BufferMovesString(u8 *str, u8 whichParty, u8 partyIdx) { u16 moves[MAX_MON_MOVES]; u16 i; - if (!sTradeMenuData->isEgg[whichParty][partyIdx]) + if (!sTradeMenu->isEgg[whichParty][partyIdx]) { for (i = 0; i < MAX_MON_MOVES; i++) { if (whichParty == TRADE_PLAYER) - { moves[i] = GetMonData(&gPlayerParty[partyIdx], i + MON_DATA_MOVE1, NULL); - } else - { moves[i] = GetMonData(&gEnemyParty[partyIdx], i + MON_DATA_MOVE1, NULL); - } } StringCopy(str, sText_EmptyString); @@ -1907,9 +1981,7 @@ static void BufferTradeMonMoves(u8 *str, u8 whichParty, u8 partyIdx) for (i = 0; i < MAX_MON_MOVES; i++) { if (moves[i] != MOVE_NONE) - { StringAppend(str, gMoveNames[moves[i]]); - } StringAppend(str, sText_NewLine); } @@ -1921,7 +1993,7 @@ static void BufferTradeMonMoves(u8 *str, u8 whichParty, u8 partyIdx) } } -static void PrintMonNicknameForTradeMenu(u8 whichParty, u8 windowId, u8 *nickname) +static void PrintPartyMonNickname(u8 whichParty, u8 windowId, u8 *nickname) { u8 xPos; windowId += (whichParty * PARTY_SIZE) + 2; @@ -1931,27 +2003,27 @@ static void PrintMonNicknameForTradeMenu(u8 whichParty, u8 windowId, u8 *nicknam CopyWindowToVram(windowId, COPYWIN_FULL); } -static void PrintPartyNicknamesForTradeMenu(u8 whichParty) +static void PrintPartyNicknames(u8 whichParty) { u8 i; u8 nickname[20]; u8 str[32]; struct Pokemon *party = (whichParty == TRADE_PLAYER) ? gPlayerParty : gEnemyParty; - for (i = 0; i < sTradeMenuData->partyCounts[whichParty]; i++) + for (i = 0; i < sTradeMenu->partyCounts[whichParty]; i++) { GetMonData(&party[i], MON_DATA_NICKNAME, nickname); StringCopy_Nickname(str, nickname); - PrintMonNicknameForTradeMenu(whichParty, i, str); + PrintPartyMonNickname(whichParty, i, str); } } -static void DrawTradeMenuPartyMonInfo(u8 whichParty, u8 monIdx, u8 x, u8 y, u8 width, u8 height) +static void PrintLevelAndGender(u8 whichParty, u8 monIdx, u8 x, u8 y, u8 width, u8 height) { u8 level; u32 symbolTile; u8 gender; - u8 nickname[12]; + u8 nickname[POKEMON_NAME_LENGTH]; CopyToBgTilemapBufferRect_ChangePalette(1, gTradeMenuMonBox_Tilemap, width, height, 6, 3, 0); CopyBgTilemapBufferToVram(1); @@ -1961,20 +2033,20 @@ static void DrawTradeMenuPartyMonInfo(u8 whichParty, u8 monIdx, u8 x, u8 y, u8 w else level = GetMonData(&gEnemyParty[monIdx], MON_DATA_LEVEL, NULL); - if (!sTradeMenuData->isEgg[whichParty][monIdx]) + if (!sTradeMenu->isEgg[whichParty][monIdx]) { if (level / 10 != 0) - sTradeMenuData->tilemapBuffer[x + (y * 32)] = (level / 10) + 0x60; + sTradeMenu->tilemapBuffer[x + (y * 32)] = (level / 10) + 0x60; - sTradeMenuData->tilemapBuffer[x + (y * 32) + 1] = (level % 10) + 0x70; + sTradeMenu->tilemapBuffer[x + (y * 32) + 1] = (level % 10) + 0x70; } else { - sTradeMenuData->tilemapBuffer[x + (y * 32) - 32] = sTradeMenuData->tilemapBuffer[x + (y * 32) - 33]; - sTradeMenuData->tilemapBuffer[x + (y * 32) - 31] = sTradeMenuData->tilemapBuffer[x + (y * 32) - 36] | 0x400; + sTradeMenu->tilemapBuffer[x + (y * 32) - 32] = sTradeMenu->tilemapBuffer[x + (y * 32) - 33]; + sTradeMenu->tilemapBuffer[x + (y * 32) - 31] = sTradeMenu->tilemapBuffer[x + (y * 32) - 36] | 0x400; } - if (sTradeMenuData->isEgg[whichParty][monIdx]) + if (sTradeMenu->isEgg[whichParty][monIdx]) { symbolTile = 0x480; } @@ -2004,62 +2076,57 @@ static void DrawTradeMenuPartyMonInfo(u8 whichParty, u8 monIdx, u8 x, u8 y, u8 w break; } } - sTradeMenuData->tilemapBuffer[(y - 1) * 32 + x + 1] = symbolTile; + sTradeMenu->tilemapBuffer[(y - 1) * 32 + x + 1] = symbolTile; } -static void DrawTradeMenuPartyInfo(u8 whichParty) +static void PrintPartyLevelsAndGenders(u8 whichParty) { s32 i; - for (i = 0; i < sTradeMenuData->partyCounts[whichParty]; i++) + for (i = 0; i < sTradeMenu->partyCounts[whichParty]; i++) { - const u8 (*r5)[2]; - const u8 (*r4)[2]; - u32 r0 = 3 * whichParty; - const u8 (*r1)[2][2] = sTradeMonLevelCoords; - - r5 = r1[r0]; - r4 = sTradeMonBoxCoords[r0]; - DrawTradeMenuPartyMonInfo( + s32 j = i + PARTY_SIZE * whichParty; + PrintLevelAndGender( whichParty, i, - r5[i][0], - r5[i][1], - r4[i][0], - r4[i][1] + sTradeMonLevelCoords[j][0], + sTradeMonLevelCoords[j][1], + sTradeMonBoxCoords[j][0], + sTradeMonBoxCoords[j][1] ); } } -static void ResetTradeMenuPartyPositions(u8 whichParty) +static void ShowTradePartyMonIcons(u8 whichParty) { int i; - for (i = 0; i < sTradeMenuData->partyCounts[whichParty]; i++) + for (i = 0; i < sTradeMenu->partyCounts[whichParty]; i++) { - gSprites[sTradeMenuData->partySpriteIds[whichParty][i]].invisible = FALSE; - gSprites[sTradeMenuData->partySpriteIds[whichParty][i]].x = sTradeMonSpriteCoords[(whichParty * PARTY_SIZE) + i][0] * 8 + 14; - gSprites[sTradeMenuData->partySpriteIds[whichParty][i]].y = sTradeMonSpriteCoords[(whichParty * PARTY_SIZE) + i][1] * 8 - 12; - gSprites[sTradeMenuData->partySpriteIds[whichParty][i]].x2 = 0; - gSprites[sTradeMenuData->partySpriteIds[whichParty][i]].y2 = 0; + gSprites[sTradeMenu->partySpriteIds[whichParty][i]].invisible = FALSE; + gSprites[sTradeMenu->partySpriteIds[whichParty][i]].x = sTradeMonSpriteCoords[(whichParty * PARTY_SIZE) + i][0] * 8 + 14; + gSprites[sTradeMenu->partySpriteIds[whichParty][i]].y = sTradeMonSpriteCoords[(whichParty * PARTY_SIZE) + i][1] * 8 - 12; + gSprites[sTradeMenu->partySpriteIds[whichParty][i]].x2 = 0; + gSprites[sTradeMenu->partySpriteIds[whichParty][i]].y2 = 0; } } -static void PrintNicknamesForTradeMenu(void) +static void PrintTradePartnerPartyNicknames(void) { rbox_fill_rectangle(1); - //PrintPartyNicknamesForTradeMenu(TRADE_PLAYER); ? - PrintPartyNicknamesForTradeMenu(TRADE_PARTNER); + //PrintPartyNicknames(TRADE_PLAYER); ? + PrintPartyNicknames(TRADE_PARTNER); } -static void RedrawTradeMenuParty(u8 whichParty) +// Returning to the party selection screen from the "is this trade ok?" screen +static void RedrawPartyWindow(u8 whichParty) { CopyToBgTilemapBufferRect_ChangePalette(1, sTradePartyBoxTilemap, whichParty * 15, 0, 15, 17, 0); CopyBgTilemapBufferToVram(1); - DrawTradeMenuPartyInfo(whichParty); - PrintPartyNicknamesForTradeMenu(whichParty); - ResetTradeMenuPartyPositions(whichParty); - DrawBottomRowText(sTradeActionTexts[TRADE_TEXT_CHOOSE_MON], (void *)(OBJ_VRAM0 + (sTradeMenuData->bottomTextTileStart * 32)), 24); - sTradeMenuData->drawPartyState[whichParty] = 0; + PrintPartyLevelsAndGenders(whichParty); + PrintPartyNicknames(whichParty); + ShowTradePartyMonIcons(whichParty); + DrawBottomRowText(sActionTexts[TEXT_CHOOSE_MON], (void *)(OBJ_VRAM0 + (sTradeMenu->bottomTextTileStart * 32)), 24); + sTradeMenu->drawSelectedMonState[whichParty] = 0; } static void Task_DrawSelectionSummary(u8 taskId) @@ -2078,13 +2145,14 @@ static void QueueAction(u16 delay, u8 actionId) { int i; - for (i = 0; i < (int)ARRAY_COUNT(sTradeMenuData->queuedActions); i++) + for (i = 0; i < (int)ARRAY_COUNT(sTradeMenu->queuedActions); i++) { - if (!sTradeMenuData->queuedActions[i].queued) + // Find first available spot + if (!sTradeMenu->queuedActions[i].active) { - sTradeMenuData->queuedActions[i].queueDelay = delay; - sTradeMenuData->queuedActions[i].actionId = actionId; - sTradeMenuData->queuedActions[i].queued = TRUE; + sTradeMenu->queuedActions[i].delay = delay; + sTradeMenu->queuedActions[i].actionId = actionId; + sTradeMenu->queuedActions[i].active = TRUE; break; } } @@ -2095,9 +2163,9 @@ static u32 GetNumQueuedActions(void) u32 numActions = 0; int i; - for (i = 0; i < (int)ARRAY_COUNT(sTradeMenuData->queuedActions); i++) + for (i = 0; i < (int)ARRAY_COUNT(sTradeMenu->queuedActions); i++) { - numActions += sTradeMenuData->queuedActions[i].queued; + numActions += sTradeMenu->queuedActions[i].active; } return numActions; @@ -2107,43 +2175,43 @@ static void DoQueuedActions(void) { int i; - for (i = 0; i < (int)ARRAY_COUNT(sTradeMenuData->queuedActions); i++) + for (i = 0; i < (int)ARRAY_COUNT(sTradeMenu->queuedActions); i++) { - if (sTradeMenuData->queuedActions[i].queued) + if (sTradeMenu->queuedActions[i].active) { - if (sTradeMenuData->queuedActions[i].queueDelay) + if (sTradeMenu->queuedActions[i].delay != 0) { - sTradeMenuData->queuedActions[i].queueDelay--; + sTradeMenu->queuedActions[i].delay--; } else { - switch (sTradeMenuData->queuedActions[i].actionId) + switch (sTradeMenu->queuedActions[i].actionId) { case QUEUE_SEND_DATA: - SendLinkData(sTradeMenuData->linkData, 20); + SendLinkData(sTradeMenu->linkData, 20); break; case QUEUE_STANDBY: - PrintTradeMessage(TRADE_MSG_STANDBY); + PrintTradeMessage(MSG_STANDBY); break; case QUEUE_ONLY_MON1: - PrintTradeMessage(TRADE_MSG_ONLY_MON1); + PrintTradeMessage(MSG_ONLY_MON1); break; case QUEUE_ONLY_MON2: case QUEUE_UNUSED1: case QUEUE_UNUSED2: - PrintTradeMessage(TRADE_MSG_ONLY_MON2); + PrintTradeMessage(MSG_ONLY_MON2); break; case QUEUE_MON_CANT_BE_TRADED: - PrintTradeMessage(TRADE_MSG_MON_CANT_BE_TRADED); + PrintTradeMessage(MSG_MON_CANT_BE_TRADED); break; case QUEUE_EGG_CANT_BE_TRADED: - PrintTradeMessage(TRADE_MSG_EGG_CANT_BE_TRADED); + PrintTradeMessage(MSG_EGG_CANT_BE_TRADED); break; case QUEUE_FRIENDS_MON_CANT_BE_TRADED: - PrintTradeMessage(TRADE_MSG_FRIENDS_MON_CANT_BE_TRADED); + PrintTradeMessage(MSG_FRIENDS_MON_CANT_BE_TRADED); break; } - sTradeMenuData->queuedActions[i].queued = FALSE; + sTradeMenu->queuedActions[i].active = FALSE; } } } @@ -2152,24 +2220,24 @@ static void DoQueuedActions(void) static void PrintTradeMessage(u8 messageId) { FillWindowPixelBuffer(0, PIXEL_FILL(1)); - AddTextPrinterParameterized(0, FONT_NORMAL, sTradeMessages[messageId], 0, 1, TEXT_SKIP_DRAW, NULL); + AddTextPrinterParameterized(0, FONT_NORMAL, sMessages[messageId], 0, 1, TEXT_SKIP_DRAW, NULL); DrawTextBorderOuter(0, 20, 12); PutWindowTilemap(0); CopyWindowToVram(0, COPYWIN_FULL); } -static bool8 LoadTradeMenuSpriteSheetsAndPalettes(void) +static bool8 LoadUISpriteGfx(void) { struct SpriteSheet sheet; - if (sTradeMenuData->timer < GFXTAG_MENU_TEXT_COUNT) + if (sTradeMenu->timer < NUM_MENU_TEXT_SPRITES) { - sheet.data = sMenuTextTileBuffers[sTradeMenuData->timer]; + sheet.data = sMenuTextTileBuffers[sTradeMenu->timer]; sheet.size = 0x100; - sheet.tag = GFXTAG_MENU_TEXT + sTradeMenuData->timer; + sheet.tag = GFXTAG_MENU_TEXT + sTradeMenu->timer; } - switch (sTradeMenuData->timer) + switch (sTradeMenu->timer) { case GFXTAG_PLAYER_NAME_L: case GFXTAG_PLAYER_NAME_M: @@ -2180,11 +2248,11 @@ static bool8 LoadTradeMenuSpriteSheetsAndPalettes(void) case GFXTAG_CANCEL_L: case GFXTAG_CANCEL_R: LoadSpriteSheet(&sheet); - sTradeMenuData->timer++; + sTradeMenu->timer++; break; case GFXTAG_CHOOSE_PKMN_L: - sTradeMenuData->bottomTextTileStart = LoadSpriteSheet(&sheet); - sTradeMenuData->timer++; + sTradeMenu->bottomTextTileStart = LoadSpriteSheet(&sheet); + sTradeMenu->timer++; break; case GFXTAG_CHOOSE_PKMN_M: case GFXTAG_CHOOSE_PKMN_R: @@ -2192,22 +2260,22 @@ static bool8 LoadTradeMenuSpriteSheetsAndPalettes(void) case GFXTAG_CHOOSE_PKMN_EMPTY_2: case GFXTAG_CHOOSE_PKMN_EMPTY_3: LoadSpriteSheet(&sheet); - sTradeMenuData->timer++; + sTradeMenu->timer++; break; - case GFXTAG_MENU_TEXT_COUNT: - LoadSpritePalette(&sSpritePalette_TradeScreenText); - sTradeMenuData->timer++; + case NUM_MENU_TEXT_SPRITES: + LoadSpritePalette(&sSpritePalette_MenuText); + sTradeMenu->timer++; break; - case GFXTAG_MENU_TEXT_COUNT + 1: + case NUM_MENU_TEXT_SPRITES + 1: LoadSpritePalette(&sCursor_SpritePalette); - sTradeMenuData->timer++; + sTradeMenu->timer++; break; - case GFXTAG_MENU_TEXT_COUNT + 2: + case NUM_MENU_TEXT_SPRITES + 2: LoadSpriteSheet(&sCursor_SpriteSheet); - sTradeMenuData->timer++; + sTradeMenu->timer++; break; - case GFXTAG_MENU_TEXT_COUNT + 3: - sTradeMenuData->timer = 0; + case NUM_MENU_TEXT_SPRITES + 3: + sTradeMenu->timer = 0; return TRUE; } @@ -2219,75 +2287,75 @@ static void DrawBottomRowText(const u8 *str, u8 *dest, u8 unused) DrawTextWindowAndBufferTiles(str, dest, 0, 0, 6); } -static void SetTradePartyLiveStatuses(u8 whichParty) +static void ComputePartyTradeableFlags(u8 whichParty) { int i; switch (whichParty) { case TRADE_PLAYER: - for (i = 0; i < sTradeMenuData->partyCounts[whichParty]; i++) + for (i = 0; i < sTradeMenu->partyCounts[whichParty]; i++) { if (GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG) == TRUE) { - sTradeMenuData->isLiveMon[whichParty][i] = FALSE; - sTradeMenuData->isEgg[whichParty][i] = TRUE; + sTradeMenu->isLiveMon[whichParty][i] = FALSE; + sTradeMenu->isEgg[whichParty][i] = TRUE; } else if (GetMonData(&gPlayerParty[i], MON_DATA_HP) == 0) { - sTradeMenuData->isLiveMon[whichParty][i] = FALSE; - sTradeMenuData->isEgg[whichParty][i] = FALSE; + sTradeMenu->isLiveMon[whichParty][i] = FALSE; + sTradeMenu->isEgg[whichParty][i] = FALSE; } else { - sTradeMenuData->isLiveMon[whichParty][i] = TRUE; - sTradeMenuData->isEgg[whichParty][i] = FALSE; + sTradeMenu->isLiveMon[whichParty][i] = TRUE; + sTradeMenu->isEgg[whichParty][i] = FALSE; } } break; case TRADE_PARTNER: - for (i = 0; i < sTradeMenuData->partyCounts[whichParty]; i++) + for (i = 0; i < sTradeMenu->partyCounts[whichParty]; i++) { if (GetMonData(&gEnemyParty[i], MON_DATA_IS_EGG) == TRUE) { - sTradeMenuData->isLiveMon[whichParty][i] = FALSE; - sTradeMenuData->isEgg[whichParty][i] = TRUE; + sTradeMenu->isLiveMon[whichParty][i] = FALSE; + sTradeMenu->isEgg[whichParty][i] = TRUE; } else if (GetMonData(&gEnemyParty[i], MON_DATA_HP) == 0) { - sTradeMenuData->isLiveMon[whichParty][i] = FALSE; - sTradeMenuData->isEgg[whichParty][i] = FALSE; + sTradeMenu->isLiveMon[whichParty][i] = FALSE; + sTradeMenu->isEgg[whichParty][i] = FALSE; } else { - sTradeMenuData->isLiveMon[whichParty][i] = TRUE; - sTradeMenuData->isEgg[whichParty][i] = FALSE; + sTradeMenu->isLiveMon[whichParty][i] = TRUE; + sTradeMenu->isEgg[whichParty][i] = FALSE; } } break; } } -static void GetTradePartyHPBarLevels(u8 who) +static void ComputePartyHPBarLevels(u8 whichParty) { u16 i, curHp, maxHp; - switch (who) + switch (whichParty) { case TRADE_PLAYER: - for (i = 0; i < sTradeMenuData->partyCounts[TRADE_PLAYER]; i++) + for (i = 0; i < sTradeMenu->partyCounts[TRADE_PLAYER]; i++) { curHp = GetMonData(&gPlayerParty[i], MON_DATA_HP); maxHp = GetMonData(&gPlayerParty[i], MON_DATA_MAX_HP); - sTradeMenuData->hpBarLevels[TRADE_PLAYER][i] = GetHPBarLevel(curHp, maxHp); + sTradeMenu->hpBarLevels[TRADE_PLAYER][i] = GetHPBarLevel(curHp, maxHp); } break; case TRADE_PARTNER: - for (i = 0; i < sTradeMenuData->partyCounts[TRADE_PARTNER]; i++) + for (i = 0; i < sTradeMenu->partyCounts[TRADE_PARTNER]; i++) { curHp = GetMonData(&gEnemyParty[i], MON_DATA_HP); maxHp = GetMonData(&gEnemyParty[i], MON_DATA_MAX_HP); - sTradeMenuData->hpBarLevels[TRADE_PARTNER][i] = GetHPBarLevel(curHp, maxHp); + sTradeMenu->hpBarLevels[TRADE_PARTNER][i] = GetHPBarLevel(curHp, maxHp); } break; } @@ -2299,10 +2367,8 @@ static void SetTradePartyHPBarSprites(void) for (i = 0; i < 2; i++) { - for (j = 0; j < sTradeMenuData->partyCounts[i]; j++) - { - SetPartyHPBarSprite(&gSprites[sTradeMenuData->partySpriteIds[i][j]], 4 - sTradeMenuData->hpBarLevels[i][j]); - } + for (j = 0; j < sTradeMenu->partyCounts[i]; j++) + SetPartyHPBarSprite(&gSprites[sTradeMenu->partySpriteIds[i][j]], 4 - sTradeMenu->hpBarLevels[i][j]); } } @@ -2310,12 +2376,12 @@ static void SaveTradeGiftRibbons(void) { int i; - for (i = 0; i < (int)ARRAY_COUNT(sTradeMenuData->giftRibbons); i++) + for (i = 0; i < (int)ARRAY_COUNT(sTradeMenu->giftRibbons); i++) { - if (gSaveBlock1Ptr->giftRibbons[i] == 0 && sTradeMenuData->giftRibbons[i] != 0) + if (gSaveBlock1Ptr->giftRibbons[i] == 0 && sTradeMenu->giftRibbons[i] != 0) { - if (sTradeMenuData->giftRibbons[i] < 64) - gSaveBlock1Ptr->giftRibbons[i] = sTradeMenuData->giftRibbons[i]; + if (sTradeMenu->giftRibbons[i] < 64) + gSaveBlock1Ptr->giftRibbons[i] = sTradeMenu->giftRibbons[i]; } } } @@ -2323,7 +2389,7 @@ static void SaveTradeGiftRibbons(void) static u32 CanTradeSelectedMon(struct Pokemon *playerParty, int partyCount, int monIdx) { int i, numMonsLeft; - struct LinkPlayer *player; + struct LinkPlayer *partner; u32 species[PARTY_SIZE]; u32 species2[PARTY_SIZE]; @@ -2343,15 +2409,15 @@ static u32 CanTradeSelectedMon(struct Pokemon *playerParty, int partyCount, int return CANT_TRADE_NATIONAL; } - player = &gLinkPlayers[GetMultiplayerId() ^ 1]; - if ((player->version & 0xFF) != VERSION_RUBY && - (player->version & 0xFF) != VERSION_SAPPHIRE) + partner = &gLinkPlayers[GetMultiplayerId() ^ 1]; + if ((partner->version & 0xFF) != VERSION_RUBY && + (partner->version & 0xFF) != VERSION_SAPPHIRE) { // Does partner not have National Dex - if (!(player->progressFlagsCopy & 0xF)) + if (!(partner->progressFlagsCopy & 0xF)) { if (species2[monIdx] == SPECIES_EGG) - return CANT_TRADE_EGG_YET2; + return CANT_TRADE_PARTNER_EGG_YET; if (!IsSpeciesInHoennDex(species2[monIdx])) return CANT_TRADE_INVALID_MON; @@ -2386,30 +2452,30 @@ static u32 CanTradeSelectedMon(struct Pokemon *playerParty, int partyCount, int s32 GetGameProgressForLinkTrade(void) { - // isGameFrLg could have been a bool but they use 2 and > 0 instead - // possible other checks (for other game versions?) were planned/removed - s32 isGameFrLg; + // The usage of this value is a little unusual given it's treated as a bool, + // but it's the result of its usage in FRLG, where 0 is FRLG, 1 is RS, and 2 is Emerald. + s32 versionId; // 0: RSE, 2: FRLG u16 version; if (gReceivedRemoteLinkPlayers) { - isGameFrLg = 0; + versionId = 0; version = (gLinkPlayers[GetMultiplayerId() ^ 1].version & 0xFF); if (version == VERSION_RUBY || version == VERSION_SAPPHIRE || version == VERSION_EMERALD) - isGameFrLg = 0; + versionId = 0; else if (version == VERSION_FIRE_RED || version == VERSION_LEAF_GREEN) - isGameFrLg = 2; + versionId = 2; - // If trading with FRLG, both players must be champion - if (isGameFrLg > 0) + // If trading with FRLG, both players must have progessed the story enough + if (versionId > 0) { // Is player champion if (gLinkPlayers[GetMultiplayerId()].progressFlagsCopy & 0xF0) { - if (isGameFrLg == 2) //unnecessary check, isGameFrLg always 2 here + if (versionId == 2) // Check is only relevant in FRLG, this will always be true { - // Is partner champion + // Has FRLG partner finished the Sevii Islands if (gLinkPlayers[GetMultiplayerId() ^ 1].progressFlagsCopy & 0xF0) return TRADE_BOTH_PLAYERS_READY; else @@ -2438,17 +2504,18 @@ static bool32 IsDeoxysOrMewUntradable(u16 species, bool8 isEventLegal) int GetUnionRoomTradeMessageId(struct RfuGameCompatibilityData player, struct RfuGameCompatibilityData partner, u16 playerSpecies2, u16 partnerSpecies, u8 requestedType, u16 playerSpecies, bool8 isEventLegal) { bool8 playerHasNationalDex = player.hasNationalDex; - bool8 playerIsChampion = player.isChampion; + bool8 playerCanLinkNationally = player.canLinkNationally; bool8 partnerHasNationalDex = partner.hasNationalDex; - bool8 partnerIsChampion = partner.isChampion; + bool8 partnerCanLinkNationally = partner.canLinkNationally; u8 partnerVersion = partner.version; - // If partner is not using Emerald, both players must be champion + // If partner is not using Emerald, both players must have progressed the story + // to a certain point (becoming champion in RSE, finishing the Sevii islands in FRLG) if (partnerVersion != VERSION_EMERALD) { - if (!playerIsChampion) + if (!playerCanLinkNationally) return UR_TRADE_MSG_CANT_TRADE_WITH_PARTNER_1; - else if (!partnerIsChampion) + else if (!partnerCanLinkNationally) return UR_TRADE_MSG_CANT_TRADE_WITH_PARTNER_2; } @@ -4377,14 +4444,14 @@ static void UpdateTradeFinishFlags(void) SetMainCallback2(CB2_TryLinkTradeEvolution); if (gBlockRecvBuffer[0][0] == LINKCMD_READY_FINISH_TRADE) - sTradeData->playerLinkFlagFinishTrade = READY_FINISH_TRADE; + sTradeData->playerLinkFlagFinishTrade = STATUS_READY; ResetBlockReceivedFlag(0); } if (blockReceivedStatus & 0x02) { if (gBlockRecvBuffer[1][0] == LINKCMD_READY_FINISH_TRADE) - sTradeData->partnerLinkFlagFinishTrade = READY_FINISH_TRADE; + sTradeData->partnerLinkFlagFinishTrade = STATUS_READY; ResetBlockReceivedFlag(1); } @@ -4596,13 +4663,13 @@ static void CB2_TryFinishTrade(void) { UpdateTradeFinishFlags(); if (mpId == 0 - && sTradeData->playerLinkFlagFinishTrade == READY_FINISH_TRADE - && sTradeData->partnerLinkFlagFinishTrade == READY_FINISH_TRADE) + && sTradeData->playerLinkFlagFinishTrade == STATUS_READY + && sTradeData->partnerLinkFlagFinishTrade == STATUS_READY) { sTradeData->linkData[0] = LINKCMD_CONFIRM_FINISH_TRADE; SendBlock(BitmaskAllOtherLinkPlayers(), sTradeData->linkData, sizeof(sTradeData->linkData)); - sTradeData->playerLinkFlagFinishTrade = FINISH_TRADE; - sTradeData->partnerLinkFlagFinishTrade = FINISH_TRADE; + sTradeData->playerLinkFlagFinishTrade = STATUS_CANCEL; + sTradeData->partnerLinkFlagFinishTrade = STATUS_CANCEL; } } RunTasks(); diff --git a/src/trainer_see.c b/src/trainer_see.c index b333e0324..44bc774f5 100644 --- a/src/trainer_see.c +++ b/src/trainer_see.c @@ -689,8 +689,8 @@ void TryPrepareSecondApproachingTrainer(void) #define sLocalId data[0] #define sMapNum data[1] #define sMapGroup data[2] -#define sData3 data[3] -#define sData4 data[4] +#define sYVelocity data[3] +#define sYOffset data[4] #define sFldEffId data[7] u8 FldEff_ExclamationMarkIcon(void) @@ -736,7 +736,7 @@ static void SetIconSpriteData(struct Sprite *sprite, u16 fldEffId, u8 spriteAnim sprite->sLocalId = gFieldEffectArguments[0]; sprite->sMapNum = gFieldEffectArguments[1]; sprite->sMapGroup = gFieldEffectArguments[2]; - sprite->sData3 = -5; + sprite->sYVelocity = -5; sprite->sFldEffId = fldEffId; StartSpriteAnim(sprite, spriteAnimNum); @@ -754,23 +754,23 @@ static void SpriteCB_TrainerIcons(struct Sprite *sprite) else { struct Sprite *objEventSprite = &gSprites[gObjectEvents[objEventId].spriteId]; - sprite->sData4 += sprite->sData3; + sprite->sYOffset += sprite->sYVelocity; sprite->x = objEventSprite->x; sprite->y = objEventSprite->y - 16; sprite->x2 = objEventSprite->x2; - sprite->y2 = objEventSprite->y2 + sprite->sData4; - if (sprite->sData4) - sprite->sData3++; + sprite->y2 = objEventSprite->y2 + sprite->sYOffset; + if (sprite->sYOffset) + sprite->sYVelocity++; else - sprite->sData3 = 0; + sprite->sYVelocity = 0; } } #undef sLocalId #undef sMapNum #undef sMapGroup -#undef sData3 -#undef sData4 +#undef sYVelocity +#undef sYOffset #undef sFldEffId u8 GetCurrentApproachingTrainerObjectEventId(void) diff --git a/src/union_room.c b/src/union_room.c index aad8dbaa9..e1c80468d 100644 --- a/src/union_room.c +++ b/src/union_room.c @@ -1271,7 +1271,7 @@ static u32 IsTryingToTradeAcrossVersionTooSoon(struct WirelessLink_Group *data, { if (!(gSaveBlock2Ptr->specialSaveWarpFlags & CHAMPION_SAVEWARP)) return UR_TRADE_PLAYER_NOT_READY; - else if (partner->rfu.data.compatibility.isChampion) + else if (partner->rfu.data.compatibility.canLinkNationally) return UR_TRADE_READY; } else From b873d69679933181d29c69122c1c179141fef44a Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 15 Dec 2022 16:00:53 -0500 Subject: [PATCH 21/69] Sync trade anim --- include/constants/trade.h | 2 - src/data/trade.h | 30 +- src/trade.c | 1760 ++++++++++++++++++------------------- 3 files changed, 884 insertions(+), 908 deletions(-) diff --git a/include/constants/trade.h b/include/constants/trade.h index 0f205d6d2..df1f8d279 100644 --- a/include/constants/trade.h +++ b/include/constants/trade.h @@ -4,8 +4,6 @@ #define TRADE_PLAYER 0 #define TRADE_PARTNER 1 -#define LINK_TRADE_TIMEOUT 300 - // In-game Trade IDs #define INGAME_TRADE_SEEDOT 0 #define INGAME_TRADE_PLUSLE 1 diff --git a/src/data/trade.h b/src/data/trade.h index 433e36247..ef7e9231d 100644 --- a/src/data/trade.h +++ b/src/data/trade.h @@ -287,15 +287,15 @@ static const u8 sCursorMoveDestinations[(PARTY_SIZE * 2) + 1][4][PARTY_SIZE] = static const u8 sTradeMonSpriteCoords[(PARTY_SIZE * 2) + 1][2] = { // Player's party - {COL0_X, ROW0_Y }, - {COL1_X, ROW0_Y }, + {COL0_X, ROW0_Y}, + {COL1_X, ROW0_Y}, {COL0_X, ROW1_Y}, {COL1_X, ROW1_Y}, {COL0_X, ROW2_Y}, {COL1_X, ROW2_Y}, // Partners's party - {COL2_X, ROW0_Y }, - {COL3_X, ROW0_Y }, + {COL2_X, ROW0_Y}, + {COL3_X, ROW0_Y}, {COL2_X, ROW1_Y}, {COL3_X, ROW1_Y}, {COL2_X, ROW2_Y}, @@ -624,8 +624,8 @@ static const u8 sSelectedMonLevelGenderCoords[3][2] = static const u16 sPokeball_Pal[] = INCBIN_U16("graphics/trade/pokeball.gbapal"); static const u8 sPokeball_Gfx[] = INCBIN_U8("graphics/trade/pokeball.4bpp"); static const u8 sPokeballSymbol_Gfx[] = INCBIN_U8("graphics/trade/pokeball_symbol.8bpp"); // unused -static const u16 sCrossingHighlightCable_Tilemap[] = INCBIN_U16("graphics/trade/crossing_highlight_cable.bin"); -static const u16 sTradeTilemap_PokeBallSymbol[] = INCBIN_U16("graphics/trade/pokeball_symbol_map.bin"); // unused? +static const u16 sCableCloseup_Map[] = INCBIN_U16("graphics/trade/crossing_highlight_cable.bin"); +static const u16 sPokeballSymbol_Map[] = INCBIN_U16("graphics/trade/pokeball_symbol_map.bin"); // unused? static const u16 sUnusedPal1[] = INCBIN_U16("graphics/trade/unused1.gbapal"); static const u16 sGba_Pal[] = INCBIN_U16("graphics/trade/gba.gbapal"); static const u16 sUnusedPal2[] = INCBIN_U16("graphics/trade/unused2.gbapal"); @@ -638,11 +638,11 @@ static const u8 sGbaScreen_Gfx[] = INCBIN_U8("graphics/trade/gba_screen.4bpp"); const u16 gTradePlatform_Tilemap[] = INCBIN_U16("graphics/trade/platform.bin"); static const u8 sGbaAffine_Gfx[] = INCBIN_U8("graphics/trade/gba_affine.8bpp"); // Only the gfx for when the GBA is zooming in/out static const u8 sEmptyGfx[64] = {}; -static const u8 sGbaCable_AffineTilemap[] = INCBIN_U8("graphics/trade/gba_affine_map_cable.bin"); -static const u8 sGbaWireless_AffineTilemap[] = INCBIN_U8("graphics/trade/gba_affine_map_wireless.bin"); -static const u16 sGbaWireless_Tilemap[] = INCBIN_U16("graphics/trade/gba_map_wireless.bin"); -static const u16 sGbaCable_Tilemap[] = INCBIN_U16("graphics/trade/gba_map_cable.bin"); -static const u32 sCrossingHighlightWireless_Tilemap[] = INCBIN_U32("graphics/trade/crossing_highlight_wireless.bin.lz"); +static const u8 sGbaAffineMapCable[] = INCBIN_U8("graphics/trade/gba_affine_map_cable.bin"); +static const u8 sGbaAffineMapWireless[] = INCBIN_U8("graphics/trade/gba_affine_map_wireless.bin"); +static const u16 sGbaMapWireless[] = INCBIN_U16("graphics/trade/gba_map_wireless.bin"); +static const u16 sGbaMapCable[] = INCBIN_U16("graphics/trade/gba_map_cable.bin"); +static const u32 sWirelessCloseup_Map[] = INCBIN_U32("graphics/trade/crossing_highlight_wireless.bin.lz"); static const u16 sWirelessSignalSend_Pal[] = INCBIN_U16("graphics/trade/wireless_signal_send.gbapal"); static const u16 sWirelessSignalRecv_Pal[] = INCBIN_U16("graphics/trade/wireless_signal_receive.gbapal"); static const u16 sWirelessSignalNone_Pal[] = INCBIN_U16("graphics/trade/wireless_signal_none.gbapal"); @@ -730,7 +730,7 @@ static const union AffineAnimCmd *const sAffineAnims_Pokeball[] = static const struct SpriteSheet sPokeBallSpriteSheet = { .data = sPokeball_Gfx, - .size = 0x600, + .size = sizeof(sPokeball_Gfx), .tag = GFXTAG_POKEBALL }; @@ -786,7 +786,7 @@ static const union AffineAnimCmd *const sAffineAnims_LinkMonGlow[] = static const struct SpriteSheet sSpriteSheet_LinkMonGlow = { .data = sLinkMonGlow_Gfx, - .size = 0x200, + .size = sizeof(sLinkMonGlow_Gfx), .tag = GFXTAG_LINK_MON_GLOW }; @@ -943,7 +943,7 @@ static const union AnimCmd *const sAnims_GbaScreen_Short[] = static const struct SpriteSheet sSpriteSheet_GbaScreen = { .data = sGbaScreen_Gfx, - .size = 0x1000, + .size = sizeof(sGbaScreen_Gfx), .tag = GFXTAG_GBA_SCREEN }; @@ -1166,7 +1166,7 @@ static const s8 sTradeBallVerticalVelocityTable[] = 0, 0, 0, 1, 0, 1, 1, 2, 3 }; -static const u8 sWirelessSignalTiming[][2] = +static const u8 sWirelessSignalAnimParams[][2] = { { 0, 1}, { 1, 1}, diff --git a/src/trade.c b/src/trade.c index 1032d0d5d..b95cdd235 100644 --- a/src/trade.c +++ b/src/trade.c @@ -148,19 +148,19 @@ enum { #define DRAW_SELECTED_FINISH 5 struct InGameTrade { - /*0x00*/ u8 nickname[POKEMON_NAME_LENGTH + 1]; - /*0x0C*/ u16 species; - /*0x0E*/ u8 ivs[NUM_STATS]; - /*0x14*/ u8 abilityNum; - /*0x18*/ u32 otId; - /*0x1C*/ u8 conditions[CONTEST_CATEGORIES_COUNT]; - /*0x24*/ u32 personality; - /*0x28*/ u16 heldItem; - /*0x2A*/ u8 mailNum; - /*0x2B*/ u8 otName[11]; - /*0x36*/ u8 otGender; - /*0x37*/ u8 sheen; - /*0x38*/ u16 requestedSpecies; + u8 nickname[POKEMON_NAME_LENGTH + 1]; + u16 species; + u8 ivs[NUM_STATS]; + u8 abilityNum; + u32 otId; + u8 conditions[CONTEST_CATEGORIES_COUNT]; + u32 personality; + u16 heldItem; + u8 mailNum; + u8 otName[11]; + u8 otGender; + u8 sheen; + u16 requestedSpecies; }; static EWRAM_DATA u8 *sMenuTextTileBuffer = NULL; @@ -212,50 +212,50 @@ static EWRAM_DATA struct { } *sTradeMenu = NULL; static EWRAM_DATA struct { - /*0x00*/ struct Pokemon tempMon; // Used as a temp variable when swapping Pokémon - /*0x64*/ u32 timer; - /*0x68*/ u32 monPersonalities[2]; - /*0x70*/ u8 filler_70[2]; - /*0x72*/ u8 playerLinkFlagFinishTrade; - /*0x73*/ u8 partnerLinkFlagFinishTrade; - /*0x74*/ u16 linkData[10]; - /*0x88*/ u8 linkTimeoutZero1; - /*0x89*/ u8 linkTimeoutZero2; - /*0x8A*/ u16 linkTimeoutCounter; - /*0x8C*/ u16 neverRead_8C; - /*0x8E*/ u8 monSpriteIds[2]; - /*0x90*/ u8 connectionSpriteId1; // Multi-purpose sprite ids used during the transfer sequence - /*0x91*/ u8 connectionSpriteId2; - /*0x92*/ u8 cableEndSpriteId; - /*0x93*/ u8 sendTradeFinishState; - /*0x94*/ u16 state; - /*0x96*/ u8 filler_96[0xD2 - 0x96]; - /*0xD2*/ u8 releasePokeballSpriteId; - /*0xD3*/ u8 bouncingPokeballSpriteId; - /*0xD4*/ u16 texX; - /*0xD6*/ u16 texY; - /*0xD8*/ u16 neverRead_D8; - /*0xDA*/ u16 neverRead_DA; - /*0xDC*/ u16 scrX; - /*0xDE*/ u16 scrY; - /*0xE0*/ s16 bg1vofs; - /*0xE2*/ s16 bg1hofs; - /*0xE4*/ s16 bg2vofs; - /*0xE6*/ s16 bg2hofs; - /*0xE8*/ u16 sXY; - /*0xEA*/ u16 gbaScale; - /*0xEC*/ u16 alpha; - /*0xEE*/ bool8 isLinkTrade; - /*0xF0*/ u16 monSpecies[2]; - /*0xF4*/ u16 cachedMapMusic; - /*0xF6*/ u8 textColors[3]; - /*0xF9*/ u8 filler_F9; - /*0xFA*/ bool8 isCableTrade; - /*0xFB*/ u8 wirelessWinLeft; - /*0xFC*/ u8 wirelessWinTop; - /*0xFD*/ u8 wirelessWinRight; - /*0xFE*/ u8 wirelessWinBottom; -} *sTradeData = {NULL}; + struct Pokemon tempMon; // Used as a temp variable when swapping Pokémon + u32 timer; + u32 monPersonalities[2]; + u8 filler_70[2]; + u8 playerFinishStatus; + u8 partnerFinishStatus; + u16 linkData[10]; + u8 linkTimeoutZero1; + u8 linkTimeoutZero2; + u16 linkTimeoutTimer; + u16 neverRead_8C; + u8 monSpriteIds[2]; + u8 connectionSpriteId1; // Multi-purpose sprite ids used during the transfer sequence + u8 connectionSpriteId2; + u8 cableEndSpriteId; + u8 scheduleLinkTransfer; + u16 state; + u8 filler_96[0x3C]; + u8 releasePokeballSpriteId; + u8 bouncingPokeballSpriteId; + u16 texX; + u16 texY; + u16 neverRead_D8; + u16 neverRead_DA; + u16 scrX; + u16 scrY; + s16 bg1vofs; + s16 bg1hofs; + s16 bg2vofs; + s16 bg2hofs; + u16 sXY; + u16 gbaScale; + u16 alpha; + bool8 isLinkTrade; + u16 monSpecies[2]; + u16 cachedMapMusic; + u8 textColors[3]; + u8 filler_F9; + bool8 isCableTrade; + u8 wirelessWinLeft; + u8 wirelessWinTop; + u8 wirelessWinRight; + u8 wirelessWinBottom; +} *sTradeAnim = NULL; static bool32 IsWirelessTrade(void); static void CB2_CreateTradeMenu(void); @@ -293,29 +293,29 @@ static void SpriteCB_LinkMonShadow(struct Sprite *); static void SpriteCB_CableEndSending(struct Sprite *); static void SpriteCB_CableEndReceiving(struct Sprite *); static void SpriteCB_GbaScreen(struct Sprite *); -static void InitTradeBgInternal(void); -static void CB2_UpdateInGameTrade(void); +static void TradeAnimInit_LoadGfx(void); +static void CB2_InGameTrade(void); static void SetTradeSequenceBgGpuRegs(u8); static void LoadTradeSequenceSpriteSheetsAndPalettes(void); static void BufferTradeSceneStrings(void); -static bool8 AnimateTradeSequence(void); -static bool8 AnimateTradeSequenceCable(void); -static bool8 AnimateTradeSequenceWireless(void); +static bool8 DoTradeAnim(void); +static bool8 DoTradeAnim_Cable(void); +static bool8 DoTradeAnim_Wireless(void); static void SpriteCB_BouncingPokeball(struct Sprite *); static void SpriteCB_BouncingPokeballDepart(struct Sprite *); static void SpriteCB_BouncingPokeballDepartEnd(struct Sprite *); static void SpriteCB_BouncingPokeballArrive(struct Sprite *); static void BufferInGameTradeMonName(void); -static void SetInGameTradeMail(struct Mail *, const struct InGameTrade *); +static void GetInGameTradeMail(struct Mail *, const struct InGameTrade *); static void CB2_UpdateLinkTrade(void); -static void CB2_TryFinishTrade(void); +static void CB2_WaitTradeComplete(void); static void CB2_SaveAndEndTrade(void); -static void CB2_FreeTradeData(void); +static void CB2_FreeTradeAnim(void); static void Task_InGameTrade(u8); static void CheckPartnersMonForRibbons(void); static void Task_AnimateWirelessSignal(u8); -static void Task_NarrowWindowForCrossing_Wireless(u8); -static void Task_NarrowWindowForCrossing_Cable(u8); +static void Task_OpenCenterWhiteColumn(u8); +static void Task_CloseCenterWhiteColumn(u8); static void CB2_SaveAndEndWirelessTrade(void); #include "data/trade.h" @@ -1028,7 +1028,7 @@ static void SetActiveMenuOptions(void) } else { - // Absent partner pokemno + // Absent partner pokemon sTradeMenu->optionsActive[i + PARTY_SIZE] = FALSE; } } @@ -2665,6 +2665,7 @@ static void SpriteCB_LinkMonGlowWireless(struct Sprite *sprite) } } +// Palette flash for trade glow core static void SpriteCB_LinkMonShadow(struct Sprite *sprite) { if (!sprite->data[1]) @@ -2709,7 +2710,7 @@ static void SetTradeBGAffine(void) { struct BgAffineDstData affine; - DoBgAffineSet(&affine, sTradeData->texX * 0x100, sTradeData->texY * 0x100, sTradeData->scrX, sTradeData->scrY, sTradeData->sXY, sTradeData->sXY, sTradeData->alpha); + DoBgAffineSet(&affine, sTradeAnim->texX * 0x100, sTradeAnim->texY * 0x100, sTradeAnim->scrX, sTradeAnim->scrY, sTradeAnim->sXY, sTradeAnim->sXY, sTradeAnim->alpha); SetGpuReg(REG_OFFSET_BG2PA, affine.pa); SetGpuReg(REG_OFFSET_BG2PB, affine.pb); SetGpuReg(REG_OFFSET_BG2PC, affine.pc); @@ -2724,14 +2725,14 @@ static void SetTradeGpuRegs(void) { u16 dispcnt; - SetGpuReg(REG_OFFSET_BG1VOFS, sTradeData->bg1vofs); - SetGpuReg(REG_OFFSET_BG1HOFS, sTradeData->bg1hofs); + SetGpuReg(REG_OFFSET_BG1VOFS, sTradeAnim->bg1vofs); + SetGpuReg(REG_OFFSET_BG1HOFS, sTradeAnim->bg1hofs); dispcnt = GetGpuReg(REG_OFFSET_DISPCNT); if ((dispcnt & 7) == DISPCNT_MODE_0) { - SetGpuReg(REG_OFFSET_BG2VOFS, sTradeData->bg2vofs); - SetGpuReg(REG_OFFSET_BG2HOFS, sTradeData->bg2hofs); + SetGpuReg(REG_OFFSET_BG2VOFS, sTradeAnim->bg2vofs); + SetGpuReg(REG_OFFSET_BG2HOFS, sTradeAnim->bg2hofs); } else { @@ -2739,7 +2740,7 @@ static void SetTradeGpuRegs(void) } } -static void VBlankCB_Trade(void) +static void VBlankCB_TradeAnim(void) { SetTradeGpuRegs(); LoadOam(); @@ -2747,30 +2748,30 @@ static void VBlankCB_Trade(void) TransferPlttBuffer(); } -static void ClearLinkTimeoutCounter(void) +static void ClearLinkTimeoutTimer(void) { - sTradeData->linkTimeoutCounter = 0; - sTradeData->linkTimeoutZero1 = 0; - sTradeData->linkTimeoutZero2 = 0; + sTradeAnim->linkTimeoutTimer = 0; + sTradeAnim->linkTimeoutZero1 = 0; + sTradeAnim->linkTimeoutZero2 = 0; } static void CheckForLinkTimeout(void) { - if (sTradeData->linkTimeoutZero1 == sTradeData->linkTimeoutZero2) - sTradeData->linkTimeoutCounter++; + if (sTradeAnim->linkTimeoutZero1 == sTradeAnim->linkTimeoutZero2) + sTradeAnim->linkTimeoutTimer++; else - sTradeData->linkTimeoutCounter = 0; + sTradeAnim->linkTimeoutTimer = 0; - if (sTradeData->linkTimeoutCounter > LINK_TRADE_TIMEOUT) + if (sTradeAnim->linkTimeoutTimer > 300) { CloseLink(); SetMainCallback2(CB2_LinkError); - sTradeData->linkTimeoutCounter = 0; - sTradeData->linkTimeoutZero2 = 0; - sTradeData->linkTimeoutZero1 = 0; + sTradeAnim->linkTimeoutTimer = 0; + sTradeAnim->linkTimeoutZero2 = 0; + sTradeAnim->linkTimeoutZero1 = 0; } - sTradeData->linkTimeoutZero2 = sTradeData->linkTimeoutZero1; + sTradeAnim->linkTimeoutZero2 = sTradeAnim->linkTimeoutZero1; } static u32 TradeGetMultiplayerId(void) @@ -2811,14 +2812,14 @@ static void LoadTradeMonPic(u8 whichParty, u8 state) HandleLoadSpecialPokePic_DontHandleDeoxys(&gMonFrontPicTable[species], gMonSpritesGfxPtr->sprites.ptr[whichParty * 2 + B_POSITION_OPPONENT_LEFT], species, personality); LoadCompressedSpritePalette(GetMonSpritePalStruct(mon)); - sTradeData->monSpecies[whichParty] = species; - sTradeData->monPersonalities[whichParty] = personality; + sTradeAnim->monSpecies[whichParty] = species; + sTradeAnim->monPersonalities[whichParty] = personality; break; case 1: SetMultiuseSpriteTemplateToPokemon(GetMonSpritePalStruct(mon)->tag, pos); - sTradeData->monSpriteIds[whichParty] = CreateSprite(&gMultiuseSpriteTemplate, 120, 60, 6); - gSprites[sTradeData->monSpriteIds[whichParty]].invisible = TRUE; - gSprites[sTradeData->monSpriteIds[whichParty]].callback = SpriteCallbackDummy; + sTradeAnim->monSpriteIds[whichParty] = CreateSprite(&gMultiuseSpriteTemplate, 120, 60, 6); + gSprites[sTradeAnim->monSpriteIds[whichParty]].invisible = TRUE; + gSprites[sTradeAnim->monSpriteIds[whichParty]].callback = SpriteCallbackDummy; break; } } @@ -2833,34 +2834,34 @@ void CB2_LinkTrade(void) gLinkType = LINKTYPE_TRADE_DISCONNECTED; CloseLink(); } - sTradeData = AllocZeroed(sizeof(*sTradeData)); + sTradeAnim = AllocZeroed(sizeof(*sTradeAnim)); AllocateMonSpritesGfx(); ResetTasks(); ResetSpriteData(); FreeAllSpritePalettes(); - SetVBlankCallback(VBlankCB_Trade); - InitTradeBgInternal(); - ClearLinkTimeoutCounter(); + SetVBlankCallback(VBlankCB_TradeAnim); + TradeAnimInit_LoadGfx(); + ClearLinkTimeoutTimer(); gMain.state++; - sTradeData->neverRead_8C = 0; - sTradeData->state = 0; - sTradeData->isLinkTrade = TRUE; - sTradeData->texX = 64; - sTradeData->texY = 64; - sTradeData->neverRead_D8 = 0; - sTradeData->neverRead_DA = 0; - sTradeData->scrX = 120; - sTradeData->scrY = 80; - sTradeData->sXY = 256; - sTradeData->alpha = 0; + sTradeAnim->neverRead_8C = 0; + sTradeAnim->state = 0; + sTradeAnim->isLinkTrade = TRUE; + sTradeAnim->texX = 64; + sTradeAnim->texY = 64; + sTradeAnim->neverRead_D8 = 0; + sTradeAnim->neverRead_DA = 0; + sTradeAnim->scrX = DISPLAY_WIDTH / 2; + sTradeAnim->scrY = DISPLAY_HEIGHT / 2; + sTradeAnim->sXY = 256; + sTradeAnim->alpha = 0; break; case 1: if (!gReceivedRemoteLinkPlayers) { - sTradeData->isCableTrade = TRUE; + sTradeAnim->isCableTrade = TRUE; OpenLink(); gMain.state++; - sTradeData->timer = 0; + sTradeAnim->timer = 0; } else { @@ -2868,9 +2869,9 @@ void CB2_LinkTrade(void) } break; case 2: - if (++sTradeData->timer > 60) + if (++sTradeAnim->timer > 60) { - sTradeData->timer = 0; + sTradeAnim->timer = 0; gMain.state++; } break; @@ -2879,7 +2880,7 @@ void CB2_LinkTrade(void) { if (GetLinkPlayerCount_2() >= GetSavedPlayerCount()) { - if (++sTradeData->timer > 30) + if (++sTradeAnim->timer > 30) { CheckShouldAdvanceLinkState(); gMain.state++; @@ -2901,9 +2902,9 @@ void CB2_LinkTrade(void) gMain.state++; break; case 5: - sTradeData->playerLinkFlagFinishTrade = 0; - sTradeData->partnerLinkFlagFinishTrade = 0; - sTradeData->sendTradeFinishState = 0; + sTradeAnim->playerFinishStatus = 0; + sTradeAnim->partnerFinishStatus = 0; + sTradeAnim->scheduleLinkTransfer = 0; LoadTradeMonPic(TRADE_PLAYER, 0); gMain.state++; break; @@ -2968,7 +2969,7 @@ void LinkTradeDrawWindow(void) CopyWindowToVram(0, COPYWIN_FULL); } -static void InitTradeBgInternal(void) +static void TradeAnimInit_LoadGfx(void) { SetGpuReg(REG_OFFSET_DISPCNT, 0); ResetBgsAndClearDma3BusyFlags(0); @@ -2979,18 +2980,20 @@ static void InitTradeBgInternal(void) SetBgTilemapBuffer(1, Alloc(BG_SCREEN_SIZE)); SetBgTilemapBuffer(3, Alloc(BG_SCREEN_SIZE)); DeactivateAllTextPrinters(); + // Doing the graphics load... DecompressAndLoadBgGfxUsingHeap(0, gBattleTextboxTiles, 0, 0, 0); LZDecompressWram(gBattleTextboxTilemap, gDecompressionBuffer); - CopyToBgTilemapBuffer(0, gDecompressionBuffer, 0x800, 0); + CopyToBgTilemapBuffer(0, gDecompressionBuffer, BG_SCREEN_SIZE, 0); LoadCompressedPalette(gBattleTextboxPalette, 0, 0x20); InitWindows(sTradeSequenceWindowTemplates); + // ... and doing the same load again DecompressAndLoadBgGfxUsingHeap(0, gBattleTextboxTiles, 0, 0, 0); LZDecompressWram(gBattleTextboxTilemap, gDecompressionBuffer); - CopyToBgTilemapBuffer(0, gDecompressionBuffer, 0x800, 0); + CopyToBgTilemapBuffer(0, gDecompressionBuffer, BG_SCREEN_SIZE, 0); LoadCompressedPalette(gBattleTextboxPalette, 0, 0x20); } -static void CB2_InGameTrade(void) +static void CB2_InitInGameTrade(void) { u8 otName[11]; @@ -3004,25 +3007,25 @@ static void CB2_InGameTrade(void) StringCopy(gLinkPlayers[1].name, otName); gLinkPlayers[0].language = GAME_LANGUAGE; gLinkPlayers[1].language = GetMonData(&gEnemyParty[0], MON_DATA_LANGUAGE); - sTradeData = AllocZeroed(sizeof(*sTradeData)); + sTradeAnim = AllocZeroed(sizeof(*sTradeAnim)); AllocateMonSpritesGfx(); ResetTasks(); ResetSpriteData(); FreeAllSpritePalettes(); - SetVBlankCallback(VBlankCB_Trade); - InitTradeBgInternal(); - sTradeData->isLinkTrade = FALSE; - sTradeData->neverRead_8C = 0; - sTradeData->state = 0; - sTradeData->texX = 64; - sTradeData->texY = 64; - sTradeData->neverRead_D8 = 0; - sTradeData->neverRead_DA = 0; - sTradeData->scrX = 120; - sTradeData->scrY = 80; - sTradeData->sXY = 256; - sTradeData->alpha = 0; - sTradeData->timer = 0; + SetVBlankCallback(VBlankCB_TradeAnim); + TradeAnimInit_LoadGfx(); + sTradeAnim->isLinkTrade = FALSE; + sTradeAnim->neverRead_8C = 0; + sTradeAnim->state = 0; + sTradeAnim->texX = 64; + sTradeAnim->texY = 64; + sTradeAnim->neverRead_D8 = 0; + sTradeAnim->neverRead_DA = 0; + sTradeAnim->scrX = DISPLAY_WIDTH / 2; + sTradeAnim->scrY = DISPLAY_HEIGHT / 2; + sTradeAnim->sXY = 256; + sTradeAnim->alpha = 0; + sTradeAnim->timer = 0; gMain.state = 5; break; case 5: @@ -3062,7 +3065,7 @@ static void CB2_InGameTrade(void) gMain.state++; break; case 12: - SetMainCallback2(CB2_UpdateInGameTrade); + SetMainCallback2(CB2_InGameTrade); break; } @@ -3106,11 +3109,14 @@ static void TradeMons(u8 playerPartyIdx, u8 partnerPartyIdx) struct Pokemon *partnerMon = &gEnemyParty[partnerPartyIdx]; u16 partnerMail = GetMonData(partnerMon, MON_DATA_MAIL); + // The mail attached to the sent Pokemon no longer exists in your file. if (playerMail != MAIL_NONE) ClearMail(&gSaveBlock1Ptr->mail[playerMail]); - SWAP(*playerMon, *partnerMon, sTradeData->tempMon); + SWAP(*playerMon, *partnerMon, sTradeAnim->tempMon); + // By default, a Pokemon received from a trade will have 70 Friendship. + // Eggs use Friendship to track egg cycles, so don't set this on Eggs. friendship = 70; if (!GetMonData(playerMon, MON_DATA_IS_EGG)) SetMonData(playerMon, MON_DATA_FRIENDSHIP, &friendship); @@ -3123,26 +3129,26 @@ static void TradeMons(u8 playerPartyIdx, u8 partnerPartyIdx) TryEnableNationalDexFromLinkPartner(); } -static void TrySendTradeFinishData(void) +static void HandleLinkDataSend(void) { - switch (sTradeData->sendTradeFinishState) + switch (sTradeAnim->scheduleLinkTransfer) { case 1: if (IsLinkTaskFinished()) { - SendBlock(BitmaskAllOtherLinkPlayers(), sTradeData->linkData, sizeof(sTradeData->linkData)); - sTradeData->sendTradeFinishState++; + SendBlock(BitmaskAllOtherLinkPlayers(), sTradeAnim->linkData, sizeof(sTradeAnim->linkData)); + sTradeAnim->scheduleLinkTransfer++; } // fallthrough case 2: - sTradeData->sendTradeFinishState = 0; + sTradeAnim->scheduleLinkTransfer = 0; break; } } -static void CB2_UpdateInGameTrade(void) +static void CB2_InGameTrade(void) { - AnimateTradeSequence(); + DoTradeAnim(); RunTasks(); RunTextPrinters(); AnimateSprites(); @@ -3155,8 +3161,8 @@ static void SetTradeSequenceBgGpuRegs(u8 state) switch (state) { case 0: - sTradeData->bg2vofs = 0; - sTradeData->bg2hofs = 180; + sTradeAnim->bg2vofs = 0; + sTradeAnim->bg2hofs = 180; SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | @@ -3172,8 +3178,8 @@ static void SetTradeSequenceBgGpuRegs(u8 state) DmaCopy16Defvars(3, gTradePlatform_Tilemap, (void *) BG_SCREEN_ADDR(18), 0x1000); break; case 1: - sTradeData->bg1hofs = 0; - sTradeData->bg1vofs = 348; + sTradeAnim->bg1hofs = 0; + sTradeAnim->bg1vofs = 348; SetGpuReg(REG_OFFSET_BG1VOFS, 348); SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(2) | BGCNT_CHARBASE(0) | @@ -3186,13 +3192,13 @@ static void SetTradeSequenceBgGpuRegs(u8 state) BGCNT_SCREENBASE(18) | BGCNT_TXT256x512); - if (sTradeData->isCableTrade) + if (sTradeAnim->isCableTrade) { - DmaCopy16Defvars(3, sGbaCable_Tilemap, (void *) BG_SCREEN_ADDR(5), 0x1000); + DmaCopy16Defvars(3, sGbaMapCable, (void *) BG_SCREEN_ADDR(5), 0x1000); } else { - DmaCopy16Defvars(3, sGbaWireless_Tilemap, (void *) BG_SCREEN_ADDR(5), 0x1000); + DmaCopy16Defvars(3, sGbaMapWireless, (void *) BG_SCREEN_ADDR(5), 0x1000); } DmaCopyLarge16(3, gTradeGba_Gfx, (void *) BG_CHAR_ADDR(0), 0x1420, 0x1000); @@ -3202,15 +3208,15 @@ static void SetTradeSequenceBgGpuRegs(u8 state) DISPCNT_OBJ_ON); break; case 2: - sTradeData->bg1vofs = 0; - sTradeData->bg1hofs = 0; - if (!sTradeData->isCableTrade) + sTradeAnim->bg1vofs = 0; + sTradeAnim->bg1hofs = 0; + if (!sTradeAnim->isCableTrade) { SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_OBJ_ON); - LZ77UnCompVram(sCrossingHighlightWireless_Tilemap, (void *) BG_SCREEN_ADDR(5)); + LZ77UnCompVram(sWirelessCloseup_Map, (void *) BG_SCREEN_ADDR(5)); BlendPalettes(0x8, 16, RGB_BLACK); } else @@ -3219,7 +3225,7 @@ static void SetTradeSequenceBgGpuRegs(u8 state) DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_OBJ_ON); - DmaCopy16Defvars(3, sCrossingHighlightCable_Tilemap, (void *) BG_SCREEN_ADDR(5), 0x800); + DmaCopy16Defvars(3, sCableCloseup_Map, (void *) BG_SCREEN_ADDR(5), 0x800); BlendPalettes(0x1, 16, RGB_BLACK); } break; @@ -3227,7 +3233,7 @@ static void SetTradeSequenceBgGpuRegs(u8 state) LoadPalette(sWirelessSignalNone_Pal, 48, 0x20); LZ77UnCompVram(sWirelessSignal_Gfx, (void *) BG_CHAR_ADDR(1)); LZ77UnCompVram(sWirelessSignal_Tilemap, (void *) BG_SCREEN_ADDR(18)); - sTradeData->bg2vofs = 80; + sTradeAnim->bg2vofs = 80; SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | @@ -3244,26 +3250,26 @@ static void SetTradeSequenceBgGpuRegs(u8 state) BGCNT_256COLOR | BGCNT_SCREENBASE(18) | BGCNT_AFF128x128); - sTradeData->texX = 64; - sTradeData->texY = 92; - sTradeData->sXY = 32; - sTradeData->gbaScale = 1024; - sTradeData->alpha = 0; + sTradeAnim->texX = 64; + sTradeAnim->texY = 92; + sTradeAnim->sXY = 32; + sTradeAnim->gbaScale = 1024; + sTradeAnim->alpha = 0; DmaCopyLarge16(3, sGbaAffine_Gfx, (void *) BG_CHAR_ADDR(1), 0x2840, 0x1000); - if (sTradeData->isCableTrade) + if (sTradeAnim->isCableTrade) { - DmaCopy16Defvars(3, sGbaCable_AffineTilemap, (void *) BG_SCREEN_ADDR(18), 0x100); + DmaCopy16Defvars(3, sGbaAffineMapCable, (void *) BG_SCREEN_ADDR(18), 0x100); } else { - DmaCopy16Defvars(3, sGbaWireless_AffineTilemap, (void *) BG_SCREEN_ADDR(18), 0x100); + DmaCopy16Defvars(3, sGbaAffineMapWireless, (void *) BG_SCREEN_ADDR(18), 0x100); } break; case 5: - sTradeData->bg1vofs = 0; - sTradeData->bg1hofs = 0; + sTradeAnim->bg1vofs = 0; + sTradeAnim->bg1hofs = 0; break; case 6: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1 | @@ -3275,28 +3281,28 @@ static void SetTradeSequenceBgGpuRegs(u8 state) BGCNT_256COLOR | BGCNT_SCREENBASE(18) | BGCNT_AFF128x128); - sTradeData->texX = 64; - sTradeData->texY = 92; - sTradeData->sXY = 256; - sTradeData->gbaScale = 128; - sTradeData->scrX = 120; - sTradeData->scrY = 80; - sTradeData->alpha = 0; + sTradeAnim->texX = 64; + sTradeAnim->texY = 92; + sTradeAnim->sXY = 256; + sTradeAnim->gbaScale = 128; + sTradeAnim->scrX = 120; + sTradeAnim->scrY = 80; + sTradeAnim->alpha = 0; DmaCopyLarge16(3, sGbaAffine_Gfx, (void *) BG_CHAR_ADDR(1), 0x2840, 0x1000); - if (sTradeData->isCableTrade) + if (sTradeAnim->isCableTrade) { - DmaCopy16Defvars(3, sGbaCable_AffineTilemap, (void *) BG_SCREEN_ADDR(18), 0x100); + DmaCopy16Defvars(3, sGbaAffineMapCable, (void *) BG_SCREEN_ADDR(18), 0x100); } else { - DmaCopy16Defvars(3, sGbaWireless_AffineTilemap, (void *) BG_SCREEN_ADDR(18), 0x100); + DmaCopy16Defvars(3, sGbaAffineMapWireless, (void *) BG_SCREEN_ADDR(18), 0x100); } break; case 7: - sTradeData->bg2vofs = 0; - sTradeData->bg2hofs = 0; + sTradeAnim->bg2vofs = 0; + sTradeAnim->bg2hofs = 0; SetGpuReg(REG_OFFSET_BLDCNT, 0); SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(2) | BGCNT_CHARBASE(1) | @@ -3327,7 +3333,7 @@ static void BufferTradeSceneStrings(void) u8 name[20]; const struct InGameTrade *ingameTrade; - if (sTradeData->isLinkTrade) + if (sTradeAnim->isLinkTrade) { mpId = GetMultiplayerId(); StringCopy(gStringVar1, gLinkPlayers[mpId ^ 1].name); @@ -3347,476 +3353,476 @@ static void BufferTradeSceneStrings(void) } // returns TRUE if it finished a link trade, FALSE if it finished an in-game trade or if sequence is still going -static bool8 AnimateTradeSequence(void) +static bool8 DoTradeAnim(void) { - if (sTradeData->isCableTrade) - return AnimateTradeSequenceCable(); + if (sTradeAnim->isCableTrade) + return DoTradeAnim_Cable(); else - return AnimateTradeSequenceWireless(); + return DoTradeAnim_Wireless(); } -// Below are the states for the main switch in AnimateTradeSequenceCable and AnimateTradeSequenceWireless -// When AnimateTradeSequenceWireless has a unique version of a -// state used by AnimateTradeSequenceCable, it adds the below modifier -#define TS_WIRELESS_STATE 100 +// Below are the states for the main switch in DoTradeAnim_Cable and DoTradeAnim_Wireless +// When DoTradeAnim_Wireless has a unique version of a state used by DoTradeAnim_Cable, it adds the below modifier +#define STATE_WIRELESS 100 enum { - TS_STATE_START, - TS_STATE_MON_SLIDE_IN, + STATE_START, + STATE_MON_SLIDE_IN, // 2-9 unused - TS_STATE_SEND_MSG = 10, - TS_STATE_BYE_BYE, - TS_STATE_POKEBALL_DEPART, - TS_STATE_POKEBALL_DEPART_WAIT, - TS_STATE_FADE_OUT_TO_GBA_SEND, + STATE_SEND_MSG = 10, + STATE_BYE_BYE, + STATE_POKEBALL_DEPART, + STATE_POKEBALL_DEPART_WAIT, + STATE_FADE_OUT_TO_GBA_SEND, // 15-19 unused - TS_STATE_WAIT_FADE_OUT_TO_GBA_SEND = 20, - TS_STATE_FADE_IN_TO_GBA_SEND, - TS_STATE_WAIT_FADE_IN_TO_GBA_SEND, - TS_STATE_GBA_ZOOM_OUT, - TS_STATE_GBA_FLASH_SEND, - TS_STATE_GBA_STOP_FLASH_SEND, - TS_STATE_PAN_AWAY_GBA, - TS_STATE_CREATE_LINK_MON_LEAVING, - TS_STATE_LINK_MON_TRAVEL_OUT, - TS_STATE_FADE_OUT_TO_CROSSING, - TS_STATE_WAIT_FADE_OUT_TO_CROSSING, - TS_STATE_FADE_IN_TO_CROSSING, - TS_STATE_WAIT_FADE_IN_TO_CROSSING, - TS_STATE_CROSSING_LINK_MONS_ENTER, - TS_STATE_CROSSING_BLEND_WHITE_1, - TS_STATE_CROSSING_BLEND_WHITE_2, - TS_STATE_CROSSING_BLEND_WHITE_3, - TS_STATE_CROSSING_CREATE_MON_PICS, - TS_STATE_CROSSING_MON_PICS_MOVE, - TS_STATE_CROSSING_LINK_MONS_EXIT, - TS_STATE_CREATE_LINK_MON_ARRIVING, - TS_STATE_FADE_OUT_TO_GBA_RECV, - TS_STATE_WAIT_FADE_OUT_TO_GBA_RECV, - TS_STATE_LINK_MON_TRAVEL_IN, - TS_STATE_PAN_TO_GBA, - TS_STATE_DESTROY_LINK_MON, - TS_STATE_LINK_MON_ARRIVED_DELAY, - TS_STATE_MOVE_GBA_TO_CENTER, - TS_STATE_GBA_FLASH_RECV, - TS_STATE_UNUSED, - TS_STATE_GBA_STOP_FLASH_RECV, - TS_STATE_GBA_ZOOM_IN, - TS_STATE_FADE_OUT_TO_NEW_MON, + STATE_WAIT_FADE_OUT_TO_GBA_SEND = 20, + STATE_FADE_IN_TO_GBA_SEND, + STATE_WAIT_FADE_IN_TO_GBA_SEND, + STATE_GBA_ZOOM_OUT, + STATE_GBA_FLASH_SEND, + STATE_GBA_STOP_FLASH_SEND, + STATE_PAN_AWAY_GBA, + STATE_CREATE_LINK_MON_LEAVING, + STATE_LINK_MON_TRAVEL_OUT, + STATE_FADE_OUT_TO_CROSSING, + STATE_WAIT_FADE_OUT_TO_CROSSING, + STATE_FADE_IN_TO_CROSSING, + STATE_WAIT_FADE_IN_TO_CROSSING, + STATE_CROSSING_LINK_MONS_ENTER, + STATE_CROSSING_BLEND_WHITE_1, + STATE_CROSSING_BLEND_WHITE_2, + STATE_CROSSING_BLEND_WHITE_3, + STATE_CROSSING_CREATE_MON_PICS, + STATE_CROSSING_MON_PICS_MOVE, + STATE_CROSSING_LINK_MONS_EXIT, + STATE_CREATE_LINK_MON_ARRIVING, + STATE_FADE_OUT_TO_GBA_RECV, + STATE_WAIT_FADE_OUT_TO_GBA_RECV, + STATE_LINK_MON_TRAVEL_IN, + STATE_PAN_TO_GBA, + STATE_DESTROY_LINK_MON, + STATE_LINK_MON_ARRIVED_DELAY, + STATE_MOVE_GBA_TO_CENTER, + STATE_GBA_FLASH_RECV, + STATE_UNUSED, + STATE_GBA_STOP_FLASH_RECV, + STATE_GBA_ZOOM_IN, + STATE_FADE_OUT_TO_NEW_MON, // 53-59 unused - TS_STATE_WAIT_FADE_OUT_TO_NEW_MON = 60, - TS_STATE_FADE_IN_TO_NEW_MON, - TS_STATE_WAIT_FADE_IN_TO_NEW_MON, - TS_STATE_POKEBALL_ARRIVE, - TS_STATE_FADE_POKEBALL_TO_NORMAL, - TS_STATE_POKEBALL_ARRIVE_WAIT, - TS_STATE_SHOW_NEW_MON, - TS_STATE_NEW_MON_MSG, - TS_STATE_TAKE_CARE_OF_MON, - TS_STATE_AFTER_NEW_MON_DELAY, - TS_STATE_CHECK_RIBBONS, - TS_STATE_END_LINK_TRADE, - TS_STATE_TRY_EVOLUTION, - TS_STATE_FADE_OUT_END, - TS_STATE_WAIT_FADE_OUT_END, + STATE_WAIT_FADE_OUT_TO_NEW_MON = 60, + STATE_FADE_IN_TO_NEW_MON, + STATE_WAIT_FADE_IN_TO_NEW_MON, + STATE_POKEBALL_ARRIVE, + STATE_FADE_POKEBALL_TO_NORMAL, + STATE_POKEBALL_ARRIVE_WAIT, + STATE_SHOW_NEW_MON, + STATE_NEW_MON_MSG, + STATE_TAKE_CARE_OF_MON, + STATE_AFTER_NEW_MON_DELAY, + STATE_CHECK_RIBBONS, + STATE_END_LINK_TRADE, + STATE_TRY_EVOLUTION, + STATE_FADE_OUT_END, + STATE_WAIT_FADE_OUT_END, // Special states - TS_STATE_GBA_FLASH_SEND_WIRELESS = TS_STATE_GBA_FLASH_SEND + TS_WIRELESS_STATE, - TS_STATE_GBA_STOP_FLASH_SEND_WIRELESS, - TS_STATE_WAIT_WIRELESS_SIGNAL_SEND, - TS_STATE_PAN_TO_GBA_WIRELESS = TS_STATE_PAN_TO_GBA + TS_WIRELESS_STATE, - TS_STATE_DESTROY_LINK_MON_WIRELESS, - TS_STATE_WAIT_WIRELESS_SIGNAL_RECV, - TS_STATE_DELAY_FOR_MON_ANIM = 167, - TS_STATE_LINK_MON_TRAVEL_OFFSCREEN = 200, - TS_STATE_WAIT_FOR_MON_CRY = 267, + STATE_GBA_FLASH_SEND_WIRELESS = STATE_GBA_FLASH_SEND + STATE_WIRELESS, + STATE_GBA_STOP_FLASH_SEND_WIRELESS, + STATE_WAIT_WIRELESS_SIGNAL_SEND, + STATE_PAN_TO_GBA_WIRELESS = STATE_PAN_TO_GBA + STATE_WIRELESS, + STATE_DESTROY_LINK_MON_WIRELESS, + STATE_WAIT_WIRELESS_SIGNAL_RECV, + STATE_DELAY_FOR_MON_ANIM = 167, + STATE_LINK_MON_TRAVEL_OFFSCREEN = 200, + STATE_WAIT_FOR_MON_CRY = 267, }; -static bool8 AnimateTradeSequenceCable(void) +static bool8 DoTradeAnim_Cable(void) { u16 evoTarget; - switch (sTradeData->state) + switch (sTradeAnim->state) { - case TS_STATE_START: - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].invisible = FALSE; - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].x2 = -180; - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].y2 = gMonFrontPicCoords[sTradeData->monSpecies[TRADE_PLAYER]].y_offset; - sTradeData->state++; - sTradeData->cachedMapMusic = GetCurrentMapMusic(); + case STATE_START: + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].invisible = FALSE; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].x2 = -180; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 = gMonFrontPicCoords[sTradeAnim->monSpecies[TRADE_PLAYER]].y_offset; + sTradeAnim->state++; + sTradeAnim->cachedMapMusic = GetCurrentMapMusic(); PlayNewMapMusic(MUS_EVOLUTION); break; - case TS_STATE_MON_SLIDE_IN: - if (sTradeData->bg2hofs > 0) + case STATE_MON_SLIDE_IN: + if (sTradeAnim->bg2hofs > 0) { // Sliding - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].x2 += 3; - sTradeData->bg2hofs -= 3; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].x2 += 3; + sTradeAnim->bg2hofs -= 3; } else { // Pokémon has arrived onscreen - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].x2 = 0; - sTradeData->bg2hofs = 0; - sTradeData->state = TS_STATE_SEND_MSG; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].x2 = 0; + sTradeAnim->bg2hofs = 0; + sTradeAnim->state = STATE_SEND_MSG; } break; - case TS_STATE_SEND_MSG: + case STATE_SEND_MSG: StringExpandPlaceholders(gStringVar4, gText_XWillBeSentToY); DrawTextOnTradeWindow(0, gStringVar4, 0); - if (sTradeData->monSpecies[TRADE_PLAYER] != SPECIES_EGG) - PlayCry_Normal(sTradeData->monSpecies[TRADE_PLAYER], 0); + if (sTradeAnim->monSpecies[TRADE_PLAYER] != SPECIES_EGG) + PlayCry_Normal(sTradeAnim->monSpecies[TRADE_PLAYER], 0); - sTradeData->state = TS_STATE_BYE_BYE; - sTradeData->timer = 0; + sTradeAnim->state = STATE_BYE_BYE; + sTradeAnim->timer = 0; break; - case TS_STATE_BYE_BYE: - if (++sTradeData->timer == 80) + case STATE_BYE_BYE: + if (++sTradeAnim->timer == 80) { - sTradeData->releasePokeballSpriteId = CreateTradePokeballSprite(sTradeData->monSpriteIds[0], gSprites[sTradeData->monSpriteIds[0]].oam.paletteNum, 120, 32, 2, 1, 0x14, 0xfffff); - sTradeData->state++; + sTradeAnim->releasePokeballSpriteId = CreateTradePokeballSprite(sTradeAnim->monSpriteIds[TRADE_PLAYER], gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].oam.paletteNum, 120, 32, 2, 1, 0x14, 0xfffff); + sTradeAnim->state++; StringExpandPlaceholders(gStringVar4, gText_ByeByeVar1); DrawTextOnTradeWindow(0, gStringVar4, 0); } break; - case TS_STATE_POKEBALL_DEPART: - if (gSprites[sTradeData->releasePokeballSpriteId].callback == SpriteCallbackDummy) + case STATE_POKEBALL_DEPART: + if (gSprites[sTradeAnim->releasePokeballSpriteId].callback == SpriteCallbackDummy) { - sTradeData->bouncingPokeballSpriteId = CreateSprite(&sSpriteTemplate_Pokeball, 120, 32, 0); - gSprites[sTradeData->bouncingPokeballSpriteId].callback = SpriteCB_BouncingPokeballDepart; - DestroySprite(&gSprites[sTradeData->releasePokeballSpriteId]); - sTradeData->state++; + sTradeAnim->bouncingPokeballSpriteId = CreateSprite(&sSpriteTemplate_Pokeball, 120, 32, 0); + gSprites[sTradeAnim->bouncingPokeballSpriteId].callback = SpriteCB_BouncingPokeballDepart; + DestroySprite(&gSprites[sTradeAnim->releasePokeballSpriteId]); + sTradeAnim->state++; } break; - case TS_STATE_POKEBALL_DEPART_WAIT: + case STATE_POKEBALL_DEPART_WAIT: // The game waits here for the sprite to finish its animation sequence. break; - case TS_STATE_FADE_OUT_TO_GBA_SEND: + case STATE_FADE_OUT_TO_GBA_SEND: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeData->state = TS_STATE_WAIT_FADE_OUT_TO_GBA_SEND; + sTradeAnim->state = STATE_WAIT_FADE_OUT_TO_GBA_SEND; break; - case TS_STATE_WAIT_FADE_OUT_TO_GBA_SEND: + case STATE_WAIT_FADE_OUT_TO_GBA_SEND: if (!gPaletteFade.active) { SetTradeSequenceBgGpuRegs(4); FillWindowPixelBuffer(0, PIXEL_FILL(15)); CopyWindowToVram(0, COPYWIN_FULL); - sTradeData->state++; + sTradeAnim->state++; } break; - case TS_STATE_FADE_IN_TO_GBA_SEND: + case STATE_FADE_IN_TO_GBA_SEND: BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_WAIT_FADE_IN_TO_GBA_SEND: + case STATE_WAIT_FADE_IN_TO_GBA_SEND: if (!gPaletteFade.active) - sTradeData->state = TS_STATE_GBA_ZOOM_OUT; + sTradeAnim->state = STATE_GBA_ZOOM_OUT; break; - case TS_STATE_GBA_ZOOM_OUT: - if (sTradeData->gbaScale > 0x100) + case STATE_GBA_ZOOM_OUT: + if (sTradeAnim->gbaScale > 0x100) { - sTradeData->gbaScale -= 0x34; + sTradeAnim->gbaScale -= 0x34; } else { SetTradeSequenceBgGpuRegs(1); - sTradeData->gbaScale = 0x80; - sTradeData->state++; - sTradeData->timer = 0; + sTradeAnim->gbaScale = 0x80; + sTradeAnim->state++; + sTradeAnim->timer = 0; } - sTradeData->sXY = 0x8000 / sTradeData->gbaScale; + sTradeAnim->sXY = 0x8000 / sTradeAnim->gbaScale; break; - case TS_STATE_GBA_FLASH_SEND: - if (++sTradeData->timer > 20) + case STATE_GBA_FLASH_SEND: + if (++sTradeAnim->timer > 20) { SetTradeBGAffine(); - sTradeData->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_GbaScreenFlash_Long, 120, 80, 0); - sTradeData->state++; + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_GbaScreenFlash_Long, 120, 80, 0); + sTradeAnim->state++; } break; - case TS_STATE_GBA_STOP_FLASH_SEND: - if (gSprites[sTradeData->connectionSpriteId2].animEnded) + case STATE_GBA_STOP_FLASH_SEND: + if (gSprites[sTradeAnim->connectionSpriteId2].animEnded) { - DestroySprite(&gSprites[sTradeData->connectionSpriteId2]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_BG1 | BLDCNT_TGT2_BG2); SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(12, 4)); - sTradeData->state++; + sTradeAnim->state++; } break; - case TS_STATE_PAN_AWAY_GBA: - if (--sTradeData->bg1vofs == 316) - sTradeData->state++; + case STATE_PAN_AWAY_GBA: + if (--sTradeAnim->bg1vofs == 316) + sTradeAnim->state++; - if (sTradeData->bg1vofs == 328) - sTradeData->cableEndSpriteId = CreateSprite(&sSpriteTemplate_CableEnd, 128, 65, 0); + if (sTradeAnim->bg1vofs == 328) + sTradeAnim->cableEndSpriteId = CreateSprite(&sSpriteTemplate_CableEnd, 128, 65, 0); break; - case TS_STATE_CREATE_LINK_MON_LEAVING: - sTradeData->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonGlow, 128, 80, 3); - sTradeData->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 128, 80, 0); - StartSpriteAnim(&gSprites[sTradeData->connectionSpriteId2], ANIM_LINKMON_SMALL); - sTradeData->state++; + case STATE_CREATE_LINK_MON_LEAVING: + sTradeAnim->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonGlow, 128, 80, 3); + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 128, 80, 0); + StartSpriteAnim(&gSprites[sTradeAnim->connectionSpriteId2], ANIM_LINKMON_SMALL); + sTradeAnim->state++; break; - case TS_STATE_LINK_MON_TRAVEL_OUT: - if ((sTradeData->bg1vofs -= 2) == 166) - sTradeData->state = TS_STATE_LINK_MON_TRAVEL_OFFSCREEN; + case STATE_LINK_MON_TRAVEL_OUT: + if ((sTradeAnim->bg1vofs -= 2) == 166) + sTradeAnim->state = STATE_LINK_MON_TRAVEL_OFFSCREEN; SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_OBJ_ON); break; - case TS_STATE_LINK_MON_TRAVEL_OFFSCREEN: - gSprites[sTradeData->connectionSpriteId1].y -= 2; - gSprites[sTradeData->connectionSpriteId2].y -= 2; - if (gSprites[sTradeData->connectionSpriteId1].y < -8) - sTradeData->state = TS_STATE_FADE_OUT_TO_CROSSING; + case STATE_LINK_MON_TRAVEL_OFFSCREEN: + gSprites[sTradeAnim->connectionSpriteId1].y -= 2; + gSprites[sTradeAnim->connectionSpriteId2].y -= 2; + if (gSprites[sTradeAnim->connectionSpriteId1].y < -8) + sTradeAnim->state = STATE_FADE_OUT_TO_CROSSING; break; - case TS_STATE_FADE_OUT_TO_CROSSING: + case STATE_FADE_OUT_TO_CROSSING: BeginNormalPaletteFade(PALETTES_ALL, -1, 0, 16, RGB_BLACK); - sTradeData->state = TS_STATE_WAIT_FADE_OUT_TO_CROSSING; + sTradeAnim->state = STATE_WAIT_FADE_OUT_TO_CROSSING; break; - case TS_STATE_WAIT_FADE_OUT_TO_CROSSING: + case STATE_WAIT_FADE_OUT_TO_CROSSING: if (!gPaletteFade.active) { - DestroySprite(&gSprites[sTradeData->connectionSpriteId1]); - DestroySprite(&gSprites[sTradeData->connectionSpriteId2]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId1]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); SetTradeSequenceBgGpuRegs(2); - sTradeData->state++; + sTradeAnim->state++; } break; - case TS_STATE_FADE_IN_TO_CROSSING: + case STATE_FADE_IN_TO_CROSSING: BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_BLACK); - sTradeData->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 111, 170, 0); - sTradeData->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 129, -10, 0); - sTradeData->state++; + sTradeAnim->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 111, 170, 0); + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 129, -10, 0); + sTradeAnim->state++; break; - case TS_STATE_WAIT_FADE_IN_TO_CROSSING: + case STATE_WAIT_FADE_IN_TO_CROSSING: if (!gPaletteFade.active) { PlaySE(SE_WARP_OUT); - sTradeData->state++; + sTradeAnim->state++; } - gSprites[sTradeData->connectionSpriteId1].y2 -= 3; - gSprites[sTradeData->connectionSpriteId2].y2 += 3; + gSprites[sTradeAnim->connectionSpriteId1].y2 -= 3; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 3; break; - case TS_STATE_CROSSING_LINK_MONS_ENTER: - gSprites[sTradeData->connectionSpriteId1].y2 -= 3; - gSprites[sTradeData->connectionSpriteId2].y2 += 3; - if (gSprites[sTradeData->connectionSpriteId1].y2 <= -90) + case STATE_CROSSING_LINK_MONS_ENTER: + gSprites[sTradeAnim->connectionSpriteId1].y2 -= 3; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 3; + if (gSprites[sTradeAnim->connectionSpriteId1].y2 <= -90) { - gSprites[sTradeData->connectionSpriteId1].data[1] = 1; - gSprites[sTradeData->connectionSpriteId2].data[1] = 1; - sTradeData->state++; + gSprites[sTradeAnim->connectionSpriteId1].data[1] = 1; + gSprites[sTradeAnim->connectionSpriteId2].data[1] = 1; + sTradeAnim->state++; } break; - case TS_STATE_CROSSING_BLEND_WHITE_1: + case STATE_CROSSING_BLEND_WHITE_1: BlendPalettes(0x1, 16, RGB_WHITEALPHA); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_CROSSING_BLEND_WHITE_2: + case STATE_CROSSING_BLEND_WHITE_2: BlendPalettes(0x1, 0, RGB_WHITEALPHA); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_CROSSING_BLEND_WHITE_3: + case STATE_CROSSING_BLEND_WHITE_3: BlendPalettes(0x1, 16, RGB_WHITEALPHA); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_CROSSING_CREATE_MON_PICS: - if (!IsMonSpriteNotFlipped(sTradeData->monSpecies[TRADE_PLAYER])) + case STATE_CROSSING_CREATE_MON_PICS: + if (!IsMonSpriteNotFlipped(sTradeAnim->monSpecies[TRADE_PLAYER])) { - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].affineAnims = sAffineAnims_CrossingMonPics; - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].oam.affineMode = ST_OAM_AFFINE_DOUBLE; - CalcCenterToCornerVec(&gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]], SPRITE_SHAPE(64x64), SPRITE_SIZE(64x64), ST_OAM_AFFINE_DOUBLE); - StartSpriteAffineAnim(&gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]], 0); + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].affineAnims = sAffineAnims_CrossingMonPics; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].oam.affineMode = ST_OAM_AFFINE_DOUBLE; + CalcCenterToCornerVec(&gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]], SPRITE_SHAPE(64x64), SPRITE_SIZE(64x64), ST_OAM_AFFINE_DOUBLE); + StartSpriteAffineAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]], 0); } else { - StartSpriteAffineAnim(&gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]], 0); + StartSpriteAffineAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]], 0); } - StartSpriteAffineAnim(&gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]], 0); - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].x = 60; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].x = 180; - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].y = 192; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].y = -32; - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].invisible = FALSE; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].invisible = FALSE; - sTradeData->state++; + StartSpriteAffineAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]], 0); + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].x = 60; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].x = 180; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y = 192; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y = -32; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].invisible = FALSE; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].invisible = FALSE; + sTradeAnim->state++; break; - case TS_STATE_CROSSING_MON_PICS_MOVE: - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].y2 -= 3; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].y2 += 3; - if (gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].y2 < -DISPLAY_HEIGHT - && gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].y2 >= -DISPLAY_HEIGHT - 3) + case STATE_CROSSING_MON_PICS_MOVE: + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 -= 3; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y2 += 3; + if (gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 < -DISPLAY_HEIGHT + && gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 >= -DISPLAY_HEIGHT - 3) { PlaySE(SE_WARP_IN); } - if (gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].y2 < -222) + if (gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 < -222) { - gSprites[sTradeData->connectionSpriteId1].data[1] = 0; - gSprites[sTradeData->connectionSpriteId2].data[1] = 0; - sTradeData->state++; - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].invisible = TRUE; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].invisible = TRUE; + gSprites[sTradeAnim->connectionSpriteId1].data[1] = 0; + gSprites[sTradeAnim->connectionSpriteId2].data[1] = 0; + sTradeAnim->state++; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].invisible = TRUE; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].invisible = TRUE; BlendPalettes(0x1, 0, RGB_WHITEALPHA); } break; - case TS_STATE_CROSSING_LINK_MONS_EXIT: - gSprites[sTradeData->connectionSpriteId1].y2 -= 3; - gSprites[sTradeData->connectionSpriteId2].y2 += 3; - if (gSprites[sTradeData->connectionSpriteId1].y2 <= -222) + case STATE_CROSSING_LINK_MONS_EXIT: + gSprites[sTradeAnim->connectionSpriteId1].y2 -= 3; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 3; + if (gSprites[sTradeAnim->connectionSpriteId1].y2 <= -222) { BeginNormalPaletteFade(PALETTES_ALL, -1, 0, 16, RGB_BLACK); - sTradeData->state++; - DestroySprite(&gSprites[sTradeData->connectionSpriteId1]); - DestroySprite(&gSprites[sTradeData->connectionSpriteId2]); + sTradeAnim->state++; + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId1]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); } break; - case TS_STATE_CREATE_LINK_MON_ARRIVING: + case STATE_CREATE_LINK_MON_ARRIVING: if (!gPaletteFade.active) { - sTradeData->state++; + sTradeAnim->state++; SetTradeSequenceBgGpuRegs(1); - sTradeData->bg1vofs = 166; - sTradeData->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonGlow, 128, -20, 3); - sTradeData->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 128, -20, 0); - StartSpriteAnim(&gSprites[sTradeData->connectionSpriteId2], ANIM_LINKMON_SMALL); + sTradeAnim->bg1vofs = 166; + sTradeAnim->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonGlow, 128, -20, 3); + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 128, -20, 0); + StartSpriteAnim(&gSprites[sTradeAnim->connectionSpriteId2], ANIM_LINKMON_SMALL); } break; - case TS_STATE_FADE_OUT_TO_GBA_RECV: + case STATE_FADE_OUT_TO_GBA_RECV: BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_WAIT_FADE_OUT_TO_GBA_RECV: + case STATE_WAIT_FADE_OUT_TO_GBA_RECV: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_OBJ_ON); if (!gPaletteFade.active) - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_LINK_MON_TRAVEL_IN: - gSprites[sTradeData->connectionSpriteId1].y2 += 3; - gSprites[sTradeData->connectionSpriteId2].y2 += 3; - if (gSprites[sTradeData->connectionSpriteId1].y2 + gSprites[sTradeData->connectionSpriteId1].y == 64) + case STATE_LINK_MON_TRAVEL_IN: + gSprites[sTradeAnim->connectionSpriteId1].y2 += 3; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 3; + if (gSprites[sTradeAnim->connectionSpriteId1].y2 + gSprites[sTradeAnim->connectionSpriteId1].y == 64) + sTradeAnim->state++; + break; + case STATE_PAN_TO_GBA: + if ((sTradeAnim->bg1vofs += 2) > 316) { - sTradeData->state++; + sTradeAnim->bg1vofs = 316; + sTradeAnim->state++; } break; - case TS_STATE_PAN_TO_GBA: - if ((sTradeData->bg1vofs += 2) > 316) + case STATE_DESTROY_LINK_MON: + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId1]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); + sTradeAnim->state++; + sTradeAnim->timer = 0; + break; + case STATE_LINK_MON_ARRIVED_DELAY: + if (++sTradeAnim->timer == 10) + sTradeAnim->state++; + break; + case STATE_MOVE_GBA_TO_CENTER: + if (++sTradeAnim->bg1vofs > 348) { - sTradeData->bg1vofs = 316; - sTradeData->state++; + sTradeAnim->bg1vofs = 348; + sTradeAnim->state++; + } + if (sTradeAnim->bg1vofs == 328 && sTradeAnim->isCableTrade) + { + sTradeAnim->cableEndSpriteId = CreateSprite(&sSpriteTemplate_CableEnd, 128, 65, 0); + gSprites[sTradeAnim->cableEndSpriteId].callback = SpriteCB_CableEndReceiving; } break; - case TS_STATE_DESTROY_LINK_MON: - DestroySprite(&gSprites[sTradeData->connectionSpriteId1]); - DestroySprite(&gSprites[sTradeData->connectionSpriteId2]); - sTradeData->state++; - sTradeData->timer = 0; + case STATE_GBA_FLASH_RECV: + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_GbaScreenFlash_Long, 120, 80, 0); + sTradeAnim->state = STATE_GBA_STOP_FLASH_RECV; break; - case TS_STATE_LINK_MON_ARRIVED_DELAY: - if (++sTradeData->timer == 10) - sTradeData->state++; - break; - case TS_STATE_MOVE_GBA_TO_CENTER: - if (++sTradeData->bg1vofs > 348) + case STATE_GBA_STOP_FLASH_RECV: + if (gSprites[sTradeAnim->connectionSpriteId2].animEnded) { - sTradeData->bg1vofs = 348; - sTradeData->state++; - } - if (sTradeData->bg1vofs == 328 && sTradeData->isCableTrade) - { - sTradeData->cableEndSpriteId = CreateSprite(&sSpriteTemplate_CableEnd, 128, 65, 0); - gSprites[sTradeData->cableEndSpriteId].callback = SpriteCB_CableEndReceiving; - } - break; - case TS_STATE_GBA_FLASH_RECV: - sTradeData->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_GbaScreenFlash_Long, 120, 80, 0); - sTradeData->state = TS_STATE_GBA_STOP_FLASH_RECV; - break; - case TS_STATE_GBA_STOP_FLASH_RECV: - if (gSprites[sTradeData->connectionSpriteId2].animEnded) - { - DestroySprite(&gSprites[sTradeData->connectionSpriteId2]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); SetTradeSequenceBgGpuRegs(6); - sTradeData->state++; + sTradeAnim->state++; PlaySE(SE_M_SAND_ATTACK); } break; - case TS_STATE_GBA_ZOOM_IN: - if (sTradeData->gbaScale < 0x400) + case STATE_GBA_ZOOM_IN: + if (sTradeAnim->gbaScale < 0x400) { - sTradeData->gbaScale += 0x34; + sTradeAnim->gbaScale += 0x34; } else { - sTradeData->gbaScale = 0x400; - sTradeData->state++; + sTradeAnim->gbaScale = 0x400; + sTradeAnim->state++; } - sTradeData->sXY = 0x8000 / sTradeData->gbaScale; + sTradeAnim->sXY = 0x8000 / sTradeAnim->gbaScale; break; - case TS_STATE_FADE_OUT_TO_NEW_MON: + case STATE_FADE_OUT_TO_NEW_MON: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeData->state = TS_STATE_WAIT_FADE_OUT_TO_NEW_MON; + sTradeAnim->state = STATE_WAIT_FADE_OUT_TO_NEW_MON; break; - case TS_STATE_WAIT_FADE_OUT_TO_NEW_MON: + case STATE_WAIT_FADE_OUT_TO_NEW_MON: if (!gPaletteFade.active) { SetTradeSequenceBgGpuRegs(5); SetTradeSequenceBgGpuRegs(7); gPaletteFade.bufferTransferDisabled = TRUE; - sTradeData->state++; + sTradeAnim->state++; } break; - case TS_STATE_FADE_IN_TO_NEW_MON: + case STATE_FADE_IN_TO_NEW_MON: gPaletteFade.bufferTransferDisabled = FALSE; BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_WAIT_FADE_IN_TO_NEW_MON: + case STATE_WAIT_FADE_IN_TO_NEW_MON: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG2_ON | DISPCNT_OBJ_ON); if (!gPaletteFade.active) - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_POKEBALL_ARRIVE: - sTradeData->bouncingPokeballSpriteId = CreateSprite(&sSpriteTemplate_Pokeball, 120, -8, 0); - gSprites[sTradeData->bouncingPokeballSpriteId].data[3] = 74; - gSprites[sTradeData->bouncingPokeballSpriteId].callback = SpriteCB_BouncingPokeballArrive; - StartSpriteAnim(&gSprites[sTradeData->bouncingPokeballSpriteId], 1); - StartSpriteAffineAnim(&gSprites[sTradeData->bouncingPokeballSpriteId], 2); - BlendPalettes(1 << (16 + gSprites[sTradeData->bouncingPokeballSpriteId].oam.paletteNum), 16, RGB_WHITEALPHA); - sTradeData->state++; - sTradeData->timer = 0; + case STATE_POKEBALL_ARRIVE: + sTradeAnim->bouncingPokeballSpriteId = CreateSprite(&sSpriteTemplate_Pokeball, 120, -8, 0); + gSprites[sTradeAnim->bouncingPokeballSpriteId].data[3] = 74; + gSprites[sTradeAnim->bouncingPokeballSpriteId].callback = SpriteCB_BouncingPokeballArrive; + StartSpriteAnim(&gSprites[sTradeAnim->bouncingPokeballSpriteId], 1); + StartSpriteAffineAnim(&gSprites[sTradeAnim->bouncingPokeballSpriteId], 2); + BlendPalettes(1 << (16 + gSprites[sTradeAnim->bouncingPokeballSpriteId].oam.paletteNum), 16, RGB_WHITEALPHA); + sTradeAnim->state++; + sTradeAnim->timer = 0; break; - case TS_STATE_FADE_POKEBALL_TO_NORMAL: - BeginNormalPaletteFade(1 << (16 + gSprites[sTradeData->bouncingPokeballSpriteId].oam.paletteNum), 1, 16, 0, RGB_WHITEALPHA); - sTradeData->state++; + case STATE_FADE_POKEBALL_TO_NORMAL: + BeginNormalPaletteFade(1 << (16 + gSprites[sTradeAnim->bouncingPokeballSpriteId].oam.paletteNum), 1, 16, 0, RGB_WHITEALPHA); + sTradeAnim->state++; break; - case TS_STATE_POKEBALL_ARRIVE_WAIT: - if (gSprites[sTradeData->bouncingPokeballSpriteId].callback == SpriteCallbackDummy) + case STATE_POKEBALL_ARRIVE_WAIT: + if (gSprites[sTradeAnim->bouncingPokeballSpriteId].callback == SpriteCallbackDummy) { - HandleLoadSpecialPokePic_2(&gMonFrontPicTable[sTradeData->monSpecies[TRADE_PARTNER]], gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_RIGHT], sTradeData->monSpecies[TRADE_PARTNER], sTradeData->monPersonalities[TRADE_PARTNER]); - sTradeData->state++; + HandleLoadSpecialPokePic_2(&gMonFrontPicTable[sTradeAnim->monSpecies[TRADE_PARTNER]], + gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_RIGHT], + sTradeAnim->monSpecies[TRADE_PARTNER], + sTradeAnim->monPersonalities[TRADE_PARTNER]); + sTradeAnim->state++; } break; - case TS_STATE_SHOW_NEW_MON: - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].x = 120; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].y = gMonFrontPicCoords[sTradeData->monSpecies[TRADE_PARTNER]].y_offset + 60; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].x2 = 0; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].y2 = 0; - StartSpriteAnim(&gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]], 0); - CreatePokeballSpriteToReleaseMon(sTradeData->monSpriteIds[TRADE_PARTNER], gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].oam.paletteNum, 120, 84, 2, 1, 20, PALETTES_BG | (0xF << 16), sTradeData->monSpecies[TRADE_PARTNER]); - FreeSpriteOamMatrix(&gSprites[sTradeData->bouncingPokeballSpriteId]); - DestroySprite(&gSprites[sTradeData->bouncingPokeballSpriteId]); - sTradeData->state++; + case STATE_SHOW_NEW_MON: + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].x = 120; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y = gMonFrontPicCoords[sTradeAnim->monSpecies[TRADE_PARTNER]].y_offset + 60; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].x2 = 0; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y2 = 0; + StartSpriteAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]], 0); + CreatePokeballSpriteToReleaseMon(sTradeAnim->monSpriteIds[TRADE_PARTNER], gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].oam.paletteNum, 120, 84, 2, 1, 20, PALETTES_BG | (0xF << 16), sTradeAnim->monSpecies[TRADE_PARTNER]); + FreeSpriteOamMatrix(&gSprites[sTradeAnim->bouncingPokeballSpriteId]); + DestroySprite(&gSprites[sTradeAnim->bouncingPokeballSpriteId]); + sTradeAnim->state++; break; - case TS_STATE_NEW_MON_MSG: + case STATE_NEW_MON_MSG: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | @@ -3824,76 +3830,70 @@ static bool8 AnimateTradeSequenceCable(void) DISPCNT_OBJ_ON); StringExpandPlaceholders(gStringVar4, gText_XSentOverY); DrawTextOnTradeWindow(0, gStringVar4, 0); - sTradeData->state = TS_STATE_DELAY_FOR_MON_ANIM; - sTradeData->timer = 0; + sTradeAnim->state = STATE_DELAY_FOR_MON_ANIM; + sTradeAnim->timer = 0; break; - case TS_STATE_DELAY_FOR_MON_ANIM: - if (++sTradeData->timer > 60) + case STATE_DELAY_FOR_MON_ANIM: + if (++sTradeAnim->timer > 60) { - sTradeData->state = TS_STATE_WAIT_FOR_MON_CRY; - sTradeData->timer = 0; + sTradeAnim->state = STATE_WAIT_FOR_MON_CRY; + sTradeAnim->timer = 0; } break; - case TS_STATE_WAIT_FOR_MON_CRY: + case STATE_WAIT_FOR_MON_CRY: if (IsCryFinished()) - sTradeData->state = TS_STATE_TAKE_CARE_OF_MON; + sTradeAnim->state = STATE_TAKE_CARE_OF_MON; break; - case TS_STATE_TAKE_CARE_OF_MON: - if (++sTradeData->timer == 10) + case STATE_TAKE_CARE_OF_MON: + if (++sTradeAnim->timer == 10) PlayFanfare(MUS_EVOLVED); - if (sTradeData->timer == 250) + if (sTradeAnim->timer == 250) { - sTradeData->state++; + sTradeAnim->state++; StringExpandPlaceholders(gStringVar4, gText_TakeGoodCareOfX); DrawTextOnTradeWindow(0, gStringVar4, 0); - sTradeData->timer = 0; + sTradeAnim->timer = 0; } break; - case TS_STATE_AFTER_NEW_MON_DELAY: - if (++sTradeData->timer == 60) - sTradeData->state++; + case STATE_AFTER_NEW_MON_DELAY: + if (++sTradeAnim->timer == 60) + sTradeAnim->state++; break; - case TS_STATE_CHECK_RIBBONS: + case STATE_CHECK_RIBBONS: CheckPartnersMonForRibbons(); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_END_LINK_TRADE: - if (sTradeData->isLinkTrade) - { + case STATE_END_LINK_TRADE: + if (sTradeAnim->isLinkTrade) return TRUE; - } else if (JOY_NEW(A_BUTTON)) - { - sTradeData->state++; - } + sTradeAnim->state++; break; - case TS_STATE_TRY_EVOLUTION: // Only if in-game trade, link trades use CB2_TryLinkTradeEvolution + case STATE_TRY_EVOLUTION: // Only if in-game trade, link trades use CB2_TryLinkTradeEvolution TradeMons(gSpecialVar_0x8005, 0); - gCB2_AfterEvolution = CB2_UpdateInGameTrade; + gCB2_AfterEvolution = CB2_InGameTrade; evoTarget = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE); if (evoTarget != SPECIES_NONE) - { - TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], evoTarget, sTradeData->monSpriteIds[TRADE_PARTNER], gSelectedTradeMonPositions[TRADE_PLAYER]); - } - sTradeData->state++; + TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], evoTarget, sTradeAnim->monSpriteIds[TRADE_PARTNER], gSelectedTradeMonPositions[TRADE_PLAYER]); + sTradeAnim->state++; break; - case TS_STATE_FADE_OUT_END: + case STATE_FADE_OUT_END: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_WAIT_FADE_OUT_END: + case STATE_WAIT_FADE_OUT_END: if (!gPaletteFade.active) { - PlayNewMapMusic(sTradeData->cachedMapMusic); - if (sTradeData) + PlayNewMapMusic(sTradeAnim->cachedMapMusic); + if (sTradeAnim) { FreeAllWindowBuffers(); Free(GetBgTilemapBuffer(3)); Free(GetBgTilemapBuffer(1)); Free(GetBgTilemapBuffer(0)); FreeMonSpritesGfx(); - FREE_AND_SET_NULL(sTradeData); + FREE_AND_SET_NULL(sTradeAnim); } SetMainCallback2(CB2_ReturnToField); BufferInGameTradeMonName(); @@ -3903,111 +3903,116 @@ static bool8 AnimateTradeSequenceCable(void) return FALSE; } -static bool8 AnimateTradeSequenceWireless(void) +// Task data for Task_AnimateWirelessSignal +#define tIdx data[0] +#define tCounter data[1] +#define tSignalComingBack data[2] + +static bool8 DoTradeAnim_Wireless(void) { u16 evoTarget; - switch (sTradeData->state) + switch (sTradeAnim->state) { - case TS_STATE_START: - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].invisible = FALSE; - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].x2 = -180; - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].y2 = gMonFrontPicCoords[sTradeData->monSpecies[TRADE_PLAYER]].y_offset; - sTradeData->state++; - sTradeData->cachedMapMusic = GetCurrentMapMusic(); + case STATE_START: + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].invisible = FALSE; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].x2 = -180; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 = gMonFrontPicCoords[sTradeAnim->monSpecies[TRADE_PLAYER]].y_offset; + sTradeAnim->state++; + sTradeAnim->cachedMapMusic = GetCurrentMapMusic(); PlayNewMapMusic(MUS_EVOLUTION); break; - case TS_STATE_MON_SLIDE_IN: - if (sTradeData->bg2hofs > 0) + case STATE_MON_SLIDE_IN: + if (sTradeAnim->bg2hofs > 0) { - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].x2 += 3; - sTradeData->bg2hofs -= 3; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].x2 += 3; + sTradeAnim->bg2hofs -= 3; } else { - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].x2 = 0; - sTradeData->bg2hofs = 0; - sTradeData->state = TS_STATE_SEND_MSG; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].x2 = 0; + sTradeAnim->bg2hofs = 0; + sTradeAnim->state = STATE_SEND_MSG; } break; - case TS_STATE_SEND_MSG: + case STATE_SEND_MSG: StringExpandPlaceholders(gStringVar4, gText_XWillBeSentToY); DrawTextOnTradeWindow(0, gStringVar4, 0); - if (sTradeData->monSpecies[TRADE_PLAYER] != SPECIES_EGG) - PlayCry_Normal(sTradeData->monSpecies[TRADE_PLAYER], 0); + if (sTradeAnim->monSpecies[TRADE_PLAYER] != SPECIES_EGG) + PlayCry_Normal(sTradeAnim->monSpecies[TRADE_PLAYER], 0); - sTradeData->state = TS_STATE_BYE_BYE; - sTradeData->timer = 0; + sTradeAnim->state = STATE_BYE_BYE; + sTradeAnim->timer = 0; break; - case TS_STATE_BYE_BYE: - if (++sTradeData->timer == 80) + case STATE_BYE_BYE: + if (++sTradeAnim->timer == 80) { - sTradeData->releasePokeballSpriteId = CreateTradePokeballSprite(sTradeData->monSpriteIds[0], gSprites[sTradeData->monSpriteIds[0]].oam.paletteNum, 120, 32, 2, 1, 0x14, 0xfffff); - sTradeData->state++; + sTradeAnim->releasePokeballSpriteId = CreateTradePokeballSprite(sTradeAnim->monSpriteIds[TRADE_PLAYER], gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].oam.paletteNum, 120, 32, 2, 1, 0x14, 0xfffff); + sTradeAnim->state++; StringExpandPlaceholders(gStringVar4, gText_ByeByeVar1); DrawTextOnTradeWindow(0, gStringVar4, 0); } break; - case TS_STATE_POKEBALL_DEPART: - if (gSprites[sTradeData->releasePokeballSpriteId].callback == SpriteCallbackDummy) + case STATE_POKEBALL_DEPART: + if (gSprites[sTradeAnim->releasePokeballSpriteId].callback == SpriteCallbackDummy) { - sTradeData->bouncingPokeballSpriteId = CreateSprite(&sSpriteTemplate_Pokeball, 120, 32, 0); - gSprites[sTradeData->bouncingPokeballSpriteId].callback = SpriteCB_BouncingPokeballDepart; - DestroySprite(&gSprites[sTradeData->releasePokeballSpriteId]); - sTradeData->state++; + sTradeAnim->bouncingPokeballSpriteId = CreateSprite(&sSpriteTemplate_Pokeball, 120, 32, 0); + gSprites[sTradeAnim->bouncingPokeballSpriteId].callback = SpriteCB_BouncingPokeballDepart; + DestroySprite(&gSprites[sTradeAnim->releasePokeballSpriteId]); + sTradeAnim->state++; } break; - case TS_STATE_POKEBALL_DEPART_WAIT: + case STATE_POKEBALL_DEPART_WAIT: // The game waits here for the sprite to finish its animation sequence. break; - case TS_STATE_FADE_OUT_TO_GBA_SEND: + case STATE_FADE_OUT_TO_GBA_SEND: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeData->state = TS_STATE_WAIT_FADE_OUT_TO_GBA_SEND; + sTradeAnim->state = STATE_WAIT_FADE_OUT_TO_GBA_SEND; break; - case TS_STATE_WAIT_FADE_OUT_TO_GBA_SEND: + case STATE_WAIT_FADE_OUT_TO_GBA_SEND: if (!gPaletteFade.active) { SetTradeSequenceBgGpuRegs(4); FillWindowPixelBuffer(0, PIXEL_FILL(15)); CopyWindowToVram(0, COPYWIN_FULL); - sTradeData->state++; + sTradeAnim->state++; } break; - case TS_STATE_FADE_IN_TO_GBA_SEND: + case STATE_FADE_IN_TO_GBA_SEND: BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_WAIT_FADE_IN_TO_GBA_SEND: + case STATE_WAIT_FADE_IN_TO_GBA_SEND: if (!gPaletteFade.active) - sTradeData->state = TS_STATE_GBA_ZOOM_OUT; + sTradeAnim->state = STATE_GBA_ZOOM_OUT; break; - case TS_STATE_GBA_ZOOM_OUT: - if (sTradeData->gbaScale > 0x100) + case STATE_GBA_ZOOM_OUT: + if (sTradeAnim->gbaScale > 0x100) { - sTradeData->gbaScale -= 0x34; + sTradeAnim->gbaScale -= 0x34; } else { SetTradeSequenceBgGpuRegs(1); - sTradeData->gbaScale = 0x80; - sTradeData->state = TS_STATE_GBA_FLASH_SEND_WIRELESS; - sTradeData->timer = 0; + sTradeAnim->gbaScale = 0x80; + sTradeAnim->state = STATE_GBA_FLASH_SEND_WIRELESS; + sTradeAnim->timer = 0; } - sTradeData->sXY = 0x8000 / sTradeData->gbaScale; + sTradeAnim->sXY = 0x8000 / sTradeAnim->gbaScale; break; - case TS_STATE_GBA_FLASH_SEND_WIRELESS: - if (++sTradeData->timer > 20) + case STATE_GBA_FLASH_SEND_WIRELESS: + if (++sTradeAnim->timer > 20) { SetTradeSequenceBgGpuRegs(3); - sTradeData->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_GbaScreenFlash_Short, 120, 80, 0); - sTradeData->state++; + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_GbaScreenFlash_Short, 120, 80, 0); + sTradeAnim->state++; } break; - case TS_STATE_GBA_STOP_FLASH_SEND_WIRELESS: - if (gSprites[sTradeData->connectionSpriteId2].animEnded) + case STATE_GBA_STOP_FLASH_SEND_WIRELESS: + if (gSprites[sTradeAnim->connectionSpriteId2].animEnded) { - DestroySprite(&gSprites[sTradeData->connectionSpriteId2]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG1 | BLDCNT_TGT1_OBJ | BLDCNT_EFFECT_BLEND | @@ -4016,307 +4021,305 @@ static bool8 AnimateTradeSequenceWireless(void) // Start wireless signal effect CreateTask(Task_AnimateWirelessSignal, 5); - sTradeData->state++; + sTradeAnim->state++; } break; - case TS_STATE_WAIT_WIRELESS_SIGNAL_SEND: + case STATE_WAIT_WIRELESS_SIGNAL_SEND: if (!FuncIsActiveTask(Task_AnimateWirelessSignal)) - sTradeData->state = TS_STATE_PAN_AWAY_GBA; + sTradeAnim->state = STATE_PAN_AWAY_GBA; break; - case TS_STATE_PAN_AWAY_GBA: - if (--sTradeData->bg1vofs == 316) - sTradeData->state++; + case STATE_PAN_AWAY_GBA: + if (--sTradeAnim->bg1vofs == 316) + sTradeAnim->state++; break; - case TS_STATE_CREATE_LINK_MON_LEAVING: - sTradeData->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonGlow, 120, 80, 3); - gSprites[sTradeData->connectionSpriteId1].callback = SpriteCB_LinkMonGlowWireless; - sTradeData->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 120, 80, 0); - StartSpriteAnim(&gSprites[sTradeData->connectionSpriteId2], ANIM_LINKMON_SMALL); - sTradeData->state++; + case STATE_CREATE_LINK_MON_LEAVING: + sTradeAnim->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonGlow, 120, 80, 3); + gSprites[sTradeAnim->connectionSpriteId1].callback = SpriteCB_LinkMonGlowWireless; + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 120, 80, 0); + StartSpriteAnim(&gSprites[sTradeAnim->connectionSpriteId2], ANIM_LINKMON_SMALL); + sTradeAnim->state++; break; - case TS_STATE_LINK_MON_TRAVEL_OUT: - if ((sTradeData->bg1vofs -= 3) == 166) - sTradeData->state = TS_STATE_LINK_MON_TRAVEL_OFFSCREEN; + case STATE_LINK_MON_TRAVEL_OUT: + if ((sTradeAnim->bg1vofs -= 3) == 166) + sTradeAnim->state = STATE_LINK_MON_TRAVEL_OFFSCREEN; SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_1 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_OBJ_ON); break; - case TS_STATE_LINK_MON_TRAVEL_OFFSCREEN: - gSprites[sTradeData->connectionSpriteId1].y -= 2; - gSprites[sTradeData->connectionSpriteId2].y -= 2; - if (gSprites[sTradeData->connectionSpriteId1].y < -8) - { - sTradeData->state = TS_STATE_FADE_OUT_TO_CROSSING; - } + case STATE_LINK_MON_TRAVEL_OFFSCREEN: + gSprites[sTradeAnim->connectionSpriteId1].y -= 2; + gSprites[sTradeAnim->connectionSpriteId2].y -= 2; + if (gSprites[sTradeAnim->connectionSpriteId1].y < -8) + sTradeAnim->state = STATE_FADE_OUT_TO_CROSSING; break; - case TS_STATE_FADE_OUT_TO_CROSSING: + case STATE_FADE_OUT_TO_CROSSING: BeginNormalPaletteFade(PALETTES_ALL, -1, 0, 16, RGB_BLACK); - sTradeData->state = TS_STATE_WAIT_FADE_OUT_TO_CROSSING; + sTradeAnim->state = STATE_WAIT_FADE_OUT_TO_CROSSING; break; - case TS_STATE_WAIT_FADE_OUT_TO_CROSSING: + case STATE_WAIT_FADE_OUT_TO_CROSSING: if (!gPaletteFade.active) { - DestroySprite(&gSprites[sTradeData->connectionSpriteId1]); - DestroySprite(&gSprites[sTradeData->connectionSpriteId2]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId1]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); SetTradeSequenceBgGpuRegs(2); - sTradeData->state++; + sTradeAnim->state++; } break; - case TS_STATE_FADE_IN_TO_CROSSING: + case STATE_FADE_IN_TO_CROSSING: BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_BLACK); - sTradeData->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 111, 170, 0); - sTradeData->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 129, -10, 0); - sTradeData->state++; + sTradeAnim->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 111, 170, 0); + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 129, -10, 0); + sTradeAnim->state++; break; - case TS_STATE_WAIT_FADE_IN_TO_CROSSING: + case STATE_WAIT_FADE_IN_TO_CROSSING: if (!gPaletteFade.active) { PlaySE(SE_WARP_OUT); - sTradeData->state++; + sTradeAnim->state++; } - gSprites[sTradeData->connectionSpriteId1].y2 -= 3; - gSprites[sTradeData->connectionSpriteId2].y2 += 3; + gSprites[sTradeAnim->connectionSpriteId1].y2 -= 3; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 3; break; - case TS_STATE_CROSSING_LINK_MONS_ENTER: - gSprites[sTradeData->connectionSpriteId1].y2 -= 3; - gSprites[sTradeData->connectionSpriteId2].y2 += 3; - if (gSprites[sTradeData->connectionSpriteId1].y2 <= -90) + case STATE_CROSSING_LINK_MONS_ENTER: + gSprites[sTradeAnim->connectionSpriteId1].y2 -= 3; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 3; + if (gSprites[sTradeAnim->connectionSpriteId1].y2 <= -90) { - gSprites[sTradeData->connectionSpriteId1].data[1] = 1; - gSprites[sTradeData->connectionSpriteId2].data[1] = 1; - sTradeData->state++; - CreateTask(Task_NarrowWindowForCrossing_Wireless, 5); + gSprites[sTradeAnim->connectionSpriteId1].data[1] = 1; + gSprites[sTradeAnim->connectionSpriteId2].data[1] = 1; + sTradeAnim->state++; + CreateTask(Task_OpenCenterWhiteColumn, 5); } break; - case TS_STATE_CROSSING_BLEND_WHITE_1: + case STATE_CROSSING_BLEND_WHITE_1: BlendPalettes(0x8, 16, RGB_WHITEALPHA); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_CROSSING_BLEND_WHITE_2: + case STATE_CROSSING_BLEND_WHITE_2: BlendPalettes(0x8, 16, RGB_WHITEALPHA); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_CROSSING_BLEND_WHITE_3: + case STATE_CROSSING_BLEND_WHITE_3: BlendPalettes(0x8, 16, RGB_WHITEALPHA); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_CROSSING_CREATE_MON_PICS: - if (!IsMonSpriteNotFlipped(sTradeData->monSpecies[TRADE_PLAYER])) + case STATE_CROSSING_CREATE_MON_PICS: + if (!IsMonSpriteNotFlipped(sTradeAnim->monSpecies[TRADE_PLAYER])) { - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].affineAnims = sAffineAnims_CrossingMonPics; - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].oam.affineMode = ST_OAM_AFFINE_DOUBLE; - CalcCenterToCornerVec(&gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]], SPRITE_SHAPE(64x64), SPRITE_SIZE(64x64), ST_OAM_AFFINE_DOUBLE); - StartSpriteAffineAnim(&gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]], 0); + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].affineAnims = sAffineAnims_CrossingMonPics; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].oam.affineMode = ST_OAM_AFFINE_DOUBLE; + CalcCenterToCornerVec(&gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]], SPRITE_SHAPE(64x64), SPRITE_SIZE(64x64), ST_OAM_AFFINE_DOUBLE); + StartSpriteAffineAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]], 0); } else { - StartSpriteAffineAnim(&gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]], 0); + StartSpriteAffineAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]], 0); } - StartSpriteAffineAnim(&gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]], 0); - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].x = 40; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].x = 200; - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].y = 192; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].y = -32; - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].invisible = FALSE; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].invisible = FALSE; - sTradeData->state++; + StartSpriteAffineAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]], 0); + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].x = 40; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].x = 200; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y = 192; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y = -32; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].invisible = FALSE; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].invisible = FALSE; + sTradeAnim->state++; break; - case TS_STATE_CROSSING_MON_PICS_MOVE: - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].y2 -= 3; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].y2 += 3; - if (gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].y2 < -DISPLAY_HEIGHT - && gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].y2 >= -DISPLAY_HEIGHT - 3) + case STATE_CROSSING_MON_PICS_MOVE: + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 -= 3; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y2 += 3; + if (gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 < -DISPLAY_HEIGHT + && gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 >= -DISPLAY_HEIGHT - 3) { PlaySE(SE_WARP_IN); } - if (gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].y2 < -222) + if (gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].y2 < -222) { - gSprites[sTradeData->connectionSpriteId1].data[1] = 0; - gSprites[sTradeData->connectionSpriteId2].data[1] = 0; - sTradeData->state++; - gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]].invisible = TRUE; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].invisible = TRUE; - CreateTask(Task_NarrowWindowForCrossing_Cable, 5); + gSprites[sTradeAnim->connectionSpriteId1].data[1] = 0; + gSprites[sTradeAnim->connectionSpriteId2].data[1] = 0; + sTradeAnim->state++; + gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]].invisible = TRUE; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].invisible = TRUE; + CreateTask(Task_CloseCenterWhiteColumn, 5); } break; - case TS_STATE_CROSSING_LINK_MONS_EXIT: - gSprites[sTradeData->connectionSpriteId1].y2 -= 3; - gSprites[sTradeData->connectionSpriteId2].y2 += 3; - if (gSprites[sTradeData->connectionSpriteId1].y2 <= -222) + case STATE_CROSSING_LINK_MONS_EXIT: + gSprites[sTradeAnim->connectionSpriteId1].y2 -= 3; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 3; + if (gSprites[sTradeAnim->connectionSpriteId1].y2 <= -222) { BeginNormalPaletteFade(PALETTES_ALL, -1, 0, 16, RGB_BLACK); - sTradeData->state++; - DestroySprite(&gSprites[sTradeData->connectionSpriteId1]); - DestroySprite(&gSprites[sTradeData->connectionSpriteId2]); + sTradeAnim->state++; + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId1]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); } break; - case TS_STATE_CREATE_LINK_MON_ARRIVING: + case STATE_CREATE_LINK_MON_ARRIVING: if (!gPaletteFade.active) { - sTradeData->state++; + sTradeAnim->state++; SetTradeSequenceBgGpuRegs(1); - sTradeData->bg1vofs = 166; + sTradeAnim->bg1vofs = 166; SetTradeSequenceBgGpuRegs(3); - sTradeData->bg2vofs = 412; - sTradeData->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonGlow, 120, -20, 3); - gSprites[sTradeData->connectionSpriteId1].callback = SpriteCB_LinkMonGlowWireless; - sTradeData->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 120, -20, 0); - StartSpriteAnim(&gSprites[sTradeData->connectionSpriteId2], ANIM_LINKMON_SMALL); + sTradeAnim->bg2vofs = 412; + sTradeAnim->connectionSpriteId1 = CreateSprite(&sSpriteTemplate_LinkMonGlow, 120, -20, 3); + gSprites[sTradeAnim->connectionSpriteId1].callback = SpriteCB_LinkMonGlowWireless; + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_LinkMonShadow, 120, -20, 0); + StartSpriteAnim(&gSprites[sTradeAnim->connectionSpriteId2], ANIM_LINKMON_SMALL); } break; - case TS_STATE_FADE_OUT_TO_GBA_RECV: + case STATE_FADE_OUT_TO_GBA_RECV: BeginNormalPaletteFade(PALETTES_ALL, -1, 16, 0, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_WAIT_FADE_OUT_TO_GBA_RECV: + case STATE_WAIT_FADE_OUT_TO_GBA_RECV: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_OBJ_ON); if (!gPaletteFade.active) - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_LINK_MON_TRAVEL_IN: - gSprites[sTradeData->connectionSpriteId1].y2 += 4; - gSprites[sTradeData->connectionSpriteId2].y2 += 4; - if (gSprites[sTradeData->connectionSpriteId1].y2 + gSprites[sTradeData->connectionSpriteId1].y == 64) + case STATE_LINK_MON_TRAVEL_IN: + gSprites[sTradeAnim->connectionSpriteId1].y2 += 4; + gSprites[sTradeAnim->connectionSpriteId2].y2 += 4; + if (gSprites[sTradeAnim->connectionSpriteId1].y2 + gSprites[sTradeAnim->connectionSpriteId1].y == 64) { - sTradeData->state = TS_STATE_PAN_TO_GBA_WIRELESS; - sTradeData->timer = 0; + sTradeAnim->state = STATE_PAN_TO_GBA_WIRELESS; + sTradeAnim->timer = 0; } break; - case TS_STATE_PAN_TO_GBA_WIRELESS: + case STATE_PAN_TO_GBA_WIRELESS: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG1_ON | DISPCNT_BG2_ON | DISPCNT_OBJ_ON); - sTradeData->bg1vofs += 3; - sTradeData->bg2vofs += 3; - if (++sTradeData->timer == 10) + sTradeAnim->bg1vofs += 3; + sTradeAnim->bg2vofs += 3; + if (++sTradeAnim->timer == 10) { u8 taskId = CreateTask(Task_AnimateWirelessSignal, 5); - gTasks[taskId].data[2] = TRUE; + gTasks[taskId].tSignalComingBack = TRUE; } - if (sTradeData->bg1vofs > 316) + if (sTradeAnim->bg1vofs > 316) { - sTradeData->bg1vofs = 316; - sTradeData->state++; + sTradeAnim->bg1vofs = 316; + sTradeAnim->state++; } break; - case TS_STATE_DESTROY_LINK_MON_WIRELESS: - DestroySprite(&gSprites[sTradeData->connectionSpriteId1]); - DestroySprite(&gSprites[sTradeData->connectionSpriteId2]); - sTradeData->state++; - sTradeData->timer = 0; + case STATE_DESTROY_LINK_MON_WIRELESS: + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId1]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); + sTradeAnim->state++; + sTradeAnim->timer = 0; break; - case TS_STATE_WAIT_WIRELESS_SIGNAL_RECV: + case STATE_WAIT_WIRELESS_SIGNAL_RECV: if (!FuncIsActiveTask(Task_AnimateWirelessSignal)) { - sTradeData->state = TS_STATE_LINK_MON_ARRIVED_DELAY; - sTradeData->timer = 0; + sTradeAnim->state = STATE_LINK_MON_ARRIVED_DELAY; + sTradeAnim->timer = 0; } break; - case TS_STATE_LINK_MON_ARRIVED_DELAY: - if (++sTradeData->timer == 10) - sTradeData->state++; + case STATE_LINK_MON_ARRIVED_DELAY: + if (++sTradeAnim->timer == 10) + sTradeAnim->state++; break; - case TS_STATE_MOVE_GBA_TO_CENTER: - if (++sTradeData->bg1vofs > 348) + case STATE_MOVE_GBA_TO_CENTER: + if (++sTradeAnim->bg1vofs > 348) { - sTradeData->bg1vofs = 348; - sTradeData->state++; + sTradeAnim->bg1vofs = 348; + sTradeAnim->state++; } break; - case TS_STATE_GBA_FLASH_RECV: - sTradeData->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_GbaScreenFlash_Long, 120, 80, 0); - sTradeData->state = TS_STATE_GBA_STOP_FLASH_RECV; + case STATE_GBA_FLASH_RECV: + sTradeAnim->connectionSpriteId2 = CreateSprite(&sSpriteTemplate_GbaScreenFlash_Long, 120, 80, 0); + sTradeAnim->state = STATE_GBA_STOP_FLASH_RECV; break; - case TS_STATE_GBA_STOP_FLASH_RECV: - if (gSprites[sTradeData->connectionSpriteId2].animEnded) + case STATE_GBA_STOP_FLASH_RECV: + if (gSprites[sTradeAnim->connectionSpriteId2].animEnded) { - DestroySprite(&gSprites[sTradeData->connectionSpriteId2]); + DestroySprite(&gSprites[sTradeAnim->connectionSpriteId2]); SetTradeSequenceBgGpuRegs(6); - sTradeData->state++; + sTradeAnim->state++; PlaySE(SE_M_SAND_ATTACK); } break; - case TS_STATE_GBA_ZOOM_IN: - if (sTradeData->gbaScale < 0x400) + case STATE_GBA_ZOOM_IN: + if (sTradeAnim->gbaScale < 0x400) { - sTradeData->gbaScale += 0x34; + sTradeAnim->gbaScale += 0x34; } else { - sTradeData->gbaScale = 0x400; - sTradeData->state++; + sTradeAnim->gbaScale = 0x400; + sTradeAnim->state++; } - sTradeData->sXY = 0x8000 / sTradeData->gbaScale; + sTradeAnim->sXY = 0x8000 / sTradeAnim->gbaScale; break; - case TS_STATE_FADE_OUT_TO_NEW_MON: + case STATE_FADE_OUT_TO_NEW_MON: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeData->state = TS_STATE_WAIT_FADE_OUT_TO_NEW_MON; + sTradeAnim->state = STATE_WAIT_FADE_OUT_TO_NEW_MON; break; - case TS_STATE_WAIT_FADE_OUT_TO_NEW_MON: + case STATE_WAIT_FADE_OUT_TO_NEW_MON: if (!gPaletteFade.active) { SetTradeSequenceBgGpuRegs(5); SetTradeSequenceBgGpuRegs(7); gPaletteFade.bufferTransferDisabled = TRUE; - sTradeData->state++; + sTradeAnim->state++; } break; - case TS_STATE_FADE_IN_TO_NEW_MON: + case STATE_FADE_IN_TO_NEW_MON: gPaletteFade.bufferTransferDisabled = FALSE; BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_WAIT_FADE_IN_TO_NEW_MON: + case STATE_WAIT_FADE_IN_TO_NEW_MON: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG2_ON | DISPCNT_OBJ_ON); if (!gPaletteFade.active) - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_POKEBALL_ARRIVE: - sTradeData->bouncingPokeballSpriteId = CreateSprite(&sSpriteTemplate_Pokeball, 120, -8, 0); - gSprites[sTradeData->bouncingPokeballSpriteId].data[3] = 74; - gSprites[sTradeData->bouncingPokeballSpriteId].callback = SpriteCB_BouncingPokeballArrive; - StartSpriteAnim(&gSprites[sTradeData->bouncingPokeballSpriteId], 1); - StartSpriteAffineAnim(&gSprites[sTradeData->bouncingPokeballSpriteId], 2); - BlendPalettes(1 << (16 + gSprites[sTradeData->bouncingPokeballSpriteId].oam.paletteNum), 16, RGB_WHITEALPHA); - sTradeData->state++; - sTradeData->timer = 0; + case STATE_POKEBALL_ARRIVE: + sTradeAnim->bouncingPokeballSpriteId = CreateSprite(&sSpriteTemplate_Pokeball, 120, -8, 0); + gSprites[sTradeAnim->bouncingPokeballSpriteId].data[3] = 74; + gSprites[sTradeAnim->bouncingPokeballSpriteId].callback = SpriteCB_BouncingPokeballArrive; + StartSpriteAnim(&gSprites[sTradeAnim->bouncingPokeballSpriteId], 1); + StartSpriteAffineAnim(&gSprites[sTradeAnim->bouncingPokeballSpriteId], 2); + BlendPalettes(1 << (16 + gSprites[sTradeAnim->bouncingPokeballSpriteId].oam.paletteNum), 16, RGB_WHITEALPHA); + sTradeAnim->state++; + sTradeAnim->timer = 0; break; - case TS_STATE_FADE_POKEBALL_TO_NORMAL: - BeginNormalPaletteFade(1 << (16 + gSprites[sTradeData->bouncingPokeballSpriteId].oam.paletteNum), 1, 16, 0, RGB_WHITEALPHA); - sTradeData->state++; + case STATE_FADE_POKEBALL_TO_NORMAL: + BeginNormalPaletteFade(1 << (16 + gSprites[sTradeAnim->bouncingPokeballSpriteId].oam.paletteNum), 1, 16, 0, RGB_WHITEALPHA); + sTradeAnim->state++; break; - case TS_STATE_POKEBALL_ARRIVE_WAIT: - if (gSprites[sTradeData->bouncingPokeballSpriteId].callback == SpriteCallbackDummy) + case STATE_POKEBALL_ARRIVE_WAIT: + if (gSprites[sTradeAnim->bouncingPokeballSpriteId].callback == SpriteCallbackDummy) { - HandleLoadSpecialPokePic_2(&gMonFrontPicTable[sTradeData->monSpecies[TRADE_PARTNER]], + HandleLoadSpecialPokePic_2(&gMonFrontPicTable[sTradeAnim->monSpecies[TRADE_PARTNER]], gMonSpritesGfxPtr->sprites.ptr[B_POSITION_OPPONENT_RIGHT], - sTradeData->monSpecies[TRADE_PARTNER], - sTradeData->monPersonalities[TRADE_PARTNER]); - sTradeData->state++; + sTradeAnim->monSpecies[TRADE_PARTNER], + sTradeAnim->monPersonalities[TRADE_PARTNER]); + sTradeAnim->state++; } break; - case TS_STATE_SHOW_NEW_MON: - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].x = 120; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].y = gMonFrontPicCoords[sTradeData->monSpecies[TRADE_PARTNER]].y_offset + 60; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].x2 = 0; - gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].y2 = 0; - StartSpriteAnim(&gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]], 0); - CreatePokeballSpriteToReleaseMon(sTradeData->monSpriteIds[TRADE_PARTNER], gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]].oam.paletteNum, 120, 84, 2, 1, 20, PALETTES_BG | (0xF << 16), sTradeData->monSpecies[TRADE_PARTNER]); - FreeSpriteOamMatrix(&gSprites[sTradeData->bouncingPokeballSpriteId]); - DestroySprite(&gSprites[sTradeData->bouncingPokeballSpriteId]); - sTradeData->state++; + case STATE_SHOW_NEW_MON: + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].x = 120; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y = gMonFrontPicCoords[sTradeAnim->monSpecies[TRADE_PARTNER]].y_offset + 60; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].x2 = 0; + gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].y2 = 0; + StartSpriteAnim(&gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]], 0); + CreatePokeballSpriteToReleaseMon(sTradeAnim->monSpriteIds[TRADE_PARTNER], gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]].oam.paletteNum, 120, 84, 2, 1, 20, PALETTES_BG | (0xF << 16), sTradeAnim->monSpecies[TRADE_PARTNER]); + FreeSpriteOamMatrix(&gSprites[sTradeAnim->bouncingPokeballSpriteId]); + DestroySprite(&gSprites[sTradeAnim->bouncingPokeballSpriteId]); + sTradeAnim->state++; break; - case TS_STATE_NEW_MON_MSG: + case STATE_NEW_MON_MSG: SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON | @@ -4324,76 +4327,70 @@ static bool8 AnimateTradeSequenceWireless(void) DISPCNT_OBJ_ON); StringExpandPlaceholders(gStringVar4, gText_XSentOverY); DrawTextOnTradeWindow(0, gStringVar4, 0); - sTradeData->state = TS_STATE_DELAY_FOR_MON_ANIM; - sTradeData->timer = 0; + sTradeAnim->state = STATE_DELAY_FOR_MON_ANIM; + sTradeAnim->timer = 0; break; - case TS_STATE_DELAY_FOR_MON_ANIM: - if (++sTradeData->timer > 60) + case STATE_DELAY_FOR_MON_ANIM: + if (++sTradeAnim->timer > 60) { - sTradeData->state = TS_STATE_WAIT_FOR_MON_CRY; - sTradeData->timer = 0; + sTradeAnim->state = STATE_WAIT_FOR_MON_CRY; + sTradeAnim->timer = 0; } break; - case TS_STATE_WAIT_FOR_MON_CRY: + case STATE_WAIT_FOR_MON_CRY: if (IsCryFinished()) - sTradeData->state = TS_STATE_TAKE_CARE_OF_MON; + sTradeAnim->state = STATE_TAKE_CARE_OF_MON; break; - case TS_STATE_TAKE_CARE_OF_MON: - if (++sTradeData->timer == 10) + case STATE_TAKE_CARE_OF_MON: + if (++sTradeAnim->timer == 10) PlayFanfare(MUS_EVOLVED); - if (sTradeData->timer == 250) + if (sTradeAnim->timer == 250) { - sTradeData->state++; + sTradeAnim->state++; StringExpandPlaceholders(gStringVar4, gText_TakeGoodCareOfX); DrawTextOnTradeWindow(0, gStringVar4, 0); - sTradeData->timer = 0; + sTradeAnim->timer = 0; } break; - case TS_STATE_AFTER_NEW_MON_DELAY: - if (++sTradeData->timer == 60) - sTradeData->state++; + case STATE_AFTER_NEW_MON_DELAY: + if (++sTradeAnim->timer == 60) + sTradeAnim->state++; break; - case TS_STATE_CHECK_RIBBONS: + case STATE_CHECK_RIBBONS: CheckPartnersMonForRibbons(); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_END_LINK_TRADE: - if (sTradeData->isLinkTrade) - { + case STATE_END_LINK_TRADE: + if (sTradeAnim->isLinkTrade) return TRUE; - } else if (JOY_NEW(A_BUTTON)) - { - sTradeData->state++; - } + sTradeAnim->state++; break; - case TS_STATE_TRY_EVOLUTION: // Only if in-game trade, link trades use CB2_TryLinkTradeEvolution + case STATE_TRY_EVOLUTION: // Only if in-game trade, link trades use CB2_TryLinkTradeEvolution TradeMons(gSpecialVar_0x8005, 0); - gCB2_AfterEvolution = CB2_UpdateInGameTrade; + gCB2_AfterEvolution = CB2_InGameTrade; evoTarget = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE); if (evoTarget != SPECIES_NONE) - { - TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], evoTarget, sTradeData->monSpriteIds[TRADE_PARTNER], gSelectedTradeMonPositions[TRADE_PLAYER]); - } - sTradeData->state++; + TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], evoTarget, sTradeAnim->monSpriteIds[TRADE_PARTNER], gSelectedTradeMonPositions[TRADE_PLAYER]); + sTradeAnim->state++; break; - case TS_STATE_FADE_OUT_END: + case STATE_FADE_OUT_END: BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); - sTradeData->state++; + sTradeAnim->state++; break; - case TS_STATE_WAIT_FADE_OUT_END: + case STATE_WAIT_FADE_OUT_END: if (!gPaletteFade.active) { - PlayNewMapMusic(sTradeData->cachedMapMusic); - if (sTradeData) + PlayNewMapMusic(sTradeAnim->cachedMapMusic); + if (sTradeAnim) { FreeAllWindowBuffers(); Free(GetBgTilemapBuffer(3)); Free(GetBgTilemapBuffer(1)); Free(GetBgTilemapBuffer(0)); FreeMonSpritesGfx(); - FREE_AND_SET_NULL(sTradeData); + FREE_AND_SET_NULL(sTradeAnim); } SetMainCallback2(CB2_ReturnToField); BufferInGameTradeMonName(); @@ -4404,7 +4401,7 @@ static bool8 AnimateTradeSequenceWireless(void) } // Try to evolve a Pokémon received in a link trade -// In-game trades resolve evolution during the trade sequence, in TS_STATE_TRY_EVOLUTION +// In-game trades resolve evolution during the trade sequence, in STATE_TRY_EVOLUTION static void CB2_TryLinkTradeEvolution(void) { u16 evoTarget; @@ -4418,7 +4415,7 @@ static void CB2_TryLinkTradeEvolution(void) gCB2_AfterEvolution = CB2_SaveAndEndTrade; evoTarget = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE); if (evoTarget != SPECIES_NONE) - TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], evoTarget, sTradeData->monSpriteIds[TRADE_PARTNER], gSelectedTradeMonPositions[TRADE_PLAYER]); + TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], evoTarget, sTradeAnim->monSpriteIds[TRADE_PARTNER], gSelectedTradeMonPositions[TRADE_PLAYER]); else if (IsWirelessTrade()) SetMainCallback2(CB2_SaveAndEndWirelessTrade); else @@ -4433,25 +4430,25 @@ static void CB2_TryLinkTradeEvolution(void) UpdatePaletteFade(); } -static void UpdateTradeFinishFlags(void) +static void HandleLinkDataReceive(void) { - u8 blockReceivedStatus; + u8 recvStatus; TradeGetMultiplayerId(); // no effect call, ret val ignored - blockReceivedStatus = GetBlockReceivedStatus(); - if (blockReceivedStatus & 0x01) + recvStatus = GetBlockReceivedStatus(); + if (recvStatus & (1 << 0)) { if (gBlockRecvBuffer[0][0] == LINKCMD_CONFIRM_FINISH_TRADE) SetMainCallback2(CB2_TryLinkTradeEvolution); if (gBlockRecvBuffer[0][0] == LINKCMD_READY_FINISH_TRADE) - sTradeData->playerLinkFlagFinishTrade = STATUS_READY; + sTradeAnim->playerFinishStatus = STATUS_READY; ResetBlockReceivedFlag(0); } - if (blockReceivedStatus & 0x02) + if (recvStatus & (1 << 1)) { if (gBlockRecvBuffer[1][0] == LINKCMD_READY_FINISH_TRADE) - sTradeData->partnerLinkFlagFinishTrade = STATUS_READY; + sTradeAnim->partnerFinishStatus = STATUS_READY; ResetBlockReceivedFlag(1); } @@ -4502,7 +4499,7 @@ static void SpriteCB_BouncingPokeballDepartEnd(struct Sprite *sprite) if (++ sprite->data[0] == 23) { DestroySprite(sprite); - sTradeData->state = TS_STATE_FADE_OUT_TO_GBA_SEND; // Resume the master trade animation + sTradeAnim->state = STATE_FADE_OUT_TO_GBA_SEND; // Resume the master trade animation } } } @@ -4549,14 +4546,14 @@ static void BufferInGameTradeMonName(void) StringCopy(gStringVar2, gSpeciesNames[inGameTrade->species]); } -static void _CreateInGameTradePokemon(u8 whichPlayerMon, u8 whichInGameTrade) +static void CreateInGameTradePokemonInternal(u8 whichPlayerMon, u8 whichInGameTrade) { const struct InGameTrade *inGameTrade = &sIngameTrades[whichInGameTrade]; u8 level = GetMonData(&gPlayerParty[whichPlayerMon], MON_DATA_LEVEL); struct Mail mail; u8 metLocation = METLOC_IN_GAME_TRADE; - u8 isMail; + u8 mailNum; struct Pokemon *pokemon = &gEnemyParty[0]; CreateMon(pokemon, inGameTrade->species, level, USE_RANDOM_IVS, TRUE, inGameTrade->personality, OT_ID_PRESET, inGameTrade->otId); @@ -4579,14 +4576,14 @@ static void _CreateInGameTradePokemon(u8 whichPlayerMon, u8 whichInGameTrade) SetMonData(pokemon, MON_DATA_SHEEN, &inGameTrade->sheen); SetMonData(pokemon, MON_DATA_MET_LOCATION, &metLocation); - isMail = FALSE; + mailNum = 0; if (inGameTrade->heldItem != ITEM_NONE) { if (ItemIsMail(inGameTrade->heldItem)) { - SetInGameTradeMail(&mail, inGameTrade); + GetInGameTradeMail(&mail, inGameTrade); gTradeMail[0] = mail; - SetMonData(pokemon, MON_DATA_MAIL, &isMail); + SetMonData(pokemon, MON_DATA_MAIL, &mailNum); SetMonData(pokemon, MON_DATA_HELD_ITEM, &inGameTrade->heldItem); } else @@ -4597,14 +4594,12 @@ static void _CreateInGameTradePokemon(u8 whichPlayerMon, u8 whichInGameTrade) CalculateMonStats(&gEnemyParty[0]); } -static void SetInGameTradeMail(struct Mail *mail, const struct InGameTrade *trade) +static void GetInGameTradeMail(struct Mail *mail, const struct InGameTrade *trade) { s32 i; for (i = 0; i < MAIL_WORDS_COUNT; i++) - { mail->words[i] = sIngameTradeMail[trade->mailNum][i]; - } StringCopy(mail->playerName, trade->otName); PadNameString(mail->playerName, CHAR_SPACE); @@ -4626,25 +4621,25 @@ u16 GetTradeSpecies(void) void CreateInGameTradePokemon(void) { - _CreateInGameTradePokemon(gSpecialVar_0x8005, gSpecialVar_0x8004); + CreateInGameTradePokemonInternal(gSpecialVar_0x8005, gSpecialVar_0x8004); } static void CB2_UpdateLinkTrade(void) { - if (AnimateTradeSequence() == TRUE) + if (DoTradeAnim() == TRUE) { - DestroySprite(&gSprites[sTradeData->monSpriteIds[TRADE_PLAYER]]); - FreeSpriteOamMatrix(&gSprites[sTradeData->monSpriteIds[TRADE_PARTNER]]); + DestroySprite(&gSprites[sTradeAnim->monSpriteIds[TRADE_PLAYER]]); + FreeSpriteOamMatrix(&gSprites[sTradeAnim->monSpriteIds[TRADE_PARTNER]]); TradeMons(gSelectedTradeMonPositions[TRADE_PLAYER], gSelectedTradeMonPositions[TRADE_PARTNER] % PARTY_SIZE); if (!IsWirelessTrade()) { - sTradeData->linkData[0] = LINKCMD_READY_FINISH_TRADE; - sTradeData->sendTradeFinishState = 1; + sTradeAnim->linkData[0] = LINKCMD_READY_FINISH_TRADE; + sTradeAnim->scheduleLinkTransfer = 1; } - SetMainCallback2(CB2_TryFinishTrade); + SetMainCallback2(CB2_WaitTradeComplete); } - TrySendTradeFinishData(); - UpdateTradeFinishFlags(); + HandleLinkDataSend(); + HandleLinkDataReceive(); RunTasks(); RunTextPrinters(); AnimateSprites(); @@ -4652,7 +4647,7 @@ static void CB2_UpdateLinkTrade(void) UpdatePaletteFade(); } -static void CB2_TryFinishTrade(void) +static void CB2_WaitTradeComplete(void) { u8 mpId = TradeGetMultiplayerId(); if (IsWirelessTrade()) @@ -4661,15 +4656,15 @@ static void CB2_TryFinishTrade(void) } else { - UpdateTradeFinishFlags(); + HandleLinkDataReceive(); if (mpId == 0 - && sTradeData->playerLinkFlagFinishTrade == STATUS_READY - && sTradeData->partnerLinkFlagFinishTrade == STATUS_READY) + && sTradeAnim->playerFinishStatus == STATUS_READY + && sTradeAnim->partnerFinishStatus == STATUS_READY) { - sTradeData->linkData[0] = LINKCMD_CONFIRM_FINISH_TRADE; - SendBlock(BitmaskAllOtherLinkPlayers(), sTradeData->linkData, sizeof(sTradeData->linkData)); - sTradeData->playerLinkFlagFinishTrade = STATUS_CANCEL; - sTradeData->partnerLinkFlagFinishTrade = STATUS_CANCEL; + sTradeAnim->linkData[0] = LINKCMD_CONFIRM_FINISH_TRADE; + SendBlock(BitmaskAllOtherLinkPlayers(), sTradeAnim->linkData, sizeof(sTradeAnim->linkData)); + sTradeAnim->playerFinishStatus = STATUS_CANCEL; + sTradeAnim->partnerFinishStatus = STATUS_CANCEL; } } RunTasks(); @@ -4690,24 +4685,20 @@ static void CB2_SaveAndEndTrade(void) case 1: SetTradeLinkStandbyCallback(0); gMain.state = 100; - sTradeData->timer = 0; + sTradeAnim->timer = 0; break; case 100: - if (++sTradeData->timer > 180) + if (++sTradeAnim->timer > 180) { gMain.state = 101; - sTradeData->timer = 0; + sTradeAnim->timer = 0; } if (_IsLinkTaskFinished()) - { gMain.state = 2; - } break; case 101: if (_IsLinkTaskFinished()) - { gMain.state = 2; - } break; case 2: gMain.state = 50; @@ -4723,10 +4714,10 @@ static void CB2_SaveAndEndTrade(void) SetContinueGameWarpStatusToDynamicWarp(); LinkFullSave_Init(); gMain.state++; - sTradeData->timer = 0; + sTradeAnim->timer = 0; break; case 51: - if (++sTradeData->timer == 5) + if (++sTradeAnim->timer == 5) gMain.state++; break; case 52: @@ -4738,38 +4729,34 @@ static void CB2_SaveAndEndTrade(void) else { // Save isn't finished, delay again - sTradeData->timer = 0; + sTradeAnim->timer = 0; gMain.state = 51; } break; case 4: LinkFullSave_ReplaceLastSector(); gMain.state = 40; - sTradeData->timer = 0; + sTradeAnim->timer = 0; break; case 40: - if (++sTradeData->timer > 50) + if (++sTradeAnim->timer > 50) { if (GetMultiplayerId() == 0) - { - sTradeData->timer = Random() % 30; - } + sTradeAnim->timer = Random() % 30; else - { - sTradeData->timer = 0; - } + sTradeAnim->timer = 0; gMain.state = 41; } break; case 41: - if (sTradeData->timer == 0) + if (sTradeAnim->timer == 0) { SetTradeLinkStandbyCallback(1); gMain.state = 42; } else { - sTradeData->timer--; + sTradeAnim->timer--; } break; case 42: @@ -4780,7 +4767,7 @@ static void CB2_SaveAndEndTrade(void) } break; case 5: - if (++sTradeData->timer > 60) + if (++sTradeAnim->timer > 60) { gMain.state++; SetTradeLinkStandbyCallback(2); @@ -4804,13 +4791,9 @@ static void CB2_SaveAndEndTrade(void) if (IsBGMStopped() == TRUE) { if (gWirelessCommType && gMain.savedCallback == CB2_StartCreateTradeMenu) - { SetTradeLinkStandbyCallback(3); - } else - { SetCloseLinkCallback(); - } gMain.state++; } break; @@ -4820,13 +4803,13 @@ static void CB2_SaveAndEndTrade(void) if (_IsLinkTaskFinished()) { gSoftResetDisabled = FALSE; - SetMainCallback2(CB2_FreeTradeData); + SetMainCallback2(CB2_FreeTradeAnim); } } else if (!gReceivedRemoteLinkPlayers) { gSoftResetDisabled = FALSE; - SetMainCallback2(CB2_FreeTradeData); + SetMainCallback2(CB2_FreeTradeAnim); } break; } @@ -4839,7 +4822,7 @@ static void CB2_SaveAndEndTrade(void) UpdatePaletteFade(); } -static void CB2_FreeTradeData(void) +static void CB2_FreeTradeAnim(void) { if (!gPaletteFade.active) { @@ -4848,7 +4831,7 @@ static void CB2_FreeTradeData(void) Free(GetBgTilemapBuffer(1)); Free(GetBgTilemapBuffer(0)); FreeMonSpritesGfx(); - FREE_AND_SET_NULL(sTradeData); + FREE_AND_SET_NULL(sTradeAnim); if (gWirelessCommType) DestroyWirelessStatusIndicatorSprite(); SetMainCallback2(gMain.savedCallback); @@ -4870,7 +4853,7 @@ static void Task_InGameTrade(u8 taskId) { if (!gPaletteFade.active) { - SetMainCallback2(CB2_InGameTrade); + SetMainCallback2(CB2_InitInGameTrade); gFieldCallback = FieldCB_ContinueScriptHandleMusic; DestroyTask(taskId); } @@ -4880,40 +4863,35 @@ static void CheckPartnersMonForRibbons(void) { u8 i; u8 numRibbons = 0; - for (i = 0; i < (MON_DATA_UNUSED_RIBBONS - MON_DATA_CHAMPION_RIBBON); i ++) - { + for (i = 0; i < (MON_DATA_UNUSED_RIBBONS - MON_DATA_CHAMPION_RIBBON); i++) numRibbons += GetMonData(&gEnemyParty[gSelectedTradeMonPositions[TRADE_PARTNER] % PARTY_SIZE], MON_DATA_CHAMPION_RIBBON + i); - } + if (numRibbons != 0) FlagSet(FLAG_SYS_RIBBON_GET); } void LoadTradeAnimGfx(void) { - InitTradeBgInternal(); + TradeAnimInit_LoadGfx(); } void DrawTextOnTradeWindow(u8 windowId, const u8 *str, u8 speed) { FillWindowPixelBuffer(windowId, PIXEL_FILL(15)); - sTradeData->textColors[0] = TEXT_DYNAMIC_COLOR_6; - sTradeData->textColors[1] = TEXT_COLOR_WHITE; - sTradeData->textColors[2] = TEXT_COLOR_GREEN; - AddTextPrinterParameterized4(windowId, FONT_NORMAL, 0, 2, 0, 0, sTradeData->textColors, speed, str); + sTradeAnim->textColors[0] = TEXT_DYNAMIC_COLOR_6; + sTradeAnim->textColors[1] = TEXT_COLOR_WHITE; + sTradeAnim->textColors[2] = TEXT_COLOR_GREEN; + AddTextPrinterParameterized4(windowId, FONT_NORMAL, 0, 2, 0, 0, sTradeAnim->textColors, speed, str); CopyWindowToVram(windowId, COPYWIN_FULL); } -#define idx data[0] -#define counter data[1] -#define signalComingBack data[2] - static void Task_AnimateWirelessSignal(u8 taskId) { s16 *data = gTasks[taskId].data; - u16 paletteIdx = sWirelessSignalTiming[idx][0] * 16; + u16 paletteIdx = sWirelessSignalAnimParams[tIdx][0] * 16; - if (!signalComingBack) + if (!tSignalComingBack) { if (paletteIdx == 256) LoadPalette(sWirelessSignalNone_Pal, 0x30, 32); @@ -4928,37 +4906,37 @@ static void Task_AnimateWirelessSignal(u8 taskId) LoadPalette(&sWirelessSignalRecv_Pal[paletteIdx], 0x30, 32); } - if (sWirelessSignalTiming[idx][0] == 0 && counter == 0) + if (sWirelessSignalAnimParams[tIdx][0] == 0 && tCounter == 0) PlaySE(SE_M_HEAL_BELL); - if (counter == sWirelessSignalTiming[idx][1]) + if (tCounter == sWirelessSignalAnimParams[tIdx][1]) { - idx++; - counter = 0; - if (sWirelessSignalTiming[idx][1] == 0xFF) + tIdx++; + tCounter = 0; + if (sWirelessSignalAnimParams[tIdx][1] == 0xFF) { DestroyTask(taskId); } } else { - counter++; + tCounter++; } } -#undef idx -#undef counter -#undef signalComingBack +#undef tIdx +#undef tCounter +#undef tSignalComingBack -static void Task_NarrowWindowForCrossing_Wireless(u8 taskId) +static void Task_OpenCenterWhiteColumn(u8 taskId) { s16 *data = gTasks[taskId].data; if (data[0] == 0) { - sTradeData->wirelessWinLeft = sTradeData->wirelessWinRight = DISPLAY_WIDTH / 2; - sTradeData->wirelessWinTop = 0; - sTradeData->wirelessWinBottom = DISPLAY_HEIGHT; + sTradeAnim->wirelessWinLeft = sTradeAnim->wirelessWinRight = DISPLAY_WIDTH / 2; + sTradeAnim->wirelessWinTop = 0; + sTradeAnim->wirelessWinBottom = DISPLAY_HEIGHT; SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN0_ON); SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_OBJ); SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG0 | @@ -4966,41 +4944,41 @@ static void Task_NarrowWindowForCrossing_Wireless(u8 taskId) WININ_WIN0_OBJ); } - SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE2(sTradeData->wirelessWinLeft, sTradeData->wirelessWinRight)); - SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE2(sTradeData->wirelessWinTop, sTradeData->wirelessWinBottom)); + SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE2(sTradeAnim->wirelessWinLeft, sTradeAnim->wirelessWinRight)); + SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE2(sTradeAnim->wirelessWinTop, sTradeAnim->wirelessWinBottom)); data[0]++; - sTradeData->wirelessWinLeft -= 5; - sTradeData->wirelessWinRight += 5; + sTradeAnim->wirelessWinLeft -= 5; + sTradeAnim->wirelessWinRight += 5; - if (sTradeData->wirelessWinLeft < 80) + if (sTradeAnim->wirelessWinLeft < 80) DestroyTask(taskId); } -static void Task_NarrowWindowForCrossing_Cable(u8 taskId) +static void Task_CloseCenterWhiteColumn(u8 taskId) { s16 *data = gTasks[taskId].data; if (data[0] == 0) { - sTradeData->wirelessWinLeft = 80; - sTradeData->wirelessWinRight = DISPLAY_WIDTH - 80; + sTradeAnim->wirelessWinLeft = 80; + sTradeAnim->wirelessWinRight = DISPLAY_WIDTH - 80; SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_OBJ); SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG0 | WININ_WIN0_BG1 | WININ_WIN0_OBJ); } - SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE2(sTradeData->wirelessWinLeft, sTradeData->wirelessWinRight)); - SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE2(sTradeData->wirelessWinTop, sTradeData->wirelessWinBottom)); + SetGpuReg(REG_OFFSET_WIN0H, WIN_RANGE2(sTradeAnim->wirelessWinLeft, sTradeAnim->wirelessWinRight)); + SetGpuReg(REG_OFFSET_WIN0V, WIN_RANGE2(sTradeAnim->wirelessWinTop, sTradeAnim->wirelessWinBottom)); - if (sTradeData->wirelessWinLeft != DISPLAY_WIDTH / 2) + if (sTradeAnim->wirelessWinLeft != DISPLAY_WIDTH / 2) { data[0]++; - sTradeData->wirelessWinLeft += 5; - sTradeData->wirelessWinRight -= 5; + sTradeAnim->wirelessWinLeft += 5; + sTradeAnim->wirelessWinRight -= 5; - if (sTradeData->wirelessWinLeft > DISPLAY_WIDTH / 2 - 5) + if (sTradeAnim->wirelessWinLeft > DISPLAY_WIDTH / 2 - 5) BlendPalettes(0x8, 0, RGB_WHITEALPHA); } else @@ -5022,7 +5000,7 @@ static void CB2_SaveAndEndWirelessTrade(void) case 1: SetTradeLinkStandbyCallback(0); gMain.state = 2; - sTradeData->timer = 0; + sTradeAnim->timer = 0; break; case 2: if (_IsLinkTaskFinished()) @@ -5032,11 +5010,11 @@ static void CB2_SaveAndEndWirelessTrade(void) DrawTextOnTradeWindow(0, gStringVar4, 0); IncrementGameStat(GAME_STAT_POKEMON_TRADES); LinkFullSave_Init(); - sTradeData->timer = 0; + sTradeAnim->timer = 0; } break; case 3: - if (++sTradeData->timer == 5) + if (++sTradeAnim->timer == 5) gMain.state = 4; break; case 4: @@ -5046,34 +5024,34 @@ static void CB2_SaveAndEndWirelessTrade(void) } else { - sTradeData->timer = 0; + sTradeAnim->timer = 0; gMain.state = 3; } break; case 5: LinkFullSave_ReplaceLastSector(); gMain.state = 6; - sTradeData->timer = 0; + sTradeAnim->timer = 0; break; case 6: - if (++sTradeData->timer > 10) + if (++sTradeAnim->timer > 10) { if (GetMultiplayerId() == 0) - sTradeData->timer = Random() % 30; + sTradeAnim->timer = Random() % 30; else - sTradeData->timer = 0; + sTradeAnim->timer = 0; gMain.state = 7; } break; case 7: - if (sTradeData->timer == 0) + if (sTradeAnim->timer == 0) { SetTradeLinkStandbyCallback(1); gMain.state = 8; } else { - sTradeData->timer--; + sTradeAnim->timer--; } break; case 8: @@ -5084,7 +5062,7 @@ static void CB2_SaveAndEndWirelessTrade(void) } break; case 9: - if (++sTradeData->timer > 60) + if (++sTradeAnim->timer > 60) { gMain.state++; SetTradeLinkStandbyCallback(2); @@ -5109,7 +5087,7 @@ static void CB2_SaveAndEndWirelessTrade(void) if (_IsLinkTaskFinished()) { gSoftResetDisabled = FALSE; - SetMainCallback2(CB2_FreeTradeData); + SetMainCallback2(CB2_FreeTradeAnim); } break; } From 65d476d57539a7680dea2e51b462d4019ad4e8fe Mon Sep 17 00:00:00 2001 From: GriffinR Date: Wed, 1 Feb 2023 09:32:41 -0500 Subject: [PATCH 22/69] Remove some incorrect color constant usage --- src/battle_message.c | 371 ++++++++++++++++--------------------------- 1 file changed, 136 insertions(+), 235 deletions(-) diff --git a/src/battle_message.c b/src/battle_message.c index 9a0ba84b4..586fdd268 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -1481,288 +1481,236 @@ static const struct BattleWindowText sTextOnWindowsInfo_Normal[] = .fontId = FONT_NORMAL, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 1, - .fgColor = TEXT_COLOR_WHITE, - .bgColor = TEXT_DYNAMIC_COLOR_6, - .shadowColor = TEXT_COLOR_GREEN, + .fgColor = 1, + .bgColor = 15, + .shadowColor = 6, }, [B_WIN_ACTION_PROMPT] = { .fillValue = PIXEL_FILL(0xF), .fontId = FONT_NORMAL, .x = 1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_COLOR_WHITE, - .bgColor = TEXT_DYNAMIC_COLOR_6, - .shadowColor = TEXT_COLOR_GREEN, + .fgColor = 1, + .bgColor = 15, + .shadowColor = 6, }, [B_WIN_ACTION_MENU] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_MOVE_NAME_1] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NARROW, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_MOVE_NAME_2] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NARROW, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_MOVE_NAME_3] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NARROW, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_MOVE_NAME_4] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NARROW, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_PP] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NARROW, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_3, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_2, + .fgColor = 12, + .bgColor = 14, + .shadowColor = 11, }, [B_WIN_DUMMY] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_PP_REMAINING] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = 2, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_3, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_2, + .fgColor = 12, + .bgColor = 14, + .shadowColor = 11, }, [B_WIN_MOVE_TYPE] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NARROW, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_SWITCH_PROMPT] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NARROW, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_YESNO] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_LEVEL_UP_BOX] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_LEVEL_UP_BANNER] = { .fillValue = PIXEL_FILL(0), .fontId = FONT_NORMAL, .x = 32, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_COLOR_WHITE, - .bgColor = TEXT_COLOR_TRANSPARENT, - .shadowColor = TEXT_COLOR_DARK_GRAY, + .fgColor = 1, + .shadowColor = 2, }, [B_WIN_VS_PLAYER] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_VS_OPPONENT] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_VS_MULTI_PLAYER_1] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_VS_MULTI_PLAYER_2] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_VS_MULTI_PLAYER_3] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_VS_MULTI_PLAYER_4] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_VS_OUTCOME_DRAW] = { .fillValue = PIXEL_FILL(0), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_COLOR_WHITE, - .bgColor = TEXT_COLOR_TRANSPARENT, - .shadowColor = TEXT_COLOR_GREEN, + .fgColor = 1, + .shadowColor = 6, }, [B_WIN_VS_OUTCOME_LEFT] = { .fillValue = PIXEL_FILL(0), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_COLOR_WHITE, - .bgColor = TEXT_COLOR_TRANSPARENT, - .shadowColor = TEXT_COLOR_GREEN, + .fgColor = 1, + .shadowColor = 6, }, [B_WIN_VS_OUTCOME_RIGHT] = { .fillValue = PIXEL_FILL(0x0), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_COLOR_WHITE, - .bgColor = TEXT_COLOR_TRANSPARENT, - .shadowColor = TEXT_COLOR_GREEN, + .fgColor = 1, + .shadowColor = 6, }, }; @@ -1773,276 +1721,229 @@ static const struct BattleWindowText sTextOnWindowsInfo_Arena[] = .fontId = FONT_NORMAL, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 1, - .fgColor = TEXT_COLOR_WHITE, - .bgColor = TEXT_DYNAMIC_COLOR_6, - .shadowColor = TEXT_COLOR_GREEN, + .fgColor = 1, + .bgColor = 15, + .shadowColor = 6, }, [B_WIN_ACTION_PROMPT] = { .fillValue = PIXEL_FILL(0xF), .fontId = FONT_NORMAL, .x = 1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_COLOR_WHITE, - .bgColor = TEXT_DYNAMIC_COLOR_6, - .shadowColor = TEXT_COLOR_GREEN, + .fgColor = 1, + .bgColor = 15, + .shadowColor = 6, }, [B_WIN_ACTION_MENU] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_MOVE_NAME_1] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NARROW, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_MOVE_NAME_2] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NARROW, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_MOVE_NAME_3] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NARROW, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_MOVE_NAME_4] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NARROW, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_PP] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NARROW, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_3, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_2, + .fgColor = 12, + .bgColor = 14, + .shadowColor = 11, }, [B_WIN_DUMMY] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_PP_REMAINING] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = 2, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_3, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_2, + .fgColor = 12, + .bgColor = 14, + .shadowColor = 11, }, [B_WIN_MOVE_TYPE] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NARROW, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_SWITCH_PROMPT] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NARROW, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_YESNO] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_LEVEL_UP_BOX] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [B_WIN_LEVEL_UP_BANNER] = { .fillValue = PIXEL_FILL(0), .fontId = FONT_NORMAL, .x = 32, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_COLOR_WHITE, - .bgColor = TEXT_COLOR_TRANSPARENT, - .shadowColor = TEXT_COLOR_DARK_GRAY, + .fgColor = 1, + .shadowColor = 2, }, [ARENA_WIN_PLAYER_NAME] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_COLOR_WHITE, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 1, + .bgColor = 14, + .shadowColor = 15, }, [ARENA_WIN_VS] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [ARENA_WIN_OPPONENT_NAME] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [ARENA_WIN_MIND] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [ARENA_WIN_SKILL] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [ARENA_WIN_BODY] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [ARENA_WIN_JUDGMENT_TITLE] = { .fillValue = PIXEL_FILL(0xE), .fontId = FONT_NORMAL, .x = -1, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 0, - .fgColor = TEXT_DYNAMIC_COLOR_4, - .bgColor = TEXT_DYNAMIC_COLOR_5, - .shadowColor = TEXT_DYNAMIC_COLOR_6, + .fgColor = 13, + .bgColor = 14, + .shadowColor = 15, }, [ARENA_WIN_JUDGMENT_TEXT] = { .fillValue = PIXEL_FILL(0x1), .fontId = FONT_NORMAL, .x = 0, .y = 1, - .letterSpacing = 0, - .lineSpacing = 0, .speed = 1, - .fgColor = TEXT_COLOR_DARK_GRAY, - .bgColor = TEXT_COLOR_WHITE, - .shadowColor = TEXT_COLOR_LIGHT_GRAY, + .fgColor = 2, + .bgColor = 1, + .shadowColor = 3, }, }; From 603d870ea0f4fb510a894bde4a1f999a021c9ac9 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Wed, 1 Feb 2023 09:36:18 -0500 Subject: [PATCH 23/69] Fix debug printing negative values --- src/mini_printf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mini_printf.c b/src/mini_printf.c index 8345a3935..d96a9379a 100644 --- a/src/mini_printf.c +++ b/src/mini_printf.c @@ -142,7 +142,7 @@ static s32 mini_strlen(const char *s) return len; } -static s32 mini_itoa(u32 value, u32 radix, s32 uppercase, bool32 unsig, char *buffer) +static s32 mini_itoa(s32 value, u32 radix, s32 uppercase, bool32 unsig, char *buffer) { char *pbuffer = buffer; s32 negative = 0; From 27a5e05f757271cdbf8c6eaf7c5111267ad9dca2 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Wed, 1 Feb 2023 10:20:18 -0500 Subject: [PATCH 24/69] Label data for screen effect tasks --- src/field_specials.c | 123 +++++++++++++++++++++++++++---------------- 1 file changed, 78 insertions(+), 45 deletions(-) diff --git a/src/field_specials.c b/src/field_specials.c index a2023196b..dd03358eb 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -94,8 +94,8 @@ static void LoadLinkPartnerObjectEventSpritePalette(u8, u8, u8); static void Task_PetalburgGymSlideOpenRoomDoors(u8); static void PetalburgGymSetDoorMetatiles(u8, u16); static void Task_PCTurnOnEffect(u8); -static void PCTurnOnEffect_0(struct Task *); -static void PCTurnOnEffect_1(s16, s8, s8); +static void PCTurnOnEffect(struct Task *); +static void PCTurnOnEffect_SetMetatile(s16, s8, s8); static void PCTurnOffEffect(void); static void Task_LotteryCornerComputerEffect(u8); static void LotteryCornerComputerEffect(struct Task *); @@ -966,34 +966,44 @@ void FieldShowRegionMap(void) SetMainCallback2(CB2_FieldShowRegionMap); } +// Task data for Task_PCTurnOnEffect and Task_LotteryCornerComputerEffect +#define tPaused data[0] // Never set +#define tTaskId data[1] +#define tFlickerCount data[2] +#define tTimer data[3] +#define tIsScreenOn data[4] + +// For this special, gSpecialVar_0x8004 is expected to be some PC_LOCATION_* value. void DoPCTurnOnEffect(void) { if (FuncIsActiveTask(Task_PCTurnOnEffect) != TRUE) { u8 taskId = CreateTask(Task_PCTurnOnEffect, 8); - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[1] = taskId; - gTasks[taskId].data[2] = 0; - gTasks[taskId].data[3] = 0; - gTasks[taskId].data[4] = 0; + gTasks[taskId].tPaused = FALSE; + gTasks[taskId].tTaskId = taskId; + gTasks[taskId].tFlickerCount = 0; + gTasks[taskId].tTimer = 0; + gTasks[taskId].tIsScreenOn = FALSE; } } static void Task_PCTurnOnEffect(u8 taskId) { struct Task *task = &gTasks[taskId]; - if (task->data[0] == 0) - PCTurnOnEffect_0(task); + if (!task->tPaused) + PCTurnOnEffect(task); } -static void PCTurnOnEffect_0(struct Task *task) +static void PCTurnOnEffect(struct Task *task) { u8 playerDirection; s8 dx = 0; s8 dy = 0; - if (task->data[3] == 6) + if (task->tTimer == 6) { - task->data[3] = 0; + task->tTimer = 0; + + // Get where the PC should be, depending on where the player is looking. playerDirection = GetPlayerFacingDirection(); switch (playerDirection) { @@ -1010,39 +1020,47 @@ static void PCTurnOnEffect_0(struct Task *task) dy = -1; break; } - PCTurnOnEffect_1(task->data[4], dx, dy); + + // Update map + PCTurnOnEffect_SetMetatile(task->tIsScreenOn, dx, dy); DrawWholeMapView(); - task->data[4] ^= 1; - if ((++task->data[2]) == 5) - DestroyTask(task->data[1]); + + // Screen flickers 5 times. Odd number and starting with the + // screen off means the animation ends with the screen on. + task->tIsScreenOn ^= 1; + if (++task->tFlickerCount == 5) + DestroyTask(task->tTaskId); } - task->data[3]++; + task->tTimer++; } -static void PCTurnOnEffect_1(s16 isPcTurnedOn, s8 dx, s8 dy) +static void PCTurnOnEffect_SetMetatile(s16 isScreenOn, s8 dx, s8 dy) { - u16 tileId = 0; - if (isPcTurnedOn) + u16 metatileId = 0; + if (isScreenOn) { + // Screen is off, set it on if (gSpecialVar_0x8004 == PC_LOCATION_OTHER) - tileId = METATILE_Building_PC_Off; + metatileId = METATILE_Building_PC_Off; else if (gSpecialVar_0x8004 == PC_LOCATION_BRENDANS_HOUSE) - tileId = METATILE_BrendansMaysHouse_BrendanPC_Off; + metatileId = METATILE_BrendansMaysHouse_BrendanPC_Off; else if (gSpecialVar_0x8004 == PC_LOCATION_MAYS_HOUSE) - tileId = METATILE_BrendansMaysHouse_MayPC_Off; + metatileId = METATILE_BrendansMaysHouse_MayPC_Off; } else { + // Screen is on, set it off if (gSpecialVar_0x8004 == PC_LOCATION_OTHER) - tileId = METATILE_Building_PC_On; + metatileId = METATILE_Building_PC_On; else if (gSpecialVar_0x8004 == PC_LOCATION_BRENDANS_HOUSE) - tileId = METATILE_BrendansMaysHouse_BrendanPC_On; + metatileId = METATILE_BrendansMaysHouse_BrendanPC_On; else if (gSpecialVar_0x8004 == PC_LOCATION_MAYS_HOUSE) - tileId = METATILE_BrendansMaysHouse_MayPC_On; + metatileId = METATILE_BrendansMaysHouse_MayPC_On; } - MapGridSetMetatileIdAt(gSaveBlock1Ptr->pos.x + dx + MAP_OFFSET, gSaveBlock1Ptr->pos.y + dy + MAP_OFFSET, tileId | MAPGRID_COLLISION_MASK); + MapGridSetMetatileIdAt(gSaveBlock1Ptr->pos.x + dx + MAP_OFFSET, gSaveBlock1Ptr->pos.y + dy + MAP_OFFSET, metatileId | MAPGRID_COLLISION_MASK); } +// For this special, gSpecialVar_0x8004 is expected to be some PC_LOCATION_* value. void DoPCTurnOffEffect(void) { PCTurnOffEffect(); @@ -1052,7 +1070,9 @@ static void PCTurnOffEffect(void) { s8 dx = 0; s8 dy = 0; - u16 tileId = 0; + u16 metatileId = 0; + + // Get where the PC should be, depending on where the player is looking. u8 playerDirection = GetPlayerFacingDirection(); switch (playerDirection) { @@ -1069,13 +1089,15 @@ static void PCTurnOffEffect(void) dy = -1; break; } + if (gSpecialVar_0x8004 == PC_LOCATION_OTHER) - tileId = METATILE_Building_PC_Off; + metatileId = METATILE_Building_PC_Off; else if (gSpecialVar_0x8004 == PC_LOCATION_BRENDANS_HOUSE) - tileId = METATILE_BrendansMaysHouse_BrendanPC_Off; + metatileId = METATILE_BrendansMaysHouse_BrendanPC_Off; else if (gSpecialVar_0x8004 == PC_LOCATION_MAYS_HOUSE) - tileId = METATILE_BrendansMaysHouse_MayPC_Off; - MapGridSetMetatileIdAt(gSaveBlock1Ptr->pos.x + dx + MAP_OFFSET, gSaveBlock1Ptr->pos.y + dy + MAP_OFFSET, tileId | MAPGRID_COLLISION_MASK); + metatileId = METATILE_BrendansMaysHouse_MayPC_Off; + + MapGridSetMetatileIdAt(gSaveBlock1Ptr->pos.x + dx + MAP_OFFSET, gSaveBlock1Ptr->pos.y + dy + MAP_OFFSET, metatileId | MAPGRID_COLLISION_MASK); DrawWholeMapView(); } @@ -1084,42 +1106,47 @@ void DoLotteryCornerComputerEffect(void) if (FuncIsActiveTask(Task_LotteryCornerComputerEffect) != TRUE) { u8 taskId = CreateTask(Task_LotteryCornerComputerEffect, 8); - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[1] = taskId; - gTasks[taskId].data[2] = 0; - gTasks[taskId].data[3] = 0; - gTasks[taskId].data[4] = 0; + gTasks[taskId].tPaused = FALSE; + gTasks[taskId].tTaskId = taskId; + gTasks[taskId].tFlickerCount = 0; + gTasks[taskId].tTimer = 0; + gTasks[taskId].tIsScreenOn = FALSE; } } static void Task_LotteryCornerComputerEffect(u8 taskId) { struct Task *task = &gTasks[taskId]; - if (task->data[0] == 0) + if (!task->tPaused) LotteryCornerComputerEffect(task); } static void LotteryCornerComputerEffect(struct Task *task) { - if (task->data[3] == 6) + if (task->tTimer == 6) { - task->data[3] = 0; - if (task->data[4] != 0) + task->tTimer = 0; + if (task->tIsScreenOn) { + // Screen is on, set it off MapGridSetMetatileIdAt(11 + MAP_OFFSET, 1 + MAP_OFFSET, METATILE_Shop_Laptop1_Normal | MAPGRID_COLLISION_MASK); MapGridSetMetatileIdAt(11 + MAP_OFFSET, 2 + MAP_OFFSET, METATILE_Shop_Laptop2_Normal | MAPGRID_COLLISION_MASK); } else { + // Screen is off, set it on MapGridSetMetatileIdAt(11 + MAP_OFFSET, 1 + MAP_OFFSET, METATILE_Shop_Laptop1_Flash | MAPGRID_COLLISION_MASK); MapGridSetMetatileIdAt(11 + MAP_OFFSET, 2 + MAP_OFFSET, METATILE_Shop_Laptop2_Flash | MAPGRID_COLLISION_MASK); } DrawWholeMapView(); - task->data[4] ^= 1; - if ((++task->data[2]) == 5) - DestroyTask(task->data[1]); + + // Screen flickers 5 times. Odd number and starting with the + // screen off means the animation ends with the screen on. + task->tIsScreenOn ^= 1; + if (++task->tFlickerCount == 5) + DestroyTask(task->tTaskId); } - task->data[3]++; + task->tTimer++; } void EndLotteryCornerComputerEffect(void) @@ -1129,6 +1156,12 @@ void EndLotteryCornerComputerEffect(void) DrawWholeMapView(); } +#undef tPaused +#undef tTaskId +#undef tFlickerCount +#undef tTimer +#undef tIsScreenOn + void SetTrickHouseNuggetFlag(void) { u16 *specVar = &gSpecialVar_0x8004; From 43af7d46ca500de5244a94f1dab51988f833dce5 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Wed, 1 Feb 2023 10:37:11 -0500 Subject: [PATCH 25/69] Label data for elevator effects --- src/field_specials.c | 124 +++++++++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 45 deletions(-) diff --git a/src/field_specials.c b/src/field_specials.c index dd03358eb..cfa12a418 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -1664,7 +1664,7 @@ void OffsetCameraForBattle(void) SetCameraPanning(8, 0); } -const struct WindowTemplate gElevatorFloor_WindowTemplate = +static const struct WindowTemplate sWindowTemplate_ElevatorFloor = { .bg = 0, .tilemapLeft = 21, @@ -1675,7 +1675,7 @@ const struct WindowTemplate gElevatorFloor_WindowTemplate = .baseBlock = 8, }; -const u8 *const gDeptStoreFloorNames[] = +static const u8 *const sDeptStoreFloorNames[] = { [DEPT_STORE_FLOORNUM_B4F] = gText_B4F, [DEPT_STORE_FLOORNUM_B3F] = gText_B3F, @@ -1695,7 +1695,11 @@ const u8 *const gDeptStoreFloorNames[] = [DEPT_STORE_FLOORNUM_ROOFTOP] = gText_Rooftop }; -static const u16 sElevatorWindowTiles_Ascending[][3] = +#define ELEVATOR_WINDOW_WIDTH 3 +#define ELEVATOR_WINDOW_HEIGHT 3 +#define ELEVATOR_LIGHT_STAGES 3 + +static const u16 sElevatorWindowTiles_Ascending[ELEVATOR_WINDOW_HEIGHT][ELEVATOR_LIGHT_STAGES] = { { METATILE_BattleFrontier_Elevator_Top0, @@ -1714,7 +1718,7 @@ static const u16 sElevatorWindowTiles_Ascending[][3] = }, }; -static const u16 sElevatorWindowTiles_Descending[][3] = +static const u16 sElevatorWindowTiles_Descending[ELEVATOR_WINDOW_HEIGHT][ELEVATOR_LIGHT_STAGES] = { { METATILE_BattleFrontier_Elevator_Top0, @@ -1798,53 +1802,66 @@ u16 GetDeptStoreDefaultFloorChoice(void) return sLilycoveDeptStore_DefaultFloorChoice; } +// Task data for Task_MoveElevator +#define tTimer data[1] +#define tMoveCounter data[2] +#define tVerticalPan data[4] +#define tTotalMoves data[5] +#define tDescending data[6] + +// The maximum considered difference between floors. +// Elevator trips with a larger difference are treated the same +// (i.e. traveling 9 floors and 200 floors would take the same amount of time). +#define MAX_ELEVATOR_TRIP 9 + +// gSpecialVar_0x8005 here is expected to be the current floor number, and +// gSpecialVar_0x8006 is expected to be the destination floor number. void MoveElevator(void) { - static const u8 sElevatorTripLength[] = { 8, 16, 24, 32, 38, 46, 52, 56, 57 }; + static const u8 sElevatorTripLength[MAX_ELEVATOR_TRIP] = { 8, 16, 24, 32, 38, 46, 52, 56, 57 }; s16 *data = gTasks[CreateTask(Task_MoveElevator, 9)].data; u16 floorDelta; - data[1] = 0; - data[2] = 0; - data[4] = 1; + tTimer = 0; + tMoveCounter = 0; + tVerticalPan = 1; - // descending if (gSpecialVar_0x8005 > gSpecialVar_0x8006) { floorDelta = gSpecialVar_0x8005 - gSpecialVar_0x8006; - data[6] = TRUE; + tDescending = TRUE; } else { floorDelta = gSpecialVar_0x8006 - gSpecialVar_0x8005; - data[6] = FALSE; + tDescending = FALSE; } - if (floorDelta > 8) - floorDelta = 8; + if (floorDelta > MAX_ELEVATOR_TRIP - 1) + floorDelta = MAX_ELEVATOR_TRIP - 1; - data[5] = sElevatorTripLength[floorDelta]; + tTotalMoves = sElevatorTripLength[floorDelta]; SetCameraPanningCallback(NULL); - MoveElevatorWindowLights(floorDelta, data[6]); + MoveElevatorWindowLights(floorDelta, tDescending); PlaySE(SE_ELEVATOR); } static void Task_MoveElevator(u8 taskId) { s16 *data = gTasks[taskId].data; - data[1]++; - if (data[1] % 3 == 0) + tTimer++; + if (tTimer % 3 == 0) { - data[1] = 0; - data[2]++; - data[4] = -data[4]; - SetCameraPanning(0, data[4]); + tTimer = 0; + tMoveCounter++; + tVerticalPan = -tVerticalPan; + SetCameraPanning(0, tVerticalPan); - // arrived at floor - if (data[2] == data[5]) + if (tMoveCounter == tTotalMoves) { + // Arrived at floor PlaySE(SE_DING_DONG); DestroyTask(taskId); ScriptContext_Enable(); @@ -1853,18 +1870,24 @@ static void Task_MoveElevator(u8 taskId) } } +#undef tTimer +#undef tMoveCounter +#undef tVerticalPan +#undef tTotalMoves +#undef tDescending + void ShowDeptStoreElevatorFloorSelect(void) { int xPos; - sTutorMoveAndElevatorWindowId = AddWindow(&gElevatorFloor_WindowTemplate); + sTutorMoveAndElevatorWindowId = AddWindow(&sWindowTemplate_ElevatorFloor); SetStandardWindowBorderStyle(sTutorMoveAndElevatorWindowId, FALSE); xPos = GetStringCenterAlignXOffset(FONT_NORMAL, gText_ElevatorNowOn, 64); AddTextPrinterParameterized(sTutorMoveAndElevatorWindowId, FONT_NORMAL, gText_ElevatorNowOn, xPos, 1, TEXT_SKIP_DRAW, NULL); - xPos = GetStringCenterAlignXOffset(FONT_NORMAL, gDeptStoreFloorNames[gSpecialVar_0x8005], 64); - AddTextPrinterParameterized(sTutorMoveAndElevatorWindowId, FONT_NORMAL, gDeptStoreFloorNames[gSpecialVar_0x8005], xPos, 17, TEXT_SKIP_DRAW, NULL); + xPos = GetStringCenterAlignXOffset(FONT_NORMAL, sDeptStoreFloorNames[gSpecialVar_0x8005], 64); + AddTextPrinterParameterized(sTutorMoveAndElevatorWindowId, FONT_NORMAL, sDeptStoreFloorNames[gSpecialVar_0x8005], xPos, 17, TEXT_SKIP_DRAW, NULL); PutWindowTilemap(sTutorMoveAndElevatorWindowId); CopyWindowToVram(sTutorMoveAndElevatorWindowId, COPYWIN_FULL); @@ -1876,17 +1899,23 @@ void CloseDeptStoreElevatorWindow(void) RemoveWindow(sTutorMoveAndElevatorWindowId); } +// Task data for Task_MoveElevatorWindowLights +#define tMoveCounter data[0] +#define tTimer data[1] +#define tDescending data[2] +#define tTotalMoves data[3] + static void MoveElevatorWindowLights(u16 floorDelta, bool8 descending) { - static const u8 sElevatorLightCycles[] = { 3, 6, 9, 12, 15, 18, 21, 24, 27 }; + static const u8 sElevatorLightCycles[MAX_ELEVATOR_TRIP] = { 3, 6, 9, 12, 15, 18, 21, 24, 27 }; if (FuncIsActiveTask(Task_MoveElevatorWindowLights) != TRUE) { u8 taskId = CreateTask(Task_MoveElevatorWindowLights, 8); - gTasks[taskId].data[0] = 0; - gTasks[taskId].data[1] = 0; - gTasks[taskId].data[2] = descending; - gTasks[taskId].data[3] = sElevatorLightCycles[floorDelta]; + gTasks[taskId].tMoveCounter = 0; + gTasks[taskId].tTimer = 0; + gTasks[taskId].tDescending = descending; + gTasks[taskId].tTotalMoves = sElevatorLightCycles[floorDelta]; } } @@ -1895,36 +1924,41 @@ static void Task_MoveElevatorWindowLights(u8 taskId) u8 x, y; s16 *data = gTasks[taskId].data; - if (data[1] == 6) + if (tTimer == 6) { - data[0]++; + tMoveCounter++; - // ascending - if (data[2] == FALSE) + if (!tDescending) { - for (y = 0; y < 3; y++) + // Ascending + for (y = 0; y < ELEVATOR_WINDOW_HEIGHT; y++) { - for (x = 0; x < 3; x++) - MapGridSetMetatileIdAt(x + MAP_OFFSET + 1, y + MAP_OFFSET, sElevatorWindowTiles_Ascending[y][data[0] % 3] | MAPGRID_COLLISION_MASK); + for (x = 0; x < ELEVATOR_WINDOW_WIDTH; x++) + MapGridSetMetatileIdAt(x + MAP_OFFSET + 1, y + MAP_OFFSET, sElevatorWindowTiles_Ascending[y][tMoveCounter % ELEVATOR_LIGHT_STAGES] | MAPGRID_COLLISION_MASK); } } - // descending else { - for (y = 0; y < 3; y++) + // Descending + for (y = 0; y < ELEVATOR_WINDOW_HEIGHT; y++) { - for (x = 0; x < 3; x++) - MapGridSetMetatileIdAt(x + MAP_OFFSET + 1, y + MAP_OFFSET, sElevatorWindowTiles_Descending[y][data[0] % 3] | MAPGRID_COLLISION_MASK); + for (x = 0; x < ELEVATOR_WINDOW_WIDTH; x++) + MapGridSetMetatileIdAt(x + MAP_OFFSET + 1, y + MAP_OFFSET, sElevatorWindowTiles_Descending[y][tMoveCounter % ELEVATOR_LIGHT_STAGES] | MAPGRID_COLLISION_MASK); } } DrawWholeMapView(); - data[1] = 0; - if (data[0] == data[3]) + tTimer = 0; + if (tMoveCounter == tTotalMoves) DestroyTask(taskId); } - data[1]++; + tTimer++; } +#undef tMoveCounter +#undef tTimer +#undef tDescending +#undef tTotalMoves + void BufferVarsForIVRater(void) { u8 i; From 9003966fcc4e3081db28774c26941a588d49ffbe Mon Sep 17 00:00:00 2001 From: GriffinR Date: Wed, 1 Feb 2023 11:43:21 -0500 Subject: [PATCH 26/69] Misc field_specials cleanup --- data/maps/BirthIsland_Exterior/scripts.inc | 17 +-- data/maps/PetalburgCity/scripts.inc | 2 +- data/specials.inc | 2 +- include/constants/battle_pyramid.h | 2 +- include/constants/field_specials.h | 6 + src/battle_pyramid.c | 20 +-- .../battle_pyramid_open_level_wild_mons.h | 2 +- src/field_effect.c | 71 +++++++---- src/field_specials.c | 119 ++++++++++-------- 9 files changed, 141 insertions(+), 100 deletions(-) diff --git a/data/maps/BirthIsland_Exterior/scripts.inc b/data/maps/BirthIsland_Exterior/scripts.inc index 68d3124d9..d2174eee9 100644 --- a/data/maps/BirthIsland_Exterior/scripts.inc +++ b/data/maps/BirthIsland_Exterior/scripts.inc @@ -48,21 +48,24 @@ BirthIsland_Exterior_EventScript_Triangle:: special DoDeoxysRockInteraction waitstate switch VAR_RESULT - case 0, BirthIsland_Exterior_EventScript_NotSolved1 - case 1, BirthIsland_Exterior_EventScript_NotSolved2 - case 2, BirthIsland_Exterior_EventScript_Deoxys - case 3, BirthIsland_Exterior_EventScript_NotSolved3 + case DEOXYS_ROCK_FAILED, BirthIsland_Exterior_EventScript_Failed + case DEOXYS_ROCK_PROGRESSED, BirthIsland_Exterior_EventScript_Progressed + case DEOXYS_ROCK_SOLVED, BirthIsland_Exterior_EventScript_Deoxys + case DEOXYS_ROCK_COMPLETE, BirthIsland_Exterior_EventScript_Complete end -BirthIsland_Exterior_EventScript_NotSolved1:: +@ The actual rock triangle movement is handled by DoDeoxysRockInteraction. +@ Unless the player has solved the puzzle and needs to encounter Deoxys, +@ there's nothing else the script needs to do. +BirthIsland_Exterior_EventScript_Failed:: release end -BirthIsland_Exterior_EventScript_NotSolved2:: +BirthIsland_Exterior_EventScript_Progressed:: release end -BirthIsland_Exterior_EventScript_NotSolved3:: +BirthIsland_Exterior_EventScript_Complete:: release end diff --git a/data/maps/PetalburgCity/scripts.inc b/data/maps/PetalburgCity/scripts.inc index 3609b2622..a9dd1014f 100644 --- a/data/maps/PetalburgCity/scripts.inc +++ b/data/maps/PetalburgCity/scripts.inc @@ -38,7 +38,7 @@ PetalburgCity_OnFrame: PetalburgCity_EventScript_WallyTutorial:: lockall special SavePlayerParty - special PutZigzagoonInPlayerParty + special LoadWallyZigzagoon applymovement LOCALID_WALLY, PetalburgCity_Movement_WallyTutorialWally applymovement OBJ_EVENT_ID_PLAYER, PetalburgCity_Movement_WallyTutorialPlayer waitmovement 0 diff --git a/data/specials.inc b/data/specials.inc index 187e49ec7..26eb4e134 100644 --- a/data/specials.inc +++ b/data/specials.inc @@ -311,7 +311,7 @@ gSpecials:: def_special TryUpdateRusturfTunnelState def_special IsGrassTypeInParty def_special DoContestHallWarp - def_special PutZigzagoonInPlayerParty + def_special LoadWallyZigzagoon def_special IsStarterInParty def_special CopyCurSecretBaseOwnerName_StrVar1 def_special ScriptCheckFreePokemonStorageSpace diff --git a/include/constants/battle_pyramid.h b/include/constants/battle_pyramid.h index 297f3b1ff..ac80a2d7d 100644 --- a/include/constants/battle_pyramid.h +++ b/include/constants/battle_pyramid.h @@ -1,7 +1,7 @@ #ifndef GUARD_CONSTANTS_BATTLE_PYRAMID_H #define GUARD_CONSTANTS_BATTLE_PYRAMID_H -#define TOTAL_ROUNDS 20 +#define TOTAL_PYRAMID_ROUNDS 20 #define PICKUP_ITEMS_PER_ROUND 10 #define HINT_EXIT_DIRECTION 0 diff --git a/include/constants/field_specials.h b/include/constants/field_specials.h index a01151378..665940331 100644 --- a/include/constants/field_specials.h +++ b/include/constants/field_specials.h @@ -80,4 +80,10 @@ #define FANCOUNTER_FINISHED_CONTEST 2 #define FANCOUNTER_USED_BATTLE_TOWER 3 +// Return values for DoDeoxysRockInteraction +#define DEOXYS_ROCK_FAILED 0 +#define DEOXYS_ROCK_PROGRESSED 1 +#define DEOXYS_ROCK_SOLVED 2 +#define DEOXYS_ROCK_COMPLETE 3 + #endif // GUARD_CONSTANTS_FIELD_SPECIALS_H diff --git a/src/battle_pyramid.c b/src/battle_pyramid.c index 32fab3402..84a439037 100644 --- a/src/battle_pyramid.c +++ b/src/battle_pyramid.c @@ -284,7 +284,7 @@ static const u8 sFloorTemplateOffsets[FRONTIER_STAGES_PER_CHALLENGE] = 0, 4, 9, 14, 19, 24, 29 }; -static const u16 sPickupItemsLvl50[TOTAL_ROUNDS][PICKUP_ITEMS_PER_ROUND] = +static const u16 sPickupItemsLvl50[TOTAL_PYRAMID_ROUNDS][PICKUP_ITEMS_PER_ROUND] = { {ITEM_HYPER_POTION, ITEM_FLUFFY_TAIL, ITEM_CHERI_BERRY, ITEM_ETHER, ITEM_LUM_BERRY, ITEM_REVIVE, ITEM_BRIGHT_POWDER, ITEM_SHELL_BELL, ITEM_MAX_REVIVE, ITEM_SACRED_ASH}, {ITEM_HYPER_POTION, ITEM_DIRE_HIT, ITEM_PECHA_BERRY, ITEM_ETHER, ITEM_LEPPA_BERRY, ITEM_REVIVE, ITEM_LEFTOVERS, ITEM_CHOICE_BAND, ITEM_FULL_RESTORE, ITEM_MAX_ELIXIR}, @@ -308,7 +308,7 @@ static const u16 sPickupItemsLvl50[TOTAL_ROUNDS][PICKUP_ITEMS_PER_ROUND] = {ITEM_HYPER_POTION, ITEM_X_DEFEND, ITEM_LUM_BERRY, ITEM_ETHER, ITEM_LEPPA_BERRY, ITEM_REVIVE, ITEM_QUICK_CLAW, ITEM_KINGS_ROCK, ITEM_FULL_RESTORE, ITEM_MAX_ELIXIR}, }; -static const u16 sPickupItemsLvlOpen[TOTAL_ROUNDS][PICKUP_ITEMS_PER_ROUND] = +static const u16 sPickupItemsLvlOpen[TOTAL_PYRAMID_ROUNDS][PICKUP_ITEMS_PER_ROUND] = { {ITEM_HYPER_POTION, ITEM_FLUFFY_TAIL, ITEM_CHERI_BERRY, ITEM_ETHER, ITEM_LUM_BERRY, ITEM_REVIVE, ITEM_BRIGHT_POWDER, ITEM_SHELL_BELL, ITEM_MAX_REVIVE, ITEM_SACRED_ASH}, {ITEM_HYPER_POTION, ITEM_DIRE_HIT, ITEM_PECHA_BERRY, ITEM_ETHER, ITEM_LEPPA_BERRY, ITEM_REVIVE, ITEM_LEFTOVERS, ITEM_CHOICE_BAND, ITEM_FULL_RESTORE, ITEM_MAX_ELIXIR}, @@ -977,10 +977,10 @@ static void SetPickupItem(void) u8 id; u32 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; u32 floor = gSaveBlock2Ptr->frontier.curChallengeBattleNum; - u32 round = (gSaveBlock2Ptr->frontier.pyramidWinStreaks[lvlMode] / FRONTIER_STAGES_PER_CHALLENGE) % TOTAL_ROUNDS; + u32 round = (gSaveBlock2Ptr->frontier.pyramidWinStreaks[lvlMode] / FRONTIER_STAGES_PER_CHALLENGE) % TOTAL_PYRAMID_ROUNDS; - if (round >= TOTAL_ROUNDS) - round = TOTAL_ROUNDS - 1; + if (round >= TOTAL_PYRAMID_ROUNDS) + round = TOTAL_PYRAMID_ROUNDS - 1; id = GetPyramidFloorTemplateId(); itemIndex = (gSpecialVar_LastTalked - sPyramidFloorTemplates[id].numTrainers) - 1; @@ -1345,10 +1345,10 @@ void GenerateBattlePyramidWildMon(void) const struct PyramidWildMon *wildMons; u32 id; u32 lvl = gSaveBlock2Ptr->frontier.lvlMode; - u16 round = (gSaveBlock2Ptr->frontier.pyramidWinStreaks[lvl] / FRONTIER_STAGES_PER_CHALLENGE) % TOTAL_ROUNDS; + u16 round = (gSaveBlock2Ptr->frontier.pyramidWinStreaks[lvl] / FRONTIER_STAGES_PER_CHALLENGE) % TOTAL_PYRAMID_ROUNDS; - if (round >= TOTAL_ROUNDS) - round = TOTAL_ROUNDS - 1; + if (round >= TOTAL_PYRAMID_ROUNDS) + round = TOTAL_PYRAMID_ROUNDS - 1; if (lvl != FRONTIER_LVL_50) wildMons = sOpenLevelWildMonPointers[round]; @@ -1961,8 +1961,8 @@ u16 GetBattlePyramidPickupItemId(void) u32 lvlMode = gSaveBlock2Ptr->frontier.lvlMode; int round = (gSaveBlock2Ptr->frontier.pyramidWinStreaks[lvlMode] / FRONTIER_STAGES_PER_CHALLENGE); - if (round >= TOTAL_ROUNDS) - round = TOTAL_ROUNDS - 1; + if (round >= TOTAL_PYRAMID_ROUNDS) + round = TOTAL_PYRAMID_ROUNDS - 1; rand = Random() % 100; diff --git a/src/data/battle_frontier/battle_pyramid_open_level_wild_mons.h b/src/data/battle_frontier/battle_pyramid_open_level_wild_mons.h index f09448b82..792bc28dd 100644 --- a/src/data/battle_frontier/battle_pyramid_open_level_wild_mons.h +++ b/src/data/battle_frontier/battle_pyramid_open_level_wild_mons.h @@ -1038,7 +1038,7 @@ static const struct PyramidWildMon sOpenLevelWildMons_Round20[] = } }; -static const struct PyramidWildMon *const sOpenLevelWildMonPointers[TOTAL_ROUNDS] = +static const struct PyramidWildMon *const sOpenLevelWildMonPointers[TOTAL_PYRAMID_ROUNDS] = { sOpenLevelWildMons_Round1, sOpenLevelWildMons_Round2, diff --git a/src/field_effect.c b/src/field_effect.c index 8ffc9b3a6..7cae89d22 100644 --- a/src/field_effect.c +++ b/src/field_effect.c @@ -3831,26 +3831,38 @@ static void SpriteCB_DeoxysRockFragment(struct Sprite *sprite) DestroySprite(sprite); } +// Task data for Task_MoveDeoxysRock +#define tState data[0] +#define tSpriteId data[1] +#define tTargetX data[2] +#define tTargetY data[3] +#define tCurX data[4] +#define tCurY data[5] +#define tVelocityX data[6] +#define tVelocityY data[7] +#define tMoveSteps data[8] +#define tObjEventId data[9] + bool8 FldEff_MoveDeoxysRock(struct Sprite *sprite) { - u8 objectEventIdBuffer; - if (!TryGetObjectEventIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2], &objectEventIdBuffer)) + u8 objectEventId; + if (!TryGetObjectEventIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2], &objectEventId)) { struct ObjectEvent *object; int xPos, yPos; u8 taskId; - object = &gObjectEvents[objectEventIdBuffer]; + object = &gObjectEvents[objectEventId]; xPos = object->currentCoords.x - MAP_OFFSET; yPos = object->currentCoords.y - MAP_OFFSET; xPos = (gFieldEffectArguments[3] - xPos) * 16; yPos = (gFieldEffectArguments[4] - yPos) * 16; ShiftObjectEventCoords(object, gFieldEffectArguments[3] + MAP_OFFSET, gFieldEffectArguments[4] + MAP_OFFSET); taskId = CreateTask(Task_MoveDeoxysRock, 80); - gTasks[taskId].data[1] = object->spriteId; - gTasks[taskId].data[2] = gSprites[object->spriteId].x + xPos; - gTasks[taskId].data[3] = gSprites[object->spriteId].y + yPos; - gTasks[taskId].data[8] = gFieldEffectArguments[5]; - gTasks[taskId].data[9] = objectEventIdBuffer; + gTasks[taskId].tSpriteId = object->spriteId; + gTasks[taskId].tTargetX = gSprites[object->spriteId].x + xPos; + gTasks[taskId].tTargetY = gSprites[object->spriteId].y + yPos; + gTasks[taskId].tMoveSteps = gFieldEffectArguments[5]; + gTasks[taskId].tObjEventId = objectEventId; } return FALSE; } @@ -3858,29 +3870,30 @@ bool8 FldEff_MoveDeoxysRock(struct Sprite *sprite) static void Task_MoveDeoxysRock(u8 taskId) { s16 *data = gTasks[taskId].data; - struct Sprite *sprite = &gSprites[data[1]]; - switch (data[0]) + struct Sprite *sprite = &gSprites[tSpriteId]; + switch (tState) { case 0: - data[4] = sprite->x << 4; - data[5] = sprite->y << 4; - data[6] = SAFE_DIV(data[2] * 16 - data[4], data[8]); - data[7] = SAFE_DIV(data[3] * 16 - data[5], data[8]); - data[0]++; + tCurX = sprite->x << 4; + tCurY = sprite->y << 4; + tVelocityX = SAFE_DIV(tTargetX * 16 - tCurX, tMoveSteps); + tVelocityY = SAFE_DIV(tTargetY * 16 - tCurY, tMoveSteps); + tState++; + // fallthrough case 1: - if (data[8] != 0) + if (tMoveSteps != 0) { - data[8]--; - data[4] += data[6]; - data[5] += data[7]; - sprite->x = data[4] >> 4; - sprite->y = data[5] >> 4; + tMoveSteps--; + tCurX += tVelocityX; + tCurY += tVelocityY; + sprite->x = tCurX >> 4; + sprite->y = tCurY >> 4; } else { - struct ObjectEvent *object = &gObjectEvents[data[9]]; - sprite->x = data[2]; - sprite->y = data[3]; + struct ObjectEvent *object = &gObjectEvents[tObjEventId]; + sprite->x = tTargetX; + sprite->y = tTargetY; ShiftStillObjectEventCoords(object); object->triggerGroundEffectsOnStop = TRUE; FieldEffectActiveListRemove(FLDEFF_MOVE_DEOXYS_ROCK); @@ -3890,3 +3903,13 @@ static void Task_MoveDeoxysRock(u8 taskId) } } +#undef tState +#undef tSpriteId +#undef tTargetX +#undef tTargetY +#undef tCurX +#undef tCurY +#undef tVelocityX +#undef tVelocityY +#undef tMoveSteps +#undef tObjEventId diff --git a/src/field_specials.c b/src/field_specials.c index cfa12a418..7e8d10256 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -46,6 +46,7 @@ #include "wallclock.h" #include "window.h" #include "constants/battle_frontier.h" +#include "constants/battle_pyramid.h" #include "constants/battle_tower.h" #include "constants/decorations.h" #include "constants/event_objects.h" @@ -66,6 +67,15 @@ #include "constants/metatile_labels.h" #include "palette.h" +#define TAG_ITEM_ICON 5500 + +#define GFXTAG_MULTICHOICE_SCROLL_ARROWS 2000 +#define PALTAG_MULTICHOICE_SCROLL_ARROWS 100 + +#define ELEVATOR_WINDOW_WIDTH 3 +#define ELEVATOR_WINDOW_HEIGHT 3 +#define ELEVATOR_LIGHT_STAGES 3 + EWRAM_DATA bool8 gBikeCyclingChallenge = FALSE; EWRAM_DATA u8 gBikeCollisions = 0; static EWRAM_DATA u32 sBikeCyclingTimer = 0; @@ -1246,7 +1256,7 @@ void SpawnCameraObject(void) OBJ_EVENT_ID_CAMERA, gSaveBlock1Ptr->pos.x + MAP_OFFSET, gSaveBlock1Ptr->pos.y + MAP_OFFSET, - 3); + 3); // elevation gObjectEvents[obj].invisible = TRUE; CameraObjectSetFollowedSpriteId(gObjectEvents[obj].spriteId); } @@ -1411,7 +1421,7 @@ void SetShoalItemFlag(u16 unused) FlagSet(FLAG_SYS_SHOAL_ITEM); } -void PutZigzagoonInPlayerParty(void) +void LoadWallyZigzagoon(void) { u16 monData; CreateMon(&gPlayerParty[0], SPECIES_ZIGZAGOON, 7, USE_RANDOM_IVS, FALSE, 0, OT_ID_PLAYER_ID, 0); @@ -1451,20 +1461,21 @@ bool8 IsPokerusInParty(void) return TRUE; } -#define horizontalPan data[0] -#define delayCounter data[1] -#define numShakes data[2] -#define delay data[3] -#define verticalPan data[4] +// Task data for Task_ShakeCamera +#define tHorizontalPan data[0] +#define tDelayCounter data[1] +#define tNumShakes data[2] +#define tDelay data[3] +#define tVerticalPan data[4] void ShakeCamera(void) { u8 taskId = CreateTask(Task_ShakeCamera, 9); - gTasks[taskId].horizontalPan = gSpecialVar_0x8005; - gTasks[taskId].delayCounter = 0; - gTasks[taskId].numShakes = gSpecialVar_0x8006; - gTasks[taskId].delay = gSpecialVar_0x8007; - gTasks[taskId].verticalPan = gSpecialVar_0x8004; + gTasks[taskId].tHorizontalPan = gSpecialVar_0x8005; + gTasks[taskId].tDelayCounter = 0; + gTasks[taskId].tNumShakes = gSpecialVar_0x8006; + gTasks[taskId].tDelay = gSpecialVar_0x8007; + gTasks[taskId].tVerticalPan = gSpecialVar_0x8004; SetCameraPanningCallback(NULL); PlaySE(SE_M_STRENGTH); } @@ -1473,15 +1484,15 @@ static void Task_ShakeCamera(u8 taskId) { s16 *data = gTasks[taskId].data; - delayCounter++; - if (delayCounter % delay == 0) + tDelayCounter++; + if (tDelayCounter % tDelay == 0) { - delayCounter = 0; - numShakes--; - horizontalPan = -horizontalPan; - verticalPan = -verticalPan; - SetCameraPanning(horizontalPan, verticalPan); - if (numShakes == 0) + tDelayCounter = 0; + tNumShakes--; + tHorizontalPan = -tHorizontalPan; + tVerticalPan = -tVerticalPan; + SetCameraPanning(tHorizontalPan, tVerticalPan); + if (tNumShakes == 0) { StopCameraShake(taskId); InstallCameraPanAheadCallback(); @@ -1495,11 +1506,11 @@ static void StopCameraShake(u8 taskId) ScriptContext_Enable(); } -#undef horizontalPan -#undef delayCounter -#undef numShakes -#undef delay -#undef verticalPan +#undef tHorizontalPan +#undef tDelayCounter +#undef tNumShakes +#undef tDelay +#undef tVerticalPan bool8 FoundBlackGlasses(void) { @@ -1524,7 +1535,8 @@ u8 GetLeadMonIndex(void) u8 partyCount = CalculatePlayerPartyCount(); for (i = 0; i < partyCount; i++) { - if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_EGG && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != 0) + if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_EGG + && GetMonData(&gPlayerParty[i], MON_DATA_SPECIES2, NULL) != SPECIES_NONE) return i; } return 0; @@ -1695,10 +1707,6 @@ static const u8 *const sDeptStoreFloorNames[] = [DEPT_STORE_FLOORNUM_ROOFTOP] = gText_Rooftop }; -#define ELEVATOR_WINDOW_WIDTH 3 -#define ELEVATOR_WINDOW_HEIGHT 3 -#define ELEVATOR_LIGHT_STAGES 3 - static const u16 sElevatorWindowTiles_Ascending[ELEVATOR_WINDOW_HEIGHT][ELEVATOR_LIGHT_STAGES] = { { @@ -2020,13 +2028,13 @@ bool8 UsedPokemonCenterWarp(void) MAP_EVER_GRANDE_CITY_POKEMON_LEAGUE_1F, MAP_BATTLE_FRONTIER_POKEMON_CENTER_1F, MAP_UNION_ROOM, - 0xFFFF + MAP_UNDEFINED }; int i; u16 map = (gLastUsedWarp.mapGroup << 8) + gLastUsedWarp.mapNum; - for (i = 0; sPokemonCenters[i] != 0xFFFF; i++) + for (i = 0; sPokemonCenters[i] != MAP_UNDEFINED; i++) { if (sPokemonCenters[i] == map) return TRUE; @@ -2724,21 +2732,21 @@ static void ScrollableMultichoice_UpdateScrollArrows(u8 taskId) .secondY = 0, .fullyUpThreshold = 0, .fullyDownThreshold = 0, - .tileTag = 2000, - .palTag = 100, + .tileTag = GFXTAG_MULTICHOICE_SCROLL_ARROWS, + .palTag = PALTAG_MULTICHOICE_SCROLL_ARROWS, .palNum = 0 }; struct Task *task = &gTasks[taskId]; struct ScrollArrowsTemplate template = sScrollableMultichoice_ScrollArrowsTemplate; - if (task->tMaxItemsOnScreen != task->data[1]) + if (task->tMaxItemsOnScreen != task->tNumItems) { template.firstX = (task->tWidth / 2) * 8 + 12 + (task->tLeft - 1) * 8; template.firstY = 8; template.secondX = (task->tWidth / 2) * 8 + 12 + (task->tLeft - 1) * 8; template.secondY = task->tHeight * 8 + 10; template.fullyUpThreshold = 0; - template.fullyDownThreshold = task->data[1] - task->tMaxItemsOnScreen; + template.fullyDownThreshold = task->tNumItems - task->tMaxItemsOnScreen; task->tScrollArrowId = AddScrollIndicatorArrowPair(&template, &sScrollableMultichoice_ScrollOffset); } } @@ -2746,10 +2754,8 @@ static void ScrollableMultichoice_UpdateScrollArrows(u8 taskId) static void ScrollableMultichoice_RemoveScrollArrows(u8 taskId) { struct Task *task = &gTasks[taskId]; - if (task->tMaxItemsOnScreen != task->data[1]) - { + if (task->tMaxItemsOnScreen != task->tNumItems) RemoveScrollIndicatorArrowPair(task->tScrollArrowId); - } } // Removed for Emerald (replaced by ShowScrollableMultichoice) @@ -2973,8 +2979,6 @@ void CloseFrontierExchangeCornerItemIconWindow(void) RemoveWindow(sFrontierExchangeCorner_ItemIconWindowId); } -#define TAG_ITEM_ICON 5500 - static void FillFrontierExchangeCornerWindowAndItemIcon(u16 menu, u16 selection) { #include "data/battle_frontier/battle_frontier_exchange_corner.h" @@ -3255,12 +3259,14 @@ void ScrollableMultichoice_ClosePersistentMenu(void) #undef tListTaskId #undef tTaskId +#define DEOXYS_ROCK_LEVELS 11 + void DoDeoxysRockInteraction(void) { CreateTask(Task_DeoxysRockInteraction, 8); } -static const u16 sDeoxysRockPalettes[][16] = { +static const u16 sDeoxysRockPalettes[DEOXYS_ROCK_LEVELS][16] = { INCBIN_U16("graphics/field_effects/palettes/deoxys_rock_1.gbapal"), INCBIN_U16("graphics/field_effects/palettes/deoxys_rock_2.gbapal"), INCBIN_U16("graphics/field_effects/palettes/deoxys_rock_3.gbapal"), @@ -3274,7 +3280,7 @@ static const u16 sDeoxysRockPalettes[][16] = { INCBIN_U16("graphics/field_effects/palettes/deoxys_rock_11.gbapal"), }; -static const u8 sDeoxysRockCoords[][2] = { +static const u8 sDeoxysRockCoords[DEOXYS_ROCK_LEVELS][2] = { { 15, 12 }, { 11, 14 }, { 15, 8 }, @@ -3290,11 +3296,11 @@ static const u8 sDeoxysRockCoords[][2] = { static void Task_DeoxysRockInteraction(u8 taskId) { - static const u8 sStoneMaxStepCounts[] = { 4, 8, 8, 8, 4, 4, 4, 6, 3, 3 }; + static const u8 sStoneMaxStepCounts[DEOXYS_ROCK_LEVELS - 1] = { 4, 8, 8, 8, 4, 4, 4, 6, 3, 3 }; if (FlagGet(FLAG_DEOXYS_ROCK_COMPLETE) == TRUE) { - gSpecialVar_Result = 3; + gSpecialVar_Result = DEOXYS_ROCK_COMPLETE; ScriptContext_Enable(); DestroyTask(taskId); } @@ -3309,13 +3315,13 @@ static void Task_DeoxysRockInteraction(u8 taskId) // Player failed to take the shortest path to the stone, so it resets. ChangeDeoxysRockLevel(0); VarSet(VAR_DEOXYS_ROCK_LEVEL, 0); - gSpecialVar_Result = 0; + gSpecialVar_Result = DEOXYS_ROCK_FAILED; DestroyTask(taskId); } - else if (rockLevel == 10) + else if (rockLevel == DEOXYS_ROCK_LEVELS - 1) { FlagSet(FLAG_DEOXYS_ROCK_COMPLETE); - gSpecialVar_Result = 2; + gSpecialVar_Result = DEOXYS_ROCK_SOLVED; ScriptContext_Enable(); DestroyTask(taskId); } @@ -3324,7 +3330,7 @@ static void Task_DeoxysRockInteraction(u8 taskId) rockLevel++; ChangeDeoxysRockLevel(rockLevel); VarSet(VAR_DEOXYS_ROCK_LEVEL, rockLevel); - gSpecialVar_Result = 1; + gSpecialVar_Result = DEOXYS_ROCK_PROGRESSED; DestroyTask(taskId); } } @@ -3337,9 +3343,9 @@ static void ChangeDeoxysRockLevel(u8 rockLevel) TryGetObjectEventIdByLocalIdAndMap(LOCALID_BIRTH_ISLAND_EXTERIOR_ROCK, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, &objectEventId); if (rockLevel == 0) - PlaySE(SE_M_CONFUSE_RAY); + PlaySE(SE_M_CONFUSE_RAY); // Failure sound else - PlaySE(SE_RG_DEOXYS_MOVE); + PlaySE(SE_RG_DEOXYS_MOVE); // Success sound CreateTask(WaitForDeoxysRockMovement, 8); gFieldEffectArguments[0] = LOCALID_BIRTH_ISLAND_EXTERIOR_ROCK; @@ -3348,6 +3354,8 @@ static void ChangeDeoxysRockLevel(u8 rockLevel) gFieldEffectArguments[3] = sDeoxysRockCoords[rockLevel][0]; gFieldEffectArguments[4] = sDeoxysRockCoords[rockLevel][1]; + // Set number of movement steps. + // Resetting for failure is slow, successful movement is fast. if (rockLevel == 0) gFieldEffectArguments[5] = 60; else @@ -3865,8 +3873,9 @@ static void Task_CloseBattlePikeCurtain(u8 taskId) void GetBattlePyramidHint(void) { - gSpecialVar_Result = gSpecialVar_0x8004 / 7; - gSpecialVar_Result -= (gSpecialVar_Result / 20) * 20; + // gSpecialVar_0x8004 here is expected to be the current Battle Pyramid win streak. + gSpecialVar_Result = gSpecialVar_0x8004 / FRONTIER_STAGES_PER_CHALLENGE; + gSpecialVar_Result -= (gSpecialVar_Result / TOTAL_PYRAMID_ROUNDS) * TOTAL_PYRAMID_ROUNDS; } // Used to avoid a potential softlock if the player respawns on Dewford with no way off @@ -3901,13 +3910,13 @@ bool8 InPokemonCenter(void) MAP_TRADE_CENTER, MAP_RECORD_CORNER, MAP_BATTLE_COLOSSEUM_4P, - 0xFFFF + MAP_UNDEFINED }; int i; u16 map = (gSaveBlock1Ptr->location.mapGroup << 8) + gSaveBlock1Ptr->location.mapNum; - for (i = 0; sPokemonCenters[i] != 0xFFFF; i++) + for (i = 0; sPokemonCenters[i] != MAP_UNDEFINED; i++) { if (sPokemonCenters[i] == map) return TRUE; From 30f893f2558ed8ae95ad23c2813006edd109229d Mon Sep 17 00:00:00 2001 From: GriffinR Date: Wed, 1 Feb 2023 11:52:32 -0500 Subject: [PATCH 27/69] Fix comment mistake --- src/field_specials.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/field_specials.c b/src/field_specials.c index 7e8d10256..6251a4db7 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -1049,7 +1049,7 @@ static void PCTurnOnEffect_SetMetatile(s16 isScreenOn, s8 dx, s8 dy) u16 metatileId = 0; if (isScreenOn) { - // Screen is off, set it on + // Screen is on, set it off if (gSpecialVar_0x8004 == PC_LOCATION_OTHER) metatileId = METATILE_Building_PC_Off; else if (gSpecialVar_0x8004 == PC_LOCATION_BRENDANS_HOUSE) @@ -1059,7 +1059,7 @@ static void PCTurnOnEffect_SetMetatile(s16 isScreenOn, s8 dx, s8 dy) } else { - // Screen is on, set it off + // Screen is off, set it on if (gSpecialVar_0x8004 == PC_LOCATION_OTHER) metatileId = METATILE_Building_PC_On; else if (gSpecialVar_0x8004 == PC_LOCATION_BRENDANS_HOUSE) From 07e00b2e41cf0180acbf57b3573cf99fbecacd16 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Wed, 1 Feb 2023 15:24:15 -0500 Subject: [PATCH 28/69] Additional window id constant usage --- src/berry_tag_screen.c | 12 ++++++------ src/contest.c | 4 ++-- src/pokeblock.c | 4 ++-- src/wireless_communication_status_screen.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/berry_tag_screen.c b/src/berry_tag_screen.c index b65341e67..e43d68600 100644 --- a/src/berry_tag_screen.c +++ b/src/berry_tag_screen.c @@ -599,7 +599,7 @@ static void Task_DisplayAnotherBerry(u8 taskId) switch (data[0]) { case 0x30: - FillWindowPixelBuffer(0, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_BERRY_NAME, PIXEL_FILL(0)); break; case 0x40: PrintBerryNumberAndName(); @@ -609,7 +609,7 @@ static void Task_DisplayAnotherBerry(u8 taskId) CreateBerrySprite(); break; case 0x60: - FillWindowPixelBuffer(1, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_SIZE_FIRM, PIXEL_FILL(0)); break; case 0x70: PrintBerrySize(); @@ -621,7 +621,7 @@ static void Task_DisplayAnotherBerry(u8 taskId) SetFlavorCirclesVisiblity(); break; case 0xA0: - FillWindowPixelBuffer(2, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_DESC, PIXEL_FILL(0)); break; case 0xB0: PrintBerryDescription1(); @@ -636,7 +636,7 @@ static void Task_DisplayAnotherBerry(u8 taskId) switch (data[0]) { case 0x30: - FillWindowPixelBuffer(2, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_DESC, PIXEL_FILL(0)); break; case 0x40: PrintBerryDescription2(); @@ -648,7 +648,7 @@ static void Task_DisplayAnotherBerry(u8 taskId) SetFlavorCirclesVisiblity(); break; case 0x70: - FillWindowPixelBuffer(1, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_SIZE_FIRM, PIXEL_FILL(0)); break; case 0x80: PrintBerryFirmness(); @@ -661,7 +661,7 @@ static void Task_DisplayAnotherBerry(u8 taskId) CreateBerrySprite(); break; case 0xB0: - FillWindowPixelBuffer(0, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_BERRY_NAME, PIXEL_FILL(0)); break; case 0xC0: PrintBerryNumberAndName(); diff --git a/src/contest.c b/src/contest.c index 2a0e163a5..2c0f66f6b 100644 --- a/src/contest.c +++ b/src/contest.c @@ -5459,7 +5459,7 @@ static void Contest_StartTextPrinter(const u8 *currChar, bool32 b) u8 speed; printerTemplate.currentChar = currChar; - printerTemplate.windowId = 4; + printerTemplate.windowId = WIN_GENERAL_TEXT; printerTemplate.fontId = FONT_NORMAL; printerTemplate.x = 0; printerTemplate.y = 1; @@ -5485,7 +5485,7 @@ static void Contest_StartTextPrinter(const u8 *currChar, bool32 b) AddTextPrinter(&printerTemplate, speed, 0); } - PutWindowTilemap(4); + PutWindowTilemap(WIN_GENERAL_TEXT); Contest_SetBgCopyFlags(0); } diff --git a/src/pokeblock.c b/src/pokeblock.c index 3f0b3b5c5..e490f372c 100644 --- a/src/pokeblock.c +++ b/src/pokeblock.c @@ -765,7 +765,7 @@ static void DrawPokeblockInfo(s32 pkblId) struct Pokeblock *pokeblock; u16 rectTilemapSrc[2]; - FillWindowPixelBuffer(7, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_FEEL, PIXEL_FILL(0)); if (pkblId != LIST_CANCEL) { @@ -802,7 +802,7 @@ static void DrawPokeblockInfo(s32 pkblId) for (i = 0; i < FLAVOR_COUNT; i++) CopyToBgTilemapBufferRect(2, rectTilemapSrc, (i / 3 * 6) + 1, (i % 3 * 2) + 13, 1, 2); - CopyWindowToVram(7, COPYWIN_GFX); + CopyWindowToVram(WIN_FEEL, COPYWIN_GFX); } ScheduleBgCopyTilemapToVram(0); diff --git a/src/wireless_communication_status_screen.c b/src/wireless_communication_status_screen.c index 488a3291e..dd99188ea 100644 --- a/src/wireless_communication_status_screen.c +++ b/src/wireless_communication_status_screen.c @@ -266,7 +266,7 @@ static void PrintHeaderTexts(void) s32 i; FillWindowPixelBuffer(WIN_TITLE, PIXEL_FILL(0)); FillWindowPixelBuffer(WIN_GROUP_NAMES, PIXEL_FILL(0)); - FillWindowPixelBuffer(2, PIXEL_FILL(0)); + FillWindowPixelBuffer(WIN_GROUP_COUNTS, PIXEL_FILL(0)); // Print title WCSS_AddTextPrinterParameterized(WIN_TITLE, FONT_NORMAL, sHeaderTexts[0], GetStringCenterAlignXOffset(FONT_NORMAL, sHeaderTexts[0], 0xC0), 6, COLORMODE_GREEN); From 020266463c0bdd279db78981d14391d366e86e06 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Wed, 1 Feb 2023 15:44:48 -0500 Subject: [PATCH 29/69] Add fix for described UB --- src/wireless_communication_status_screen.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/wireless_communication_status_screen.c b/src/wireless_communication_status_screen.c index a3c2f4e22..dc60f591d 100644 --- a/src/wireless_communication_status_screen.c +++ b/src/wireless_communication_status_screen.c @@ -126,7 +126,6 @@ static const u8 *const sHeaderTexts[NUM_GROUPTYPES + 1] = { // Activity, group type, number of players // 0 players means the number of players can change and should be counted dynamically // GROUPTYPE_TOTAL have no unique group and are simply counted in the total of "people communicating" -// UB: GROUPTYPE_NONE (-1) can potentially be used as an index into a u8[4] in CountPlayersInGroupAndGetActivity static const u8 sActivityGroupInfo[][3] = { {ACTIVITY_BATTLE_SINGLE, GROUPTYPE_BATTLE, 2}, {ACTIVITY_BATTLE_DOUBLE, GROUPTYPE_BATTLE, 2}, @@ -382,6 +381,13 @@ static u32 CountPlayersInGroupAndGetActivity(struct RfuPlayer * player, u32 * gr for (i = 0; i < ARRAY_COUNT(sActivityGroupInfo); i++) { +#ifdef UBFIX + // GROUPTYPE_NONE is -1, and shouldn't be used as an index into groupCounts. + // In theory the only activity with this group type (ACTIVITY_SEARCH) wouldn't + // satisfy the condition below, but not necessarily. + if (group_type(i) == GROUPTYPE_NONE) + continue; +#endif if (activity == group_activity(i) && player->groupScheduledAnim == UNION_ROOM_SPAWN_IN) { if (group_players(i) == 0) From 62aed217fe7fcb162bfcef13cc4bb856465590e1 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 15 Aug 2022 14:09:07 -0400 Subject: [PATCH 30/69] Remove unused common symbols in window.c --- common_syms/window.txt | 3 --- gflib/window.c | 3 --- gflib/window.h | 3 --- 3 files changed, 9 deletions(-) diff --git a/common_syms/window.txt b/common_syms/window.txt index 416d9d732..24c093a22 100644 --- a/common_syms/window.txt +++ b/common_syms/window.txt @@ -1,5 +1,2 @@ -gUnusedWindowVar1 -gUnusedWindowVar2 gTransparentTileNumber -gUnusedWindowVar3 gWindowBgTilemapBuffers diff --git a/gflib/window.c b/gflib/window.c index ff9e8a6e0..1621a0884 100644 --- a/gflib/window.c +++ b/gflib/window.c @@ -4,11 +4,8 @@ #include "bg.h" #include "blit.h" -u32 gUnusedWindowVar1; -u32 gUnusedWindowVar2; // This global is set to 0 and never changed. u8 gTransparentTileNumber; -u32 gUnusedWindowVar3; void *gWindowBgTilemapBuffers[NUM_BACKGROUNDS]; extern u32 gWindowTileAutoAllocEnabled; diff --git a/gflib/window.h b/gflib/window.h index 583e7e167..0000dd864 100644 --- a/gflib/window.h +++ b/gflib/window.h @@ -74,8 +74,5 @@ void CopyWindowToVram8Bit(u8 windowId, u8 mode); extern struct Window gWindows[]; extern void *gWindowBgTilemapBuffers[]; -extern u32 gUnusedWindowVar1; -extern u32 gUnusedWindowVar2; -extern u32 gUnusedWindowVar3; #endif // GUARD_WINDOW_H From 717ba22ea1d453b248b23b4857d39e33362c8e89 Mon Sep 17 00:00:00 2001 From: Jaizu Date: Fri, 3 Feb 2023 15:49:22 +0100 Subject: [PATCH 31/69] Make contest opponents an enum I'm sure that at least 2 people eventually might consider editing them, this makes it easier. --- src/data/contest_opponents.h | 194 ++++++++++++++++++----------------- 1 file changed, 98 insertions(+), 96 deletions(-) diff --git a/src/data/contest_opponents.h b/src/data/contest_opponents.h index 19019be91..7c3aad315 100644 --- a/src/data/contest_opponents.h +++ b/src/data/contest_opponents.h @@ -2,102 +2,104 @@ #include "global.h" #include "contest.h" -#define CONTEST_OPPONENT_JIMMY 0 -#define CONTEST_OPPONENT_EDITH 1 -#define CONTEST_OPPONENT_EVAN 2 -#define CONTEST_OPPONENT_KELSEY 3 -#define CONTEST_OPPONENT_MADISON 4 -#define CONTEST_OPPONENT_RAYMOND 5 -#define CONTEST_OPPONENT_GRANT 6 -#define CONTEST_OPPONENT_PAIGE 7 -#define CONTEST_OPPONENT_ALEC 8 -#define CONTEST_OPPONENT_SYDNEY 9 -#define CONTEST_OPPONENT_MORRIS 10 -#define CONTEST_OPPONENT_MARIAH 11 -#define CONTEST_OPPONENT_RUSSELL 12 -#define CONTEST_OPPONENT_MELANIE 13 -#define CONTEST_OPPONENT_CHANCE 14 -#define CONTEST_OPPONENT_AGATHA 15 -#define CONTEST_OPPONENT_BEAU 16 -#define CONTEST_OPPONENT_KAY 17 -#define CONTEST_OPPONENT_CALE 18 -#define CONTEST_OPPONENT_CAITLIN 19 -#define CONTEST_OPPONENT_COLBY 20 -#define CONTEST_OPPONENT_KYLIE 21 -#define CONTEST_OPPONENT_LIAM 22 -#define CONTEST_OPPONENT_MILO 23 -#define CONTEST_OPPONENT_KARINA 24 -#define CONTEST_OPPONENT_BOBBY 25 -#define CONTEST_OPPONENT_CLAIRE 26 -#define CONTEST_OPPONENT_WILLIE 27 -#define CONTEST_OPPONENT_CASSIDY 28 -#define CONTEST_OPPONENT_MORGAN 29 -#define CONTEST_OPPONENT_SUMMER 30 -#define CONTEST_OPPONENT_MILES 31 -#define CONTEST_OPPONENT_AUDREY 32 -#define CONTEST_OPPONENT_AVERY 33 -#define CONTEST_OPPONENT_ARIANA 34 -#define CONTEST_OPPONENT_ASHTON 35 -#define CONTEST_OPPONENT_SANDRA 36 -#define CONTEST_OPPONENT_CARSON 37 -#define CONTEST_OPPONENT_KATRINA 38 -#define CONTEST_OPPONENT_LUKE 39 -#define CONTEST_OPPONENT_RAUL 40 -#define CONTEST_OPPONENT_JADA 41 -#define CONTEST_OPPONENT_ZEEK 42 -#define CONTEST_OPPONENT_DIEGO 43 -#define CONTEST_OPPONENT_ALIYAH 44 -#define CONTEST_OPPONENT_NATALIA 45 -#define CONTEST_OPPONENT_DEVIN 46 -#define CONTEST_OPPONENT_TYLOR 47 -#define CONTEST_OPPONENT_RONNIE 48 -#define CONTEST_OPPONENT_CLAUDIA 49 -#define CONTEST_OPPONENT_ELIAS 50 -#define CONTEST_OPPONENT_JADE 51 -#define CONTEST_OPPONENT_FRANCIS 52 -#define CONTEST_OPPONENT_ALISHA 53 -#define CONTEST_OPPONENT_SAUL 54 -#define CONTEST_OPPONENT_FELICIA 55 -#define CONTEST_OPPONENT_EMILIO 56 -#define CONTEST_OPPONENT_KARLA 57 -#define CONTEST_OPPONENT_DARRYL 58 -#define CONTEST_OPPONENT_SELENA 59 -#define CONTEST_OPPONENT_NOEL 60 -#define CONTEST_OPPONENT_LACEY 61 -#define CONTEST_OPPONENT_CORBIN 62 -#define CONTEST_OPPONENT_GRACIE 63 -#define CONTEST_OPPONENT_COLTIN 64 -#define CONTEST_OPPONENT_ELLIE 65 -#define CONTEST_OPPONENT_MARCUS 66 -#define CONTEST_OPPONENT_KIARA 67 -#define CONTEST_OPPONENT_BRYCE 68 -#define CONTEST_OPPONENT_JAMIE 69 -#define CONTEST_OPPONENT_JORGE 70 -#define CONTEST_OPPONENT_DEVON 71 -#define CONTEST_OPPONENT_JUSTINA 72 -#define CONTEST_OPPONENT_RALPH 73 -#define CONTEST_OPPONENT_ROSA 74 -#define CONTEST_OPPONENT_KEATON 75 -#define CONTEST_OPPONENT_MAYRA 76 -#define CONTEST_OPPONENT_LAMAR 77 -#define CONTEST_OPPONENT_AUBREY 78 -#define CONTEST_OPPONENT_NIGEL 79 -#define CONTEST_OPPONENT_CAMILLE 80 -#define CONTEST_OPPONENT_DEON 81 -#define CONTEST_OPPONENT_JANELLE 82 -#define CONTEST_OPPONENT_HEATH 83 -#define CONTEST_OPPONENT_SASHA 84 -#define CONTEST_OPPONENT_FRANKIE 85 -#define CONTEST_OPPONENT_HELEN 86 -#define CONTEST_OPPONENT_CAMILE 87 -#define CONTEST_OPPONENT_MARTIN 88 -#define CONTEST_OPPONENT_SERGIO 89 -#define CONTEST_OPPONENT_KAILEY 90 -#define CONTEST_OPPONENT_PERLA 91 -#define CONTEST_OPPONENT_CLARA 92 -#define CONTEST_OPPONENT_JAKOB 93 -#define CONTEST_OPPONENT_TREY 94 -#define CONTEST_OPPONENT_LANE 95 +enum { + CONTEST_OPPONENT_JIMMY, + CONTEST_OPPONENT_EDITH, + CONTEST_OPPONENT_EVAN, + CONTEST_OPPONENT_KELSEY, + CONTEST_OPPONENT_MADISON, + CONTEST_OPPONENT_RAYMOND, + CONTEST_OPPONENT_GRANT, + CONTEST_OPPONENT_PAIGE, + CONTEST_OPPONENT_ALEC, + CONTEST_OPPONENT_SYDNEY, + CONTEST_OPPONENT_MORRIS, + CONTEST_OPPONENT_MARIAH, + CONTEST_OPPONENT_RUSSELL, + CONTEST_OPPONENT_MELANIE, + CONTEST_OPPONENT_CHANCE, + CONTEST_OPPONENT_AGATHA, + CONTEST_OPPONENT_BEAU, + CONTEST_OPPONENT_KAY, + CONTEST_OPPONENT_CALE, + CONTEST_OPPONENT_CAITLIN, + CONTEST_OPPONENT_COLBY, + CONTEST_OPPONENT_KYLIE, + CONTEST_OPPONENT_LIAM, + CONTEST_OPPONENT_MILO, + CONTEST_OPPONENT_KARINA, + CONTEST_OPPONENT_BOBBY, + CONTEST_OPPONENT_CLAIRE, + CONTEST_OPPONENT_WILLIE, + CONTEST_OPPONENT_CASSIDY, + CONTEST_OPPONENT_MORGAN, + CONTEST_OPPONENT_SUMMER, + CONTEST_OPPONENT_MILES, + CONTEST_OPPONENT_AUDREY, + CONTEST_OPPONENT_AVERY, + CONTEST_OPPONENT_ARIANA, + CONTEST_OPPONENT_ASHTON, + CONTEST_OPPONENT_SANDRA, + CONTEST_OPPONENT_CARSON, + CONTEST_OPPONENT_KATRINA, + CONTEST_OPPONENT_LUKE, + CONTEST_OPPONENT_RAUL, + CONTEST_OPPONENT_JADA, + CONTEST_OPPONENT_ZEEK, + CONTEST_OPPONENT_DIEGO, + CONTEST_OPPONENT_ALIYAH, + CONTEST_OPPONENT_NATALIA, + CONTEST_OPPONENT_DEVIN, + CONTEST_OPPONENT_TYLOR, + CONTEST_OPPONENT_RONNIE, + CONTEST_OPPONENT_CLAUDIA, + CONTEST_OPPONENT_ELIAS, + CONTEST_OPPONENT_JADE, + CONTEST_OPPONENT_FRANCIS, + CONTEST_OPPONENT_ALISHA, + CONTEST_OPPONENT_SAUL, + CONTEST_OPPONENT_FELICIA, + CONTEST_OPPONENT_EMILIO, + CONTEST_OPPONENT_KARLA, + CONTEST_OPPONENT_DARRYL, + CONTEST_OPPONENT_SELENA, + CONTEST_OPPONENT_NOEL, + CONTEST_OPPONENT_LACEY, + CONTEST_OPPONENT_CORBIN, + CONTEST_OPPONENT_GRACIE, + CONTEST_OPPONENT_COLTIN, + CONTEST_OPPONENT_ELLIE, + CONTEST_OPPONENT_MARCUS, + CONTEST_OPPONENT_KIARA, + CONTEST_OPPONENT_BRYCE, + CONTEST_OPPONENT_JAMIE, + CONTEST_OPPONENT_JORGE, + CONTEST_OPPONENT_DEVON, + CONTEST_OPPONENT_JUSTINA, + CONTEST_OPPONENT_RALPH, + CONTEST_OPPONENT_ROSA, + CONTEST_OPPONENT_KEATON, + CONTEST_OPPONENT_MAYRA, + CONTEST_OPPONENT_LAMAR, + CONTEST_OPPONENT_AUBREY, + CONTEST_OPPONENT_NIGEL, + CONTEST_OPPONENT_CAMILLE, + CONTEST_OPPONENT_DEON, + CONTEST_OPPONENT_JANELLE, + CONTEST_OPPONENT_HEATH, + CONTEST_OPPONENT_SASHA, + CONTEST_OPPONENT_FRANKIE, + CONTEST_OPPONENT_HELEN, + CONTEST_OPPONENT_CAMILE, + CONTEST_OPPONENT_MARTIN, + CONTEST_OPPONENT_SERGIO, + CONTEST_OPPONENT_KAILEY, + CONTEST_OPPONENT_PERLA, + CONTEST_OPPONENT_CLARA, + CONTEST_OPPONENT_JAKOB, + CONTEST_OPPONENT_TREY, + CONTEST_OPPONENT_LANE +}; // All contest opponents have a common set of AI flags (which contains all of the actually // useful AI scripts, as well as some dummys) and a random combination of 2-3 dummy flags. From c1cfd3ac665b939be0e853b12e110ff8f3471bae Mon Sep 17 00:00:00 2001 From: GriffinR Date: Fri, 3 Feb 2023 16:01:13 -0500 Subject: [PATCH 32/69] Add fix for commented bug --- src/frontier_pass.c | 15 +++++++++++++-- src/graphics.c | 1 - 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/frontier_pass.c b/src/frontier_pass.c index 61bd1d409..07e06ad3b 100644 --- a/src/frontier_pass.c +++ b/src/frontier_pass.c @@ -30,6 +30,17 @@ #include "constants/region_map_sections.h" #include "constants/songs.h" +// gFrontierPassBg_Pal has 8*16 colors, but they attempt to load 13*16 colors. +// As a result it goes out of bounds and interprets 160 bytes of whatever comes +// after gFrontierPassBg_Pal (by default, gFrontierPassBg_Gfx) as a palette. +// Nothing uses these colors (except the Trainer Card, which correctly writes them) +// so in practice this bug has no effect on the game. +#ifdef BUGFIX +#define NUM_BG_PAL_SLOTS 8 +#else +#define NUM_BG_PAL_SLOTS 13 +#endif + // All windows displayed in the frontier pass. enum { @@ -768,7 +779,7 @@ static bool32 InitFrontierPass(void) CopyBgTilemapBufferToVram(2); break; case 8: - LoadPalette(gFrontierPassBg_Pal[0], 0, 13 * PLTT_SIZE_4BPP); + LoadPalette(gFrontierPassBg_Pal, 0, NUM_BG_PAL_SLOTS * PLTT_SIZE_4BPP); LoadPalette(gFrontierPassBg_Pal[1 + sPassData->trainerStars], BG_PLTT_ID(1), PLTT_SIZE_4BPP); LoadPalette(GetTextWindowPalette(0), BG_PLTT_ID(15), PLTT_SIZE_4BPP); DrawFrontierPassBg(); @@ -1412,7 +1423,7 @@ static bool32 InitFrontierMap(void) case 5: if (FreeTempTileDataBuffersIfPossible()) return FALSE; - LoadPalette(gFrontierPassBg_Pal[0], BG_PLTT_ID(0), 13 * PLTT_SIZE_4BPP); + LoadPalette(gFrontierPassBg_Pal, BG_PLTT_ID(0), NUM_BG_PAL_SLOTS * PLTT_SIZE_4BPP); LoadPalette(GetTextWindowPalette(0), BG_PLTT_ID(15), PLTT_SIZE_4BPP); CopyToBgTilemapBuffer(2, sMapScreen_Tilemap, 0, 0); CopyBgTilemapBufferToVram(2); diff --git a/src/graphics.c b/src/graphics.c index e0045ba6b..f6b3ce0af 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -1520,7 +1520,6 @@ const u16 gTitleScreenPressStartPal[] = INCBIN_U16("graphics/title_screen/p const u32 gTitleScreenPressStartGfx[] = INCBIN_U32("graphics/title_screen/press_start.4bpp.lz"); const u32 gTitleScreenPokemonLogoTilemap[] = INCBIN_U32("graphics/title_screen/pokemon_logo.bin.lz"); -// size in LoadPalette calls is reported as 0xD0 << 1, which is 0x1A0, but palette is only 0x100 bytes long so it loads garbage as well const u16 gFrontierPassBg_Pal[][16] = INCBIN_U16("graphics/frontier_pass/bg.gbapal"); const u32 gFrontierPassBg_Gfx[] = INCBIN_U32("graphics/frontier_pass/bg.4bpp.lz"); const u32 gFrontierPassMapAndCard_Gfx[] = INCBIN_U32("graphics/frontier_pass/map_and_card.8bpp.lz"); From bbf0cf0103de221fd54b9348f1ee0b1e5510c2ce Mon Sep 17 00:00:00 2001 From: GriffinR Date: Sat, 4 Feb 2023 00:00:38 -0500 Subject: [PATCH 33/69] Stop hard-coding number of preset names --- src/main_menu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main_menu.c b/src/main_menu.c index 845939674..6808a8f11 100644 --- a/src/main_menu.c +++ b/src/main_menu.c @@ -503,7 +503,9 @@ static const u8 *const sFemalePresetNames[] = { gText_DefaultNameHalie }; -// .text +// The number of male vs. female names is assumed to be the same. +// If they aren't, the smaller of the two sizes will be used and any extra names will be ignored. +#define NUM_PRESET_NAMES min(ARRAY_COUNT(sMalePresetNames), ARRAY_COUNT(sFemalePresetNames)) enum { @@ -1597,7 +1599,7 @@ static void Task_NewGameBirchSpeech_StartNamingScreen(u8 taskId) { FreeAllWindowBuffers(); FreeAndDestroyMonPicSprite(gTasks[taskId].tLotadSpriteId); - NewGameBirchSpeech_SetDefaultPlayerName(Random() % 20); + NewGameBirchSpeech_SetDefaultPlayerName(Random() % NUM_PRESET_NAMES); DestroyTask(taskId); DoNamingScreen(NAMING_SCREEN_PLAYER, gSaveBlock2Ptr->playerName, gSaveBlock2Ptr->playerGender, 0, 0, CB2_NewGameBirchSpeech_ReturnFromNamingScreen); } From 5bf607049e9365fa1e765ffad05999046438abbd Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 7 Feb 2023 16:41:30 +0100 Subject: [PATCH 34/69] Fix Pollen Puff score --- src/battle_ai_main.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 560457dcc..bcf4801ee 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -2427,6 +2427,13 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) break; } break; + case EFFECT_HEAL_PULSE: // and floral healing + if (!IsTargetingPartner(battlerAtk, battlerDef)) // Don't heal enemies + { + score -= 10; + break; + } + // fallthrough case EFFECT_HIT_ENEMY_HEAL_ALLY: // pollen puff if (IsTargetingPartner(battlerAtk, battlerDef)) { @@ -2436,20 +2443,6 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) score -= 10; else if (gBattleMons[battlerDef].hp > gBattleMons[battlerDef].maxHP / 2) score -= 5; - break; - } - // fallthrough - case EFFECT_HEAL_PULSE: // and floral healing - if (!IsTargetingPartner(battlerAtk, battlerDef)) // Don't heal enemies - { - score -= 10; - } - else - { - if (AtMaxHp(battlerDef)) - score -= 10; - else if (gBattleMons[battlerDef].hp > gBattleMons[battlerDef].maxHP / 2) - score -= 5; } break; case EFFECT_ELECTRIFY: From 6c30c5490cfdb61e7e45a29de94b6b3e67862465 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Wed, 8 Feb 2023 00:51:59 -0300 Subject: [PATCH 35/69] Test PR --- src/battle_ai_switch_items.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 5bcd17716..0ae1c8a9a 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -205,7 +205,7 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void) if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_ACE_POKEMON && i == (CalculateEnemyPartyCount()-1)) continue; - + species = GetMonData(&party[i], MON_DATA_SPECIES); if (GetMonData(&party[i], MON_DATA_ABILITY_NUM) != 0) From 8c257bde9940ade994e1e64afed71f35407c0493 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 8 Feb 2023 10:24:19 +0100 Subject: [PATCH 36/69] Fix 1 vs 2 battles with eggs --- src/battle_gfx_sfx_util.c | 3 +++ src/battle_main.c | 2 +- src/battle_script_commands.c | 5 ++++- src/reshow_battle_screen.c | 4 +++- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index 193452613..389832fb2 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -557,6 +557,9 @@ static void BattleLoadMonSpriteGfx(struct Pokemon *mon, u32 battlerId, bool32 op if (illusionMon != NULL) mon = illusionMon; + if (GetMonData(mon, MON_DATA_IS_EGG)) // Don't load GFX of egg pokemon. + return; + monsPersonality = GetMonData(mon, MON_DATA_PERSONALITY); if (gBattleSpritesDataPtr->battlerData[battlerId].transformSpecies == SPECIES_NONE) { diff --git a/src/battle_main.c b/src/battle_main.c index 90540fa92..b23d8af55 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3655,7 +3655,7 @@ static void TryDoEventsBeforeFirstTurn(void) { for (i = 0; i < gBattlersCount; i++) { - if (gBattleMons[i].hp == 0 || gBattleMons[i].species == SPECIES_NONE) + if (gBattleMons[i].hp == 0 || gBattleMons[i].species == SPECIES_NONE || GetMonData(GetBattlerPartyData(i), MON_DATA_IS_EGG)) gAbsentBattlerFlags |= gBitTable[i]; } } diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index be5e2ee21..3227168dc 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -4036,6 +4036,8 @@ static void Cmd_getexp(void) { if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) == SPECIES_NONE || GetMonData(&gPlayerParty[i], MON_DATA_HP) == 0) continue; + if (GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)) + continue; if (gBitTable[i] & sentIn) viaSentIn++; @@ -4125,7 +4127,8 @@ static void Cmd_getexp(void) gBattleStruct->wildVictorySong++; } - if (GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_HP)) + if (GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_HP) + && !GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_IS_EGG)) { if (gBattleStruct->sentInPokes & 1) gBattleMoveDamage = *exp; diff --git a/src/reshow_battle_screen.c b/src/reshow_battle_screen.c index 16310a7c3..b24db3f87 100644 --- a/src/reshow_battle_screen.c +++ b/src/reshow_battle_screen.c @@ -258,6 +258,8 @@ static void CreateBattlerSprite(u8 battler) { if (GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_HP) == 0) return; + if (GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_IS_EGG)) + return; SetMultiuseSpriteTemplateToPokemon(GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_SPECIES), GetBattlerPosition(battler)); gBattlerSpriteIds[battler] = CreateSprite(&gMultiuseSpriteTemplate, GetBattlerSpriteCoord(battler, BATTLER_COORD_X_2), posY, GetBattlerSpriteSubpriority(battler)); @@ -311,7 +313,7 @@ static void CreateHealthboxSprite(u8 battler) } else if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) { - if (GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_HP) == 0) + if (GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_HP) == 0 || GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_IS_EGG)) SetHealthboxSpriteInvisible(healthboxSpriteId); } } From 41d64ea41e0070fa5c1bde0a3a7ee60baa971fc5 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 8 Feb 2023 13:02:41 +0100 Subject: [PATCH 37/69] heal pulse effect in double battles --- src/battle_ai_main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 560457dcc..2fb89bff3 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -3009,6 +3009,13 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score) RETURN_SCORE_PLUS(1); } break; + case EFFECT_HEAL_PULSE: + case EFFECT_HIT_ENEMY_HEAL_ALLY: + if (AI_WhoStrikesFirst(battlerAtk, FOE(battlerAtk), move) == AI_IS_FASTER + && AI_WhoStrikesFirst(battlerAtk, BATTLE_PARTNER(FOE(battlerAtk)), move) == AI_IS_FASTER + && gBattleMons[battlerAtkPartner].hp < gBattleMons[battlerAtkPartner].maxHP / 2) + RETURN_SCORE_PLUS(1); + break; } // attacker move effects } // check partner protecting From 8381b14c510bd76566d54193797a91bb226c5d37 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada D'Ottone Date: Wed, 8 Feb 2023 11:54:12 -0300 Subject: [PATCH 38/69] Implemented Xhyzi's RHH copyright intro (with config) (#2415) * Rhh & Pret Copyright Screen * Porygon recovered his voice * Expansion text --------- Co-authored-by: Xhyzi Co-authored-by: Jaizu --- graphics/rhh_copyright/credits.pal | 259 ++++++++++++++ graphics/rhh_copyright/powered_by.bin | Bin 0 -> 2048 bytes graphics/rhh_copyright/powered_by.png | Bin 0 -> 336 bytes graphics/rhh_copyright/rhh_credits.bin | Bin 0 -> 2048 bytes graphics/rhh_copyright/rhh_credits.png | Bin 0 -> 1703 bytes graphics/rhh_copyright/sprites/dizzy_egg.png | Bin 0 -> 1085 bytes graphics/rhh_copyright/sprites/porygon.png | Bin 0 -> 1423 bytes graphics/rhh_copyright/sprites/shiny.pal | 19 + include/config.h | 3 + include/rhh_copyright.h | 13 + ld_script.txt | 2 + src/battle_controller_player.c | 2 +- src/intro.c | 72 ++++ src/rhh_copyright.c | 345 +++++++++++++++++++ sym_ewram.txt | 1 + 15 files changed, 715 insertions(+), 1 deletion(-) create mode 100644 graphics/rhh_copyright/credits.pal create mode 100644 graphics/rhh_copyright/powered_by.bin create mode 100644 graphics/rhh_copyright/powered_by.png create mode 100644 graphics/rhh_copyright/rhh_credits.bin create mode 100644 graphics/rhh_copyright/rhh_credits.png create mode 100644 graphics/rhh_copyright/sprites/dizzy_egg.png create mode 100644 graphics/rhh_copyright/sprites/porygon.png create mode 100644 graphics/rhh_copyright/sprites/shiny.pal create mode 100644 include/rhh_copyright.h create mode 100644 src/rhh_copyright.c diff --git a/graphics/rhh_copyright/credits.pal b/graphics/rhh_copyright/credits.pal new file mode 100644 index 000000000..cdff46971 --- /dev/null +++ b/graphics/rhh_copyright/credits.pal @@ -0,0 +1,259 @@ +JASC-PAL +0100 +256 +198 231 214 +255 255 255 +222 222 222 +222 222 214 +198 198 198 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +255 255 255 +247 247 247 +231 231 231 +222 222 222 +222 222 214 +214 214 214 +198 198 198 +181 181 181 +165 165 165 +148 148 148 +132 132 132 +115 115 115 +99 99 99 +82 82 82 +66 66 66 +49 49 49 +33 33 33 +16 16 16 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 diff --git a/graphics/rhh_copyright/powered_by.bin b/graphics/rhh_copyright/powered_by.bin new file mode 100644 index 0000000000000000000000000000000000000000..13187db91138588bc182c956dbcc52c7b8619df6 GIT binary patch literal 2048 zcmZQzARjO?Fp{qssB>`YXJTMxU}0coU}InhVh*4?IT^SZxUu+jaJnChLvaX=x_>yP WUmTH*MR+v+K_M^-M?+xbh5!HwhXL>a literal 0 HcmV?d00001 diff --git a/graphics/rhh_copyright/powered_by.png b/graphics/rhh_copyright/powered_by.png new file mode 100644 index 0000000000000000000000000000000000000000..b422f6e568b80accc444bed5e8a737323d80791e GIT binary patch literal 336 zcmeAS@N?(olHy`uVBq!ia0vp^2|&!j!VDz82tKy~QtTz3zOL*~S=gB6xTTXDn}I^& zC9V-A!TD(=<%vb94DLQIKw}ijQi~Lf^-Ky|mplX+QBvUN4wNwlvKhP@H06O5OS+@4 zBLl<6e(pbstU$g&fKQ0)vFF$R|Nnmv1g;%Bb_}E(FL0f%cLS(^G0EHA<^NLlPe*~A z5>FS$kcv4=yAN_Y8}c}BZsL!7;H++N^MIU!@0R~sQ!mwX+19MMaCpHJQ-j`vhqu(X zB&JCpFNkA2c#+-yho;4w?o$Upc7HDZ5@`%ea2>C~X*ci(~>!{F)a=d#Wzp$P!&LvYFf literal 0 HcmV?d00001 diff --git a/graphics/rhh_copyright/rhh_credits.bin b/graphics/rhh_copyright/rhh_credits.bin new file mode 100644 index 0000000000000000000000000000000000000000..629a2e9544af1ebc9589eb6c6fbe444fb87cad6e GIT binary patch literal 2048 zcmeIuS5I6)3_#&;Vd=g177{}5z1Jj!un;;V^xpsf8&@kpyT5=3t}RQ}%p6;D2;(yw zh)9ttDowf!nX+Wdkt_0^dGZw~RHRsm(%`%-L0Ck&3YDr~qNUgUZ-4mV zr(c%+w&G84x0=Mq#HYr{r#GhxD(Z98`D*>_+qy6;~S|KFh_$3dPrb>`fK e%LM+)wHvqY+oZ*&9^= literal 0 HcmV?d00001 diff --git a/graphics/rhh_copyright/rhh_credits.png b/graphics/rhh_copyright/rhh_credits.png new file mode 100644 index 0000000000000000000000000000000000000000..177022a9d607fee02efd627816b253b4fa37481a GIT binary patch literal 1703 zcmeAS@N?(olHy`uVBq!ia0vp^4M1$c!3-psDj6OEDVB6cUq=RpjeRx011B>uFf#=B zgt#7ie(nGN|Mx)P+OcEDfXWC0p!)CMzdwKe9HQ&mHIT-wTemJ)RRKlU5nV~kdtNDShr?_ml4p^A^nG<$ANZ@OtQh@R#?eWY0|BCYmx^y@S!@ zvH5flExE`0P8_?C709ajiAAs>@8*p)GkR;K75on{mfaL#j9J5VL3KLAtt74a#~6BY zycz7mm}gv4dy^x4tebs}u%UyIS>cbvMhC1^jOH%<=ew6Xp~rpe)t=Hl*EAd695;HM z_FS<-x$r=e4*RRgAFl;PvbSBh(K$uJ!Ezd-!pTnz41UMHq!=z_m>R)#Azv|YKI4JI zDVD0PS%xx)?>8Phe#)qt`+?Ym48@mB3?KB4I{>r%TdGCzRPZ@XJDlW%bF<oQ$-UB+Q!YfQg^%&XsRbUQs)rU_@jWJLa+LL@c3{mX z&JQbY9)0mIaE9NG1u@?P;*M*1Nbrl=s?T|Fy!54s(<0teM_wM5^;$12UhpZzSy%j9er}}Twp9X7?9VirS1!7Ee)R+X2bUTCGt3g2wpHR! R^aW6!_H^}gS?83{1OUen%w_-p literal 0 HcmV?d00001 diff --git a/graphics/rhh_copyright/sprites/dizzy_egg.png b/graphics/rhh_copyright/sprites/dizzy_egg.png new file mode 100644 index 0000000000000000000000000000000000000000..cd03ffc152edbf7cad5e516d947b6ba70028f2fa GIT binary patch literal 1085 zcmV-D1j74?P)^i>gQq|9UaTM`v!0}p4ryf8KC3bpiFycTx@Z+~Yi0fCXphJ?_M3{XU)N_<;aY z`tvr3)9OlK1R>H+XD9qUMtNF*%v4E(td}9f^uJ;0fL+RZdIP=6Q~;wt*&Q_o zV1mvI&PIpO+-#)}+*<~JP1pRPmjb$Lu8oWIyIG6x^-Q#{t0Cc_|Q6+RDu3|nT`#uJs^_l)Gz_z)~t<~z)9`9;zn~-;FLT(}qk+oab2?=14x8?y+9ox96 zaLFVOt^=*>E{^~mJ|meof|bWsDTuG<+h9@<_dWhJhXqzakMU$LU=pk|*$zPr8Qi36P{(AKs*ooz@51iI3nl zeX##sA20o5rToLTe$GEWZXYe$hmm0#w2v(TAGQw*`pG^XLF;3ZhXYg}Xdey`ee6*m z8?BGBz$Mv3F!nf$^(WPf0P=0NFUz;ObKWjLBk=P00000NkvXXu0mjf Dk!;cK literal 0 HcmV?d00001 diff --git a/graphics/rhh_copyright/sprites/porygon.png b/graphics/rhh_copyright/sprites/porygon.png new file mode 100644 index 0000000000000000000000000000000000000000..020198df673f62c41868f8591cb0c0afefaed2a4 GIT binary patch literal 1423 zcmV;A1#tR_P)43#3!JsfdYXvD9z3Y+DjSU zTb`sj5RV45#E8rj&qlzdmq%;yjkd9O(p$V1*0RaSm3y*^H*UAz>AmnI93HX>q zZ%lhHWR-HpA_0FMnBEu2v`RVf&my+@e{q{~@|n$Db;>z_`4-VoTK&D~vV%*UZ!pQM z?iuus^91M1&zE-lU7chK=aW;yo`W0$!c45jqOH#nc&lB@)6f);I zKB;@sMU5IYYCL#=s~tKCFWvb<2aJ}jz}TXT31p9!fPk?B0fVklbifF09moc~qef$g z*=v*yp$Q3OKeQAW)o-qNv&k`{7y;zt*}NiPz-T9C$SD%dr~<}M!j!-YWbSPPMk-?C z8rX0EBe>EDBsD{hP6yr>y_2%XUrCu7x1j^Z#dF>tLj-{cV7ePf{PsNjj!j1KFh8}K zZy~#k!Dm$*<<@u*K)z5A(oWxt+}yh zgSKYRpH=G#%9`!zY6XK>>ITELpYYd`TEX0i zP%D@lP%D@kHEKL`Jd9!=&D~w>f4HaEZ~kwJeam=vi+yV2epBrKd%&&4ZLx19+%5Jg ziQCr~2#MR*7wm)plE>!t1%e=@$e4b8fh45jg7Xel>;oYa6Ch0OcY!yWosRkI^4dX& z-Yg69{~H$jQIt!X0Qmq3F-d@HKmd^=`uzozSDEcil^X)cD@T9`P(E;M7<`w!hD*M> d#wRQ={sB@%CTxEQK7s%M002ovPDHLkV1nt{jMV@D literal 0 HcmV?d00001 diff --git a/graphics/rhh_copyright/sprites/shiny.pal b/graphics/rhh_copyright/sprites/shiny.pal new file mode 100644 index 000000000..1950f6e0b --- /dev/null +++ b/graphics/rhh_copyright/sprites/shiny.pal @@ -0,0 +1,19 @@ +JASC-PAL +0100 +16 +199 225 209 +248 248 248 +197 197 197 +139 213 238 +89 189 230 +7 172 213 +7 131 164 +7 89 114 +246 213 246 +238 172 238 +255 97 207 +197 56 165 +123 40 88 +0 0 0 +0 0 0 +0 0 0 diff --git a/include/config.h b/include/config.h index 3a2461717..b785d5878 100644 --- a/include/config.h +++ b/include/config.h @@ -73,4 +73,7 @@ #define GEN_9 6 #define GEN_LATEST GEN_8 +// General settings +#define RHH_COPYRIGHT_INTRO TRUE // If TRUE, a custom RHH intro will play instead of the vanilla copyright screen. + #endif // GUARD_CONFIG_H diff --git a/include/rhh_copyright.h b/include/rhh_copyright.h new file mode 100644 index 000000000..5dc9576e4 --- /dev/null +++ b/include/rhh_copyright.h @@ -0,0 +1,13 @@ +#ifndef GUARD_RHH_COPYRIGHT_H +#define GUARD_RHH_COPYRIGHT_H + +#if RHH_COPYRIGHT_INTRO == TRUE +void RhhIntro_InitCopyrightBgs(); +void RhhIntro_LoadCopyrightBgGraphics(); +void RhhIntro_ShowRhhCredits(); +void RhhIntro_LoadCopyrightSpriteGraphics(); +void RhhIntro_CreateCopyRightSprites(); +void RhhIntro_DestroyRhhCreditSprites(); +#endif + +#endif /* GUARD_RHH_COPYRIGHT_H */ diff --git a/ld_script.txt b/ld_script.txt index 4c3085f59..e3f9703b4 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -343,6 +343,7 @@ SECTIONS { src/battle_transition_frontier.o(.text); src/international_string_util.o(.text); src/pokemon_debug.o(.text); + src/rhh_copyright.o(.text); } =0 script_data : @@ -709,6 +710,7 @@ SECTIONS { src/m4a_tables.o(.rodata); data/sound_data.o(.rodata); src/pokemon_debug.o(.rodata); + src/rhh_copyright.o(.rodata); } =0 song_data : diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index a57bd2995..e0d47630a 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -2917,7 +2917,7 @@ static void PlayerHandleChoosePokemon(void) *(&gBattleStruct->battlerPreventingSwitchout) = gBattleResources->bufferA[gActiveBattler][1] >> 4; *(&gBattleStruct->prevSelectedPartySlot) = gBattleResources->bufferA[gActiveBattler][2]; *(&gBattleStruct->abilityPreventingSwitchout) = (gBattleResources->bufferA[gActiveBattler][3] & 0xFF) | (gBattleResources->bufferA[gActiveBattler][7] << 8); - BeginNormalPaletteFade(0xFFFFFFFF, 0, 0, 0x10, RGB_BLACK); + BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 0x10, RGB_BLACK); gBattlerControllerFuncs[gActiveBattler] = OpenPartyMenuToChooseMon; gBattlerInMenuId = gActiveBattler; } diff --git a/src/intro.c b/src/intro.c index fd9c12467..e75d4e1bb 100644 --- a/src/intro.c +++ b/src/intro.c @@ -23,6 +23,7 @@ #include "sound.h" #include "util.h" #include "title_screen.h" +#include "rhh_copyright.h" #include "constants/rgb.h" #include "constants/battle_anim.h" @@ -1024,6 +1025,18 @@ static const struct SpritePalette sSpritePalette_RayquazaOrb[] = {}, }; +#if RHH_COPYRIGHT_INTRO == TRUE +static void VBlankCB_PretIntro() +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); + ScanlineEffect_InitHBlankDmaTransfer(); + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); +} +#endif static void VBlankCB_Intro(void) { @@ -1080,11 +1093,14 @@ static u8 SetUpCopyrightScreen(void) CpuFill32(0, (void *)OAM, OAM_SIZE); CpuFill16(0, (void *)(PLTT + 2), PLTT_SIZE - 2); ResetPaletteFade(); +#if RHH_COPYRIGHT_INTRO == FALSE LoadCopyrightGraphics(0, 0x3800, BG_PLTT_ID(0)); +#endif ScanlineEffect_Stop(); ResetTasks(); ResetSpriteData(); FreeAllSpritePalettes(); +#if RHH_COPYRIGHT_INTRO == FALSE BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_WHITEALPHA); SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) @@ -1094,14 +1110,59 @@ static u8 SetUpCopyrightScreen(void) EnableInterrupts(INTR_FLAG_VBLANK); SetVBlankCallback(VBlankCB_Intro); REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON; +#else + SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0) + | BGCNT_CHARBASE(0) + | BGCNT_SCREENBASE(7) + | BGCNT_16COLOR + | BGCNT_TXT256x256); + EnableInterrupts(INTR_FLAG_VBLANK); + REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON; + + gMain.state++; + break; + case 1: + RhhIntro_InitCopyrightBgs(); + BeginNormalPaletteFade(PALETTES_ALL, 0, 0x10, 0, RGB_WHITEALPHA); + SetVBlankCallback(VBlankCB_PretIntro); +#endif SetSerialCallback(SerialCB_CopyrightScreen); GameCubeMultiBoot_Init(&gMultibootProgramStruct); default: +#if RHH_COPYRIGHT_INTRO == TRUE + RunTasks(); + UpdatePaletteFade(); + gMain.state++; + GameCubeMultiBoot_Main(&gMultibootProgramStruct); + break; + case 30: + RhhIntro_LoadCopyrightBgGraphics(); + BeginNormalPaletteFade(0x00000001, 0, 0x10, 0, RGB_BLACK); + UpdatePaletteFade(); + GameCubeMultiBoot_Main(&gMultibootProgramStruct); + gMain.state++; + break; + case 31: + RhhIntro_LoadCopyrightSpriteGraphics(); + RhhIntro_CreateCopyRightSprites(); + UpdatePaletteFade(); + GameCubeMultiBoot_Main(&gMultibootProgramStruct); + gMain.state++; + break; + case 45: + RhhIntro_ShowRhhCredits(); + UpdatePaletteFade(); + GameCubeMultiBoot_Main(&gMultibootProgramStruct); + gMain.state++; + break; + case 253: +#else UpdatePaletteFade(); gMain.state++; GameCubeMultiBoot_Main(&gMultibootProgramStruct); break; case 140: +#endif GameCubeMultiBoot_Main(&gMultibootProgramStruct); if (gMultibootProgramStruct.gcmb_field_2 != 1) { @@ -1109,9 +1170,20 @@ static u8 SetUpCopyrightScreen(void) gMain.state++; } break; +#if RHH_COPYRIGHT_INTRO == TRUE + case 254: + if (UpdatePaletteFade()) + break; + RhhIntro_DestroyRhhCreditSprites(); + gMain.state++; + break; + + case 255: +#else case 141: if (UpdatePaletteFade()) break; +#endif CreateTask(Task_Scene1_Load, 0); SetMainCallback2(MainCB2_Intro); if (gMultibootProgramStruct.gcmb_field_2 != 0) diff --git a/src/rhh_copyright.c b/src/rhh_copyright.c new file mode 100644 index 000000000..c16cb0eda --- /dev/null +++ b/src/rhh_copyright.c @@ -0,0 +1,345 @@ +#include "global.h" +#include "bg.h" +#include "clear_save_data_menu.h" +#include "decompress.h" +#include "palette.h" +#include "sound.h" +#include "sprite.h" +#include "task.h" +#include "gpu_regs.h" +#include "trig.h" +#include "rhh_copyright.h" +#include "constants/rgb.h" +#include "constants/songs.h" + +#if RHH_COPYRIGHT_INTRO == TRUE + +static const u32 sBgTiles_PoweredBy[] = INCBIN_U32("graphics/rhh_copyright/powered_by.4bpp.lz"); +static const u32 sBgTiles_RhhCredits[] = INCBIN_U32("graphics/rhh_copyright/rhh_credits.8bpp.lz"); +static const u32 sBgMap_PoweredBy[] = INCBIN_U32("graphics/rhh_copyright/powered_by.bin.lz"); +static const u32 sBgMap_RhhCredits[] = INCBIN_U32("graphics/rhh_copyright/rhh_credits.bin.lz"); +static const u32 sBgPal_Credits[] = INCBIN_U32("graphics/rhh_copyright/credits.gbapal.lz"); +static const u32 sSpriteTiles_DizzyEgg[] = INCBIN_U32("graphics/rhh_copyright/sprites/dizzy_egg.4bpp.lz"); +static const u32 sSpriteTiles_Porygon[] = INCBIN_U32("graphics/rhh_copyright/sprites/porygon.4bpp.lz"); +static const u16 sSpritePal_DizzyEgg[] = INCBIN_U16("graphics/rhh_copyright/sprites/dizzy_egg.gbapal"); +static const u16 sSpritePal_Porygon[] = INCBIN_U16("graphics/rhh_copyright/sprites/porygon.gbapal"); +static const u16 sSpritePal_PorygonShiny[] = INCBIN_U16("graphics/rhh_copyright/sprites/shiny.gbapal"); + + +#define TAG_DIZZY 20000 +#define TAG_PORYGON 20001 + +#define PAL_TAG_DIZZY 20000 +#define PAL_TAG_PORYGON 20001 + +#define DIZZY_POS_X 300 +#define DIZZY_POS_Y 138 +#define DIZZY_COLLISION_POS_X 172 +#define PORY_POS_X -32 +#define PORY_POS_Y 115 +#define PORYGON_COLLISION_POS_X 140 +#define PORYGON_WAIT_TIME 99 + +#define DIZZY_ANIM_SPEED 4 +#define DIZZY_STARS_SPEED 12 + +static void SpriteCallbacK_DizzyWalking(struct Sprite* sprite); +static void SpriteCallback_PorygonFlying(struct Sprite* sprite); + +static const union AnimCmd sAnimCmd_DizzyWalking[] = { + ANIMCMD_FRAME(32, DIZZY_ANIM_SPEED), + ANIMCMD_FRAME(16, DIZZY_ANIM_SPEED), + ANIMCMD_FRAME(0, DIZZY_ANIM_SPEED), + ANIMCMD_FRAME(16, DIZZY_ANIM_SPEED), + ANIMCMD_FRAME(32, DIZZY_ANIM_SPEED), + ANIMCMD_FRAME(48, DIZZY_ANIM_SPEED), + ANIMCMD_FRAME(64, DIZZY_ANIM_SPEED), + ANIMCMD_FRAME(48, DIZZY_ANIM_SPEED), + ANIMCMD_JUMP(0), +}; + +static const union AnimCmd sAnimCmd_DizzyisDizzy[] = { + ANIMCMD_FRAME(80, DIZZY_STARS_SPEED), + ANIMCMD_FRAME(96, DIZZY_STARS_SPEED), + ANIMCMD_FRAME(112, DIZZY_STARS_SPEED), + ANIMCMD_FRAME(96, DIZZY_STARS_SPEED), + ANIMCMD_JUMP(0), +}; + +enum {ANIM_DIZZY_WALKING, ANIM_DIZZY_DIZZY}; + +static const union AnimCmd *const sAnimCmdTable_DizzyEgg[] = { + [ANIM_DIZZY_WALKING] = sAnimCmd_DizzyWalking, + [ANIM_DIZZY_DIZZY] = sAnimCmd_DizzyisDizzy, +}; + +static const union AnimCmd sAnimCmd_PorygonIdle[] = { + ANIMCMD_FRAME(0, 0), + ANIMCMD_END, +}; + +static const union AnimCmd sAnimCmd_PorygonHitted[] = { + ANIMCMD_FRAME(64, 0), + ANIMCMD_END, +}; + +static const union AnimCmd sAnimCmd_PorygonGoUp[] = { + ANIMCMD_FRAME(64, 20), + ANIMCMD_FRAME(128, 10), + ANIMCMD_END, +}; + +enum {ANIM_PORY_IDLE, ANIM_PORY_HIT, ANIM_PORY_GO_UP}; + +static const union AnimCmd *const sAnimCmdTable_Porygon[] = { + [ANIM_PORY_IDLE] = sAnimCmd_PorygonIdle, + [ANIM_PORY_HIT] = sAnimCmd_PorygonHitted, + [ANIM_PORY_GO_UP] = sAnimCmd_PorygonGoUp, +}; + +static const union AffineAnimCmd sAffineAnimCmd_PorygonScale[] = { + AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), + AFFINEANIMCMD_END, +}; + +static const union AffineAnimCmd *const sAffineAnimCmdTable_Porygon[] = { + sAffineAnimCmd_PorygonScale, +}; + +static const struct CompressedSpriteSheet sSpriteSheet_DizzyEgg = { + .data = sSpriteTiles_DizzyEgg, + .size = 0x1000, + .tag = TAG_DIZZY, +}; + +static const struct CompressedSpriteSheet sSpriteSheet_Porygon = { + .data = sSpriteTiles_Porygon, + .size = 0x2800, + .tag = PAL_TAG_PORYGON, +}; + +static const struct SpritePalette sSpritePalette_DizzyEgg = { + .data = sSpritePal_DizzyEgg, + .tag = PAL_TAG_DIZZY, +}; + +static const struct SpritePalette sSpritePalette_Porygon = { + .data = sSpritePal_Porygon, + .tag = PAL_TAG_PORYGON, +}; + +static const struct OamData sOamData_DizzyEgg = { + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .mosaic = 0, + .bpp = ST_OAM_4BPP, + .shape = SPRITE_SHAPE(32x32), + .size = SPRITE_SIZE(32x32), + .priority = 0, +}; + +static const struct OamData sOamData_Porygon = { + .affineMode = ST_OAM_AFFINE_NORMAL, + .objMode = ST_OAM_OBJ_NORMAL, + .mosaic = 0, + .bpp = ST_OAM_4BPP, + .shape = SPRITE_SHAPE(64x64), + .size = SPRITE_SIZE(64x64), + .priority = 0, +}; + +static const struct SpriteTemplate sSpriteTemplate_DizzyEgg = { + .tileTag = TAG_DIZZY, + .paletteTag = PAL_TAG_DIZZY, + .oam = &sOamData_DizzyEgg, + .anims = sAnimCmdTable_DizzyEgg, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCallbacK_DizzyWalking, +}; + +static const struct SpriteTemplate sSpriteTemplate_Porygon = { + .tileTag = TAG_PORYGON, + .paletteTag = PAL_TAG_PORYGON, + .oam = &sOamData_Porygon, + .anims = sAnimCmdTable_Porygon, + .images = NULL, + .affineAnims = sAffineAnimCmdTable_Porygon, + .callback = SpriteCallback_PorygonFlying, +}; + +enum {BG_0, BG_1, BG_2, BG_3}; + +static const struct BgTemplate sBgTemplates_RhhCopyrightScreen[] = { + [BG_0] = { + .bg = BG_0, + .charBaseIndex = 3, + .mapBaseIndex = 24, + .screenSize = 2, + .paletteMode = 0, + .priority = 0, + .baseTile = 0, + }, + [BG_1] = { + .bg = BG_1, + .charBaseIndex = 3, + .mapBaseIndex = 24, + .screenSize = 2, + .paletteMode = 0, + .priority = 0, + .baseTile = 0, + }, + [BG_2] = { + .bg = BG_2, + .charBaseIndex = 1, + .mapBaseIndex = 20, + .screenSize = 2, + .paletteMode = 1, + .priority = 0, + .baseTile = 0, + }, + [BG_3] = { + .bg = BG_3, + .charBaseIndex = 0, + .mapBaseIndex = 22, + .screenSize = 2, + .paletteMode = 0, + .priority = 0, + .baseTile = 0, + }, +}; + +static EWRAM_DATA u8 sDizzyId = 0; +static EWRAM_DATA u8 sPoryId = 0; + +static void Task_ShowRhhCredits(u8 taskId); + +void RhhIntro_InitCopyrightBgs() +{ + ResetBgsAndClearDma3BusyFlags(0); + InitBgsFromTemplates(0, sBgTemplates_RhhCopyrightScreen, ARRAY_COUNT(sBgTemplates_RhhCopyrightScreen)); + SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_1D_MAP | DISPCNT_OBJ_ON); + SetGpuReg(REG_OFFSET_BLDCNT, BLDCNT_TGT1_BG2 | BLDCNT_TGT2_BG3 | BLDCNT_EFFECT_DARKEN); + SetGpuReg(REG_OFFSET_BLDY, 0x1F); + HideBg(0); + HideBg(1); + HideBg(2); + ShowBg(3); +} + +void RhhIntro_LoadCopyrightBgGraphics() +{ + LZ77UnCompVram(sBgTiles_PoweredBy, (void*) BG_CHAR_ADDR(sBgTemplates_RhhCopyrightScreen[BG_3].charBaseIndex)); + LZ77UnCompVram(sBgMap_PoweredBy, (u16*) BG_SCREEN_ADDR(sBgTemplates_RhhCopyrightScreen[BG_3].mapBaseIndex)); + LZ77UnCompVram(sBgTiles_RhhCredits, (void*) BG_CHAR_ADDR(sBgTemplates_RhhCopyrightScreen[BG_2].charBaseIndex)); + LZ77UnCompVram(sBgMap_RhhCredits, (u16*) BG_SCREEN_ADDR(sBgTemplates_RhhCopyrightScreen[BG_2].mapBaseIndex)); + LoadCompressedPalette(sBgPal_Credits, 0x00, 0x60); +} + +void RhhIntro_LoadCopyrightSpriteGraphics() +{ + LoadCompressedSpriteSheet(&sSpriteSheet_DizzyEgg); + LoadCompressedSpriteSheet(&sSpriteSheet_Porygon); + LoadSpritePalette(&sSpritePalette_DizzyEgg); + LoadSpritePalette(&sSpritePalette_Porygon); +} + +void RhhIntro_CreateCopyRightSprites() +{ + sDizzyId = CreateSprite(&sSpriteTemplate_DizzyEgg, 0, DIZZY_POS_Y, 0); + gSprites[sDizzyId].x2 = DIZZY_POS_X; + + sPoryId = CreateSprite(&sSpriteTemplate_Porygon, 0, PORY_POS_Y, 0); + gSprites[sPoryId].x2 = PORY_POS_X; +} + +void RhhIntro_ShowRhhCredits() +{ + ShowBg(2); + CreateTask(Task_ShowRhhCredits, 0); +} + +static void Task_ShowRhhCredits(u8 taskId) +{ + if (GetGpuReg(REG_OFFSET_BLDY) != 0) + { + SetGpuReg(REG_OFFSET_BLDY, GetGpuReg(REG_OFFSET_BLDY) - 1); + } + else + { + SetGpuReg(REG_OFFSET_BLDCNT, 0); + DestroyTask(taskId); + } +} + +#define sTimer data[0] +static void SpriteCallbacK_DizzyWalking(struct Sprite* sprite) +{ + sprite->x2--; + + if (sprite->x2 <= DIZZY_COLLISION_POS_X) + { + StartSpriteAnim(sprite, ANIM_DIZZY_DIZZY); + sprite->callback = SpriteCallbackDummy; + } + + if (sprite->sTimer % 16 == 0 && sprite->sTimer / 16 > 2) + PlaySE(SE_BIKE_HOP); + + sprite->sTimer++; +} + + +static void SpriteCallback_PorygonHit(struct Sprite* sprite) +{ + sprite->x2-=2; + sprite ->y2 = Sin2(180 + sprite->sTimer * 4) / 128; + + if (sprite->sTimer >= 48) + { + StartSpriteAnim(sprite, ANIM_PORY_GO_UP); + sprite->callback = SpriteCallbackDummy; + } + + if (sprite->sTimer % 8 == 0) + { + if (sprite->sTimer % 16 == 0) + LoadPalette(sSpritePal_PorygonShiny, 0x10 * (16 + sprite->oam.paletteNum), 0x20); + else + LoadPalette(sSpritePal_Porygon, 0x10 * (16 + sprite->oam.paletteNum), 0x20); + } + + sprite->sTimer++; +} + +static void SpriteCallback_PorygonFlying(struct Sprite* sprite) +{ + if (sprite->sTimer >= PORYGON_WAIT_TIME) + { + sprite->x2 += 6; + + if (sprite->sTimer % 32 >= 16) + sprite->y2--; + else + sprite->y2++; + + if (sprite->x2 >= PORYGON_COLLISION_POS_X) + { + StartSpriteAnim(sprite, ANIM_PORY_HIT); + sprite->callback = SpriteCallback_PorygonHit; + sprite->sTimer = 0; + PlaySE(SE_M_DOUBLE_SLAP); + PlayCryInternal(SPECIES_PORYGON, 0, 120, 10, 0); + } + } + sprite->sTimer++; +} +#undef sTimer + +void RhhIntro_DestroyRhhCreditSprites() +{ + DestroySpriteAndFreeResources(&gSprites[sDizzyId]); + DestroySpriteAndFreeResources(&gSprites[sPoryId]); +} + +#endif //RHH_COPYRIGHT_INTRO diff --git a/sym_ewram.txt b/sym_ewram.txt index 914501a08..4611fa241 100644 --- a/sym_ewram.txt +++ b/sym_ewram.txt @@ -149,3 +149,4 @@ .include "src/trainer_hill.o" .include "src/rayquaza_scene.o" .include "src/debug.o" + .include "src/rhh_copyright.o" From 0048e59e0599e4a7f8f2a3e0632a422011dd1efc Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 8 Feb 2023 22:08:12 +0100 Subject: [PATCH 39/69] Fix SpeciesInfo struct offsets --- include/pokemon.h | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/include/pokemon.h b/include/pokemon.h index 89910d6ee..05b9d1ac9 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -294,7 +294,7 @@ struct BattlePokemon /*0x59*/ u8 metLevel; }; -struct SpeciesInfo +struct SpeciesInfo /*0x24*/ { /* 0x00 */ u8 baseHP; /* 0x01 */ u8 baseAttack; @@ -304,25 +304,26 @@ struct SpeciesInfo /* 0x05 */ u8 baseSpDefense; /* 0x06 */ u8 types[2]; /* 0x08 */ u8 catchRate; - /* 0x09 */ u16 expYield; - /* 0x0A */ u16 evYield_HP:2; - /* 0x0A */ u16 evYield_Attack:2; - /* 0x0A */ u16 evYield_Defense:2; - /* 0x0A */ u16 evYield_Speed:2; - /* 0x0B */ u16 evYield_SpAttack:2; - /* 0x0B */ u16 evYield_SpDefense:2; - /* 0x0C */ u16 itemCommon; - /* 0x0E */ u16 itemRare; - /* 0x10 */ u8 genderRatio; - /* 0x11 */ u8 eggCycles; - /* 0x12 */ u8 friendship; - /* 0x13 */ u8 growthRate; - /* 0x14 */ u8 eggGroups[2]; - /* 0x16 */ u16 abilities[NUM_ABILITY_SLOTS]; - /* 0x19 */ u8 safariZoneFleeRate; - /* 0x1A */ u8 bodyColor : 7; + /* 0x09 padding */ + /* 0x0A */ u16 expYield; // expYield was changed from u8 to u16 for the new Exp System. + /* 0x0C */ u16 evYield_HP:2; + u16 evYield_Attack:2; + u16 evYield_Defense:2; + u16 evYield_Speed:2; + /* 0x0D */ u16 evYield_SpAttack:2; + u16 evYield_SpDefense:2; + /* 0x0E */ u16 itemCommon; + /* 0x10 */ u16 itemRare; + /* 0x12 */ u8 genderRatio; + /* 0x13 */ u8 eggCycles; + /* 0x14 */ u8 friendship; + /* 0x15 */ u8 growthRate; + /* 0x16 */ u8 eggGroups[2]; + /* 0x18 */ u16 abilities[NUM_ABILITY_SLOTS]; // 3 abilities, no longer u8 because we have over 255 abilities now. + /* 0x1E */ u8 safariZoneFleeRate; + /* 0x1F */ u8 bodyColor : 7; u8 noFlip : 1; - /* 0x1B */ u16 flags; + /* 0x20 */ u16 flags; }; struct BattleMove From 9f7267e48d7e4274cb692a7398e64ba7adac5073 Mon Sep 17 00:00:00 2001 From: Jaizu Date: Thu, 9 Feb 2023 11:29:29 +0100 Subject: [PATCH 40/69] Fix Giga Impact on contests. --- data/battle_anim_scripts.s | 1 - .../backgrounds/giga_impact_contest.bin | 6 +++--- .../backgrounds/giga_impact_contest.png | Bin 0 -> 1251 bytes include/graphics.h | 1 + src/data/battle_anim.h | 2 +- src/graphics.c | 1 + 6 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 graphics/battle_anims/backgrounds/giga_impact_contest.png diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 9080c075e..f97853d84 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -2644,7 +2644,6 @@ GigaImpactContinuity: delay 11 createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 26, 0, 0, 5 delay 6 - waitbgfadeout createsprite gBasicHitSplatSpriteTemplate, 4, 4, -10, 0, 1, 0 playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET delay 1 diff --git a/graphics/battle_anims/backgrounds/giga_impact_contest.bin b/graphics/battle_anims/backgrounds/giga_impact_contest.bin index 03c709bb9..ce383cf24 100644 --- a/graphics/battle_anims/backgrounds/giga_impact_contest.bin +++ b/graphics/battle_anims/backgrounds/giga_impact_contest.bin @@ -1,3 +1,3 @@ -ˆ$‡$†$…$„$ƒ$‚$�$€$€ � ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ � Ž � D!E!F!G!H!I!@!˜$—$–$•$”$“$’$‘$�$� ‘ ’ “ ” • – — ˜ ™ š › œ � ž Ÿ ú û ü ý þ ÿ ò ¨$§$¦$¥$¤$£$¢$¡$ $  ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ -! ! ! !!!!¸$·$¶$µ$´$³$²$±$°$° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ !!!!!!!È$Ç$Æ$Å$Ä$Ã$Â$Á$À$À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï *!+!,!-!.!/!"!Ø$×$Ö$Õ$Ô$Ó$Ò$Ñ$Ð$Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß :!;!!?!2!è$ç$æ$å$ä$ã$â$á$à$à á â ã ä å æ ç è é ê ë ì í î ï J!K!L!M!N!O!B!è,ç,æ,å,ä,ã,â,á,à,à(á(â(ã(ä(å(æ(ç(è(é(ê(ë(ì(í(î(ï(J)K)L)M)N)O)B)Ø,×,Ö,Õ,Ô,Ó,Ò,Ñ,Ð,Ð(Ñ(Ò(Ó(Ô(Õ(Ö(×(Ø(Ù(Ú(Û(Ü(Ý(Þ(ß(:);)<)=)>)?)2)È,Ç,Æ,Å,Ä,Ã,Â,Á,À,À(Á(Â(Ã(Ä(Å(Æ(Ç(È(É(Ê(Ë(Ì(Í(Î(Ï(*)+),)-).)/)")¸,·,¶,µ,´,³,²,±,°,°(±(²(³(´(µ(¶(·(¸(¹(º(»(¼(½(¾(¿()))))))¨,§,¦,¥,¤,£,¢,¡, , (¡(¢(£(¤(¥(¦(§(¨(©(ª(«(¬(­(®(¯( -) ) ) ))))˜,—,–,•,”,“,’,‘,�,�(‘(’(“(”(•(–(—(˜(™(š(›(œ(�(ž(Ÿ(ú(û(ü(ý(þ(ÿ(ò(ˆ,‡,†,…,„,ƒ,‚,�,€,€(�(‚(ƒ(„(…(†(‡(ˆ(‰(Š(‹(Œ(�(Ž(�(D)E)F)G)H)I)@) \ No newline at end of file +         $$ $$$$$ +             $$ $$$$$        ! " # $ % & ' (  ) * + , ,$+$*$)$ ($'$&$%$- . / 0 1 2 3 4 5 6 7 8 9 : ; < = > >$=$<$;$:$9$8$7$6$ ? @ A B C D E E F F$E E D$C$B$A$@$?$G H I J K L M N O P Q E E E E Q$P$O$N$M$L$K$R S T U V W X Y Z [ \ ] ^ _ ` a b E E E E E E E E b$a$`$_$^$ c d e f g h i j k ^(_(`(a(b(E E E E E E E E b,a,`,_,^, c(d(e(f(g(h(i(j(k( K(L(M(N(O(P(Q(E E E E Q,P,O,N,M,L,K,R(S(T( U(V(W(X(Y(Z([(\(](?(@(A(B(C(D(E E F(F,E E D,C,B,A,@,?,G(H(I(J( 6(7(8(9(:(;(<(=(>(>,=,<,;,:,9,8,7,6, %(&('((( )(*(+(,(,,+,*,), (,',&,%,-(.( /(0(1( 2(3(4(5( ((((( ((,, ,,,,, ((( (((( ( !("(#($( ((((( ((,, ,,,,, +( ( ( (( (( \ No newline at end of file diff --git a/graphics/battle_anims/backgrounds/giga_impact_contest.png b/graphics/battle_anims/backgrounds/giga_impact_contest.png new file mode 100644 index 0000000000000000000000000000000000000000..80698b8d8b0fdcfd59d445b67b55efd8025fa751 GIT binary patch literal 1251 zcmV<91RVQ`P)Px#Fi=cXMF0Q*@QAqRXsCz?DEJs?*dSowNQj^SFxUV<$S7FA064H9fUp=ym=HL~ zFi_YypqBQ*z5oCOVM#X5n|(h|(ACl>@q_qLG1#{4z=!ht7v`F&29OBYe=2%Na8x1+0PW!wfTKnL zB7vI-^6rvBe%=|t_7?!>mH@`FAXK>nUBL7U0LH*Q25_S>02AOd6VxDp0Dv(#o&iki z6M*?RfxtBvoI?m&44wc;@)JNLnDj9XfO)`eGzK$(bK~K6-}RgG zy9+c;0+>TE>EDN7v3*nJ8^Fi$1IW<^rCDf;_DQSv{Jof)xOfr(Ja^UjX=?W82}qfbJjD05AzO1EAagqL05*gM1-q2>axKng*vYNx%R= zbpKksggafTIWQ2M;B?OiuM|Xku*5@SgKI(ffCufL#V6EQ8qkW*1ME)^2r|I2HHF`FJ zoFvW{ljYX{Og-&CeRapSur~rXbqPRyYbO9V$}a#0^&@rZoZ0&>5s)G|nhO$uMgSY# zG0eQ7Cf^J&svqT$D6Lf>(5z3O3zBAz0mL`S9kA%OBfun&-zx`nxB*z^Lik9NLZB0(>j=yNHUBkK{TvesKoUsOVKJm+i#2&Nf-Sx%0Rs5w z0tC=Az>UNg;}@kuu#sNuYXK$#TLIvg0A`vK*qmD0aoxD9vi7F{hEEDeun`wD0tCm#Pwps;UzZ)O`&J3!q#0%K5l{{T$bm7YSeKH1Wn5pQJ3irYb_#_0L5x^24 zgv<4L96Q4`jdXm?1TdVbC4U_faQ$XX`y$guvdb8`JGDKwHH8ph`4$2%MUn!H;zgeT zNC<-m#?cpBSR+^g2;z7h(ahjlWq}eVZ>%403&FwzK~#s!2msSL(fq3Bn@8ot)1$Qx zZn8Sc8*`o)ED?N}cT%oV4r(ONT=yoHXvh<7; zcJ@v^&Jbk2$Or0lnsbk<98W?(_1z2gC?{S)I|%{U2LN(N*{1(W{HYZTN>BkTXbSL5 zy~OCP`tU~|We3aM`=NHTNAmsK^v^yM!2V5Mu77apwX$Ql6x?~>UOyZQ{WZZbP>)BS zVr`0aAVGW4{BHE4xcX+jSphvG>F&bvcK|-eK9~3%0Q12A0Pz0<;2%7;iBYWO5gq^l N002ovPDHLkV1hd`D|-L{ literal 0 HcmV?d00001 diff --git a/include/graphics.h b/include/graphics.h index e5a47ca88..55174442c 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -9981,6 +9981,7 @@ extern const u32 gBattleAnimBgTilemap_GigaImpactPlayer[]; extern const u32 gBattleAnimBgTilemap_GigaImpactOpponent[]; extern const u32 gBattleAnimBgTilemap_GigaImpactContest[]; extern const u32 gBattleAnimBgImage_GigaImpact[]; +extern const u32 gBattleAnimBgImage_GigaImpactContest[]; extern const u32 gBattleAnimBgPalette_GigaImpact[]; extern const u32 gBattleAnimBgImage_SpacialRend[]; extern const u32 gBattleAnimBgPalette_SpacialRend[]; diff --git a/src/data/battle_anim.h b/src/data/battle_anim.h index 5be53fe66..b1f158310 100644 --- a/src/data/battle_anim.h +++ b/src/data/battle_anim.h @@ -1937,7 +1937,7 @@ const struct BattleAnimBackground gBattleAnimBackgroundTable[] = [BG_MAGMA_STORM] = {gBattleAnimBgImage_InAir, gBattleAnimBgPalette_MagmaStorm, gBattleAnimBgTilemap_InAir}, [BG_GIGA_IMPACT_OPPONENT] = {gBattleAnimBgImage_GigaImpact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_GigaImpactOpponent}, [BG_GIGA_IMPACT_PLAYER] = {gBattleAnimBgImage_GigaImpact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_GigaImpactPlayer}, - [BG_GIGA_IMPACT_CONTEST] = {gBattleAnimBgImage_GigaImpact, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_GigaImpactContest}, + [BG_GIGA_IMPACT_CONTEST] = {gBattleAnimBgImage_GigaImpactContest, gBattleAnimBgPalette_GigaImpact, gBattleAnimBgTilemap_GigaImpactContest}, [BG_TRICK_ROOM] = {gBattleAnimBgImage_TrickRoom, gBattleAnimBgPalette_TrickRoom, gBattleAnimBgTilemap_TrickRoom}, [BG_ROCK_WRECKER] = {gBattleAnimBgImage_Hurricane, gBattleAnimBgPalette_RockWrecker, gBattleAnimBgTilemap_Hurricane}, [BG_SPACIAL_REND_ON_OPPONENT] = {gBattleAnimBgImage_SpacialRend, gBattleAnimBgPalette_SpacialRend, gBattleAnimBgTilemap_GigaImpactOpponent}, diff --git a/src/graphics.c b/src/graphics.c index c8040a827..f1ffeb56c 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -1381,6 +1381,7 @@ const u32 gBattleAnimBgTilemap_GigaImpactPlayer[] = INCBIN_U32("graphics/battle_ const u32 gBattleAnimBgTilemap_GigaImpactOpponent[] = INCBIN_U32("graphics/battle_anims/backgrounds/giga_impact_opponent.bin.lz"); const u32 gBattleAnimBgTilemap_GigaImpactContest[] = INCBIN_U32("graphics/battle_anims/backgrounds/giga_impact_contest.bin.lz"); const u32 gBattleAnimBgImage_GigaImpact[] = INCBIN_U32("graphics/battle_anims/backgrounds/giga_impact.4bpp.lz"); +const u32 gBattleAnimBgImage_GigaImpactContest[] = INCBIN_U32("graphics/battle_anims/backgrounds/giga_impact_contest.4bpp.lz"); const u32 gBattleAnimBgPalette_GigaImpact[] = INCBIN_U32("graphics/battle_anims/backgrounds/giga_impact.gbapal.lz"); const u32 gBattleAnimBgImage_SpacialRend[] = INCBIN_U32("graphics/battle_anims/backgrounds/spacial_rend.4bpp.lz"); From 513ecd50babab17346208ab409df4f7da140bfbc Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 9 Feb 2023 13:24:23 +0100 Subject: [PATCH 41/69] Fix Spacial Rend animation --- data/battle_anim_scripts.s | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 9080c075e..d4053adec 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -4333,12 +4333,12 @@ Move_SPACIAL_REND: waitbgfadein loopsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET, 3, 5 createsprite gSpacialRendBladesTemplate2, ANIM_TARGET, 1, 0, 10, SOUND_PAN_ATTACKER, 0xb0, 0x28 - createsprite gSpacialRendBladesTemplate2, ANIM_TARGET, 1, 5, 0, 10, 0xff40, 0xf0, 0x28 - createsprite gSpacialRendBladesTemplate2, ANIM_TARGET, 1, 5, 0, 10, SOUND_PAN_ATTACKER, 0xff60, 0x28 - createsprite gSpacialRendBladesTemplate2, ANIM_TARGET, 1, 5, 0, 10, 0xff40, 0xff90, 0x28 - createsprite gSpacialRendBladesTemplate2, ANIM_TARGET, 1, 5, 0, 10, 0xa0, 0x30, 0x28 - createsprite gSpacialRendBladesTemplate2, ANIM_TARGET, 1, 5, 0, 10, 0xff20, 0xffe0, 0x28 - createsprite gSpacialRendBladesTemplate2, ANIM_TARGET, 1, 5, 0, 10, 0x70, 0xff80, 0x28 + createsprite gSpacialRendBladesTemplate2, ANIM_TARGET, 1, 0, 10, 0xff40, 0xf0, 0x28 + createsprite gSpacialRendBladesTemplate2, ANIM_TARGET, 1, 0, 10, SOUND_PAN_ATTACKER, 0xff60, 0x28 + createsprite gSpacialRendBladesTemplate2, ANIM_TARGET, 1, 0, 10, 0xff40, 0xff90, 0x28 + createsprite gSpacialRendBladesTemplate2, ANIM_TARGET, 1, 0, 10, 0xa0, 0x30, 0x28 + createsprite gSpacialRendBladesTemplate2, ANIM_TARGET, 1, 0, 10, 0xff20, 0xffe0, 0x28 + createsprite gSpacialRendBladesTemplate2, ANIM_TARGET, 1, 0, 10, 0x70, 0xff80, 0x28 createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 15, 1 waitforvisualfinish restorebg From 4bcbb7c9e1a5bb66ad6450fb05fd740a5337fdb7 Mon Sep 17 00:00:00 2001 From: sbird Date: Wed, 8 Feb 2023 22:32:54 +0100 Subject: [PATCH 42/69] [intro] refactor expansion intro --- .../credits.pal | 2 +- .../powered_by.bin | Bin .../powered_by.png | Bin .../rhh_credits.bin | Bin .../rhh_credits.png | Bin .../sprites/dizzy_egg.png | Bin .../sprites/porygon.png | Bin .../sprites/shiny.pal | 0 include/config.h | 2 +- include/expansion_intro.h | 9 + include/intro.h | 3 + include/rhh_copyright.h | 13 - ld_script.txt | 4 +- src/{rhh_copyright.c => expansion_intro.c} | 254 +++++++++++------- src/intro.c | 83 +----- sym_ewram.txt | 1 - 16 files changed, 178 insertions(+), 193 deletions(-) rename graphics/{rhh_copyright => expansion_intro}/credits.pal (99%) rename graphics/{rhh_copyright => expansion_intro}/powered_by.bin (100%) rename graphics/{rhh_copyright => expansion_intro}/powered_by.png (100%) rename graphics/{rhh_copyright => expansion_intro}/rhh_credits.bin (100%) rename graphics/{rhh_copyright => expansion_intro}/rhh_credits.png (100%) rename graphics/{rhh_copyright => expansion_intro}/sprites/dizzy_egg.png (100%) rename graphics/{rhh_copyright => expansion_intro}/sprites/porygon.png (100%) rename graphics/{rhh_copyright => expansion_intro}/sprites/shiny.pal (100%) create mode 100644 include/expansion_intro.h delete mode 100644 include/rhh_copyright.h rename src/{rhh_copyright.c => expansion_intro.c} (57%) diff --git a/graphics/rhh_copyright/credits.pal b/graphics/expansion_intro/credits.pal similarity index 99% rename from graphics/rhh_copyright/credits.pal rename to graphics/expansion_intro/credits.pal index cdff46971..5f6c06d72 100644 --- a/graphics/rhh_copyright/credits.pal +++ b/graphics/expansion_intro/credits.pal @@ -1,7 +1,7 @@ JASC-PAL 0100 256 -198 231 214 +0 0 0 255 255 255 222 222 222 222 222 214 diff --git a/graphics/rhh_copyright/powered_by.bin b/graphics/expansion_intro/powered_by.bin similarity index 100% rename from graphics/rhh_copyright/powered_by.bin rename to graphics/expansion_intro/powered_by.bin diff --git a/graphics/rhh_copyright/powered_by.png b/graphics/expansion_intro/powered_by.png similarity index 100% rename from graphics/rhh_copyright/powered_by.png rename to graphics/expansion_intro/powered_by.png diff --git a/graphics/rhh_copyright/rhh_credits.bin b/graphics/expansion_intro/rhh_credits.bin similarity index 100% rename from graphics/rhh_copyright/rhh_credits.bin rename to graphics/expansion_intro/rhh_credits.bin diff --git a/graphics/rhh_copyright/rhh_credits.png b/graphics/expansion_intro/rhh_credits.png similarity index 100% rename from graphics/rhh_copyright/rhh_credits.png rename to graphics/expansion_intro/rhh_credits.png diff --git a/graphics/rhh_copyright/sprites/dizzy_egg.png b/graphics/expansion_intro/sprites/dizzy_egg.png similarity index 100% rename from graphics/rhh_copyright/sprites/dizzy_egg.png rename to graphics/expansion_intro/sprites/dizzy_egg.png diff --git a/graphics/rhh_copyright/sprites/porygon.png b/graphics/expansion_intro/sprites/porygon.png similarity index 100% rename from graphics/rhh_copyright/sprites/porygon.png rename to graphics/expansion_intro/sprites/porygon.png diff --git a/graphics/rhh_copyright/sprites/shiny.pal b/graphics/expansion_intro/sprites/shiny.pal similarity index 100% rename from graphics/rhh_copyright/sprites/shiny.pal rename to graphics/expansion_intro/sprites/shiny.pal diff --git a/include/config.h b/include/config.h index b785d5878..2ad84f29c 100644 --- a/include/config.h +++ b/include/config.h @@ -74,6 +74,6 @@ #define GEN_LATEST GEN_8 // General settings -#define RHH_COPYRIGHT_INTRO TRUE // If TRUE, a custom RHH intro will play instead of the vanilla copyright screen. +#define EXPANSION_INTRO TRUE // If TRUE, a custom RHH intro will play after the vanilla copyright screen. #endif // GUARD_CONFIG_H diff --git a/include/expansion_intro.h b/include/expansion_intro.h new file mode 100644 index 000000000..7d8d31677 --- /dev/null +++ b/include/expansion_intro.h @@ -0,0 +1,9 @@ +#ifndef GUARD_EXPANSION_INTRO_H +#define GUARD_EXPANSION_INTRO_H + +#if EXPANSION_INTRO == TRUE +void CB2_ExpansionIntro(void); +void Task_HandleExpansionIntro(u8 taskId); +#endif + +#endif /* GUARD_EXPANSION_INTRO_H */ diff --git a/include/intro.h b/include/intro.h index 8ba030a28..1c89c6595 100644 --- a/include/intro.h +++ b/include/intro.h @@ -9,5 +9,8 @@ void CB2_InitCopyrightScreenAfterBootup(void); void CB2_InitCopyrightScreenAfterTitleScreen(void); void PanFadeAndZoomScreen(u16, u16, u16, u16); +void MainCB2_Intro(void); +void Task_Scene1_Load(u8); + #endif // GUARD_INTRO_H diff --git a/include/rhh_copyright.h b/include/rhh_copyright.h deleted file mode 100644 index 5dc9576e4..000000000 --- a/include/rhh_copyright.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef GUARD_RHH_COPYRIGHT_H -#define GUARD_RHH_COPYRIGHT_H - -#if RHH_COPYRIGHT_INTRO == TRUE -void RhhIntro_InitCopyrightBgs(); -void RhhIntro_LoadCopyrightBgGraphics(); -void RhhIntro_ShowRhhCredits(); -void RhhIntro_LoadCopyrightSpriteGraphics(); -void RhhIntro_CreateCopyRightSprites(); -void RhhIntro_DestroyRhhCreditSprites(); -#endif - -#endif /* GUARD_RHH_COPYRIGHT_H */ diff --git a/ld_script.txt b/ld_script.txt index e3f9703b4..dcce51a0f 100644 --- a/ld_script.txt +++ b/ld_script.txt @@ -343,7 +343,7 @@ SECTIONS { src/battle_transition_frontier.o(.text); src/international_string_util.o(.text); src/pokemon_debug.o(.text); - src/rhh_copyright.o(.text); + src/expansion_intro.o(.text); } =0 script_data : @@ -710,7 +710,7 @@ SECTIONS { src/m4a_tables.o(.rodata); data/sound_data.o(.rodata); src/pokemon_debug.o(.rodata); - src/rhh_copyright.o(.rodata); + src/expansion_intro.o(.rodata); } =0 song_data : diff --git a/src/rhh_copyright.c b/src/expansion_intro.c similarity index 57% rename from src/rhh_copyright.c rename to src/expansion_intro.c index c16cb0eda..63bcce4e9 100644 --- a/src/rhh_copyright.c +++ b/src/expansion_intro.c @@ -8,23 +8,13 @@ #include "task.h" #include "gpu_regs.h" #include "trig.h" -#include "rhh_copyright.h" +#include "main.h" +#include "intro.h" +#include "expansion_intro.h" #include "constants/rgb.h" #include "constants/songs.h" -#if RHH_COPYRIGHT_INTRO == TRUE - -static const u32 sBgTiles_PoweredBy[] = INCBIN_U32("graphics/rhh_copyright/powered_by.4bpp.lz"); -static const u32 sBgTiles_RhhCredits[] = INCBIN_U32("graphics/rhh_copyright/rhh_credits.8bpp.lz"); -static const u32 sBgMap_PoweredBy[] = INCBIN_U32("graphics/rhh_copyright/powered_by.bin.lz"); -static const u32 sBgMap_RhhCredits[] = INCBIN_U32("graphics/rhh_copyright/rhh_credits.bin.lz"); -static const u32 sBgPal_Credits[] = INCBIN_U32("graphics/rhh_copyright/credits.gbapal.lz"); -static const u32 sSpriteTiles_DizzyEgg[] = INCBIN_U32("graphics/rhh_copyright/sprites/dizzy_egg.4bpp.lz"); -static const u32 sSpriteTiles_Porygon[] = INCBIN_U32("graphics/rhh_copyright/sprites/porygon.4bpp.lz"); -static const u16 sSpritePal_DizzyEgg[] = INCBIN_U16("graphics/rhh_copyright/sprites/dizzy_egg.gbapal"); -static const u16 sSpritePal_Porygon[] = INCBIN_U16("graphics/rhh_copyright/sprites/porygon.gbapal"); -static const u16 sSpritePal_PorygonShiny[] = INCBIN_U16("graphics/rhh_copyright/sprites/shiny.gbapal"); - +#if EXPANSION_INTRO == TRUE #define TAG_DIZZY 20000 #define TAG_PORYGON 20001 @@ -43,10 +33,47 @@ static const u16 sSpritePal_PorygonShiny[] = INCBIN_U16("graphics/rhh_copyright/ #define DIZZY_ANIM_SPEED 4 #define DIZZY_STARS_SPEED 12 -static void SpriteCallbacK_DizzyWalking(struct Sprite* sprite); -static void SpriteCallback_PorygonFlying(struct Sprite* sprite); +enum +{ + EXPANSION_INTRO_BG2, + EXPANSION_INTRO_BG3 +}; -static const union AnimCmd sAnimCmd_DizzyWalking[] = { +enum +{ + ANIM_PORY_IDLE, + ANIM_PORY_HIT, + ANIM_PORY_GO_UP +}; + +enum +{ + ANIM_DIZZY_WALKING, + ANIM_DIZZY_DIZZY +}; + +static const u32 sBgTiles_PoweredBy[] = INCBIN_U32("graphics/expansion_intro/powered_by.4bpp.lz"); +static const u32 sBgTiles_RhhCredits[] = INCBIN_U32("graphics/expansion_intro/rhh_credits.8bpp.lz"); +static const u32 sBgMap_PoweredBy[] = INCBIN_U32("graphics/expansion_intro/powered_by.bin.lz"); +static const u32 sBgMap_RhhCredits[] = INCBIN_U32("graphics/expansion_intro/rhh_credits.bin.lz"); +static const u32 sBgPal_Credits[] = INCBIN_U32("graphics/expansion_intro/credits.gbapal.lz"); +static const u32 sSpriteTiles_DizzyEgg[] = INCBIN_U32("graphics/expansion_intro/sprites/dizzy_egg.4bpp.lz"); +static const u32 sSpriteTiles_Porygon[] = INCBIN_U32("graphics/expansion_intro/sprites/porygon.4bpp.lz"); +static const u16 sSpritePal_DizzyEgg[] = INCBIN_U16("graphics/expansion_intro/sprites/dizzy_egg.gbapal"); +static const u16 sSpritePal_Porygon[] = INCBIN_U16("graphics/expansion_intro/sprites/porygon.gbapal"); +static const u16 sSpritePal_PorygonShiny[] = INCBIN_U16("graphics/expansion_intro/sprites/shiny.gbapal"); + +static void SpriteCallback_DizzyWalking(struct Sprite* sprite); +static void SpriteCallback_PorygonFlying(struct Sprite* sprite); +static void Task_ExpansionIntro_HandleBlend(u8 taskId); +static void VBlankCB_ExpansionIntro(void); +static void ExpansionIntro_InitBgs(); +static void ExpansionIntro_StartBlend(); +static void ExpansionIntro_LoadGraphics(); +static void ExpansionIntro_CreateSprites(); + +static const union AnimCmd sAnimCmd_DizzyWalking[] = +{ ANIMCMD_FRAME(32, DIZZY_ANIM_SPEED), ANIMCMD_FRAME(16, DIZZY_ANIM_SPEED), ANIMCMD_FRAME(0, DIZZY_ANIM_SPEED), @@ -58,7 +85,8 @@ static const union AnimCmd sAnimCmd_DizzyWalking[] = { ANIMCMD_JUMP(0), }; -static const union AnimCmd sAnimCmd_DizzyisDizzy[] = { +static const union AnimCmd sAnimCmd_DizzyisDizzy[] = +{ ANIMCMD_FRAME(80, DIZZY_STARS_SPEED), ANIMCMD_FRAME(96, DIZZY_STARS_SPEED), ANIMCMD_FRAME(112, DIZZY_STARS_SPEED), @@ -66,69 +94,77 @@ static const union AnimCmd sAnimCmd_DizzyisDizzy[] = { ANIMCMD_JUMP(0), }; -enum {ANIM_DIZZY_WALKING, ANIM_DIZZY_DIZZY}; - -static const union AnimCmd *const sAnimCmdTable_DizzyEgg[] = { +static const union AnimCmd *const sAnimCmdTable_DizzyEgg[] = +{ [ANIM_DIZZY_WALKING] = sAnimCmd_DizzyWalking, [ANIM_DIZZY_DIZZY] = sAnimCmd_DizzyisDizzy, }; -static const union AnimCmd sAnimCmd_PorygonIdle[] = { +static const union AnimCmd sAnimCmd_PorygonIdle[] = +{ ANIMCMD_FRAME(0, 0), ANIMCMD_END, }; -static const union AnimCmd sAnimCmd_PorygonHitted[] = { +static const union AnimCmd sAnimCmd_PorygonHitted[] = +{ ANIMCMD_FRAME(64, 0), ANIMCMD_END, }; -static const union AnimCmd sAnimCmd_PorygonGoUp[] = { +static const union AnimCmd sAnimCmd_PorygonGoUp[] = +{ ANIMCMD_FRAME(64, 20), ANIMCMD_FRAME(128, 10), ANIMCMD_END, }; -enum {ANIM_PORY_IDLE, ANIM_PORY_HIT, ANIM_PORY_GO_UP}; - -static const union AnimCmd *const sAnimCmdTable_Porygon[] = { +static const union AnimCmd *const sAnimCmdTable_Porygon[] = +{ [ANIM_PORY_IDLE] = sAnimCmd_PorygonIdle, [ANIM_PORY_HIT] = sAnimCmd_PorygonHitted, [ANIM_PORY_GO_UP] = sAnimCmd_PorygonGoUp, }; -static const union AffineAnimCmd sAffineAnimCmd_PorygonScale[] = { +static const union AffineAnimCmd sAffineAnimCmd_PorygonScale[] = +{ AFFINEANIMCMD_FRAME(0x100, 0x100, 0, 0), AFFINEANIMCMD_END, }; -static const union AffineAnimCmd *const sAffineAnimCmdTable_Porygon[] = { +static const union AffineAnimCmd *const sAffineAnimCmdTable_Porygon[] = +{ sAffineAnimCmd_PorygonScale, }; -static const struct CompressedSpriteSheet sSpriteSheet_DizzyEgg = { +static const struct CompressedSpriteSheet sSpriteSheet_DizzyEgg = +{ .data = sSpriteTiles_DizzyEgg, .size = 0x1000, .tag = TAG_DIZZY, }; -static const struct CompressedSpriteSheet sSpriteSheet_Porygon = { +static const struct CompressedSpriteSheet sSpriteSheet_Porygon = +{ .data = sSpriteTiles_Porygon, .size = 0x2800, .tag = PAL_TAG_PORYGON, }; -static const struct SpritePalette sSpritePalette_DizzyEgg = { +static const struct SpritePalette sSpritePalette_DizzyEgg = +{ .data = sSpritePal_DizzyEgg, .tag = PAL_TAG_DIZZY, }; -static const struct SpritePalette sSpritePalette_Porygon = { +static const struct SpritePalette sSpritePalette_Porygon = +{ .data = sSpritePal_Porygon, .tag = PAL_TAG_PORYGON, }; -static const struct OamData sOamData_DizzyEgg = { +static const struct OamData sOamData_DizzyEgg = +{ .affineMode = ST_OAM_AFFINE_OFF, .objMode = ST_OAM_OBJ_NORMAL, .mosaic = 0, @@ -138,7 +174,8 @@ static const struct OamData sOamData_DizzyEgg = { .priority = 0, }; -static const struct OamData sOamData_Porygon = { +static const struct OamData sOamData_Porygon = +{ .affineMode = ST_OAM_AFFINE_NORMAL, .objMode = ST_OAM_OBJ_NORMAL, .mosaic = 0, @@ -148,17 +185,19 @@ static const struct OamData sOamData_Porygon = { .priority = 0, }; -static const struct SpriteTemplate sSpriteTemplate_DizzyEgg = { +static const struct SpriteTemplate sSpriteTemplate_DizzyEgg = +{ .tileTag = TAG_DIZZY, .paletteTag = PAL_TAG_DIZZY, .oam = &sOamData_DizzyEgg, .anims = sAnimCmdTable_DizzyEgg, .images = NULL, .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCallbacK_DizzyWalking, + .callback = SpriteCallback_DizzyWalking, }; -static const struct SpriteTemplate sSpriteTemplate_Porygon = { +static const struct SpriteTemplate sSpriteTemplate_Porygon = +{ .tileTag = TAG_PORYGON, .paletteTag = PAL_TAG_PORYGON, .oam = &sOamData_Porygon, @@ -168,53 +207,75 @@ static const struct SpriteTemplate sSpriteTemplate_Porygon = { .callback = SpriteCallback_PorygonFlying, }; -enum {BG_0, BG_1, BG_2, BG_3}; - -static const struct BgTemplate sBgTemplates_RhhCopyrightScreen[] = { - [BG_0] = { - .bg = BG_0, - .charBaseIndex = 3, - .mapBaseIndex = 24, - .screenSize = 2, - .paletteMode = 0, - .priority = 0, - .baseTile = 0, - }, - [BG_1] = { - .bg = BG_1, - .charBaseIndex = 3, - .mapBaseIndex = 24, - .screenSize = 2, - .paletteMode = 0, - .priority = 0, - .baseTile = 0, - }, - [BG_2] = { - .bg = BG_2, +static const struct BgTemplate sBgTemplates_RhhCopyrightScreen[] = +{ + [EXPANSION_INTRO_BG2] = { + .bg = 2, .charBaseIndex = 1, .mapBaseIndex = 20, .screenSize = 2, - .paletteMode = 1, - .priority = 0, - .baseTile = 0, + .paletteMode = 1 }, - [BG_3] = { - .bg = BG_3, - .charBaseIndex = 0, + [EXPANSION_INTRO_BG3] = { + .bg = 3, .mapBaseIndex = 22, - .screenSize = 2, - .paletteMode = 0, - .priority = 0, - .baseTile = 0, + .screenSize = 2 }, }; -static EWRAM_DATA u8 sDizzyId = 0; -static EWRAM_DATA u8 sPoryId = 0; +void CB2_ExpansionIntro(void) +{ + RunTasks(); + AnimateSprites(); + BuildOamBuffer(); + UpdatePaletteFade(); +} -static void Task_ShowRhhCredits(u8 taskId); +#define tState gTasks[taskId].data[0] +#define tFrameCounter gTasks[taskId].data[1] +void Task_HandleExpansionIntro(u8 taskId) +{ + switch (tState) + { + case 0: + SetVBlankCallback(VBlankCB_ExpansionIntro); + ExpansionIntro_InitBgs(); + ExpansionIntro_LoadGraphics(); + CpuFastFill16(RGB_BLACK, gPlttBufferFaded, 32); + ShowBg(3); + BeginNormalPaletteFade(1, 0, 16, 0, RGB_BLACK); + ExpansionIntro_StartBlend(); + ExpansionIntro_CreateSprites(); + tState++; + break; + case 1: + if (!gPaletteFade.active) + tState++; + break; + case 2: + if (tFrameCounter == 208 || gMain.newKeys != 0) + tState++; + else + tFrameCounter++; + break; + case 3: + ResetSpriteData(); + DestroyTask(taskId); + CreateTask(Task_Scene1_Load, 0); + SetMainCallback2(MainCB2_Intro); + break; + } +} +#undef tState -void RhhIntro_InitCopyrightBgs() +static void VBlankCB_ExpansionIntro(void) +{ + LoadOam(); + ProcessSpriteCopyRequests(); + TransferPlttBuffer(); +} + +static void ExpansionIntro_InitBgs(void) { ResetBgsAndClearDma3BusyFlags(0); InitBgsFromTemplates(0, sBgTemplates_RhhCopyrightScreen, ARRAY_COUNT(sBgTemplates_RhhCopyrightScreen)); @@ -224,42 +285,41 @@ void RhhIntro_InitCopyrightBgs() HideBg(0); HideBg(1); HideBg(2); - ShowBg(3); + HideBg(3); } -void RhhIntro_LoadCopyrightBgGraphics() +static void ExpansionIntro_LoadGraphics(void) { - LZ77UnCompVram(sBgTiles_PoweredBy, (void*) BG_CHAR_ADDR(sBgTemplates_RhhCopyrightScreen[BG_3].charBaseIndex)); - LZ77UnCompVram(sBgMap_PoweredBy, (u16*) BG_SCREEN_ADDR(sBgTemplates_RhhCopyrightScreen[BG_3].mapBaseIndex)); - LZ77UnCompVram(sBgTiles_RhhCredits, (void*) BG_CHAR_ADDR(sBgTemplates_RhhCopyrightScreen[BG_2].charBaseIndex)); - LZ77UnCompVram(sBgMap_RhhCredits, (u16*) BG_SCREEN_ADDR(sBgTemplates_RhhCopyrightScreen[BG_2].mapBaseIndex)); + LZ77UnCompVram(sBgTiles_PoweredBy, (void*) BG_CHAR_ADDR(sBgTemplates_RhhCopyrightScreen[EXPANSION_INTRO_BG3].charBaseIndex)); + LZ77UnCompVram(sBgMap_PoweredBy, (u16*) BG_SCREEN_ADDR(sBgTemplates_RhhCopyrightScreen[EXPANSION_INTRO_BG3].mapBaseIndex)); + LZ77UnCompVram(sBgTiles_RhhCredits, (void*) BG_CHAR_ADDR(sBgTemplates_RhhCopyrightScreen[EXPANSION_INTRO_BG2].charBaseIndex)); + LZ77UnCompVram(sBgMap_RhhCredits, (u16*) BG_SCREEN_ADDR(sBgTemplates_RhhCopyrightScreen[EXPANSION_INTRO_BG2].mapBaseIndex)); LoadCompressedPalette(sBgPal_Credits, 0x00, 0x60); -} -void RhhIntro_LoadCopyrightSpriteGraphics() -{ LoadCompressedSpriteSheet(&sSpriteSheet_DizzyEgg); LoadCompressedSpriteSheet(&sSpriteSheet_Porygon); LoadSpritePalette(&sSpritePalette_DizzyEgg); LoadSpritePalette(&sSpritePalette_Porygon); } -void RhhIntro_CreateCopyRightSprites() +static void ExpansionIntro_CreateSprites(void) { - sDizzyId = CreateSprite(&sSpriteTemplate_DizzyEgg, 0, DIZZY_POS_Y, 0); - gSprites[sDizzyId].x2 = DIZZY_POS_X; + u32 dizzyId, poryId; - sPoryId = CreateSprite(&sSpriteTemplate_Porygon, 0, PORY_POS_Y, 0); - gSprites[sPoryId].x2 = PORY_POS_X; + dizzyId = CreateSprite(&sSpriteTemplate_DizzyEgg, 0, DIZZY_POS_Y, 0); + gSprites[dizzyId].x2 = DIZZY_POS_X; + + poryId = CreateSprite(&sSpriteTemplate_Porygon, 0, PORY_POS_Y, 0); + gSprites[poryId].x2 = PORY_POS_X; } -void RhhIntro_ShowRhhCredits() +static void ExpansionIntro_StartBlend(void) { ShowBg(2); - CreateTask(Task_ShowRhhCredits, 0); + CreateTask(Task_ExpansionIntro_HandleBlend, 0); } -static void Task_ShowRhhCredits(u8 taskId) +static void Task_ExpansionIntro_HandleBlend(u8 taskId) { if (GetGpuReg(REG_OFFSET_BLDY) != 0) { @@ -273,7 +333,7 @@ static void Task_ShowRhhCredits(u8 taskId) } #define sTimer data[0] -static void SpriteCallbacK_DizzyWalking(struct Sprite* sprite) +static void SpriteCallback_DizzyWalking(struct Sprite* sprite) { sprite->x2--; @@ -336,10 +396,4 @@ static void SpriteCallback_PorygonFlying(struct Sprite* sprite) } #undef sTimer -void RhhIntro_DestroyRhhCreditSprites() -{ - DestroySpriteAndFreeResources(&gSprites[sDizzyId]); - DestroySpriteAndFreeResources(&gSprites[sPoryId]); -} - -#endif //RHH_COPYRIGHT_INTRO +#endif //EXPANSION_INTRO diff --git a/src/intro.c b/src/intro.c index e75d4e1bb..38b2f0027 100644 --- a/src/intro.c +++ b/src/intro.c @@ -23,7 +23,7 @@ #include "sound.h" #include "util.h" #include "title_screen.h" -#include "rhh_copyright.h" +#include "expansion_intro.h" #include "constants/rgb.h" #include "constants/battle_anim.h" @@ -38,7 +38,6 @@ */ // Scene 1 main tasks -static void Task_Scene1_Load(u8); static void Task_Scene1_FadeIn(u8); static void Task_Scene1_WaterDrops(u8); static void Task_Scene1_PanUp(u8); @@ -1025,18 +1024,6 @@ static const struct SpritePalette sSpritePalette_RayquazaOrb[] = {}, }; -#if RHH_COPYRIGHT_INTRO == TRUE -static void VBlankCB_PretIntro() -{ - LoadOam(); - ProcessSpriteCopyRequests(); - TransferPlttBuffer(); - ScanlineEffect_InitHBlankDmaTransfer(); - RunTasks(); - AnimateSprites(); - BuildOamBuffer(); -} -#endif static void VBlankCB_Intro(void) { @@ -1046,7 +1033,7 @@ static void VBlankCB_Intro(void) ScanlineEffect_InitHBlankDmaTransfer(); } -static void MainCB2_Intro(void) +void MainCB2_Intro(void) { RunTasks(); AnimateSprites(); @@ -1093,14 +1080,11 @@ static u8 SetUpCopyrightScreen(void) CpuFill32(0, (void *)OAM, OAM_SIZE); CpuFill16(0, (void *)(PLTT + 2), PLTT_SIZE - 2); ResetPaletteFade(); -#if RHH_COPYRIGHT_INTRO == FALSE LoadCopyrightGraphics(0, 0x3800, BG_PLTT_ID(0)); -#endif ScanlineEffect_Stop(); ResetTasks(); ResetSpriteData(); FreeAllSpritePalettes(); -#if RHH_COPYRIGHT_INTRO == FALSE BeginNormalPaletteFade(PALETTES_ALL, 0, 16, 0, RGB_WHITEALPHA); SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) @@ -1110,59 +1094,14 @@ static u8 SetUpCopyrightScreen(void) EnableInterrupts(INTR_FLAG_VBLANK); SetVBlankCallback(VBlankCB_Intro); REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON; -#else - SetGpuReg(REG_OFFSET_BG0CNT, BGCNT_PRIORITY(0) - | BGCNT_CHARBASE(0) - | BGCNT_SCREENBASE(7) - | BGCNT_16COLOR - | BGCNT_TXT256x256); - EnableInterrupts(INTR_FLAG_VBLANK); - REG_DISPCNT = DISPCNT_MODE_0 | DISPCNT_OBJ_1D_MAP | DISPCNT_BG0_ON; - - gMain.state++; - break; - case 1: - RhhIntro_InitCopyrightBgs(); - BeginNormalPaletteFade(PALETTES_ALL, 0, 0x10, 0, RGB_WHITEALPHA); - SetVBlankCallback(VBlankCB_PretIntro); -#endif SetSerialCallback(SerialCB_CopyrightScreen); GameCubeMultiBoot_Init(&gMultibootProgramStruct); default: -#if RHH_COPYRIGHT_INTRO == TRUE - RunTasks(); - UpdatePaletteFade(); - gMain.state++; - GameCubeMultiBoot_Main(&gMultibootProgramStruct); - break; - case 30: - RhhIntro_LoadCopyrightBgGraphics(); - BeginNormalPaletteFade(0x00000001, 0, 0x10, 0, RGB_BLACK); - UpdatePaletteFade(); - GameCubeMultiBoot_Main(&gMultibootProgramStruct); - gMain.state++; - break; - case 31: - RhhIntro_LoadCopyrightSpriteGraphics(); - RhhIntro_CreateCopyRightSprites(); - UpdatePaletteFade(); - GameCubeMultiBoot_Main(&gMultibootProgramStruct); - gMain.state++; - break; - case 45: - RhhIntro_ShowRhhCredits(); - UpdatePaletteFade(); - GameCubeMultiBoot_Main(&gMultibootProgramStruct); - gMain.state++; - break; - case 253: -#else UpdatePaletteFade(); gMain.state++; GameCubeMultiBoot_Main(&gMultibootProgramStruct); break; case 140: -#endif GameCubeMultiBoot_Main(&gMultibootProgramStruct); if (gMultibootProgramStruct.gcmb_field_2 != 1) { @@ -1170,22 +1109,16 @@ static u8 SetUpCopyrightScreen(void) gMain.state++; } break; -#if RHH_COPYRIGHT_INTRO == TRUE - case 254: - if (UpdatePaletteFade()) - break; - RhhIntro_DestroyRhhCreditSprites(); - gMain.state++; - break; - - case 255: -#else case 141: if (UpdatePaletteFade()) break; -#endif +#if EXPANSION_INTRO == TRUE + SetMainCallback2(CB2_ExpansionIntro); + CreateTask(Task_HandleExpansionIntro, 0); +#else CreateTask(Task_Scene1_Load, 0); SetMainCallback2(MainCB2_Intro); +#endif if (gMultibootProgramStruct.gcmb_field_2 != 0) { if (gMultibootProgramStruct.gcmb_field_2 == 2) @@ -1232,7 +1165,7 @@ void CB2_InitCopyrightScreenAfterTitleScreen(void) #define sBigDropSpriteId data[0] -static void Task_Scene1_Load(u8 taskId) +void Task_Scene1_Load(u8 taskId) { SetVBlankCallback(NULL); sIntroCharacterGender = Random() & 1; diff --git a/sym_ewram.txt b/sym_ewram.txt index 4611fa241..914501a08 100644 --- a/sym_ewram.txt +++ b/sym_ewram.txt @@ -149,4 +149,3 @@ .include "src/trainer_hill.o" .include "src/rayquaza_scene.o" .include "src/debug.o" - .include "src/rhh_copyright.o" From dac138cef66c4dcb01b01b41a8264c0be75b1c4f Mon Sep 17 00:00:00 2001 From: sbird Date: Fri, 3 Feb 2023 00:22:02 +0100 Subject: [PATCH 43/69] [test] add some ability tests --- test/ability_cloud_nine.c | 16 +++++++ test/ability_compound_eyes.c | 37 +++++++++++++++ test/ability_damp.c | 54 ++++++++++++++++++++++ test/ability_drizzle.c | 24 ++++++++++ test/ability_insomnia.c | 59 ++++++++++++++++++++++++ test/ability_intimidate.c | 50 +++++++++++++++++++++ test/ability_limber.c | 16 +++++++ test/ability_oblivious.c | 68 ++++++++++++++++++++++++++++ test/ability_sand_veil.c | 30 +++++++++++++ test/ability_speed_boost.c | 20 +++++++++ test/ability_stench.c | 34 ++++++++++++++ test/ability_volt_absorb.c | 85 +++++++++++++++++++++++++++++++++++ test/ability_water_absorb.c | 87 ++++++++++++++++++++++++++++++++++++ 13 files changed, 580 insertions(+) create mode 100644 test/ability_cloud_nine.c create mode 100644 test/ability_compound_eyes.c create mode 100644 test/ability_damp.c create mode 100644 test/ability_drizzle.c create mode 100644 test/ability_insomnia.c create mode 100644 test/ability_intimidate.c create mode 100644 test/ability_limber.c create mode 100644 test/ability_oblivious.c create mode 100644 test/ability_sand_veil.c create mode 100644 test/ability_speed_boost.c create mode 100644 test/ability_stench.c create mode 100644 test/ability_volt_absorb.c create mode 100644 test/ability_water_absorb.c diff --git a/test/ability_cloud_nine.c b/test/ability_cloud_nine.c new file mode 100644 index 000000000..02da15ee1 --- /dev/null +++ b/test/ability_cloud_nine.c @@ -0,0 +1,16 @@ +#include "global.h" +#include "test_battle.h" + +SINGLE_BATTLE_TEST("Cloud Nine prevents weather effects") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_SANDSTORM].effect == EFFECT_SANDSTORM); + PLAYER(SPECIES_PSYDUCK) { Ability(ABILITY_CLOUD_NINE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SANDSTORM); } + TURN {} + } SCENE { + NONE_OF { HP_BAR(player); } + } +} diff --git a/test/ability_compound_eyes.c b/test/ability_compound_eyes.c new file mode 100644 index 000000000..97ab84dd2 --- /dev/null +++ b/test/ability_compound_eyes.c @@ -0,0 +1,37 @@ +#include "global.h" +#include "test_battle.h" + +SINGLE_BATTLE_TEST("Compound Eyes raises accuracy") +{ + PASSES_RANDOMLY(91, 100); + GIVEN { + ASSUME(gBattleMoves[MOVE_THUNDER].accuracy == 70); + PLAYER(SPECIES_BUTTERFREE) { Ability(ABILITY_COMPOUND_EYES); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_THUNDER); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDER, player); + HP_BAR(opponent); + } +} + +// This fails even though the ability works correctly. The failure is due to +// a statistical anomaly in the test system where FISSURE hits 3 times more often +// than we expect. +SINGLE_BATTLE_TEST("Compound Eyes does not affect OHKO moves") +{ + KNOWN_FAILING; + PASSES_RANDOMLY(30, 100); + GIVEN { + ASSUME(gBattleMoves[MOVE_FISSURE].accuracy == 30); + ASSUME(gBattleMoves[MOVE_FISSURE].effect == EFFECT_OHKO); + PLAYER(SPECIES_BUTTERFREE) { Ability(ABILITY_TINTED_LENS); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_FISSURE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FISSURE, player); + HP_BAR(opponent, hp: 0); + } +} diff --git a/test/ability_damp.c b/test/ability_damp.c new file mode 100644 index 000000000..33d1ae466 --- /dev/null +++ b/test/ability_damp.c @@ -0,0 +1,54 @@ +#include "global.h" +#include "test_battle.h" + +SINGLE_BATTLE_TEST("Damp prevents explosion-like moves from enemies") +{ + u32 move; + PARAMETRIZE { move = MOVE_EXPLOSION; } + PARAMETRIZE { move = MOVE_SELF_DESTRUCT; } + PARAMETRIZE { move = MOVE_MIND_BLOWN; } + PARAMETRIZE { move = MOVE_MISTY_EXPLOSION; } + GIVEN { + PLAYER(SPECIES_PARAS) { Ability(ABILITY_DAMP); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, move); } + } SCENE { + ABILITY_POPUP(player, ABILITY_DAMP); + NONE_OF { HP_BAR(player); HP_BAR(opponent); } + } +} + +SINGLE_BATTLE_TEST("Damp prevents explosion-like moves from self") +{ + u32 move; + PARAMETRIZE { move = MOVE_EXPLOSION; } + PARAMETRIZE { move = MOVE_SELF_DESTRUCT; } + PARAMETRIZE { move = MOVE_MIND_BLOWN; } + PARAMETRIZE { move = MOVE_MISTY_EXPLOSION; } + GIVEN { + PLAYER(SPECIES_PARAS) { Ability(ABILITY_DAMP); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, move); } + } SCENE { + ABILITY_POPUP(player, ABILITY_DAMP); + NONE_OF { HP_BAR(player); HP_BAR(opponent); } + } +} + +SINGLE_BATTLE_TEST("Damp prevents damage from aftermath") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_TACKLE].flags & FLAG_MAKES_CONTACT); + PLAYER(SPECIES_PARAS) { Ability(ABILITY_DAMP); }; + OPPONENT(SPECIES_VOLTORB) { Ability(ABILITY_AFTERMATH); HP(1); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); SEND_OUT(opponent, 1); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_AFTERMATH); + ABILITY_POPUP(player, ABILITY_DAMP); + NONE_OF { HP_BAR(player); } + } +} diff --git a/test/ability_drizzle.c b/test/ability_drizzle.c new file mode 100644 index 000000000..1b9932476 --- /dev/null +++ b/test/ability_drizzle.c @@ -0,0 +1,24 @@ +#include "global.h" +#include "test_battle.h" + +SINGLE_BATTLE_TEST("Drizzle summons rain", s16 damage) +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_DRIZZLE; } + PARAMETRIZE { ability = ABILITY_DAMP; } + + GIVEN { + PLAYER(SPECIES_POLITOED) { Ability(ability); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_BUBBLE); } + } SCENE { + if (ability == ABILITY_DRIZZLE) { + ABILITY_POPUP(player, ABILITY_DRIZZLE); + MESSAGE("Politoed's Drizzle made it rain!"); + } + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[1].damage, Q_4_12(1.5), results[0].damage); + } +} diff --git a/test/ability_insomnia.c b/test/ability_insomnia.c new file mode 100644 index 000000000..b9fe38753 --- /dev/null +++ b/test/ability_insomnia.c @@ -0,0 +1,59 @@ +#include "global.h" +#include "test_battle.h" + +SINGLE_BATTLE_TEST("Insomnia prevents sleep") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_SPORE].effect == EFFECT_SLEEP); + PLAYER(SPECIES_DROWZEE) { Ability(ABILITY_INSOMNIA); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SPORE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_INSOMNIA); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + STATUS_ICON(player, sleep: TRUE); + } + } +} + +SINGLE_BATTLE_TEST("Insomnia prevents yawn") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_YAWN].effect == EFFECT_YAWN); + PLAYER(SPECIES_DROWZEE) { Ability(ABILITY_INSOMNIA); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SPORE); } + TURN { } + TURN { } + } SCENE { + ABILITY_POPUP(player, ABILITY_INSOMNIA); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_YAWN, opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + STATUS_ICON(player, sleep: TRUE); + } + } +} + +SINGLE_BATTLE_TEST("Insomnia prevents rest") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_REST].effect == EFFECT_REST); + PLAYER(SPECIES_DROWZEE) { Ability(ABILITY_INSOMNIA); HP(1); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_REST); } + } SCENE { + ABILITY_POPUP(player, ABILITY_INSOMNIA); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_REST, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + STATUS_ICON(player, sleep: TRUE); + HP_BAR(player); + } + } +} diff --git a/test/ability_intimidate.c b/test/ability_intimidate.c new file mode 100644 index 000000000..450ca6402 --- /dev/null +++ b/test/ability_intimidate.c @@ -0,0 +1,50 @@ +#include "global.h" +#include "test_battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_TACKLE].split == SPLIT_PHYSICAL); +} + +SINGLE_BATTLE_TEST("Intimidate (opponent) lowers player's attack after switch out", s16 damage) +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_INTIMIDATE; } + PARAMETRIZE { ability = ABILITY_RECKLESS; } + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_STARAPTOR) { Ability(ability); }; + } WHEN { + TURN { SWITCH(opponent, 1); } + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + if (ability == ABILITY_INTIMIDATE) + ABILITY_POPUP(opponent, ABILITY_INTIMIDATE); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage); + } +} + +SINGLE_BATTLE_TEST("Intimidate (opponent) lowers player's attack after KO", s16 damage) +{ + u32 ability; + KNOWN_FAILING; + PARAMETRIZE { ability = ABILITY_INTIMIDATE; } + PARAMETRIZE { ability = ABILITY_RECKLESS; } + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Speed(2); }; + OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(1); }; + OPPONENT(SPECIES_STARAPTOR) { Ability(ABILITY_INTIMIDATE); Speed(1); }; + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); SEND_OUT(opponent, 1); } + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + if (ability == ABILITY_INTIMIDATE) + ABILITY_POPUP(opponent, ABILITY_INTIMIDATE); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage); + } +} diff --git a/test/ability_limber.c b/test/ability_limber.c new file mode 100644 index 000000000..4b428d0c1 --- /dev/null +++ b/test/ability_limber.c @@ -0,0 +1,16 @@ +#include "global.h" +#include "test_battle.h" + +SINGLE_BATTLE_TEST("Limber prevents paralysis") +{ + GIVEN { + PLAYER(SPECIES_PERSIAN) { Ability(ABILITY_LIMBER); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_THUNDER_SHOCK); } + } SCENE { + HP_BAR(player); + NONE_OF { ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PRZ, player); } + NONE_OF { STATUS_ICON(player, paralysis: TRUE); } + } +} diff --git a/test/ability_oblivious.c b/test/ability_oblivious.c new file mode 100644 index 000000000..0708845ed --- /dev/null +++ b/test/ability_oblivious.c @@ -0,0 +1,68 @@ +#include "global.h" +#include "test_battle.h" + +SINGLE_BATTLE_TEST("Oblivious prevents Infatuation") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_ATTRACT].effect == EFFECT_ATTRACT); + PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); Gender(MON_MALE); }; + OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); }; + } WHEN { + TURN { MOVE(opponent, MOVE_ATTRACT); } + } SCENE { + ABILITY_POPUP(player, ABILITY_OBLIVIOUS); + NONE_OF { ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_INFATUATION, player); } + MESSAGE("It doesn't affect Slowpoke…"); + } +} + +SINGLE_BATTLE_TEST("Oblivious prevents Captivate") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_CAPTIVATE].effect == EFFECT_CAPTIVATE); + PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); Gender(MON_MALE); }; + OPPONENT(SPECIES_WOBBUFFET) { Gender(MON_FEMALE); }; + } WHEN { + TURN { MOVE(opponent, MOVE_ATTRACT); } + } SCENE { + ABILITY_POPUP(player, ABILITY_OBLIVIOUS); + NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); } + MESSAGE("It doesn't affect Slowpoke…"); + } +} + +SINGLE_BATTLE_TEST("Oblivious prevents Taunt") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_TAUNT].effect == EFFECT_TAUNT); + ASSUME(B_OBLIVIOUS_TAUNT >= GEN_6); + PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_TAUNT); } + TURN { MOVE(player, MOVE_SPORE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_OBLIVIOUS); + NONE_OF { ANIMATION(ANIM_TYPE_MOVE, MOVE_TAUNT, opponent); } + MESSAGE("It doesn't affect Slowpoke…"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, opponent); + } +} + +SINGLE_BATTLE_TEST("Oblivious prevents Intimidate") +{ + GIVEN { + ASSUME(B_UPDATED_INTIMIDATE >= GEN_8); + PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); }; + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }; + } WHEN { + TURN { SWITCH(opponent, 1); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_INTIMIDATE); + ABILITY_POPUP(player, ABILITY_OBLIVIOUS); + NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); } + MESSAGE("Slowpoke's attack was not lowered!"); + } +} diff --git a/test/ability_sand_veil.c b/test/ability_sand_veil.c new file mode 100644 index 000000000..5d2325140 --- /dev/null +++ b/test/ability_sand_veil.c @@ -0,0 +1,30 @@ +#include "global.h" +#include "test_battle.h" + +SINGLE_BATTLE_TEST("Sand Veil prevents damage from sandstorm") +{ + GIVEN { + PLAYER(SPECIES_SANDSHREW) { Ability(ABILITY_SAND_VEIL); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SANDSTORM); } + TURN {} + } SCENE { + NONE_OF { HP_BAR(player); } + } +} + +SINGLE_BATTLE_TEST("Sand Veil reduces accuracy during sandstorm") +{ + PASSES_RANDOMLY(4,5); + GIVEN { + ASSUME(gBattleMoves[MOVE_POUND].accuracy == 100); + PLAYER(SPECIES_SANDSHREW) { Ability(ABILITY_SAND_VEIL); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SANDSTORM); } + TURN { MOVE(opponent, MOVE_POUND); } + } SCENE { + HP_BAR(player); + } +} diff --git a/test/ability_speed_boost.c b/test/ability_speed_boost.c new file mode 100644 index 000000000..b3e128931 --- /dev/null +++ b/test/ability_speed_boost.c @@ -0,0 +1,20 @@ +#include "global.h" +#include "test_battle.h" + +SINGLE_BATTLE_TEST("Speed Boost gradually boosts speed") +{ + GIVEN { + PLAYER(SPECIES_TORCHIC) { Ability(ABILITY_SPEED_BOOST); Speed(99); }; + OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }; + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + MESSAGE("Foe Wobbuffet used Celebrate!"); + MESSAGE("Torchic used Celebrate!"); + ABILITY_POPUP(player, ABILITY_SPEED_BOOST); + MESSAGE("Torchic's Speed Boost raised its SPEED!"); + MESSAGE("Torchic used Celebrate!"); + MESSAGE("Foe Wobbuffet used Celebrate!"); + } +} diff --git a/test/ability_stench.c b/test/ability_stench.c new file mode 100644 index 000000000..7285ee768 --- /dev/null +++ b/test/ability_stench.c @@ -0,0 +1,34 @@ +#include "global.h" +#include "test_battle.h" + +SINGLE_BATTLE_TEST("Stench has a 10% chance to flinch") +{ + PASSES_RANDOMLY(1,10); + GIVEN { + ASSUME(gBattleMoves[MOVE_TACKLE].power > 0); + PLAYER(SPECIES_STUNKY) { Ability(ABILITY_STENCH); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + MESSAGE("Foe Wobbuffet flinched!"); + } +} + +SINGLE_BATTLE_TEST("Stench does not stack with King's Rock") +{ + PASSES_RANDOMLY(1,10); + GIVEN { + ASSUME(gItems[ITEM_KINGS_ROCK].holdEffect == HOLD_EFFECT_FLINCH); + ASSUME(gBattleMoves[MOVE_TACKLE].power > 0); + + PLAYER(SPECIES_STUNKY) { Ability(ABILITY_STENCH); Item(ITEM_KINGS_ROCK); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + MESSAGE("Foe Wobbuffet flinched!"); + } +} + +// TODO: Test against interaction with multi hits diff --git a/test/ability_volt_absorb.c b/test/ability_volt_absorb.c new file mode 100644 index 000000000..f485f6557 --- /dev/null +++ b/test/ability_volt_absorb.c @@ -0,0 +1,85 @@ +#include "global.h" +#include "test_battle.h" + +#define TEST_MAX_HP (100) + +SINGLE_BATTLE_TEST("Volt Absorb heals 25% when hit by electric type moves") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC); + PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(TEST_MAX_HP); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_THUNDER_SHOCK); } + } SCENE { + ABILITY_POPUP(player, ABILITY_VOLT_ABSORB); + HP_BAR(player, hp: TEST_MAX_HP / 4 + 1); + MESSAGE("Jolteon restored HP using its Volt Absorb!"); + } +} + +SINGLE_BATTLE_TEST("Volt Absorb does not activate if protected") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC); + PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(TEST_MAX_HP); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_PROTECT); MOVE(opponent, MOVE_THUNDER_SHOCK); } + } SCENE { + NONE_OF { ABILITY_POPUP(player, ABILITY_VOLT_ABSORB); HP_BAR(player); MESSAGE("Jolteon restored HP using its Volt Absorb!"); } + } +} + +SINGLE_BATTLE_TEST("Volt Absorb activates on status moves") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_THUNDER_WAVE].type == TYPE_ELECTRIC); + ASSUME(gBattleMoves[MOVE_THUNDER_WAVE].split == SPLIT_STATUS); + PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(TEST_MAX_HP); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_THUNDER_WAVE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_VOLT_ABSORB); + HP_BAR(player, hp: TEST_MAX_HP / 4 + 1); + MESSAGE("Jolteon restored HP using its Volt Absorb!"); + } +} + +SINGLE_BATTLE_TEST("Volt Absorb is only triggered once on multi strike moves") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_FURY_SWIPES].type == TYPE_NORMAL); + ASSUME(gBattleMoves[MOVE_FURY_SWIPES].effect == EFFECT_MULTI_HIT); + PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(TEST_MAX_HP); }; + OPPONENT(SPECIES_GRAVELER_ALOLAN) { Ability(ABILITY_GALVANIZE); }; + } WHEN { + TURN { MOVE(opponent, MOVE_FURY_SWIPES); } + } SCENE { + ABILITY_POPUP(player, ABILITY_VOLT_ABSORB); + HP_BAR(player, hp: TEST_MAX_HP / 4 + 1); + MESSAGE("Jolteon restored HP using its Volt Absorb!"); + } +} + +SINGLE_BATTLE_TEST("Volt Absorb prevents Cell Battery from activating") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC); + PLAYER(SPECIES_JOLTEON) { Ability(ABILITY_VOLT_ABSORB); HP(1); MaxHP(TEST_MAX_HP); Item(ITEM_CELL_BATTERY); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_THUNDER_SHOCK); } + } SCENE { + ABILITY_POPUP(player, ABILITY_VOLT_ABSORB); + HP_BAR(player, hp: TEST_MAX_HP / 4 + 1); + MESSAGE("Jolteon restored HP using its Volt Absorb!"); + NONE_OF { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Cell Battery, the attack of Jolteon rose!"); + } + + } +} diff --git a/test/ability_water_absorb.c b/test/ability_water_absorb.c new file mode 100644 index 000000000..1748ee7ff --- /dev/null +++ b/test/ability_water_absorb.c @@ -0,0 +1,87 @@ +#include "global.h" +#include "test_battle.h" + +#define TEST_MAX_HP (100) + +SINGLE_BATTLE_TEST("Water Absorb heals 25% when hit by water type moves") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_BUBBLE].type == TYPE_WATER); + PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(TEST_MAX_HP); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_BUBBLE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_WATER_ABSORB); + HP_BAR(player, hp: TEST_MAX_HP / 4 + 1); + MESSAGE("Poliwag restored HP using its Water Absorb!"); + } +} + +SINGLE_BATTLE_TEST("Water Absorb does not activate if protected") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_BUBBLE].type == TYPE_WATER); + PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(TEST_MAX_HP); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_PROTECT); MOVE(opponent, MOVE_BUBBLE); } + } SCENE { + NONE_OF { ABILITY_POPUP(player, ABILITY_WATER_ABSORB); HP_BAR(player); MESSAGE("Poliwag restored HP using its Water Absorb!"); } + } +} + +SINGLE_BATTLE_TEST("Water Absorb activates on status moves") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_SOAK].type == TYPE_WATER); + ASSUME(gBattleMoves[MOVE_SOAK].split == SPLIT_STATUS); + PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(TEST_MAX_HP); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SOAK); } + } SCENE { + ABILITY_POPUP(player, ABILITY_WATER_ABSORB); + HP_BAR(player, hp: TEST_MAX_HP / 4 + 1); + MESSAGE("Poliwag restored HP using its Water Absorb!"); + } +} + +SINGLE_BATTLE_TEST("Water Absorb is only triggered once on multi strike moves") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_WATER_SHURIKEN].type == TYPE_WATER); + ASSUME(gBattleMoves[MOVE_WATER_SHURIKEN].effect == EFFECT_MULTI_HIT); + PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(TEST_MAX_HP); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_WATER_SHURIKEN); } + } SCENE { + ABILITY_POPUP(player, ABILITY_WATER_ABSORB); + HP_BAR(player, hp: TEST_MAX_HP / 4 + 1); + MESSAGE("Poliwag restored HP using its Water Absorb!"); + } +} + +SINGLE_BATTLE_TEST("Water Absorb prevents Items from activating") +{ + u32 item; + PARAMETRIZE { item = ITEM_ABSORB_BULB; } + PARAMETRIZE { item = ITEM_LUMINOUS_MOSS; } + GIVEN { + ASSUME(gBattleMoves[MOVE_BUBBLE].type == TYPE_WATER); + PLAYER(SPECIES_POLIWAG) { Ability(ABILITY_WATER_ABSORB); HP(1); MaxHP(TEST_MAX_HP); Item(item); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_BUBBLE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_WATER_ABSORB); + HP_BAR(player, hp: TEST_MAX_HP / 4 + 1); + MESSAGE("Poliwag restored HP using its Water Absorb!"); + NONE_OF { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } + + } +} From 074f1b544e4cc86c3a05381f365ebc8fb0ba3710 Mon Sep 17 00:00:00 2001 From: Martin Griffin Date: Wed, 8 Feb 2023 07:43:49 +0000 Subject: [PATCH 44/69] Use variable in patchelf invocation --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 696820cd9..8df33de4c 100644 --- a/Makefile +++ b/Makefile @@ -459,7 +459,7 @@ $(TESTELF): $(OBJ_DIR)/ld_script_test.ld $(OBJS) $(TEST_OBJS) libagbsyscall @echo "cd $(OBJ_DIR) && $(LD) -T ld_script_test.ld -o ../../$@ " @cd $(OBJ_DIR) && $(LD) $(TESTLDFLAGS) -T ld_script_test.ld -o ../../$@ $(OBJS_REL) $(TEST_OBJS_REL) $(LIB) $(FIX) $@ -t"$(TITLE)" -c$(GAME_CODE) -m$(MAKER_CODE) -r$(REVISION) --silent - $(PATCHELF) pokeemerald-test.elf gTestRunnerArgv "$(TESTS)\0" + $(PATCHELF) $(TESTELF) gTestRunnerArgv "$(TESTS)\0" ifeq ($(GITHUB_REPOSITORY_OWNER),rh-hideout) TEST_SKIP_IS_FAIL := \x01 From d59e576b5106c1a22851478b0e2864316a3b5f73 Mon Sep 17 00:00:00 2001 From: Martin Griffin Date: Thu, 9 Feb 2023 22:54:11 +0000 Subject: [PATCH 45/69] Hydra: remove tmpnam (#2668) * Use a PID-based filename instead of tmpnam * Use FILENAME_MAX over L_tmpnam --------- Co-authored-by: Martin Griffin Co-authored-by: Philipp AUER --- tools/mgba-rom-test-hydra/main.c | 96 ++++++++++++++++---------------- 1 file changed, 47 insertions(+), 49 deletions(-) diff --git a/tools/mgba-rom-test-hydra/main.c b/tools/mgba-rom-test-hydra/main.c index f9c51d505..5dfc99517 100644 --- a/tools/mgba-rom-test-hydra/main.c +++ b/tools/mgba-rom-test-hydra/main.c @@ -30,7 +30,7 @@ struct Runner { pid_t pid; int outfd; - char rom_path[L_tmpnam]; + char rom_path[FILENAME_MAX]; char test_name[256]; size_t input_buffer_size; size_t input_buffer_capacity; @@ -234,53 +234,6 @@ int main(int argc, char *argv[]) perror("pipe failed"); exit(2); } - if (!tmpnam(runners[i].rom_path)) - { - perror("tmpnam rom_path failed"); - exit(2); - } - int tmpfd; - if ((tmpfd = open(runners[i].rom_path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) == -1) - { - perror("open tmpfd failed"); - _exit(2); - } - if ((write(tmpfd, elf, elfst.st_size)) == -1) - { - perror("write tmpfd failed"); - _exit(2); - } - pid_t patchelfpid = fork(); - if (patchelfpid == -1) - { - perror("fork patchelf failed"); - _exit(2); - } - else if (patchelfpid == 0) - { - char n_arg[5], i_arg[5]; - snprintf(n_arg, sizeof(n_arg), "\\x%02x", nrunners); - snprintf(i_arg, sizeof(i_arg), "\\x%02x", i); - if (execlp("tools/patchelf/patchelf", "tools/patchelf/patchelf", runners[i].rom_path, "gTestRunnerN", n_arg, "gTestRunnerI", i_arg, NULL) == -1) - { - perror("execlp patchelf failed"); - _exit(2); - } - } - else - { - int wstatus; - if (waitpid(patchelfpid, &wstatus, 0) == -1) - { - perror("waitpid patchelfpid failed"); - _exit(2); - } - if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) - { - fprintf(stderr, "patchelf exited with an error\n"); - _exit(2); - } - } pid_t pid = fork(); if (pid == -1) { perror("fork mgba-rom-test failed"); @@ -310,15 +263,60 @@ int main(int argc, char *argv[]) perror("close pipefds[1] failed"); _exit(2); } + char rom_path[FILENAME_MAX]; + sprintf(rom_path, "/tmp/file%05d", getpid()); + int tmpfd; + if ((tmpfd = open(rom_path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) == -1) + { + perror("open tmpfd failed"); + _exit(2); + } + if ((write(tmpfd, elf, elfst.st_size)) == -1) + { + perror("write tmpfd failed"); + _exit(2); + } + pid_t patchelfpid = fork(); + if (patchelfpid == -1) + { + perror("fork patchelf failed"); + _exit(2); + } + else if (patchelfpid == 0) + { + char n_arg[5], i_arg[5]; + snprintf(n_arg, sizeof(n_arg), "\\x%02x", nrunners); + snprintf(i_arg, sizeof(i_arg), "\\x%02x", i); + if (execlp("tools/patchelf/patchelf", "tools/patchelf/patchelf", rom_path, "gTestRunnerN", n_arg, "gTestRunnerI", i_arg, NULL) == -1) + { + perror("execlp patchelf failed"); + _exit(2); + } + } + else + { + int wstatus; + if (waitpid(patchelfpid, &wstatus, 0) == -1) + { + perror("waitpid patchelfpid failed"); + _exit(2); + } + if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) + { + fprintf(stderr, "patchelf exited with an error\n"); + _exit(2); + } + } // stdbuf is required because otherwise mgba never flushes // stdout. - if (execlp("stdbuf", "stdbuf", "-oL", argv[1], "-l15", "-ClogLevel.gba.dma=16", "-Rr0", runners[i].rom_path, NULL) == -1) + if (execlp("stdbuf", "stdbuf", "-oL", argv[1], "-l15", "-ClogLevel.gba.dma=16", "-Rr0", rom_path, NULL) == -1) { perror("execl stdbuf mgba-rom-test failed"); _exit(2); } } else { runners[i].pid = pid; + sprintf(runners[i].rom_path, "/tmp/file%05d", runners[i].pid); runners[i].outfd = pipefds[0]; if (close(pipefds[1]) == -1) { From f933ad31837cf34e4cd968f74659d1867621a4ce Mon Sep 17 00:00:00 2001 From: Martin Griffin Date: Wed, 8 Feb 2023 17:35:28 +0000 Subject: [PATCH 46/69] Build patchelf and hydra only for check --- Makefile | 21 +++++++++++++++------ make_tools.mk | 3 +-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 8df33de4c..8e3ff2975 100644 --- a/Makefile +++ b/Makefile @@ -142,7 +142,8 @@ ROMTESTHYDRA := tools/mgba-rom-test-hydra/mgba-rom-test-hydra$(EXE) PERL := perl -TOOLDIRS := $(filter-out tools/mgba tools/agbcc tools/binutils,$(wildcard tools/*)) +TOOLDIRS := tools/aif2pcm tools/bin2c tools/gbafix tools/gbagfx tools/jsonproc tools/mapjson tools/mid2agb tools/preproc tools/ramscrgen tools/rsfont tools/scaninc +CHECKTOOLDIRS = tools/patchelf tools/mgba-rom-test-hydra TOOLBASE = $(TOOLDIRS:tools/%=%) TOOLS = $(foreach tool,$(TOOLBASE),tools/$(tool)/$(tool)$(EXE)) @@ -158,7 +159,7 @@ MAKEFLAGS += --no-print-directory # Secondary expansion is required for dependency variables in object rules. .SECONDEXPANSION: -.PHONY: all rom clean compare tidy tools mostlyclean clean-tools $(TOOLDIRS) libagbsyscall modern tidymodern tidynonmodern check +.PHONY: all rom clean compare tidy tools check-tools mostlyclean clean-tools clean-check-tools $(TOOLDIRS) $(CHECKTOOLDIRS) libagbsyscall modern tidymodern tidynonmodern check infoshell = $(foreach line, $(shell $1 | sed "s/ /__SPACE__/g"), $(info $(subst __SPACE__, ,$(line)))) @@ -176,9 +177,9 @@ endif ifeq (,$(MAKECMDGOALS)) SCAN_DEPS ?= 1 else - # clean, tidy, tools, mostlyclean, clean-tools, $(TOOLDIRS), tidymodern, tidynonmodern don't even build the ROM + # clean, tidy, tools, check-tools, mostlyclean, clean-tools, clean-check-tools, $(TOOLDIRS), $(CHECKTOOLDIRS), tidymodern, tidynonmodern don't even build the ROM # libagbsyscall does its own thing - ifeq (,$(filter-out clean tidy tools mostlyclean clean-tools $(TOOLDIRS) tidymodern tidynonmodern libagbsyscall,$(MAKECMDGOALS))) + ifeq (,$(filter-out clean tidy tools mostlyclean clean-tools $(TOOLDIRS) clean-check-tools $(CHECKTOOLDIRS) tidymodern tidynonmodern libagbsyscall,$(MAKECMDGOALS))) SCAN_DEPS ?= 0 else SCAN_DEPS ?= 1 @@ -229,11 +230,16 @@ all: rom tools: $(TOOLDIRS) +check-tools: $(CHECKTOOLDIRS) + syms: $(SYM) $(TOOLDIRS): @$(MAKE) -C $@ +$(CHECKTOOLDIRS): + @$(MAKE) -C $@ + rom: $(ROM) ifeq ($(COMPARE),1) @$(SHA1) rom.sha1 @@ -242,11 +248,14 @@ endif # For contributors to make sure a change didn't affect the contents of the ROM. compare: all -clean: mostlyclean clean-tools +clean: mostlyclean clean-tools clean-check-tools clean-tools: @$(foreach tooldir,$(TOOLDIRS),$(MAKE) clean -C $(tooldir);) +clean-check-tools: + @$(foreach tooldir,$(CHECKTOOLDIRS),$(MAKE) clean -C $(tooldir);) + mostlyclean: tidynonmodern tidymodern rm -f $(SAMPLE_SUBDIR)/*.bin rm -f $(CRY_SUBDIR)/*.bin @@ -455,7 +464,7 @@ LD_SCRIPT_TEST := ld_script_test.txt $(OBJ_DIR)/ld_script_test.ld: $(LD_SCRIPT_TEST) $(LD_SCRIPT_DEPS) cd $(OBJ_DIR) && sed "s#tools/#../../tools/#g" ../../$(LD_SCRIPT_TEST) > ld_script_test.ld -$(TESTELF): $(OBJ_DIR)/ld_script_test.ld $(OBJS) $(TEST_OBJS) libagbsyscall +$(TESTELF): $(OBJ_DIR)/ld_script_test.ld $(OBJS) $(TEST_OBJS) libagbsyscall check-tools @echo "cd $(OBJ_DIR) && $(LD) -T ld_script_test.ld -o ../../$@ " @cd $(OBJ_DIR) && $(LD) $(TESTLDFLAGS) -T ld_script_test.ld -o ../../$@ $(OBJS_REL) $(TEST_OBJS_REL) $(LIB) $(FIX) $@ -t"$(TITLE)" -c$(GAME_CODE) -m$(MAKER_CODE) -r$(REVISION) --silent diff --git a/make_tools.mk b/make_tools.mk index 36dbe8c90..5a5291b77 100644 --- a/make_tools.mk +++ b/make_tools.mk @@ -1,7 +1,6 @@ - MAKEFLAGS += --no-print-directory -TOOLDIRS := $(filter-out tools/mgba tools/agbcc tools/binutils,$(wildcard tools/*)) +TOOLDIRS := tools/aif2pcm tools/bin2c tools/gbafix tools/gbagfx tools/jsonproc tools/mapjson tools/mid2agb tools/preproc tools/ramscrgen tools/rsfont tools/scaninc .PHONY: all $(TOOLDIRS) From ce416be29723bc672c734663f79b7da58bd510b3 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 11 Feb 2023 18:32:07 +0100 Subject: [PATCH 47/69] z_move switch move bug --- src/battle_controller_player.c | 2 ++ src/battle_util.c | 18 +++++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index a57bd2995..aeb0203c2 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -882,6 +882,7 @@ static void HandleMoveSwitching(void) if (JOY_NEW(A_BUTTON | SELECT_BUTTON)) { + struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]); PlaySE(SE_SELECT); if (gMoveSelectionCursor[gActiveBattler] != gMultiUsePlayerCursor) @@ -973,6 +974,7 @@ static void HandleMoveSwitching(void) MoveSelectionDisplayPpString(); MoveSelectionDisplayPpNumber(); MoveSelectionDisplayMoveType(); + GetUsableZMoves(gActiveBattler, moveInfo->moves); } else if (JOY_NEW(B_BUTTON | SELECT_BUTTON)) { diff --git a/src/battle_util.c b/src/battle_util.c index 4333d0b44..17784935c 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3814,7 +3814,7 @@ u8 AtkCanceller_UnableToUseMove(void) { SetRandomMultiHitCounter(); } - + PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) } else if (gBattleMoves[gCurrentMove].flags & FLAG_TWO_STRIKES) @@ -3841,7 +3841,7 @@ u8 AtkCanceller_UnableToUseMove(void) party = gPlayerParty; else party = gEnemyParty; - + for (i = 0; i < PARTY_SIZE; i++) { if (GetMonData(&party[i], MON_DATA_HP) @@ -5487,7 +5487,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move RecordItemEffectBattle(gBattlerAttacker, HOLD_EFFECT_ABILITY_SHIELD); break; } - + gLastUsedAbility = gBattleMons[gBattlerAttacker].ability; gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = gLastUsedAbility; @@ -6858,7 +6858,7 @@ static u8 ItemEffectMoveEnd(u32 battlerId, u16 holdEffect) { u8 effect = 0; u32 i; - + switch (holdEffect) { #if B_HP_BERRIES >= GEN_4 @@ -7027,7 +7027,7 @@ static u8 ItemEffectMoveEnd(u32 battlerId, u16 holdEffect) && !(gBattleMons[battlerId].status2 & STATUS2_FOCUS_ENERGY) && HasEnoughHpToEatBerry(battlerId, GetBattlerItemHoldEffectParam(battlerId, gLastUsedItem), gLastUsedItem)) { - gBattleMons[battlerId].status2 |= STATUS2_FOCUS_ENERGY; + gBattleMons[battlerId].status2 |= STATUS2_FOCUS_ENERGY; gBattleScripting.battler = battlerId; gPotentialItemEffectBattler = battlerId; BattleScriptPushCursor(); @@ -7036,7 +7036,7 @@ static u8 ItemEffectMoveEnd(u32 battlerId, u16 holdEffect) } break; } - + return effect; } @@ -7053,7 +7053,7 @@ u8 ItemBattleEffects(u8 caseID, u8 battlerId, bool8 moveTurn) gLastUsedItem = gBattleMons[battlerId].item; battlerHoldEffect = GetBattlerHoldEffect(battlerId, TRUE); } - + atkItem = gBattleMons[gBattlerAttacker].item; atkHoldEffect = GetBattlerHoldEffect(gBattlerAttacker, TRUE); atkHoldEffectParam = GetBattlerHoldEffectParam(gBattlerAttacker); @@ -8184,7 +8184,7 @@ u32 GetBattlerHoldEffect(u8 battlerId, bool32 checkNegating) return ItemId_GetHoldEffect(gBattleMons[battlerId].item); } -// +// static u32 GetBattlerItemHoldEffectParam(u8 battlerId, u16 item) { if (item == ITEM_ENIGMA_BERRY) @@ -8234,7 +8234,7 @@ bool32 IsBattlerProtected(u8 battlerId, u16 move) else if (gProtectStructs[battlerId].protected) return FALSE; } - + if (move == MOVE_TEATIME) { return FALSE; From d363ed8152678b5945b4a428dc79207e1c2f0cc6 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 11 Feb 2023 19:55:08 +0100 Subject: [PATCH 48/69] z indicator in double battles --- src/battle_z_move.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_z_move.c b/src/battle_z_move.c index 2eccd82f5..2406c6bb3 100644 --- a/src/battle_z_move.c +++ b/src/battle_z_move.c @@ -372,7 +372,7 @@ static void ShowZMoveTriggerSprite(void) { struct Sprite *sprite = &gSprites[gBattleStruct->zmove.triggerSpriteId]; gBattleStruct->zmove.viable = TRUE; - CreateZMoveTriggerSprite(sprite->tBattler, TRUE); + CreateZMoveTriggerSprite(gActiveBattler, TRUE); } void DestroyZMoveTriggerSprite(void) From 2b32bfcdc1a4fc16641ea1651e5a7355f49b7605 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 12 Feb 2023 19:39:14 +0100 Subject: [PATCH 49/69] add battlerId arg to ShowZMoveTriggerSprite --- src/battle_z_move.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/battle_z_move.c b/src/battle_z_move.c index 2406c6bb3..bdbf5674c 100644 --- a/src/battle_z_move.c +++ b/src/battle_z_move.c @@ -50,7 +50,7 @@ static u16 GetSignatureZMove(u16 move, u16 species, u16 item); static u16 GetTypeBasedZMove(u16 move, u8 battler); static void ZMoveSelectionDisplayPpNumber(void); static void ZMoveSelectionDisplayPower(u16 move, u16 zMove); -static void ShowZMoveTriggerSprite(void); +static void ShowZMoveTriggerSprite(u8 battleId); static bool32 AreStatsMaxed(u8 battlerId, u8 n); static u8 GetZMoveScore(u8 battlerAtk, u8 battlerDef, u16 baseMove, u16 zMove); static void ZMoveSelectionDisplayMoveType(u16 zMove); @@ -258,7 +258,7 @@ bool32 TryChangeZIndicator(u8 battlerId, u8 moveIndex) if (gBattleStruct->zmove.viable && !viableZMove) HideZMoveTriggerSprite(); // Was a viable z move, now is not -> slide out else if (!gBattleStruct->zmove.viable && viableZMove) - ShowZMoveTriggerSprite(); // Was not a viable z move, now is -> slide back in + ShowZMoveTriggerSprite(battlerId); // Was not a viable z move, now is -> slide back in } #define SINGLES_Z_TRIGGER_POS_X_OPTIMAL (29) @@ -368,11 +368,11 @@ void HideZMoveTriggerSprite(void) gBattleStruct->zmove.viable = FALSE; } -static void ShowZMoveTriggerSprite(void) +static void ShowZMoveTriggerSprite(u8 battlerId) { struct Sprite *sprite = &gSprites[gBattleStruct->zmove.triggerSpriteId]; gBattleStruct->zmove.viable = TRUE; - CreateZMoveTriggerSprite(gActiveBattler, TRUE); + CreateZMoveTriggerSprite(battlerId, TRUE); } void DestroyZMoveTriggerSprite(void) From 0577d8d04d439a0fded1ecb80e3ac89f6e0b0aa0 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Mon, 13 Feb 2023 14:44:34 +0100 Subject: [PATCH 50/69] Fix Mirror Armor against Clear Body --- data/battle_scripts_1.s | 2 +- include/constants/battle_script_commands.h | 1 + src/battle_script_commands.c | 11 ++++++----- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 25386dbf0..7fecdccd5 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -3584,7 +3584,7 @@ BattleScript_MirrorArmorReflect:: call BattleScript_AbilityPopUp jumpifsubstituteblocks BattleScript_AbilityNoSpecificStatLoss BattleScript_MirrorArmorReflectStatLoss: - statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_NOT_PROTECT_AFFECTED | STAT_CHANGE_ALLOW_PTR, BattleScript_MirrorArmorReflectEnd + statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_MIRROR_ARMOR | STAT_CHANGE_NOT_PROTECT_AFFECTED | STAT_CHANGE_ALLOW_PTR, BattleScript_MirrorArmorReflectEnd jumpifbyte CMP_LESS_THAN, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_MirrorArmorReflectAnim goto BattleScript_MirrorArmorReflectWontFall BattleScript_MirrorArmorReflectAnim: diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 123fb5d49..935121394 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -273,6 +273,7 @@ // Cmd_statbuffchange #define STAT_CHANGE_ALLOW_PTR (1 << 0) // If set, allow use of jumpptr. Set in every use of statbuffchange +#define STAT_CHANGE_MIRROR_ARMOR (1 << 1) // Stat change redirection caused by Mirror Armor ability. #define STAT_CHANGE_NOT_PROTECT_AFFECTED (1 << 5) #define STAT_CHANGE_UPDATE_MOVE_EFFECT (1 << 6) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index be5e2ee21..c9488167f 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -10877,8 +10877,9 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr bool32 certain = FALSE; bool32 notProtectAffected = FALSE; u32 index; - bool32 affectsUser = (flags & MOVE_EFFECT_AFFECTS_USER); u16 activeBattlerAbility; + bool32 affectsUser = (flags & MOVE_EFFECT_AFFECTS_USER); + bool32 mirrorArmored = (flags & STAT_CHANGE_MIRROR_ARMOR); if (affectsUser) gActiveBattler = gBattlerAttacker; @@ -10889,10 +10890,10 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr gSpecialStatuses[gActiveBattler].changedStatsBattlerId = gBattlerAttacker; - flags &= ~MOVE_EFFECT_AFFECTS_USER; + flags &= ~(MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_MIRROR_ARMOR); if (flags & MOVE_EFFECT_CERTAIN) - certain++; + certain = TRUE; flags &= ~MOVE_EFFECT_CERTAIN; if (flags & STAT_CHANGE_NOT_PROTECT_AFFECTED) @@ -10948,7 +10949,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr || activeBattlerAbility == ABILITY_CLEAR_BODY || activeBattlerAbility == ABILITY_FULL_METAL_BODY || activeBattlerAbility == ABILITY_WHITE_SMOKE) - && !affectsUser && !certain && gCurrentMove != MOVE_CURSE) + && (!affectsUser || mirrorArmored) && !certain && gCurrentMove != MOVE_CURSE) { if (GetBattlerHoldEffect(gActiveBattler, TRUE) == HOLD_EFFECT_CLEAR_AMULET) { @@ -11010,7 +11011,7 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr } return STAT_CHANGE_DIDNT_WORK; } - else if (activeBattlerAbility == ABILITY_MIRROR_ARMOR && !affectsUser && gBattlerAttacker != gBattlerTarget && gActiveBattler == gBattlerTarget) + else if (activeBattlerAbility == ABILITY_MIRROR_ARMOR && !affectsUser && !mirrorArmored && gBattlerAttacker != gBattlerTarget && gActiveBattler == gBattlerTarget) { if (flags == STAT_CHANGE_ALLOW_PTR) { From 2b4d2a76950f90b7b7481dadc3978a0c8c52caa9 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Mon, 13 Feb 2023 16:27:21 +0100 Subject: [PATCH 51/69] Fix Jaw Lock locking player pokemon --- src/battle_script_commands.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index be5e2ee21..38fb1e069 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3634,7 +3634,7 @@ void SetMoveEffect(bool32 primary, u32 certain) BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_BothCanNoLongerEscape; } - if (!gBattleMons[gBattlerTarget].status2 & STATUS2_ESCAPE_PREVENTION) + if (!(gBattleMons[gBattlerTarget].status2 & STATUS2_ESCAPE_PREVENTION)) gDisableStructs[gBattlerTarget].battlerPreventingEscape = gBattlerAttacker; if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_ESCAPE_PREVENTION)) From 908b509401e497f1df540c5565c5ab498e2bbef1 Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Tue, 14 Feb 2023 10:49:50 -0500 Subject: [PATCH 52/69] Fix Round's Base Power calc, Add Turn order effects (#2602) * fix round base power calc, add turn order change * remove unused callnative cmd * fix round turn order update * fix moveTarget getting set incorrectly in HandleAction_UseMove. also redirection doesn't affect MOVE_TARGET_ALL_BATTLERS --------- Co-authored-by: ghoulslash --- data/battle_scripts_1.s | 6 +++- include/constants/battle.h | 3 +- src/battle_script_commands.c | 55 +++++++++++++++++++++++++++++++++++- src/battle_util.c | 24 ++++++++++++---- src/data/battle_moves.h | 2 +- 5 files changed, 81 insertions(+), 9 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 25386dbf0..c404dc37d 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -250,7 +250,7 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectHit @ EFFECT_GYRO_BALL .4byte BattleScript_EffectHit @ EFFECT_ECHOED_VOICE .4byte BattleScript_EffectHit @ EFFECT_PAYBACK - .4byte BattleScript_EffectHit @ EFFECT_ROUND + .4byte BattleScript_EffectRound @ EFFECT_ROUND .4byte BattleScript_EffectHit @ EFFECT_BRINE .4byte BattleScript_EffectHit @ EFFECT_VENOSHOCK .4byte BattleScript_EffectHit @ EFFECT_RETALIATE @@ -3082,6 +3082,10 @@ BattleScript_EffectPlaceholder: printstring STRINGID_NOTDONEYET goto BattleScript_MoveEnd +BattleScript_EffectRound: + setmoveeffect MOVE_EFFECT_ROUND + goto BattleScript_EffectHit + BattleScript_EffectHit:: BattleScript_HitFromAtkCanceler:: attackcanceler diff --git a/include/constants/battle.h b/include/constants/battle.h index be44c21cb..c24178cd0 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -371,8 +371,9 @@ #define MOVE_EFFECT_RELIC_SONG 69 #define MOVE_EFFECT_TRAP_BOTH 70 #define MOVE_EFFECT_DOUBLE_SHOCK 71 +#define MOVE_EFFECT_ROUND 72 -#define NUM_MOVE_EFFECTS 72 +#define NUM_MOVE_EFFECTS 73 #define MOVE_EFFECT_AFFECTS_USER 0x4000 #define MOVE_EFFECT_CERTAIN 0x8000 diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 38fb1e069..d1c0a7c77 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -318,6 +318,7 @@ static void SpriteCB_MonIconOnLvlUpBanner(struct Sprite *sprite); static bool32 CriticalCapture(u32 odds); static void BestowItem(u32 battlerAtk, u32 battlerDef); static bool8 IsFinalStrikeEffect(u16 move); +static void TryUpdateRoundTurnOrder(void); static void Cmd_attackcanceler(void); static void Cmd_accuracycheck(void); @@ -3660,6 +3661,10 @@ void SetMoveEffect(bool32 primary, u32 certain) BattleScriptPush(gBattlescriptCurrInstr + 1); gBattlescriptCurrInstr = BattleScript_DoubleShockRemoveType; break; + case MOVE_EFFECT_ROUND: + TryUpdateRoundTurnOrder(); // If another Pokémon uses Round before the user this turn, the user will use Round directly after it + gBattlescriptCurrInstr++; + break; } } } @@ -14960,7 +14965,7 @@ static void Cmd_callnative(void) func(); } -// Callnative Funcs +// Callnative Funcs void BS_CalcMetalBurstDmg(void) { u8 sideAttacker = GetBattlerSide(gBattlerAttacker); @@ -15089,3 +15094,51 @@ static bool8 IsFinalStrikeEffect(u16 move) } return FALSE; } + +static void TryUpdateRoundTurnOrder(void) +{ + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + u32 i; + u32 j = 0; + u32 k = 0; + u32 currRounder; + u8 roundUsers[3] = {0xFF, 0xFF, 0xFF}; + u8 nonRoundUsers[3] = {0xFF, 0xFF, 0xFF}; + for (i = 0; i < gBattlersCount; i++) + { + if (gBattlerByTurnOrder[i] == gBattlerAttacker) + { + currRounder = i + 1; // Current battler going after attacker + break; + } + } + + // Get battlers after us using round + for (i = currRounder; i < gBattlersCount; i++) + { + if (gChosenMoveByBattler[gBattlerByTurnOrder[i]] == MOVE_ROUND) + roundUsers[j++] = gBattlerByTurnOrder[i]; + else + nonRoundUsers[k++] = gBattlerByTurnOrder[i]; + } + + // update turn order for round users + for (i = 0; roundUsers[i] != 0xFF && i < 3; i++) + { + gBattlerByTurnOrder[currRounder] = roundUsers[i]; + gActionsByTurnOrder[currRounder] = gActionsByTurnOrder[roundUsers[i]]; + gProtectStructs[roundUsers[i]].quash = TRUE; // Make it so their turn order can't be changed again + currRounder++; + } + + // Update turn order for non-round users + for (i = 0; nonRoundUsers[i] != 0xFF && i < 3; i++) + { + gBattlerByTurnOrder[currRounder] = nonRoundUsers[i]; + gActionsByTurnOrder[currRounder] = gActionsByTurnOrder[nonRoundUsers[i]]; + currRounder++; + } + } +} + diff --git a/src/battle_util.c b/src/battle_util.c index c51585185..4503c9208 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -259,7 +259,7 @@ bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move) void HandleAction_UseMove(void) { u32 i, side, moveType, var = 4; - u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); + u16 moveTarget; gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; if (gBattleStruct->absentBattlerFlags & gBitTable[gBattlerAttacker] || !IsBattlerAlive(gBattlerAttacker)) @@ -323,6 +323,8 @@ void HandleAction_UseMove(void) { gCurrentMove = gBattleStruct->zmove.toBeUsed[gBattlerAttacker]; } + + moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); if (gBattleMons[gBattlerAttacker].hp != 0) { @@ -346,7 +348,7 @@ void HandleAction_UseMove(void) } else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gSideTimers[side].followmeTimer == 0 - && (gBattleMoves[gCurrentMove].power != 0 || moveTarget != MOVE_TARGET_USER) + && (gBattleMoves[gCurrentMove].power != 0 || (moveTarget != MOVE_TARGET_USER && moveTarget != MOVE_TARGET_ALL_BATTLERS)) && ((GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC) || (GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_STORM_DRAIN && moveType == TYPE_WATER))) { @@ -944,6 +946,10 @@ void HandleAction_ActionFinished(void) { u8 battler1 = gBattlerByTurnOrder[i]; u8 battler2 = gBattlerByTurnOrder[j]; + + if (gProtectStructs[battler1].quash || gProtectStructs[battler2].quash) + continue; + // We recalculate order only for action of the same priority. If any action other than switch/move has been taken, they should // have been executed before. The only recalculation needed is for moves/switch. Mega evolution is handled in src/battle_main.c/TryChangeOrder if((gActionsByTurnOrder[i] == B_ACTION_USE_MOVE && gActionsByTurnOrder[j] == B_ACTION_USE_MOVE)) @@ -2141,7 +2147,9 @@ u8 DoFieldEndTurnEffects(void) s32 j; for (j = i + 1; j < gBattlersCount; j++) { - if (GetWhoStrikesFirst(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], FALSE)) + if (!gProtectStructs[i].quash + && !gProtectStructs[j].quash + && GetWhoStrikesFirst(gBattlerByTurnOrder[i], gBattlerByTurnOrder[j], FALSE)) SwapTurnOrder(i, j); } } @@ -8689,8 +8697,14 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef) basePower *= 2; break; case EFFECT_ROUND: - if (gChosenMoveByBattler[BATTLE_PARTNER(battlerAtk)] == MOVE_ROUND && !(gAbsentBattlerFlags & gBitTable[BATTLE_PARTNER(battlerAtk)])) - basePower *= 2; + for (i = 0; i < gBattlersCount; i++) + { + if (i != battlerAtk && IsBattlerAlive(i) && gLastMoves[i] == MOVE_ROUND) + { + basePower *= 2; + break; + } + } break; case EFFECT_FUSION_COMBO: if (gBattleMoves[gLastUsedMove].effect == EFFECT_FUSION_COMBO && move != gLastUsedMove) diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index c34ad89d0..267381563 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -8914,7 +8914,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .type = TYPE_NORMAL, .accuracy = 100, .pp = 15, - .secondaryEffectChance = 0, + .secondaryEffectChance = 100, .target = MOVE_TARGET_SELECTED, .priority = 0, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SOUND, From 7885941d3c37d811dde77a56e85a1fb6f2065053 Mon Sep 17 00:00:00 2001 From: LOuroboros Date: Mon, 13 Feb 2023 19:27:52 -0300 Subject: [PATCH 53/69] Tweaked Task_HandleExpansionIntro to fix the water drops glitch Thanks to Tustin2121. --- src/expansion_intro.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/expansion_intro.c b/src/expansion_intro.c index 63bcce4e9..fa4d44601 100644 --- a/src/expansion_intro.c +++ b/src/expansion_intro.c @@ -260,6 +260,7 @@ void Task_HandleExpansionIntro(u8 taskId) break; case 3: ResetSpriteData(); + FreeAllSpritePalettes(); DestroyTask(taskId); CreateTask(Task_Scene1_Load, 0); SetMainCallback2(MainCB2_Intro); From 3f0f7c6b7f1c286bf997d62e055553c3a8e02b84 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 15 Feb 2023 15:30:29 +0100 Subject: [PATCH 54/69] Fix Battle Bond activating multiple times in battle --- include/battle.h | 1 + src/battle_script_commands.c | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/include/battle.h b/include/battle.h index 79413441c..01dc8d7e0 100644 --- a/include/battle.h +++ b/include/battle.h @@ -653,6 +653,7 @@ struct BattleStruct u8 targetsDone[MAX_BATTLERS_COUNT]; // Each battler as a bit. u16 overwrittenAbilities[MAX_BATTLERS_COUNT]; // abilities overwritten during battle (keep separate from battle history in case of switching) bool8 allowedToChangeFormInWeather[PARTY_SIZE][2]; // For each party member and side, used by Ice Face. + u8 battleBondTransformed[2]; // Bitfield for each party. }; #define F_DYNAMIC_TYPE_1 (1 << 6) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index d1c0a7c77..905bf2b61 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9851,8 +9851,10 @@ static void Cmd_various(void) case VARIOUS_TRY_ACTIVATE_BATTLE_BOND: if (gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_BATTLE_BOND && HasAttackerFaintedTarget() - && CalculateEnemyPartyCount() > 1) + && CalculateEnemyPartyCount() > 1 + && !(gBattleStruct->battleBondTransformed[GET_BATTLER_SIDE2(gBattlerAttacker)] & gBitTable[gBattlerPartyIndexes[gBattlerAttacker]])) { + gBattleStruct->battleBondTransformed[GET_BATTLER_SIDE2(gBattlerAttacker)] |= gBitTable[gBattlerPartyIndexes[gBattlerAttacker]]; PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].species); gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerAttacker]] = gBattleMons[gBattlerAttacker].species; gBattleMons[gBattlerAttacker].species = SPECIES_GRENINJA_ASH; @@ -14965,7 +14967,7 @@ static void Cmd_callnative(void) func(); } -// Callnative Funcs +// Callnative Funcs void BS_CalcMetalBurstDmg(void) { u8 sideAttacker = GetBattlerSide(gBattlerAttacker); From 9c1c59816085a8e773bc60a18382d673d698a8ff Mon Sep 17 00:00:00 2001 From: GriffinR Date: Wed, 15 Feb 2023 09:49:33 -0500 Subject: [PATCH 55/69] GROUPTYPE_NONE to unsigned --- src/wireless_communication_status_screen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wireless_communication_status_screen.c b/src/wireless_communication_status_screen.c index dc60f591d..3ce866479 100644 --- a/src/wireless_communication_status_screen.c +++ b/src/wireless_communication_status_screen.c @@ -32,7 +32,7 @@ enum { #define GROUPTYPE_BATTLE 1 #define GROUPTYPE_UNION 2 #define GROUPTYPE_TOTAL 3 -#define GROUPTYPE_NONE -1 +#define GROUPTYPE_NONE 0xFF #define NUM_GROUPTYPES 4 struct WirelessCommunicationStatusScreen @@ -382,7 +382,7 @@ static u32 CountPlayersInGroupAndGetActivity(struct RfuPlayer * player, u32 * gr for (i = 0; i < ARRAY_COUNT(sActivityGroupInfo); i++) { #ifdef UBFIX - // GROUPTYPE_NONE is -1, and shouldn't be used as an index into groupCounts. + // GROUPTYPE_NONE is 0xFF, and shouldn't be used as an index into groupCounts. // In theory the only activity with this group type (ACTIVITY_SEARCH) wouldn't // satisfy the condition below, but not necessarily. if (group_type(i) == GROUPTYPE_NONE) From e4045a7a5f4b2d8b4e83195aeafc67397625325c Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Wed, 15 Feb 2023 16:19:09 +0100 Subject: [PATCH 56/69] z move pp color (#2690) --- src/battle_message.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/battle_message.c b/src/battle_message.c index 7ec079e72..e6344d733 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -3913,8 +3913,13 @@ void SetPpNumbersPaletteInMoveSelection(void) { struct ChooseMoveStruct *chooseMoveStruct = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]); const u16 *palPtr = gPPTextPalette; - u8 var = GetCurrentPpToMaxPpState(chooseMoveStruct->currentPp[gMoveSelectionCursor[gActiveBattler]], + u8 var; + + if (!gBattleStruct->zmove.viewing) + var = GetCurrentPpToMaxPpState(chooseMoveStruct->currentPp[gMoveSelectionCursor[gActiveBattler]], chooseMoveStruct->maxPp[gMoveSelectionCursor[gActiveBattler]]); + else + var = GetCurrentPpToMaxPpState(chooseMoveStruct->currentPp[gMoveSelectionCursor[gActiveBattler]], gBattleMoves[gMoveSelectionCursor[gActiveBattler]].pp); gPlttBufferUnfaded[92] = palPtr[(var * 2) + 0]; gPlttBufferUnfaded[91] = palPtr[(var * 2) + 1]; From 94651e77a5719c96cd1e68271cb0426c13c7b049 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 15 Feb 2023 22:18:18 +0100 Subject: [PATCH 57/69] Fix Clang Scales target and effect --- data/battle_scripts_1.s | 5 +++++ src/data/battle_moves.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index c404dc37d..0deb12658 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -1283,8 +1283,13 @@ BattleScript_JungleHealingTryRestoreAlly: goto BattleScript_MoveEnd BattleScript_EffectAttackerDefenseDownHit: + @ Lower the Torchic's stat only once + jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_NO_ATTACKSTRING | HITMARKER_NO_PPDEDUCT, BattleScript_NoMoveEffect setmoveeffect MOVE_EFFECT_DEF_MINUS_1 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN goto BattleScript_EffectHit +BattleScript_NoMoveEffect: + setmoveeffect 0 + goto BattleScript_EffectHit BattleScript_EffectRelicSong: setmoveeffect MOVE_EFFECT_RELIC_SONG | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 267381563..eed91d524 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -11554,7 +11554,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = .accuracy = 100, .pp = 5, .secondaryEffectChance = 0, - .target = MOVE_TARGET_SELECTED, + .target = MOVE_TARGET_BOTH, .priority = 0, .flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SOUND, .split = SPLIT_SPECIAL, From f6a0c882d161d6668aa7e0c951affd95ccf530ae Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 15 Feb 2023 23:44:00 +0100 Subject: [PATCH 58/69] Fix Shield Down Ability pop-up --- data/battle_scripts_1.s | 52 ++++++++++++++++++------------------ src/battle_script_commands.c | 8 +++++- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index c404dc37d..617059d46 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -3174,12 +3174,12 @@ BattleScript_EffectSleep:: jumpifuproarwakes BattleScript_CantMakeAsleep jumpifability BS_TARGET, ABILITY_INSOMNIA, BattleScript_InsomniaProtects jumpifability BS_TARGET, ABILITY_VITAL_SPIRIT, BattleScript_InsomniaProtects - jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_LeafGuardProtects - jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_LeafGuardProtects + jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect + jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect jumpifflowerveil BattleScript_FlowerVeilProtects jumpifability BS_TARGET_SIDE, ABILITY_SWEET_VEIL, BattleScript_SweetVeilProtects - jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardProtects - jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects + jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect + jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed jumpifterrainaffected BS_TARGET, STATUS_FIELD_ELECTRIC_TERRAIN, BattleScript_ElectricTerrainPrevents jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents @@ -3259,15 +3259,15 @@ BattleScript_PastelVeilProtects: orhalfword gMoveResultFlags, MOVE_RESULT_FAILED goto BattleScript_MoveEnd -BattleScript_LeafGuardProtectsRet:: +BattleScript_AbilityProtectsDoesntAffectRet:: pause B_WAIT_TIME_SHORT call BattleScript_AbilityPopUp printstring STRINGID_ITDOESNTAFFECT waitmessage B_WAIT_TIME_LONG return -BattleScript_LeafGuardProtects: - call BattleScript_LeafGuardProtectsRet +BattleScript_AbilityProtectsDoesntAffect: + call BattleScript_AbilityProtectsDoesntAffectRet orhalfword gMoveResultFlags, MOVE_RESULT_FAILED goto BattleScript_MoveEnd @@ -3777,12 +3777,12 @@ BattleScript_EffectToxic:: attackstring ppreduce jumpifability BS_TARGET, ABILITY_IMMUNITY, BattleScript_ImmunityProtected - jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_LeafGuardProtects - jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_LeafGuardProtects + jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect + jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect jumpifability BS_TARGET_SIDE, ABILITY_PASTEL_VEIL, BattleScript_PastelVeilProtects jumpifflowerveil BattleScript_FlowerVeilProtects - jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardProtects - jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects + jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect + jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect jumpifsubstituteblocks BattleScript_ButItFailed jumpifstatus BS_TARGET, STATUS1_POISON | STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed @@ -4118,12 +4118,12 @@ BattleScript_EffectPoison:: attackstring ppreduce jumpifability BS_TARGET, ABILITY_IMMUNITY, BattleScript_ImmunityProtected - jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_LeafGuardProtects - jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_LeafGuardProtects + jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect + jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect jumpifability BS_TARGET_SIDE, ABILITY_PASTEL_VEIL, BattleScript_PastelVeilProtects jumpifflowerveil BattleScript_FlowerVeilProtects - jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardProtects - jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects + jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect + jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect jumpifsubstituteblocks BattleScript_ButItFailed jumpifstatus BS_TARGET, STATUS1_POISON, BattleScript_AlreadyPoisoned jumpifstatus BS_TARGET, STATUS1_TOXIC_POISON, BattleScript_AlreadyPoisoned @@ -4145,11 +4145,11 @@ BattleScript_EffectParalyze: attackstring ppreduce jumpifability BS_TARGET, ABILITY_LIMBER, BattleScript_LimberProtected - jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_LeafGuardProtects - jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_LeafGuardProtects + jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect + jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect jumpifflowerveil BattleScript_FlowerVeilProtects - jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardProtects - jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects + jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect + jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect jumpifsubstituteblocks BattleScript_ButItFailed typecalc BattleScript_BattleScript_EffectParalyzeNoTypeCalc: @@ -5581,11 +5581,11 @@ BattleScript_EffectWillOWisp:: jumpiftype BS_TARGET, TYPE_FIRE, BattleScript_NotAffected jumpifability BS_TARGET, ABILITY_WATER_VEIL, BattleScript_WaterVeilPrevents jumpifability BS_TARGET, ABILITY_WATER_BUBBLE, BattleScript_WaterVeilPrevents - jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_LeafGuardProtects - jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_LeafGuardProtects + jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_AbilityProtectsDoesntAffect + jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect jumpifflowerveil BattleScript_FlowerVeilProtects - jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardProtects - jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects + jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect + jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect jumpifstatus BS_TARGET, STATUS1_ANY, BattleScript_ButItFailed jumpifterrainaffected BS_TARGET, STATUS_FIELD_MISTY_TERRAIN, BattleScript_MistyTerrainPrevents accuracycheck BattleScript_ButItFailed, ACC_CURR_MOVE @@ -5875,10 +5875,10 @@ BattleScript_EffectYawn:: jumpifability BS_TARGET, ABILITY_VITAL_SPIRIT, BattleScript_PrintBattlerAbilityMadeIneffective jumpifability BS_TARGET, ABILITY_INSOMNIA, BattleScript_PrintBattlerAbilityMadeIneffective jumpifability BS_TARGET, ABILITY_COMATOSE, BattleScript_PrintBattlerAbilityMadeIneffective - jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_LeafGuardProtects + jumpifability BS_TARGET, ABILITY_PURIFYING_SALT, BattleScript_AbilityProtectsDoesntAffect jumpifflowerveil BattleScript_FlowerVeilProtects - jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardProtects - jumpifshieldsdown BS_TARGET, BattleScript_LeafGuardProtects + jumpifleafguardprotected BS_TARGET, BattleScript_AbilityProtectsDoesntAffect + jumpifshieldsdown BS_TARGET, BattleScript_AbilityProtectsDoesntAffect jumpifsubstituteblocks BattleScript_ButItFailed jumpifsafeguard BattleScript_SafeguardProtected accuracycheck BattleScript_ButItFailed, NO_ACC_CALC_CHECK_LOCK_ON diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index d1c0a7c77..04092d3b6 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3908,6 +3908,7 @@ static void Cmd_jumpifability(void) gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 4); RecordAbilityBattle(battlerId, gLastUsedAbility); gBattlerAbility = battlerId; + while (1); } else { @@ -8352,9 +8353,14 @@ static void Cmd_various(void) return; case VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED: if (IsShieldsDownProtected(gActiveBattler)) + { + gBattlerAbility = gActiveBattler; gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + } else + { gBattlescriptCurrInstr += 7; + } return; case VARIOUS_JUMP_IF_NO_HOLD_EFFECT: if (GetBattlerHoldEffect(gActiveBattler, TRUE) != gBattlescriptCurrInstr[3]) @@ -14965,7 +14971,7 @@ static void Cmd_callnative(void) func(); } -// Callnative Funcs +// Callnative Funcs void BS_CalcMetalBurstDmg(void) { u8 sideAttacker = GetBattlerSide(gBattlerAttacker); From 97f9c0a4d9a274000e17b6ae1b0350e4e3efb3db Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Wed, 15 Feb 2023 23:45:53 +0100 Subject: [PATCH 59/69] oof --- src/battle_script_commands.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 04092d3b6..15183c0b5 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3908,7 +3908,6 @@ static void Cmd_jumpifability(void) gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 4); RecordAbilityBattle(battlerId, gLastUsedAbility); gBattlerAbility = battlerId; - while (1); } else { From fea54c9277808c8de4c4a21078598dc9926d5d31 Mon Sep 17 00:00:00 2001 From: sbird Date: Wed, 15 Feb 2023 01:06:24 +0100 Subject: [PATCH 60/69] [intro] add fading, refactor abort, align intro gfx --- graphics/expansion_intro/rhh_credits.bin | Bin 2048 -> 2048 bytes graphics/expansion_intro/rhh_credits.png | Bin 1703 -> 1708 bytes src/expansion_intro.c | 31 ++++++++++++++++++----- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/graphics/expansion_intro/rhh_credits.bin b/graphics/expansion_intro/rhh_credits.bin index 629a2e9544af1ebc9589eb6c6fbe444fb87cad6e..44ec5e7e42e213a791b665e36f5402f490cf21cf 100644 GIT binary patch literal 2048 zcmeH@S5pE(5QIN;%>ff86fj`M958?ZOsAX?6v3SJ|Gzu8cvQ(B;KALg?WyhQuAOQy z=RYUl!9xX=D5|KYhFa>Vr-4S{3)Mt3URr3CcN^`39r*Oj$<5Jp(nU8t^x~(FegXtF zA7ViFL53J6%m|~5363+NdDkCQlS~m|ni*!9WB%8_z@pYIvCIllR#{_RaHGT@Bd&Fu zY_To1Lrl5b7kYvuyQ0}+U+{oKt#|*ousD)yag3!>*x2esD;)PJXPnE-=7LMoWVqt` vk3Y)|Ir37s+;PtXk31Fq&%E$TR@gV*`QVc;zKecm2XjmUCIOQ`ITH8*HG>;N literal 2048 zcmeIuS5I6)3_#&;Vd=g177{}5z1Jj!un;;V^xpsf8&@kpyT5=3t}RQ}%p6;D2;(yw zh)9ttDowf!nX+Wdkt_0^dGZw~RHRsm(%`%-L0Ck&3YDr~qNUgUZ-4mV zr(c%+w&G84x0=Mq#HYr{r#GhxD(Z98`D*>_+qy6;~S|KFh_$3dPrb>`fK e%LM+)wHvqY+oZ*&9^= diff --git a/graphics/expansion_intro/rhh_credits.png b/graphics/expansion_intro/rhh_credits.png index 177022a9d607fee02efd627816b253b4fa37481a..02e1dd3b6e871eec5fa91898acff1c787af20a39 100644 GIT binary patch delta 890 zcmV-=1BLvj4Xh2YKm&hQNkliTgDL+>V$C07|Te6N_8$5sNcT_t5VYa5}d z2S0MDlc962s>tpt_4T8;1t~#2*(p)oHFJ6wkP&|@)?|}4f?0uzX1A1W zC!FJ!?saCabc>zT>|-|nE_v4D|N(r<*A z;F=AL@2hcNo&cVc|IS@4G*j?kYMnp>Sl~Ojtuco>MFtsa%!8?P0tH~HP3BC~y$hfd zWX?35Doua31rQdG^3)8#rEcm>)2Z^vgRlufm=+JH69QoM3i836X*xyLK1xlQx59@tSvf8f>{8B zzA^xtjBDbT{ult3I@nH=i34C?5un@R#050XWM2jF&8&Z@$;A2Ii9LGGiqENERzl=~DnTruUddzES#~1Neo-;J(mkHe+>PXEHo( zH2)D`%ykCG;CF@Kq`tNUuzCP(m110q8F1{lQ;q|OTd$;)57PoBhB^~0E`X*KR17HeZLgI9gVF5FvH^szXYxc+u?q+ z_O_^dAK-)YPLp4N(*f}Gh0KR*1xg!FWgArR@ic(wFkbP+z$&JIx6=TwSO0c%HxT>V z)d@6jsKS4*2op{Nz{f%GL?~SG<@;^ypr$!*3!>c=gndpG`}P0Jf`1i&?wv7LGXoTJu0Zf)C zF{fg~;zM6bZye6^-6Xv)0t8Qp!5=Tv)8=TO+J>l55#iqf_+t45`0)UL0GaWSgubl8 QhX4Qo07*qoM6N<$f?7ME7XSbN delta 885 zcmV-*1B(2t4W|vTKm&hLNklYCJ4K)C1sxQ&ED!VnP;{YWSb|50W{+`mq;oe z0e0CG0bHyK&?SGD0NP?IpT+=;Y)b$>Rs)#QChTkz#)}866EQ$CHgWjFGQc_{GM%CR zO}z_Xj7PQAjCH)$DS+(9GV5mNA$TKkz+x;1>XY%-QdtLv(AbHT7(h9e0U*ip002(L z^kgxi0F_t@&~G78p8>$bWH}{8YB3zc-+{)*$})Qk;1++7Xd&qW0PrrvZoF%YvCR5J z%-o)vP&rD3{XmfRBe|OLM63>A!i}%(^H%dQW=SQJs}TSyu>*j8mTeDQ_djPkjN>OD zQ^Oaj#f|_L(U^?E9G4ahG`dXr&DzbibcP|zl>svVxV75>zUPgY z^W_1$*$;nGyw|ZFv9}&Ek@*qP_DhPKFApF?yabS_1Qbd}e+obx&Oo|OEav<+T%#`o z1Z(IGr+5hxgO2TA1Ypy?1h8_QJPFWl4qz&&AhD5(>L~yc#W_9LKv+X5KFHanVm?*} zz&X{Y0dSq^wwD3m_CuZrfUhFX@d^N()7cJu0$_iEpDu6;%pu*9!WY{?@fh*t06t}Z z06z|38%x2hV1If$fGb2_-NV@10WKGOx|$8e{&X=0hgWdD9l-ra1ius6SNBjq15g6N z_y3;?ejk89O$aMca9US*Ymc3jf=78h2_94;gbo47%AiOUCBmT8O~w^8#RcgrQGD_V z@ThIs#pwP~m`=E$T=!63$0|q|4;4KpoZ!cG=`=#34a&sn!yQVm8y9f$Q9)TYM+J?A zlazaB(}?(almdi$tgdtWADvkdwyF?92j(dQsiM)(tKbjd(*XYfni7_^82nq%00000 LNkvXXu0mjfJt3GW diff --git a/src/expansion_intro.c b/src/expansion_intro.c index fa4d44601..8fdb7c1cb 100644 --- a/src/expansion_intro.c +++ b/src/expansion_intro.c @@ -1,6 +1,5 @@ #include "global.h" #include "bg.h" -#include "clear_save_data_menu.h" #include "decompress.h" #include "palette.h" #include "sound.h" @@ -10,6 +9,7 @@ #include "trig.h" #include "main.h" #include "intro.h" +#include "m4a.h" #include "expansion_intro.h" #include "constants/rgb.h" #include "constants/songs.h" @@ -253,17 +253,34 @@ void Task_HandleExpansionIntro(u8 taskId) tState++; break; case 2: - if (tFrameCounter == 208 || gMain.newKeys != 0) + if (tFrameCounter == 208) + { tState++; + BeginNormalPaletteFade(PALETTES_ALL, 0, 0, 16, RGB_BLACK); + } + else if (gMain.newKeys != 0) + { + CpuFill16(0, gPlttBufferFaded, sizeof(gPlttBufferFaded)); + if (IsCryPlaying()) + StopCry(); + m4aSongNumStop(SE_BIKE_HOP); + m4aSongNumStop(SE_M_DOUBLE_SLAP); + tState++; + } else + { tFrameCounter++; + } break; case 3: - ResetSpriteData(); - FreeAllSpritePalettes(); - DestroyTask(taskId); - CreateTask(Task_Scene1_Load, 0); - SetMainCallback2(MainCB2_Intro); + if (!gPaletteFade.active) + { + ResetSpriteData(); + FreeAllSpritePalettes(); + DestroyTask(taskId); + CreateTask(Task_Scene1_Load, 0); + SetMainCallback2(MainCB2_Intro); + } break; } } From 1c970afd6a651f4e8e1c3929fa9c36ac14e3272b Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 16 Feb 2023 10:53:29 +0100 Subject: [PATCH 61/69] fix follow me working in singles (#2644) * fix follow me working in singles --- data/battle_scripts_1.s | 3 +++ 1 file changed, 3 insertions(+) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index c404dc37d..bfcc3dc72 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -5677,6 +5677,9 @@ BattleScript_EffectFollowMe:: attackcanceler attackstring ppreduce + .if B_UPDATED_MOVE_DATA >= GEN_6 + jumpifnotbattletype BATTLE_TYPE_DOUBLE, BattleScript_ButItFailed + .endif setforcedtarget attackanimation waitanimation From 4c18ed2bd40fb5a4672b27fb88a36cb78617a245 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 16 Feb 2023 15:11:48 +0100 Subject: [PATCH 62/69] remove comment --- data/battle_scripts_1.s | 1 - 1 file changed, 1 deletion(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 0deb12658..053ef2fc1 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -1283,7 +1283,6 @@ BattleScript_JungleHealingTryRestoreAlly: goto BattleScript_MoveEnd BattleScript_EffectAttackerDefenseDownHit: - @ Lower the Torchic's stat only once jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_NO_ATTACKSTRING | HITMARKER_NO_PPDEDUCT, BattleScript_NoMoveEffect setmoveeffect MOVE_EFFECT_DEF_MINUS_1 | MOVE_EFFECT_AFFECTS_USER | MOVE_EFFECT_CERTAIN goto BattleScript_EffectHit From 978d34295356e255eea3bcdfca18122ce97c42dd Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 16 Feb 2023 15:26:26 +0100 Subject: [PATCH 63/69] use NUM_BATTLE_SIDES --- include/battle.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/battle.h b/include/battle.h index 01dc8d7e0..764c292bf 100644 --- a/include/battle.h +++ b/include/battle.h @@ -653,7 +653,7 @@ struct BattleStruct u8 targetsDone[MAX_BATTLERS_COUNT]; // Each battler as a bit. u16 overwrittenAbilities[MAX_BATTLERS_COUNT]; // abilities overwritten during battle (keep separate from battle history in case of switching) bool8 allowedToChangeFormInWeather[PARTY_SIZE][2]; // For each party member and side, used by Ice Face. - u8 battleBondTransformed[2]; // Bitfield for each party. + u8 battleBondTransformed[NUM_BATTLE_SIDES]; // Bitfield for each party. }; #define F_DYNAMIC_TYPE_1 (1 << 6) From 0d78b29902c8595219cd211482ddf7f75692165f Mon Sep 17 00:00:00 2001 From: sbird Date: Wed, 8 Feb 2023 17:06:44 +0100 Subject: [PATCH 64/69] [test, output] display KNOWN_FAILING in yellow --- test/test_runner.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/test_runner.c b/test/test_runner.c index a10a3a89d..3cb1f7c21 100644 --- a/test/test_runner.c +++ b/test/test_runner.c @@ -187,7 +187,17 @@ void CB2_TestRunner(void) switch (gTestRunnerState.result) { - case TEST_RESULT_FAIL: result = "FAIL"; break; + case TEST_RESULT_FAIL: + if (gTestRunnerState.expectedResult == TEST_RESULT_FAIL) + { + result = "KNOWN_FAILING"; + color = "\e[33m"; + } + else + { + result = "FAIL"; + } + break; case TEST_RESULT_PASS: result = "PASS"; break; case TEST_RESULT_SKIP: result = "SKIP"; break; case TEST_RESULT_INVALID: result = "INVALID"; break; From d637ee3b133220876be0c49aa8d55a86bd2c1773 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Thu, 16 Feb 2023 21:59:36 +0100 Subject: [PATCH 65/69] Fix After You for gen8 (#2646) Fix After You --- include/battle.h | 1 + src/battle_script_commands.c | 3 ++- src/battle_util.c | 50 +++++++++++++++++++----------------- test/move_effect_after_you.c | 1 - 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/include/battle.h b/include/battle.h index 764c292bf..8be922384 100644 --- a/include/battle.h +++ b/include/battle.h @@ -191,6 +191,7 @@ struct SpecialStatus u8 weatherAbilityDone:1; u8 terrainAbilityDone:1; u8 emergencyExited:1; + u8 afterYou:1; }; struct SideTimer diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index b7adc22ae..57311e671 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9394,7 +9394,7 @@ static void Cmd_various(void) break; case VARIOUS_AFTER_YOU: if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget) - || GetBattlerTurnOrderNum(gBattlerAttacker) == GetBattlerTurnOrderNum(gBattlerTarget) + 1) + || GetBattlerTurnOrderNum(gBattlerAttacker) + 1 == GetBattlerTurnOrderNum(gBattlerTarget)) { gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); } @@ -9419,6 +9419,7 @@ static void Cmd_various(void) gBattlerByTurnOrder[2] = gBattlerTarget; gBattlerByTurnOrder[3] = data[2]; } + gSpecialStatuses[gBattlerTarget].afterYou = 1; gBattlescriptCurrInstr += 7; } return; diff --git a/src/battle_util.c b/src/battle_util.c index 4503c9208..8d350553d 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -323,7 +323,7 @@ void HandleAction_UseMove(void) { gCurrentMove = gBattleStruct->zmove.toBeUsed[gBattlerAttacker]; } - + moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); if (gBattleMons[gBattlerAttacker].hp != 0) @@ -909,9 +909,8 @@ void HandleAction_NothingIsFainted(void) void HandleAction_ActionFinished(void) { #if B_RECALC_TURN_AFTER_ACTIONS >= GEN_8 - u8 i, j; - u8 battler1 = 0; - u8 battler2 = 0; + u32 i, j; + bool32 afterYouActive = gSpecialStatuses[gBattlerByTurnOrder[gCurrentTurnActionNumber + 1]].afterYou; #endif *(gBattleStruct->monToSwitchIntoId + gBattlerByTurnOrder[gCurrentTurnActionNumber]) = PARTY_SIZE; gCurrentTurnActionNumber++; @@ -938,29 +937,32 @@ void HandleAction_ActionFinished(void) gBattleResources->battleScriptsStack->size = 0; #if B_RECALC_TURN_AFTER_ACTIONS >= GEN_8 - // i starts at `gCurrentTurnActionNumber` because we don't want to recalculate turn order for mon that have already - // taken action. It's been previously increased, which we want in order to not recalculate the turn of the mon that just finished its action - for (i = gCurrentTurnActionNumber; i < gBattlersCount - 1; i++) + if (!afterYouActive) { - for (j = i + 1; j < gBattlersCount; j++) + // i starts at `gCurrentTurnActionNumber` because we don't want to recalculate turn order for mon that have already + // taken action. It's been previously increased, which we want in order to not recalculate the turn of the mon that just finished its action + for (i = gCurrentTurnActionNumber; i < gBattlersCount - 1; i++) { - u8 battler1 = gBattlerByTurnOrder[i]; - u8 battler2 = gBattlerByTurnOrder[j]; - - if (gProtectStructs[battler1].quash || gProtectStructs[battler2].quash) - continue; - - // We recalculate order only for action of the same priority. If any action other than switch/move has been taken, they should - // have been executed before. The only recalculation needed is for moves/switch. Mega evolution is handled in src/battle_main.c/TryChangeOrder - if((gActionsByTurnOrder[i] == B_ACTION_USE_MOVE && gActionsByTurnOrder[j] == B_ACTION_USE_MOVE)) + for (j = i + 1; j < gBattlersCount; j++) { - if (GetWhoStrikesFirst(battler1, battler2, FALSE)) - SwapTurnOrder(i, j); - } - else if ((gActionsByTurnOrder[i] == B_ACTION_SWITCH && gActionsByTurnOrder[j] == B_ACTION_SWITCH)) - { - if (GetWhoStrikesFirst(battler1, battler2, TRUE)) // If the actions chosen are switching, we recalc order but ignoring the moves - SwapTurnOrder(i, j); + u8 battler1 = gBattlerByTurnOrder[i]; + u8 battler2 = gBattlerByTurnOrder[j]; + + if (gProtectStructs[battler1].quash || gProtectStructs[battler2].quash) + continue; + + // We recalculate order only for action of the same priority. If any action other than switch/move has been taken, they should + // have been executed before. The only recalculation needed is for moves/switch. Mega evolution is handled in src/battle_main.c/TryChangeOrder + if((gActionsByTurnOrder[i] == B_ACTION_USE_MOVE && gActionsByTurnOrder[j] == B_ACTION_USE_MOVE)) + { + if (GetWhoStrikesFirst(battler1, battler2, FALSE)) + SwapTurnOrder(i, j); + } + else if ((gActionsByTurnOrder[i] == B_ACTION_SWITCH && gActionsByTurnOrder[j] == B_ACTION_SWITCH)) + { + if (GetWhoStrikesFirst(battler1, battler2, TRUE)) // If the actions chosen are switching, we recalc order but ignoring the moves + SwapTurnOrder(i, j); + } } } } diff --git a/test/move_effect_after_you.c b/test/move_effect_after_you.c index 400fc053f..a488d7a8c 100644 --- a/test/move_effect_after_you.c +++ b/test/move_effect_after_you.c @@ -8,7 +8,6 @@ ASSUMPTIONS DOUBLE_BATTLE_TEST("After You makes the target move after user") { - if (B_RECALC_TURN_AFTER_ACTIONS >= GEN_8) KNOWN_FAILING; // #2615. GIVEN { PLAYER(SPECIES_WOBBUFFET) { Speed(4); } PLAYER(SPECIES_WYNAUT) { Speed(1); } From a60b179bcb656fea173f3cd6ecab311551ab6a90 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Thu, 16 Feb 2023 18:20:54 -0300 Subject: [PATCH 66/69] Incorporated fixes from upstream --- src/frontier_pass.c | 2 +- src/wireless_communication_status_screen.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontier_pass.c b/src/frontier_pass.c index 5c90d258a..07e06ad3b 100644 --- a/src/frontier_pass.c +++ b/src/frontier_pass.c @@ -35,7 +35,7 @@ // after gFrontierPassBg_Pal (by default, gFrontierPassBg_Gfx) as a palette. // Nothing uses these colors (except the Trainer Card, which correctly writes them) // so in practice this bug has no effect on the game. -#ifdef BUGFIX_ +#ifdef BUGFIX #define NUM_BG_PAL_SLOTS 8 #else #define NUM_BG_PAL_SLOTS 13 diff --git a/src/wireless_communication_status_screen.c b/src/wireless_communication_status_screen.c index d1fd20202..f80e2356e 100644 --- a/src/wireless_communication_status_screen.c +++ b/src/wireless_communication_status_screen.c @@ -392,7 +392,7 @@ static u32 CountPlayersInGroupAndGetActivity(struct RfuPlayer * player, u32 * gr for (i = 0; i < ARRAY_COUNT(sActivityGroupInfo); i++) { -#ifdef UBFIX_ +#ifdef UBFIX // GROUPTYPE_NONE is 0xFF, and shouldn't be used as an index into groupCounts. // In theory the only activity with this group type (ACTIVITY_SEARCH) wouldn't // satisfy the condition below, but not necessarily. From 0573aa455a140c07e5d66c2ba0750aa3fc69a08e Mon Sep 17 00:00:00 2001 From: Martin Griffin Date: Fri, 17 Feb 2023 09:47:13 +0000 Subject: [PATCH 67/69] Introduce macros to parse battle script arguments CMD_ARGS for regular commands, VARIOUS_ARGS for various commands, and NATIVE_ARGS for callnative commands. --- asm/macros/battle_script.inc | 894 +++++------ src/battle_script_commands.c | 2800 +++++++++++++++++++++++----------- 2 files changed, 2357 insertions(+), 1337 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 2d7bd436f..4f11fc78b 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -3,9 +3,9 @@ .byte 0x0 .endm - .macro accuracycheck failPtr:req, move:req + .macro accuracycheck failInstr:req, move:req .byte 0x1 - .4byte \failPtr + .4byte \failInstr .2byte \move .endm @@ -116,11 +116,11 @@ .4byte NULL .endm - .macro tryfaintmon_spikes battler:req, ptr:req + .macro tryfaintmon_spikes battler:req, instr:req .byte 0x19 .byte \battler .byte TRUE - .4byte \ptr + .4byte \instr .endm .macro dofaintanimation battler:req @@ -133,65 +133,65 @@ .byte \battler .endm - .macro jumpifstatus battler:req, status1:req, ptr:req + .macro jumpifstatus battler:req, flags:req, jumpInstr:req .byte 0x1c .byte \battler - .4byte \status1 - .4byte \ptr + .4byte \flags + .4byte \jumpInstr .endm - .macro jumpifstatus2 battler:req, status2:req, ptr:req + .macro jumpifstatus2 battler:req, flags:req, jumpInstr:req .byte 0x1d .byte \battler - .4byte \status2 - .4byte \ptr + .4byte \flags + .4byte \jumpInstr .endm - .macro jumpifability battler:req, ability:req, ptr:req + .macro jumpifability battler:req, ability:req, jumpInstr:req .byte 0x1e .byte \battler .2byte \ability - .4byte \ptr + .4byte \jumpInstr .endm - .macro jumpifsideaffecting battler:req, sidestatus:req, ptr:req + .macro jumpifsideaffecting battler:req, flags:req, jumpInstr:req .byte 0x1f .byte \battler - .4byte \sidestatus - .4byte \ptr + .4byte \flags + .4byte \jumpInstr .endm - .macro jumpifstat battler:req, ifflag:req, stat:req, value:req, ptr + .macro jumpifstat battler:req, comparison:req, stat:req, value:req, jumpInstr:req .byte 0x20 .byte \battler - .byte \ifflag + .byte \comparison .byte \stat .byte \value - .4byte \ptr + .4byte \jumpInstr .endm - .macro jumpifstatus3condition battler:req, status3:req, condition:req, ptr:req + .macro jumpifstatus3condition battler:req, flags:req, jumpIfTrue:req, jumpInstr:req .byte 0x21 .byte \battler - .4byte \status3 - .byte \condition - .4byte \ptr + .4byte \flags + .byte \jumpIfTrue + .4byte \jumpInstr .endm - .macro jumpbasedontype battler:req, type:req, case:req, ptr:req + .macro jumpbasedontype battler:req, type:req, jumpIfType:req, jumpInstr:req .byte 0x22 .byte \battler .byte \type - .byte \case - .4byte \ptr + .byte \jumpIfType + .4byte \jumpInstr .endm - .macro jumpiftype battler:req, type:req, ptr:req - jumpbasedontype \battler, \type, 1, \ptr + .macro jumpiftype battler:req, type:req, jumpInstr:req + jumpbasedontype \battler, \type, TRUE, \jumpInstr .endm - .macro jumpifnottype battler:req, type:req, ptr:req - jumpbasedontype \battler, \type, 0, \ptr + .macro jumpifnottype battler:req, type:req, jumpInstr:req + jumpbasedontype \battler, \type, FALSE, \jumpInstr .endm .macro getexp battler:req @@ -199,9 +199,9 @@ .byte \battler .endm - .macro checkteamslost ptr:req + .macro checkteamslost jumpInstr:req .byte 0x24 - .4byte \ptr + .4byte \jumpInstr .endm .macro movevaluescleanup @@ -213,72 +213,72 @@ .byte \value .endm - .macro decrementmultihit value:req + .macro decrementmultihit loopInstr:req .byte 0x27 - .4byte \value + .4byte \loopInstr .endm - .macro goto ptr:req + .macro goto instr:req .byte 0x28 - .4byte \ptr + .4byte \instr .endm - .macro jumpifbyte ifflag:req, val:req, byte:req, ptr:req + .macro jumpifbyte comparison:req, bytePtr:req, value:req, jumpInstr:req .byte 0x29 - .byte \ifflag - .4byte \val - .byte \byte - .4byte \ptr + .byte \comparison + .4byte \bytePtr + .byte \value + .4byte \jumpInstr .endm - .macro jumpifhalfword ifflag:req, val:req, hword:req, ptr:req + .macro jumpifhalfword comparison:req, halfwordPtr:req, value:req, jumpInstr:req .byte 0x2a - .byte \ifflag - .4byte \val - .2byte \hword - .4byte \ptr + .byte \comparison + .4byte \halfwordPtr + .2byte \value + .4byte \jumpInstr .endm - .macro jumpifword ifflag:req, val:req, word:req, ptr:req + .macro jumpifword comparison:req, wordPtr:req, value:req, jumpInstr:req .byte 0x2b - .byte \ifflag - .4byte \val - .4byte \word - .4byte \ptr + .byte \comparison + .4byte \wordPtr + .4byte \value + .4byte \jumpInstr .endm - .macro jumpifarrayequal val1:req, val2:req, size:req, ptr:req + .macro jumpifarrayequal array1:req, array2:req, size:req, jumpInstr:req .byte 0x2c - .4byte \val1 - .4byte \val2 + .4byte \array1 + .4byte \array2 .byte \size - .4byte \ptr + .4byte \jumpInstr .endm - .macro jumpifarraynotequal val1:req, val2:req, size:req, ptr:req + .macro jumpifarraynotequal array1:req, array2:req, size:req, jumpInstr:req .byte 0x2d - .4byte \val1 - .4byte \val2 + .4byte \array1 + .4byte \array2 .byte \size - .4byte \ptr + .4byte \jumpInstr .endm - .macro setbyte ptr:req, byte:req + .macro setbyte bytePtr:req, value:req .byte 0x2e - .4byte \ptr - .byte \byte + .4byte \bytePtr + .byte \value .endm - .macro addbyte ptr:req, byte:req + .macro addbyte bytePtr:req, value:req .byte 0x2f - .4byte \ptr - .byte \byte + .4byte \bytePtr + .byte \value .endm - .macro subbyte ptr:req, byte:req + .macro subbyte bytePtr:req, value:req .byte 0x30 - .4byte \ptr - .byte \byte + .4byte \bytePtr + .byte \value .endm .macro copyarray dest:req, src:req, size:req @@ -288,53 +288,53 @@ .byte \size .endm - .macro copyarraywithindex dest:req, src:req, index:req, size:req + .macro copyarraywithindex dest:req, src:req, indexPtr:req, size:req .byte 0x32 .4byte \dest .4byte \src - .4byte \index + .4byte \indexPtr .byte \size .endm - .macro orbyte ptr:req, byte:req + .macro orbyte bytePtr:req, value:req .byte 0x33 - .4byte \ptr - .byte \byte + .4byte \bytePtr + .byte \value .endm - .macro orhalfword ptr:req, hword:req + .macro orhalfword halfwordPtr:req, value:req .byte 0x34 - .4byte \ptr - .2byte \hword + .4byte \halfwordPtr + .2byte \value .endm - .macro orword ptr:req, word:req + .macro orword wordPtr:req, value:req .byte 0x35 - .4byte \ptr - .4byte \word + .4byte \wordPtr + .4byte \value .endm - .macro bicbyte ptr:req, byte:req + .macro bicbyte bytePtr:req, value:req .byte 0x36 - .4byte \ptr - .byte \byte + .4byte \bytePtr + .byte \value .endm - .macro bichalfword ptr:req, hword:req + .macro bichalfword halfwordPtr:req, value:req .byte 0x37 - .4byte \ptr - .2byte \hword + .4byte \halfwordPtr + .2byte \value .endm - .macro bicword ptr:req, word:req + .macro bicword wordPtr:req, value:req .byte 0x38 - .4byte \ptr - .4byte \word + .4byte \wordPtr + .4byte \value .endm - .macro pause time:req + .macro pause frames:req .byte 0x39 - .2byte \time + .2byte \frames .endm .macro waitstate @@ -362,53 +362,53 @@ .byte 0x3f .endm - .macro jumpifaffectedbyprotect ptr:req + .macro jumpifaffectedbyprotect failInstr:req .byte 0x40 - .4byte \ptr + .4byte \failInstr .endm - .macro call ptr:req + .macro call instr:req .byte 0x41 - .4byte \ptr + .4byte \instr .endm .macro setroost .byte 0x42 .endm - .macro jumpifabilitypresent ability:req, ptr:req + .macro jumpifabilitypresent ability:req, jumpInstr:req .byte 0x43 .2byte \ability - .4byte \ptr + .4byte \jumpInstr .endm .macro endselectionscript .byte 0x44 .endm - .macro playanimation battler:req, animType:req, arg=NULL + .macro playanimation battler:req, animId:req, argPtr=NULL .byte 0x45 .byte \battler - .byte \animType - .4byte \arg + .byte \animId + .4byte \argPtr .endm - .macro playanimation_var battler:req, animType:req, arg=NULL + .macro playanimation_var battler:req, animIdPtr:req, argPtr=NULL .byte 0x46 .byte \battler - .4byte \animType - .4byte \arg + .4byte \animIdPtr + .4byte \argPtr .endm .macro setgraphicalstatchangevalues .byte 0x47 .endm - .macro playstatchangeanimation battler:req, stats:req, statchange:req + .macro playstatchangeanimation battler:req, stats:req, flags:req .byte 0x48 .byte \battler .byte \stats - .byte \statchange + .byte \flags .endm .macro moveend endMode:req, endState:req @@ -449,9 +449,9 @@ moveend 2, \to .endm - .macro sethealblock ptr:req + .macro sethealblock failInstr:req .byte 0x4a - .4byte \ptr + .4byte \failInstr .endm .macro returnatktoball @@ -468,22 +468,22 @@ .byte \battler .endm - .macro switchinanim battler:req, dontclearsubstitutebit:req + .macro switchinanim battler:req, dontClearSubstitute:req .byte 0x4e .byte \battler - .byte \dontclearsubstitutebit + .byte \dontClearSubstitute .endm - .macro jumpifcantswitch battler:req, ptr:req + .macro jumpifcantswitch battler:req, jumpInstr:req .byte 0x4f .byte \battler - .4byte \ptr + .4byte \jumpInstr .endm - .macro openpartyscreen battler:req, ptr:req + .macro openpartyscreen battler:req, failInstr:req .byte 0x50 .byte \battler - .4byte \ptr + .4byte \failInstr .endm .macro switchhandleorder battler:req, state:req @@ -526,21 +526,21 @@ .byte \battler .endm - .macro handlelearnnewmove learnedMovePtr:req, nothingToLearnPtr:req, isFirstMove:req + .macro handlelearnnewmove learnedMoveInstr:req, nothingToLearnInstr:req, isFirstMove:req .byte 0x59 - .4byte \learnedMovePtr - .4byte \nothingToLearnPtr + .4byte \learnedMoveInstr + .4byte \nothingToLearnInstr .byte \isFirstMove .endm - .macro yesnoboxlearnmove forgotMovePtr:req + .macro yesnoboxlearnmove forgotMoveInstr:req .byte 0x5a - .4byte \forgotMovePtr + .4byte \forgotMoveInstr .endm - .macro yesnoboxstoplearningmove noPtr:req + .macro yesnoboxstoplearningmove noInstr:req .byte 0x5b - .4byte \noPtr + .4byte \noInstr .endm .macro hitanimation battler:req @@ -607,9 +607,9 @@ .byte 0x68 .endm - .macro setgravity ptr:req + .macro setgravity failInstr:req .byte 0x69 - .4byte \ptr + .4byte \failInstr .endm .macro removeitem battler:req @@ -647,9 +647,9 @@ .byte 0x71 .endm - .macro jumpifplayerran ptr:req + .macro jumpifplayerran jumpInstr:req .byte 0x72 - .4byte \ptr + .4byte \jumpInstr .endm .macro hpthresholds battler:req @@ -684,14 +684,14 @@ .byte 0x79 .endm - .macro jumpifnexttargetvalid ptr:req + .macro jumpifnexttargetvalid jumpInstr:req .byte 0x7a - .4byte \ptr + .4byte \jumpInstr .endm - .macro tryhealhalfhealth ptr:req, battler:req + .macro tryhealhalfhealth failInstr:req, battler:req .byte 0x7b - .4byte \ptr + .4byte \failInstr .byte \battler .endm @@ -716,24 +716,24 @@ .byte \mode .endm - .macro trysetrest ptr:req + .macro trysetrest failInstr:req .byte 0x81 - .4byte \ptr + .4byte \failInstr .endm - .macro jumpifnotfirstturn ptr:req + .macro jumpifnotfirstturn jumpInstr:req .byte 0x82 - .4byte \ptr + .4byte \jumpInstr .endm - .macro setmiracleeye ptr:req + .macro setmiracleeye failInstr:req .byte 0x83 - .4byte \ptr + .4byte \failInstr .endm - .macro jumpifuproarwakes ptr:req + .macro jumpifuproarwakes jumpInstr:req .byte 0x84 - .4byte \ptr + .4byte \jumpInstr .endm .macro stockpile id:req @@ -741,24 +741,24 @@ .byte \id .endm - .macro stockpiletobasedamage ptr:req + .macro stockpiletobasedamage failInstr:req .byte 0x86 - .4byte \ptr + .4byte \failInstr .endm - .macro stockpiletohpheal ptr:req + .macro stockpiletohpheal failInstr:req .byte 0x87 - .4byte \ptr + .4byte \failInstr .endm .macro setdrainedhp .byte 0x88 .endm - .macro statbuffchange flags:req, jumpptr:req + .macro statbuffchange flags:req, failInstr:req .byte 0x89 .2byte \flags - .4byte \jumpptr + .4byte \failInstr .endm .macro normalisebuffs @@ -773,23 +773,23 @@ .byte 0x8c .endm - .macro setmultihitcounter val:req + .macro setmultihitcounter value:req .byte 0x8d - .byte \val + .byte \value .endm .macro initmultihitstring .byte 0x8e .endm - .macro forcerandomswitch ptr:req + .macro forcerandomswitch failInstr:req .byte 0x8f - .4byte \ptr + .4byte \failInstr .endm - .macro tryconversiontypechange ptr:req + .macro tryconversiontypechange failInstr:req .byte 0x90 - .4byte \ptr + .4byte \failInstr .endm .macro givepaydaymoney @@ -800,9 +800,9 @@ .byte 0x92 .endm - .macro tryKO ptr:req + .macro tryKO failInstr:req .byte 0x93 - .4byte \ptr + .4byte \failInstr .endm .macro damagetohalftargethp @@ -817,9 +817,9 @@ .byte 0x96 .endm - .macro tryinfatuating ptr:req + .macro tryinfatuating failInstr:req .byte 0x97 - .4byte \ptr + .4byte \failInstr .endm .macro updatestatusicon battler:req @@ -843,9 +843,9 @@ .byte 0x9c .endm - .macro mimicattackcopy ptr:req + .macro mimicattackcopy failInstr:req .byte 0x9d - .4byte \ptr + .4byte \failInstr .endm .macro metronome @@ -860,48 +860,48 @@ .byte 0xa0 .endm - .macro counterdamagecalculator ptr:req + .macro counterdamagecalculator failInstr:req .byte 0xa1 - .4byte \ptr + .4byte \failInstr .endm - .macro mirrorcoatdamagecalculator ptr:req + .macro mirrorcoatdamagecalculator failInstr:req .byte 0xa2 - .4byte \ptr + .4byte \failInstr .endm - .macro disablelastusedattack ptr:req + .macro disablelastusedattack failInstr:req .byte 0xa3 - .4byte \ptr + .4byte \failInstr .endm - .macro trysetencore ptr:req + .macro trysetencore failInstr:req .byte 0xa4 - .4byte \ptr + .4byte \failInstr .endm - .macro painsplitdmgcalc ptr:req + .macro painsplitdmgcalc failInstr:req .byte 0xa5 - .4byte \ptr + .4byte \failInstr .endm - .macro settypetorandomresistance ptr:req + .macro settypetorandomresistance failInstr:req .byte 0xa6 - .4byte \ptr + .4byte \failInstr .endm .macro setalwayshitflag .byte 0xa7 .endm - .macro copymovepermanently ptr:req + .macro copymovepermanently failInstr:req .byte 0xa8 - .4byte \ptr + .4byte \failInstr .endm - .macro trychoosesleeptalkmove ptr:req + .macro trychoosesleeptalkmove failInstr:req .byte 0xa9 - .4byte \ptr + .4byte \failInstr .endm .macro setdestinybond @@ -912,56 +912,56 @@ .byte 0xab .endm - .macro settailwind ptr:req + .macro settailwind failInstr:req .byte 0xac - .4byte \ptr + .4byte \failInstr .endm - .macro tryspiteppreduce ptr:req + .macro tryspiteppreduce failInstr:req .byte 0xad - .4byte \ptr + .4byte \failInstr .endm .macro healpartystatus .byte 0xae .endm - .macro cursetarget ptr:req + .macro cursetarget failInstr:req .byte 0xaf - .4byte \ptr + .4byte \failInstr .endm - .macro trysetspikes ptr:req + .macro trysetspikes failInstr:req .byte 0xb0 - .4byte \ptr + .4byte \failInstr .endm .macro setforesight .byte 0xb1 .endm - .macro trysetperishsong ptr:req + .macro trysetperishsong failInstr:req .byte 0xb2 - .4byte \ptr + .4byte \failInstr .endm .macro handlerollout .byte 0xb3 .endm - .macro jumpifconfusedandstatmaxed stat:req, ptr:req + .macro jumpifconfusedandstatmaxed stat:req, jumpInstr:req .byte 0xb4 .byte \stat - .4byte \ptr + .4byte \jumpInstr .endm .macro handlefurycutter .byte 0xb5 .endm - .macro setembargo ptr:req + .macro setembargo failInstr:req .byte 0xb6 - .4byte \ptr + .4byte \failInstr .endm .macro presentdamagecalculation @@ -976,23 +976,23 @@ .byte 0xb9 .endm - .macro jumpifnopursuitswitchdmg ptr:req + .macro jumpifnopursuitswitchdmg jumpInstr:req .byte 0xba - .4byte \ptr + .4byte \jumpInstr .endm .macro setsunny .byte 0xbb .endm - .macro maxattackhalvehp ptr:req + .macro maxattackhalvehp failInstr:req .byte 0xbc - .4byte \ptr + .4byte \failInstr .endm - .macro copyfoestats ptr:req + .macro copyfoestats unused:req .byte 0xbd - .4byte \ptr + .4byte \unused .endm .macro rapidspinfree @@ -1003,29 +1003,29 @@ .byte 0xbf .endm - .macro recoverbasedonsunlight ptr:req + .macro recoverbasedonsunlight failInstr:req .byte 0xc0 - .4byte \ptr + .4byte \failInstr .endm - .macro setstickyweb ptr:req + .macro setstickyweb failInstr:req .byte 0xc1 - .4byte \ptr + .4byte \failInstr .endm .macro selectfirstvalidtarget .byte 0xc2 .endm - .macro trysetfutureattack ptr:req + .macro trysetfutureattack failInstr:req .byte 0xc3 - .4byte \ptr + .4byte \failInstr .endm - .macro trydobeatup endPtr=NULL, failPtr=NULL + .macro trydobeatup endInstr, failInstr .byte 0xc4 - .4byte \endPtr - .4byte \failPtr + .4byte \endInstr + .4byte \failInstr .endm .macro setsemiinvulnerablebit @@ -1044,9 +1044,9 @@ .byte 0xc8 .endm - .macro trymemento ptr:req + .macro trymemento failInstr:req .byte 0xc9 - .4byte \ptr + .4byte \failInstr .endm .macro setforcedtarget @@ -1061,105 +1061,105 @@ .byte 0xcc .endm - .macro cureifburnedparalysedorpoisoned ptr:req + .macro cureifburnedparalysedorpoisoned failInstr:req .byte 0xcd - .4byte \ptr + .4byte \failInstr .endm - .macro settorment ptr:req + .macro settorment failInstr:req .byte 0xce - .4byte \ptr + .4byte \failInstr .endm - .macro jumpifnodamage ptr:req + .macro jumpifnodamage jumpInstr:req .byte 0xcf - .4byte \ptr + .4byte \jumpInstr .endm - .macro settaunt ptr:req + .macro settaunt failInstr:req .byte 0xd0 - .4byte \ptr + .4byte \failInstr .endm - .macro trysethelpinghand ptr:req + .macro trysethelpinghand failInstr:req .byte 0xd1 - .4byte \ptr + .4byte \failInstr .endm - .macro tryswapitems ptr:req + .macro tryswapitems failInstr:req .byte 0xd2 - .4byte \ptr + .4byte \failInstr .endm - .macro trycopyability ptr:req + .macro trycopyability failInstr:req .byte 0xd3 - .4byte \ptr + .4byte \failInstr .endm - .macro trywish turnNumber:req, ptr:req + .macro trywish turnNumber:req, failInstr:req .byte 0xd4 .byte \turnNumber - .4byte \ptr + .4byte \failInstr .endm - .macro settoxicspikes ptr:req + .macro settoxicspikes failInstr:req .byte 0xd5 - .4byte \ptr + .4byte \failInstr .endm - .macro setgastroacid ptr:req + .macro setgastroacid failInstr:req .byte 0xd6 - .4byte \ptr + .4byte \failInstr .endm - .macro setyawn ptr:req + .macro setyawn failInstr:req .byte 0xd7 - .4byte \ptr + .4byte \failInstr .endm - .macro setdamagetohealthdifference ptr:req + .macro setdamagetohealthdifference failInstr:req .byte 0xd8 - .4byte \ptr + .4byte \failInstr .endm .macro setroom .byte 0xd9 .endm - .macro tryswapabilities ptr:req + .macro tryswapabilities failInstr:req .byte 0xda - .4byte \ptr + .4byte \failInstr .endm - .macro tryimprison ptr:req + .macro tryimprison failInstr:req .byte 0xdb - .4byte \ptr + .4byte \failInstr .endm - .macro setstealthrock ptr:req + .macro setstealthrock failInstr:req .byte 0xdc - .4byte \ptr + .4byte \failInstr .endm - .macro setuserstatus3 flags:req, ptr:req + .macro setuserstatus3 flags:req, failInstr:req .byte 0xdd .4byte \flags - .4byte \ptr + .4byte \failInstr .endm - .macro assistattackselect ptr:req + .macro assistattackselect failInstr:req .byte 0xde - .4byte \ptr + .4byte \failInstr .endm - .macro trysetmagiccoat ptr:req + .macro trysetmagiccoat failInstr:req .byte 0xdf - .4byte \ptr + .4byte \failInstr .endm - .macro trysetsnatch ptr:req + .macro trysetsnatch failInstr:req .byte 0xe0 - .4byte \ptr + .4byte \failInstr .endm .macro unused2 ptr:req @@ -1172,10 +1172,10 @@ .byte \battler .endm - .macro jumpifhasnohp battler:req, ptr:req + .macro jumpifhasnohp battler:req, jumpInstr:req .byte 0xe3 .byte \battler - .4byte \ptr + .4byte \jumpInstr .endm .macro getsecretpowereffect @@ -1194,29 +1194,29 @@ .byte 0xe7 .endm - .macro settypebasedhalvers ptr:req + .macro settypebasedhalvers failInstr:req .byte 0xe8 - .4byte \ptr + .4byte \failInstr .endm - .macro jumpifsubstituteblocks ptr:req + .macro jumpifsubstituteblocks jumpInstr:req .byte 0xe9 - .4byte \ptr + .4byte \jumpInstr .endm - .macro tryrecycleitem ptr:req + .macro tryrecycleitem failInstr:req .byte 0xea - .4byte \ptr + .4byte \failInstr .endm - .macro settypetoterrain ptr:req + .macro settypetoterrain failInstr:req .byte 0xeb - .4byte \ptr + .4byte \failInstr .endm - .macro pursuitdoubles ptr:req + .macro pursuitdoubles failInstr:req .byte 0xec - .4byte \ptr + .4byte \failInstr .endm .macro snatchsetbattlers @@ -1235,18 +1235,18 @@ .byte 0xf0 .endm - .macro trysetcaughtmondexflags ptr:req + .macro trysetcaughtmondexflags failInstr:req .byte 0xf1 - .4byte \ptr + .4byte \failInstr .endm .macro displaydexinfo .byte 0xf2 .endm - .macro trygivecaughtmonnick ptr:req + .macro trygivecaughtmonnick successInstr:req .byte 0xf3 - .4byte \ptr + .4byte \successInstr .endm .macro subattackerhpbydmg @@ -1270,9 +1270,9 @@ .byte \position .endm - .macro settelekinesis ptr:req + .macro settelekinesis failInstr:req .byte 0xf9 - .4byte \ptr + .4byte \failInstr .endm .macro swapstatstages stat:req @@ -1285,9 +1285,9 @@ .byte \stat .endm - .macro jumpifoppositegenders ptr:req + .macro jumpifoppositegenders jumpInstr:req .byte 0xfc - .4byte \ptr + .4byte \jumpInstr .endm .macro unused ptr:req @@ -1295,9 +1295,9 @@ .4byte \ptr .endm - .macro tryworryseed ptr:req + .macro tryworryseed failInstr:req .byte 0xfe - .4byte \ptr + .4byte \failInstr .endm .macro callnative func:req @@ -1306,16 +1306,16 @@ .endm @ callnative macros - .macro metalburstdamagecalculator ptr:req + .macro metalburstdamagecalculator failInstr:req callnative BS_CalcMetalBurstDmg - .4byte \ptr + .4byte \failInstr .endm - .macro jumpifholdeffect battler:req, holdEffect:req, ptr:req + .macro jumpifholdeffect battler:req, holdEffect:req, jumpInstr:req callnative BS_JumpIfHoldEffect .byte \battler .2byte \holdEffect - .4byte \ptr + .4byte \jumpInstr .endm @ various command changed to more readable macros @@ -1480,82 +1480,82 @@ .2byte \move .endm - .macro setluckychant battler:req, ptr:req + .macro setluckychant battler:req, failInstr:req various \battler VARIOUS_SET_LUCKY_CHANT - .4byte \ptr + .4byte \failInstr .endm - .macro suckerpunchcheck ptr:req + .macro suckerpunchcheck failInstr:req various BS_ATTACKER, VARIOUS_SUCKER_PUNCH_CHECK - .4byte \ptr + .4byte \failInstr .endm - .macro setabilitysimple battler:req, ptr:req + .macro setabilitysimple battler:req, failInstr:req various \battler VARIOUS_SET_SIMPLE_BEAM - .4byte \ptr + .4byte \failInstr .endm - .macro tryentrainment ptr:req + .macro tryentrainment failInstr:req various BS_ATTACKER, VARIOUS_TRY_ENTRAINMENT - .4byte \ptr + .4byte \failInstr .endm .macro setlastusedability battler:req various \battler, VARIOUS_SET_LAST_USED_ABILITY .endm - .macro tryhealpulse battler:req, ptr:req + .macro tryhealpulse battler:req, failInstr:req various \battler, VARIOUS_TRY_HEAL_PULSE - .4byte \ptr + .4byte \failInstr .endm - .macro tryquash ptr:req + .macro tryquash failInstr:req various BS_ATTACKER, VARIOUS_TRY_QUASH - .4byte \ptr + .4byte \failInstr .endm - .macro tryafteryou ptr:req + .macro tryafteryou failInstr:req various BS_ATTACKER, VARIOUS_AFTER_YOU - .4byte \ptr + .4byte \failInstr .endm - .macro trybestow ptr:req + .macro trybestow failInstr:req various BS_ATTACKER, VARIOUS_BESTOW - .4byte \ptr + .4byte \failInstr .endm .macro invertstatstages battler:req various \battler, VARIOUS_INVERT_STAT_STAGES .endm - .macro setterrain ptr:req + .macro setterrain failInstr:req various BS_ATTACKER, VARIOUS_SET_TERRAIN - .4byte \ptr + .4byte \failInstr .endm - .macro trymefirst ptr:req + .macro trymefirst failInstr:req various BS_ATTACKER, VARIOUS_TRY_ME_FIRST - .4byte \ptr + .4byte \failInstr .endm - .macro jumpifbattleend ptr:req + .macro jumpifbattleend jumpInstr:req various BS_ATTACKER, VARIOUS_JUMP_IF_BATTLE_END - .4byte \ptr + .4byte \jumpInstr .endm - .macro tryelectrify ptr:req + .macro tryelectrify failInstr:req various BS_ATTACKER, VARIOUS_TRY_ELECTRIFY - .4byte \ptr + .4byte \failInstr .endm - .macro tryreflecttype ptr:req + .macro tryreflecttype failInstr:req various BS_ATTACKER, VARIOUS_TRY_REFLECT_TYPE - .4byte \ptr + .4byte \failInstr .endm - .macro trysoak ptr:req + .macro trysoak failInstr:req various BS_ATTACKER, VARIOUS_TRY_SOAK - .4byte \ptr + .4byte \failInstr .endm .macro handlemegaevo battler:req, case:req @@ -1573,33 +1573,33 @@ .byte \case .endm - .macro jumpifcantuselastresort battler:req, ptr:req + .macro jumpifcantuselastresort battler:req, jumpInstr:req various \battler, VARIOUS_TRY_LAST_RESORT - .4byte \ptr + .4byte \jumpInstr .endm .macro argumentstatuseffect various BS_ATTACKER, VARIOUS_ARGUMENT_STATUS_EFFECT .endm - .macro tryhitswitchtarget ptr:req + .macro tryhitswitchtarget failInstr:req various BS_ATTACKER, VARIOUS_TRY_HIT_SWITCH_TARGET - .4byte \ptr + .4byte \failInstr .endm - .macro tryautotomize battler:req, ptr:req + .macro tryautotomize battler:req, failInstr:req various \battler, VARIOUS_TRY_AUTOTOMIZE - .4byte \ptr + .4byte \failInstr .endm - .macro jumpifcantusesynchronoise ptr:req + .macro jumpifcantusesynchronoise jumpInstr:req various BS_ATTACKER, VARIOUS_TRY_SYNCHRONOISE - .4byte \ptr + .4byte \jumpInstr .endm - .macro trycopycat ptr:req + .macro trycopycat failInstr:req various BS_ATTACKER, VARIOUS_TRY_COPYCAT - .4byte \ptr + .4byte \failInstr .endm .macro showabilitypopup battler:req @@ -1610,20 +1610,20 @@ various \battler, VARIOUS_UPDATE_ABILITY_POPUP .endm - .macro defogclear battler:req, clear:req, ptr:req + .macro defogclear battler:req, clear:req, failInstr:req various \battler, VARIOUS_DEFOG .byte \clear - .4byte \ptr + .4byte \failInstr .endm - .macro jumpiftargetally ptr:req + .macro jumpiftargetally jumpInstr:req various BS_ATTACKER, VARIOUS_JUMP_IF_TARGET_ALLY - .4byte \ptr + .4byte \jumpInstr .endm - .macro trypsychoshift ptr:req + .macro trypsychoshift failInstr:req various BS_ATTACKER, VARIOUS_PSYCHO_SHIFT - .4byte \ptr + .4byte \failInstr .endm .macro curestatus battler:req @@ -1638,14 +1638,14 @@ various BS_ATTACKER, VARIOUS_ARGUMENT_TO_MOVE_EFFECT .endm - .macro jumpifnotgrounded battler:req, ptr:req + .macro jumpifnotgrounded battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_NOT_GROUNDED - .4byte \ptr + .4byte \jumpInstr .endm - .macro handletrainerslidemsg battler:req, field:req + .macro handletrainerslidemsg battler:req, case:req various \battler, VARIOUS_HANDLE_TRAINER_SLIDE_MSG - .byte \field + .byte \case .endm .macro trytrainerslidefirstdownmsg battler:req @@ -1660,14 +1660,14 @@ various \battler, VARIOUS_SET_AURORA_VEIL .endm - .macro trysetthirdtype battler:req, ptr:req + .macro trysetthirdtype battler:req, failInstr:req various \battler, VARIOUS_TRY_THIRD_TYPE - .4byte \ptr + .4byte \failInstr .endm - .macro tryaccupressure battler:req, ptr:req + .macro tryaccupressure battler:req, failInstr:req various \battler, VARIOUS_ACUPRESSURE - .4byte \ptr + .4byte \failInstr .endm .macro setpowder battler:req @@ -1682,24 +1682,24 @@ various \battler, VARIOUS_GRAVITY_ON_AIRBORNE_MONS .endm - .macro checkgrassyterrainheal battler:req, ptr:req + .macro checkgrassyterrainheal battler:req, failInstr:req various \battler, VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS - .4byte \ptr + .4byte \failInstr .endm - .macro jumpifnotberry battler:req, ptr:req + .macro jumpifnotberry battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_NOT_BERRY - .4byte \ptr + .4byte \jumpInstr .endm - .macro jumpifroarfails ptr:req + .macro jumpifroarfails jumpInstr:req various BS_ATTACKER, VARIOUS_JUMP_IF_ROAR_FAILS - .4byte \ptr + .4byte \jumpInstr .endm - .macro tryinstruct ptr:req + .macro tryinstruct failInstr:req various BS_ATTACKER, VARIOUS_TRY_INSTRUCT - .4byte \ptr + .4byte \failInstr .endm .macro settracedability battler:req @@ -1714,19 +1714,19 @@ various \battler, VARIOUS_TRY_ILLUSION_OFF .endm - .macro spriteignore0hp val:req + .macro spriteignore0hp value:req various BS_ATTACKER, VARIOUS_SET_SPRITEIGNORE0HP - .byte \val + .byte \value .endm - .macro getstatvalue battler:req, statId:req + .macro getstatvalue battler:req, stat:req various \battler, VARIOUS_GET_STAT_VALUE - .byte \statId + .byte \stat .endm - .macro jumpiffullhp battler:req, ptr:req + .macro jumpiffullhp battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_FULL_HP - .4byte \ptr + .4byte \jumpInstr .endm .macro losetype battler:req, type:req @@ -1738,60 +1738,60 @@ various \battler, VARIOUS_TRY_FRISK .endm - .macro jumpifshieldsdown battler:req, ptr:req + .macro jumpifshieldsdown battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED - .4byte \ptr + .4byte \jumpInstr .endm - .macro trypoisontype attacker:req, target:req, ptr:req + .macro trypoisontype attacker:req, target:req, failInstr:req various \attacker, VARIOUS_POISON_TYPE_IMMUNITY .byte \target - .4byte \ptr + .4byte \failInstr .endm - .macro tryparalyzetype attacker:req, target:req, ptr:req + .macro tryparalyzetype attacker:req, target:req, failInstr:req various \attacker, VARIOUS_PARALYZE_TYPE_IMMUNITY .byte \target - .4byte \ptr + .4byte \failInstr .endm - .macro trysetfairylock ptr:req + .macro trysetfairylock failInstr:req various BS_ATTACKER, VARIOUS_TRY_FAIRY_LOCK - .4byte \ptr + .4byte \failInstr .endm - .macro jumpifnoally battler:req, ptr:req + .macro jumpifnoally battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_NO_ALLY - .4byte \ptr + .4byte \jumpInstr .endm - .macro jumpifnoholdeffect battler:req, holdEffet:req, ptr:req + .macro jumpifnoholdeffect battler:req, holdEffect:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_NO_HOLD_EFFECT - .byte \holdEffet - .4byte \ptr + .byte \holdEffect + .4byte \jumpInstr .endm - .macro infatuatewithbattler battler1:req, battler2:req - various \battler1, VARIOUS_INFATUATE_WITH_BATTLER - .byte \battler2 + .macro infatuatewithbattler battler:req, infatuateWith:req + various \battler, VARIOUS_INFATUATE_WITH_BATTLER + .byte \infatuateWith .endm .macro setlastuseditem battler:req various \battler, VARIOUS_SET_LAST_USED_ITEM .endm - .macro jumpifabsent battler:req, ptr:req + .macro jumpifabsent battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_ABSENT - .4byte \ptr + .4byte \jumpInstr .endm .macro destroyabilitypopup various BS_ABILITY_BATTLER, VARIOUS_DESTROY_ABILITY_POPUP .endm - .macro gettotemboost ptr:req + .macro gettotemboost jumpInstr:req various BS_ATTACKER, VARIOUS_TOTEM_BOOST - .4byte \ptr + .4byte \jumpInstr .endm .macro tryactivategrimneigh, battler:req @@ -1802,9 +1802,9 @@ various BS_ATTACKER, VARIOUS_SET_Z_EFFECT .endm - .macro consumeberry battler:req, frombattler:req + .macro consumeberry battler:req, fromBattler:req various \battler, VARIOUS_CONSUME_BERRY - .byte \frombattler + .byte \fromBattler .endm .macro activateitemeffects battler:req @@ -1815,44 +1815,44 @@ various 0, VARIOUS_PICKPOCKET .endm - .macro doterrainseed battler:req, ptr:req + .macro doterrainseed battler:req, failInstr:req various \battler, VARIOUS_TERRAIN_SEED - .4byte \ptr + .4byte \failInstr .endm .macro makeinvisible battler:req various \battler, VARIOUS_MAKE_INVISIBLE .endm - .macro tryroomservice battler:req, ptr:req + .macro tryroomservice battler:req, failInstr:req various \battler, VARIOUS_ROOM_SERVICE - .4byte \ptr + .4byte \failInstr .endm - .macro jumpifterrainaffected battler:req, terrainFlags:req, ptr:req + .macro jumpifterrainaffected battler:req, terrainFlags:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_TERRAIN_AFFECTED .4byte \terrainFlags - .4byte \ptr + .4byte \jumpInstr .endm - .macro jumpifpranksterblocked battler:req, ptr:req + .macro jumpifpranksterblocked battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_PRANKSTER_BLOCKED - .4byte \ptr + .4byte \jumpInstr .endm - .macro eeriespellppreduce ptr:req + .macro eeriespellppreduce failInstr:req various BS_TARGET, VARIOUS_EERIE_SPELL_PP_REDUCE - .4byte \ptr + .4byte \failInstr .endm - .macro jumpifteamhealthy battler:req, ptr:req + .macro jumpifteamhealthy battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_TEAM_HEALTHY - .4byte \ptr + .4byte \jumpInstr .endm - .macro tryhealquarterhealth battler:req, ptr:req + .macro tryhealquarterhealth battler:req, failInstr:req various \battler, VARIOUS_TRY_HEAL_QUARTER_HP - .4byte \ptr + .4byte \failInstr .endm .macro removeterrain @@ -1867,73 +1867,73 @@ various BS_TARGET, VARIOUS_SET_ATTACKER_STICKY_WEB_USER .endm - .macro getrototillertargets ptr:req + .macro getrototillertargets failInstr:req various BS_ATTACKER, VARIOUS_GET_ROTOTILLER_TARGETS - .4byte \ptr + .4byte \failInstr .endm - .macro jumpifnotrototilleraffected battler:req, ptr:req + .macro jumpifnotrototilleraffected battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED - .4byte \ptr + .4byte \jumpInstr .endm .macro tryactivatebattlebond battler:req various \battler, VARIOUS_TRY_ACTIVATE_BATTLE_BOND .endm - .macro jumpifcantreverttoprimal ptr:req + .macro jumpifcantreverttoprimal jumpInstr:req various BS_ATTACKER, VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL - .4byte \ptr + .4byte \jumpInstr .endm .macro applyplasmafists various BS_ATTACKER, VARIOUS_APPLY_PLASMA_FISTS .endm - .macro jumpifweatheraffected battler:req, weather:req, ptr:req + .macro jumpifweatheraffected battler:req, flags:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_WEATHER_AFFECTED - .4byte \weather - .4byte \ptr + .4byte \flags + .4byte \jumpInstr .endm - .macro jumpifspecies battler:req, species:req, ptr:req + .macro jumpifspecies battler:req, species:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_SPECIES .2byte \species - .4byte \ptr + .4byte \jumpInstr .endm .macro tryendneutralizinggas battler:req various \battler, VARIOUS_TRY_END_NEUTRALIZING_GAS .endm - .macro trynoretreat battler:req, ptr:req + .macro trynoretreat battler:req, failInstr:req various \battler, VARIOUS_TRY_NO_RETREAT - .4byte \ptr + .4byte \failInstr .endm - .macro trytarshot battler:req, ptr:req + .macro trytarshot battler:req, failInstr:req various \battler, VARIOUS_TRY_TAR_SHOT - .4byte \ptr + .4byte \failInstr .endm - .macro cantarshotwork battler:req, ptr:req + .macro cantarshotwork battler:req, failInstr:req various \battler, VARIOUS_CAN_TAR_SHOT_WORK - .4byte \ptr + .4byte \failInstr .endm - .macro checkpoltergeist battler:req, ptr:req + .macro checkpoltergeist battler:req, failInstr:req various \battler, VARIOUS_CHECK_POLTERGEIST - .4byte \ptr + .4byte \failInstr .endm - .macro setoctolock battler:req, ptr:req + .macro setoctolock battler:req, failInstr:req various \battler, VARIOUS_SET_OCTOLOCK - .4byte \ptr + .4byte \failInstr .endm - .macro cutonethirdhpraisestats ptr:req + .macro cutonethirdhpraisestats failInstr:req various BS_ATTACKER, VARIOUS_CUT_1_3_HP_RAISE_STATS - .4byte \ptr + .4byte \failInstr .endm .macro photongeysercheck battler:req @@ -1944,34 +1944,34 @@ various BS_ATTACKER, VARIOUS_SHELL_SIDE_ARM_CHECK .endm - .macro jumpifrodaffected battler:req, ptr:req + .macro jumpifrodaffected battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_ROD - .4byte \ptr + .4byte \jumpInstr .endm - .macro jumpifabsorbaffected battler:req, ptr:req + .macro jumpifabsorbaffected battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_ABSORB - .4byte \ptr + .4byte \jumpInstr .endm - .macro jumpifmotoraffected battler:req, ptr:req + .macro jumpifmotoraffected battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_MOTOR - .4byte \ptr + .4byte \jumpInstr .endm - .macro jumpifteanoberry ptr:req + .macro jumpifteanoberry jumpInstr:req various BS_ATTACKER, VARIOUS_TEATIME_TARGETS - .4byte \ptr + .4byte \jumpInstr .endm - .macro jumpifteainvulnerable battler:req, ptr:req + .macro jumpifteainvulnerable battler:req, jumpInstr:req various \battler, VARIOUS_TEATIME_INVUL - .4byte \ptr + .4byte \jumpInstr .endm - .macro jumpifcantfling battler:req, ptr:req + .macro jumpifcantfling battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_CANT_FLING - .4byte \ptr + .4byte \jumpInstr .endm .macro curecertainstatuses battler:req @@ -1982,15 +1982,15 @@ various \battler, VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES .endm - .macro jumpiflastuseditemberry ptr:req + .macro jumpiflastuseditemberry jumpInstr:req various BS_ATTACKER, VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY - .4byte \ptr + .4byte \jumpInstr .endm - .macro jumpiflastuseditemholdeffect battler:req, holdEffect:req, ptr:req + .macro jumpiflastuseditemholdeffect battler:req, holdEffect:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT .byte \holdEffect - .4byte \ptr + .4byte \jumpInstr .endm .macro savebattleritem battler:req @@ -2021,19 +2021,19 @@ various \battler, VARIOUS_GET_BATTLER_SIDE .endm - .macro checkparentalbondcounter counter:req, ptr:req + .macro checkparentalbondcounter counter:req, jumpInstr:req various BS_ATTACKER, VARIOUS_CHECK_PARENTAL_BOND_COUNTER .byte \counter - .4byte \ptr + .4byte \jumpInstr .endm .macro swapstats stat:req various BS_ATTACKER, VARIOUS_SWAP_STATS .byte \stat .endm - .macro trywindriderpower battler:req, ptr:req + .macro trywindriderpower battler:req, failInstr:req various \battler, VARIOUS_TRY_WIND_RIDER_POWER - .4byte \ptr + .4byte \failInstr .endm .macro activateweatherchangeabilities battler:req @@ -2044,9 +2044,9 @@ various \battler, VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES .endm - .macro jumpifnovalidtargets ptr:req + .macro jumpifnovalidtargets jumpInstr:req various BS_ATTACKER, VARIOUS_JUMP_IF_NO_VALID_TARGETS - .4byte \ptr + .4byte \jumpInstr .endm @ helpful macros @@ -2091,44 +2091,44 @@ copyarray \dst, \src, 0x4 .endm - .macro jumpifbytenotequal byte1:req, byte2:req, jumpptr:req - jumpifarraynotequal \byte1, \byte2, 0x1, \jumpptr + .macro jumpifbytenotequal byte1:req, byte2:req, jumpInstr:req + jumpifarraynotequal \byte1, \byte2, 0x1, \jumpInstr .endm - .macro jumpifbyteequal byte1:req, byte2:req, jumpptr:req - jumpifarrayequal \byte1, \byte2, 0x1, \jumpptr + .macro jumpifbyteequal byte1:req, byte2:req, jumpInstr:req + jumpifarrayequal \byte1, \byte2, 0x1, \jumpInstr .endm - .macro jumpifmove move:req, jumpptr:req - jumpifhalfword CMP_EQUAL, gCurrentMove, \move, \jumpptr + .macro jumpifmove move:req, jumpInstr:req + jumpifhalfword CMP_EQUAL, gCurrentMove, \move, \jumpInstr .endm - .macro jumpifnotmove move:req, jumpptr:req - jumpifhalfword CMP_NOT_EQUAL, gCurrentMove, \move, \jumpptr + .macro jumpifnotmove move:req, jumpInstr:req + jumpifhalfword CMP_NOT_EQUAL, gCurrentMove, \move, \jumpInstr .endm - .macro jumpifnotchosenmove move:req, jumpptr:req - jumpifhalfword CMP_NOT_EQUAL, gChosenMove, \move, \jumpptr + .macro jumpifnotchosenmove move:req, jumpInstr:req + jumpifhalfword CMP_NOT_EQUAL, gChosenMove, \move, \jumpInstr .endm - .macro jumpifstatus3 battler:req, status:req, jumpptr:req - jumpifstatus3condition \battler, \status, FALSE, \jumpptr + .macro jumpifstatus3 battler:req, flags:req, jumpInstr:req + jumpifstatus3condition \battler, \flags, FALSE, \jumpInstr .endm - .macro jumpifnostatus3 battler:req, status:req, jumpptr:req - jumpifstatus3condition \battler, \status, TRUE, \jumpptr + .macro jumpifnostatus3 battler:req, flags:req, jumpInstr:req + jumpifstatus3condition \battler, \flags, TRUE, \jumpInstr .endm - .macro jumpifmovehadnoeffect jumpptr:req - jumpifbyte CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_NO_EFFECT, \jumpptr + .macro jumpifmovehadnoeffect jumpInstr:req + jumpifbyte CMP_COMMON_BITS, gMoveResultFlags, MOVE_RESULT_NO_EFFECT, \jumpInstr .endm - .macro jumpifbattletype flags:req, jumpptr:req - jumpifword CMP_COMMON_BITS, gBattleTypeFlags, \flags, \jumpptr + .macro jumpifbattletype flags:req, jumpInstr:req + jumpifword CMP_COMMON_BITS, gBattleTypeFlags, \flags, \jumpInstr .endm - .macro jumpifnotbattletype flags:req, jumpptr:req - jumpifword CMP_NO_COMMON_BITS, gBattleTypeFlags, \flags, \jumpptr + .macro jumpifnotbattletype flags:req, jumpInstr:req + jumpifword CMP_NO_COMMON_BITS, gBattleTypeFlags, \flags, \jumpInstr .endm .macro dmg_1_8_targethp @@ -2147,42 +2147,42 @@ manipulatedamage DMG_1_2_ATTACKER_HP .endm - .macro jumpifflowerveil jumpptr:req + .macro jumpifflowerveil jumpInstr:req jumpifnottype BS_TARGET, TYPE_GRASS, 1f - jumpifability BS_TARGET_SIDE, ABILITY_FLOWER_VEIL, \jumpptr + jumpifability BS_TARGET_SIDE, ABILITY_FLOWER_VEIL, \jumpInstr 1: .endm - .macro jumpifflowerveilattacker jumpptr:req + .macro jumpifflowerveilattacker jumpInstr:req jumpifnottype BS_ATTACKER, TYPE_GRASS, 1f - jumpifability BS_ATTACKER_SIDE, ABILITY_FLOWER_VEIL, \jumpptr + jumpifability BS_ATTACKER_SIDE, ABILITY_FLOWER_VEIL, \jumpInstr 1: .endm - .macro setallytonexttarget jumpptr:req + .macro setallytonexttarget jumpInstr:req jumpifbyte CMP_GREATER_THAN, gBattlerTarget, 0x1, 1f addbyte gBattlerTarget, 0x2 - goto \jumpptr + goto \jumpInstr 1: subbyte gBattlerTarget, 0x2 - goto \jumpptr + goto \jumpInstr .endm - .macro jumpifleafguardprotected battler:req, jumpptr:req + .macro jumpifleafguardprotected battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED - .4byte \jumpptr + .4byte \jumpInstr .endm - .macro jumpifsafeguard jumpptr:req + .macro jumpifsafeguard jumpInstr:req jumpifability BS_ATTACKER, ABILITY_INFILTRATOR, 1f - jumpifsideaffecting BS_TARGET, SIDE_STATUS_SAFEGUARD, \jumpptr + jumpifsideaffecting BS_TARGET, SIDE_STATUS_SAFEGUARD, \jumpInstr 1: .endm @ Will jump to script pointer if the target weighs less than 200 kg, or 441 lbs. - .macro jumpifunder200 battler:req, ptr:req + .macro jumpifunder200 battler:req, failInstr:req various \battler, VARIOUS_JUMP_IF_UNDER_200 - .4byte \ptr + .4byte \failInstr .endm @ Sets the sky drop status and does all other necessary operations @@ -2192,9 +2192,9 @@ @ Clears the sky drop status and does all other necessary operations. @ If the target fainted in before this script is called, it goes to the given script. - .macro clearskydrop ptr:req + .macro clearskydrop failInstr:req various 0, VARIOUS_CLEAR_SKY_DROP - .4byte \ptr + .4byte \failInstr .endm @ Accounts for if the target of Sky Drop was in confuse_lock when the attacker falls asleep due to Yawn. @@ -2238,7 +2238,7 @@ waitmessage B_WAIT_TIME_LONG .endm - .macro jumpifemergencyexited battler:req, ptr:req + .macro jumpifemergencyexited battler:req, jumpInstr:req various \battler, VARIOUS_JUMP_IF_EMERGENCY_EXITED - .4byte \ptr + .4byte \jumpInstr .endm diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 57311e671..985146fab 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -60,6 +60,37 @@ #include "battle_util.h" #include "constants/pokemon.h" +// Helper for accessing command arguments and advancing gBattlescriptCurrInstr. +// +// For example accuracycheck is defined as: +// +// .macro accuracycheck failInstr:req, move:req +// .byte 0x1 +// .4byte \failInstr +// .2byte \move +// .endm +// +// Which corresponds to: +// +// CMD_ARGS(const u8 *failInstr, u16 move); +// +// The arguments can be accessed as cmd->failInstr and cmd->move. +// gBattlescriptCurrInstr = cmd->nextInstr; advances to the next instruction. +#define CMD_ARGS(...) const struct __attribute__((packed)) { u8 opcode; MEMBERS(__VA_ARGS__) const u8 nextInstr[0]; } *const cmd = (const void *)gBattlescriptCurrInstr +#define VARIOUS_ARGS(...) CMD_ARGS(u8 battler, u8 id, ##__VA_ARGS__) +#define NATIVE_ARGS(...) CMD_ARGS(void (*func)(void), ##__VA_ARGS__) + +#define MEMBERS(...) VARARG_8(MEMBERS_, __VA_ARGS__) +#define MEMBERS_0() +#define MEMBERS_1(a) a; +#define MEMBERS_2(a, b) a; b; +#define MEMBERS_3(a, b, c) a; b; c; +#define MEMBERS_4(a, b, c, d) a; b; c; d; +#define MEMBERS_5(a, b, c, d, e) a; b; c; d; e; +#define MEMBERS_6(a, b, c, d, e, f) a; b; c; d; e; f; +#define MEMBERS_7(a, b, c, d, e, f, g) a; b; c; d; e; f; g; +#define MEMBERS_8(a, b, c, d, e, f, g, h) a; b; c; d; e; f; g; h; + extern struct Evolution gEvolutionTable[][EVOS_PER_MON]; extern const u8 *const gBattleScriptsForMoveEffects[]; @@ -1413,6 +1444,8 @@ static bool32 TryAegiFormChange(void) static void Cmd_attackcanceler(void) { + CMD_ARGS(); + s32 i, moveType; u16 attackerAbility = GetBattlerAbility(gBattlerAttacker); @@ -1603,16 +1636,16 @@ static void Cmd_attackcanceler(void) gMultiHitCounter = 0; } gBattleCommunication[MISS_TYPE] = B_MSG_PROTECTED; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } else if (gProtectStructs[gBattlerTarget].beakBlastCharge && IsMoveMakingContact(gCurrentMove, gBattlerAttacker)) { gProtectStructs[gBattlerAttacker].touchedProtectLike = TRUE; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -1637,15 +1670,17 @@ static bool32 JumpIfMoveFailed(u8 adder, u16 move) static void Cmd_jumpifaffectedbyprotect(void) { + CMD_ARGS(const u8 *failInstr); + if (IsBattlerProtected(gBattlerTarget, gCurrentMove)) { gMoveResultFlags |= MOVE_RESULT_MISSED; - JumpIfMoveFailed(5, 0); + JumpIfMoveFailed(sizeof(*cmd), MOVE_NONE); gBattleCommunication[MISS_TYPE] = B_MSG_PROTECTED; } else { - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -1836,7 +1871,9 @@ u32 GetTotalAccuracy(u32 battlerAtk, u32 battlerDef, u32 move, u32 atkAbility, u static void Cmd_accuracycheck(void) { - u16 type, move = T2_READ_16(gBattlescriptCurrInstr + 5); + CMD_ARGS(const u8 *failInstr, u16 move); + + u16 type, move = cmd->move; u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, move); if (move == ACC_CURR_MOVE) @@ -1845,18 +1882,18 @@ static void Cmd_accuracycheck(void) if (move == NO_ACC_CALC_CHECK_LOCK_ON) { if (gStatuses3[gBattlerTarget] & STATUS3_ALWAYS_HITS && gDisableStructs[gBattlerTarget].battlerWithSureHit == gBattlerAttacker) - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; else if (gStatuses3[gBattlerTarget] & (STATUS3_SEMI_INVULNERABLE)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; else if (!JumpIfMoveAffectedByProtect(0)) - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } else if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_2ND_HIT || (gSpecialStatuses[gBattlerAttacker].multiHitOn && (gBattleMoves[move].effect != EFFECT_TRIPLE_KICK || GetBattlerAbility(gBattlerAttacker) == ABILITY_SKILL_LINK))) { // No acc checks for second hit of Parental Bond or multi hit moves, except Triple Kick/Triple Axel - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } else { @@ -1889,6 +1926,8 @@ static void Cmd_accuracycheck(void) static void Cmd_attackstring(void) { + CMD_ARGS(); + if (gBattleControllerExecFlags) return; @@ -1897,12 +1936,14 @@ static void Cmd_attackstring(void) PrepareStringBattle(STRINGID_USEDMOVE, gBattlerAttacker); gHitMarker |= HITMARKER_ATTACKSTRING_PRINTED; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; gBattleCommunication[MSG_DISPLAY] = 0; } static void Cmd_ppreduce(void) { + CMD_ARGS(); + s32 i, ppToDeduct = 1; if (gBattleControllerExecFlags) @@ -1962,7 +2003,7 @@ static void Cmd_ppreduce(void) } gHitMarker &= ~HITMARKER_NO_PPDEDUCT; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } // The chance is 1/N for each stage. @@ -2031,6 +2072,8 @@ s8 GetInverseCritChance(u8 battlerAtk, u8 battlerDef, u32 move) static void Cmd_critcalc(void) { + CMD_ARGS(); + u16 partySlot; s32 critChance = CalcCritChanceStage(gBattlerAttacker, gBattlerTarget, gCurrentMove, TRUE); gPotentialItemEffectBattler = gBattlerAttacker; @@ -2052,30 +2095,36 @@ static void Cmd_critcalc(void) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI && GetBattlerPosition(gBattlerAttacker) == B_POSITION_PLAYER_LEFT)) gPartyCriticalHits[partySlot]++; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_damagecalc(void) { + CMD_ARGS(); + u8 moveType; GET_MOVE_TYPE(gCurrentMove, moveType); gBattleMoveDamage = CalculateMoveDamage(gCurrentMove, gBattlerAttacker, gBattlerTarget, moveType, 0, gIsCriticalHit, TRUE, TRUE); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_typecalc(void) { + CMD_ARGS(); + u8 moveType; GET_MOVE_TYPE(gCurrentMove, moveType); CalcTypeEffectivenessMultiplier(gCurrentMove, moveType, gBattlerAttacker, gBattlerTarget, TRUE); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_adjustdamage(void) { + CMD_ARGS(); + u8 holdEffect, param; u32 moveType; u32 friendshipScore = GetBattlerFriendshipScore(gBattlerTarget); @@ -2158,7 +2207,7 @@ static void Cmd_adjustdamage(void) #endif END: - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && gBattleMoveDamage >= 1) gSpecialStatuses[gBattlerAttacker].damagedMons |= gBitTable[gBattlerTarget]; @@ -2201,6 +2250,8 @@ END: static void Cmd_multihitresultmessage(void) { + CMD_ARGS(); + if (gBattleControllerExecFlags) return; @@ -2226,7 +2277,7 @@ static void Cmd_multihitresultmessage(void) return; } } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; // Print berry reducing message after result message. if (gSpecialStatuses[gBattlerTarget].berryReduced @@ -2240,6 +2291,8 @@ static void Cmd_multihitresultmessage(void) static void Cmd_attackanimation(void) { + CMD_ARGS(); + u16 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); if (gBattleControllerExecFlags) @@ -2251,7 +2304,7 @@ static void Cmd_attackanimation(void) // In a wild double battle gotta use the teleport animation if two wild pokemon are alive. && !(gCurrentMove == MOVE_TELEPORT && WILD_DOUBLE_BATTLE && GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT && IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker)))) { - BattleScriptPush(gBattlescriptCurrInstr + 1); + BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_Pausex20; gBattleScripting.animTurn++; gBattleScripting.animTargetsHit++; @@ -2260,7 +2313,7 @@ static void Cmd_attackanimation(void) { if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_2ND_HIT) // No animation on second hit { - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; return; } @@ -2269,7 +2322,7 @@ static void Cmd_attackanimation(void) || moveTarget & MOVE_TARGET_DEPENDS) && gBattleScripting.animTargetsHit) { - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; return; } if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) @@ -2294,11 +2347,11 @@ static void Cmd_attackanimation(void) gBattleScripting.animTurn++; gBattleScripting.animTargetsHit++; MarkBattlerForControllerExec(gBattlerAttacker); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - BattleScriptPush(gBattlescriptCurrInstr + 1); + BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_Pausex20; } } @@ -2306,18 +2359,22 @@ static void Cmd_attackanimation(void) static void Cmd_waitanimation(void) { + CMD_ARGS(); + if (gBattleControllerExecFlags == 0) - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_healthbarupdate(void) { + CMD_ARGS(u8 battler); + if (gBattleControllerExecFlags) return; if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) || (gHitMarker & HITMARKER_PASSIVE_DAMAGE)) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); if (DoesSubstituteBlockMove(gBattlerAttacker, gActiveBattler, gCurrentMove) && gDisableStructs[gActiveBattler].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) { @@ -2335,11 +2392,13 @@ static void Cmd_healthbarupdate(void) } } - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_datahpupdate(void) { + CMD_ARGS(u8 battler); + u32 moveType; if (gBattleControllerExecFlags) @@ -2354,7 +2413,7 @@ static void Cmd_datahpupdate(void) if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) || (gHitMarker & HITMARKER_PASSIVE_DAMAGE)) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); if (DoesSubstituteBlockMove(gBattlerAttacker, gActiveBattler, gCurrentMove) && gDisableStructs[gActiveBattler].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE)) { if (gDisableStructs[gActiveBattler].substituteHP >= gBattleMoveDamage) @@ -2374,7 +2433,7 @@ static void Cmd_datahpupdate(void) // check substitute fading if (gDisableStructs[gActiveBattler].substituteHP == 0) { - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_SubstituteFade; return; @@ -2383,7 +2442,7 @@ static void Cmd_datahpupdate(void) else if (DoesDisguiseBlockMove(gBattlerAttacker, gActiveBattler, gCurrentMove)) { gBattleMons[gActiveBattler].species = SPECIES_MIMIKYU_BUSTED; - BattleScriptPush(gBattlescriptCurrInstr + 2); + BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_TargetFormChange; } else @@ -2405,7 +2464,7 @@ static void Cmd_datahpupdate(void) else { gTakenDmg[gActiveBattler] += gBattleMoveDamage; - if (gBattlescriptCurrInstr[1] == BS_TARGET) + if (cmd->battler == BS_TARGET) gTakenDmgByBattler[gActiveBattler] = gBattlerAttacker; else gTakenDmgByBattler[gActiveBattler] = gBattlerTarget; @@ -2429,7 +2488,7 @@ static void Cmd_datahpupdate(void) { gProtectStructs[gActiveBattler].physicalDmg = gHpDealt; gSpecialStatuses[gActiveBattler].physicalDmg = gHpDealt; - if (gBattlescriptCurrInstr[1] == BS_TARGET) + if (cmd->battler == BS_TARGET) { gProtectStructs[gActiveBattler].physicalBattlerId = gBattlerAttacker; gSpecialStatuses[gActiveBattler].physicalBattlerId = gBattlerAttacker; @@ -2444,7 +2503,7 @@ static void Cmd_datahpupdate(void) { gProtectStructs[gActiveBattler].specialDmg = gHpDealt; gSpecialStatuses[gActiveBattler].specialDmg = gHpDealt; - if (gBattlescriptCurrInstr[1] == BS_TARGET) + if (cmd->battler == BS_TARGET) { gProtectStructs[gActiveBattler].specialBattlerId = gBattlerAttacker; gSpecialStatuses[gActiveBattler].specialBattlerId = gBattlerAttacker; @@ -2463,15 +2522,17 @@ static void Cmd_datahpupdate(void) } else { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); if (gSpecialStatuses[gActiveBattler].dmg == 0) gSpecialStatuses[gActiveBattler].dmg = 0xFFFF; } - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_critmessage(void) { + CMD_ARGS(); + if (gBattleControllerExecFlags == 0) { if (gIsCriticalHit == TRUE && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) @@ -2479,12 +2540,14 @@ static void Cmd_critmessage(void) PrepareStringBattle(STRINGID_CRITICALHIT, gBattlerAttacker); gBattleCommunication[MSG_DISPLAY] = 1; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_effectivenesssound(void) { + CMD_ARGS(); + if (gBattleControllerExecFlags) return; @@ -2528,11 +2591,13 @@ static void Cmd_effectivenesssound(void) break; } } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_resultmessage(void) { + CMD_ARGS(); + u32 stringId = 0; if (gBattleControllerExecFlags) @@ -2639,7 +2704,7 @@ static void Cmd_resultmessage(void) if (stringId) PrepareStringBattle(stringId, gBattlerAttacker); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; // Print berry reducing message after result message. if (gSpecialStatuses[gBattlerTarget].berryReduced @@ -2653,42 +2718,48 @@ static void Cmd_resultmessage(void) static void Cmd_printstring(void) { + CMD_ARGS(u16 id); + if (gBattleControllerExecFlags == 0) { - u16 var = T2_READ_16(gBattlescriptCurrInstr + 1); + u16 id = cmd->id; - gBattlescriptCurrInstr += 3; - PrepareStringBattle(var, gBattlerAttacker); + gBattlescriptCurrInstr = cmd->nextInstr; + PrepareStringBattle(id, gBattlerAttacker); gBattleCommunication[MSG_DISPLAY] = 1; } } static void Cmd_printselectionstring(void) { + CMD_ARGS(u16 id); + gActiveBattler = gBattlerAttacker; - BtlController_EmitPrintSelectionString(BUFFER_A, T2_READ_16(gBattlescriptCurrInstr + 1)); + BtlController_EmitPrintSelectionString(BUFFER_A, cmd->id); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 3; + gBattlescriptCurrInstr = cmd->nextInstr; gBattleCommunication[MSG_DISPLAY] = 1; } static void Cmd_waitmessage(void) { + CMD_ARGS(u16 time); + if (gBattleControllerExecFlags == 0) { if (!gBattleCommunication[MSG_DISPLAY]) { - gBattlescriptCurrInstr += 3; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - u16 toWait = T2_READ_16(gBattlescriptCurrInstr + 1); + u16 toWait = cmd->time; if (++gPauseCounterBattle >= toWait) { gPauseCounterBattle = 0; - gBattlescriptCurrInstr += 3; + gBattlescriptCurrInstr = cmd->nextInstr; gBattleCommunication[MSG_DISPLAY] = 0; } } @@ -2697,12 +2768,14 @@ static void Cmd_waitmessage(void) static void Cmd_printfromtable(void) { + CMD_ARGS(const u16 *ptr); + if (gBattleControllerExecFlags == 0) { - const u16 *ptr = (const u16 *) T1_READ_PTR(gBattlescriptCurrInstr + 1); + const u16 *ptr = cmd->ptr; ptr += gBattleCommunication[MULTISTRING_CHOOSER]; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; PrepareStringBattle(*ptr, gBattlerAttacker); gBattleCommunication[MSG_DISPLAY] = 1; } @@ -2710,16 +2783,18 @@ static void Cmd_printfromtable(void) static void Cmd_printselectionstringfromtable(void) { + CMD_ARGS(const u16 *ptr); + if (gBattleControllerExecFlags == 0) { - const u16 *ptr = (const u16 *) T1_READ_PTR(gBattlescriptCurrInstr + 1); + const u16 *ptr = cmd->ptr; ptr += gBattleCommunication[MULTISTRING_CHOOSER]; gActiveBattler = gBattlerAttacker; BtlController_EmitPrintSelectionString(BUFFER_A, *ptr); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; gBattleCommunication[MSG_DISPLAY] = 1; } } @@ -3674,6 +3749,8 @@ void SetMoveEffect(bool32 primary, u32 certain) static void Cmd_seteffectwithchance(void) { + CMD_ARGS(); + u32 percentChance; if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE) @@ -3698,7 +3775,7 @@ static void Cmd_seteffectwithchance(void) } else { - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } gBattleScripting.moveEffect = 0; @@ -3707,17 +3784,23 @@ static void Cmd_seteffectwithchance(void) static void Cmd_seteffectprimary(void) { + CMD_ARGS(); + SetMoveEffect(TRUE, 0); } static void Cmd_seteffectsecondary(void) { + CMD_ARGS(); + SetMoveEffect(FALSE, 0); } static void Cmd_clearstatusfromeffect(void) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + CMD_ARGS(u8 battler); + + gActiveBattler = GetBattlerForBattleScript(cmd->battler); if (gBattleScripting.moveEffect <= PRIMARY_STATUS_MOVE_EFFECT) gBattleMons[gActiveBattler].status1 &= (~sStatusFlagsForMoveEffects[gBattleScripting.moveEffect]); @@ -3725,52 +3808,53 @@ static void Cmd_clearstatusfromeffect(void) gBattleMons[gActiveBattler].status2 &= (~sStatusFlagsForMoveEffects[gBattleScripting.moveEffect]); gBattleScripting.moveEffect = 0; - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; gBattleScripting.multihitMoveEffect = 0; } static void Cmd_tryfaintmon(void) { - const u8 *BS_ptr; + CMD_ARGS(u8 battler, bool8 isSpikes, const u8 *instr); + const u8 *instr; - if (gBattlescriptCurrInstr[2] != 0) + if (cmd->isSpikes != 0) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); if (gHitMarker & HITMARKER_FAINTED(gActiveBattler)) { - BS_ptr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + instr = cmd->instr; BattleScriptPop(); - gBattlescriptCurrInstr = BS_ptr; + gBattlescriptCurrInstr = instr; gSideStatuses[GetBattlerSide(gActiveBattler)] &= ~(SIDE_STATUS_SPIKES_DAMAGED | SIDE_STATUS_TOXIC_SPIKES_DAMAGED | SIDE_STATUS_STEALTH_ROCK_DAMAGED | SIDE_STATUS_STICKY_WEB_DAMAGED); } else { - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } } else { u8 battlerId; - if (gBattlescriptCurrInstr[1] == BS_ATTACKER) + if (cmd->battler == BS_ATTACKER) { gActiveBattler = gBattlerAttacker; battlerId = gBattlerTarget; - BS_ptr = BattleScript_FaintAttacker; + instr = BattleScript_FaintAttacker; } else { gActiveBattler = gBattlerTarget; battlerId = gBattlerAttacker; - BS_ptr = BattleScript_FaintTarget; + instr = BattleScript_FaintTarget; } if (!(gAbsentBattlerFlags & gBitTable[gActiveBattler]) && gBattleMons[gActiveBattler].hp == 0) { gHitMarker |= HITMARKER_FAINTED(gActiveBattler); - BattleScriptPush(gBattlescriptCurrInstr + 7); - gBattlescriptCurrInstr = BS_ptr; + BattleScriptPush(cmd->nextInstr); + gBattlescriptCurrInstr = instr; if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) { gHitMarker |= HITMARKER_PLAYER_FAINTED; @@ -3813,27 +3897,31 @@ static void Cmd_tryfaintmon(void) } else { - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } } } static void Cmd_dofaintanimation(void) { + CMD_ARGS(u8 battler); + if (gBattleControllerExecFlags == 0) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); BtlController_EmitFaintAnimation(BUFFER_A); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_cleareffectsonfaint(void) { + CMD_ARGS(u8 battler); + if (gBattleControllerExecFlags == 0) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); if (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || gBattleMons[gActiveBattler].hp == 0) { @@ -3843,44 +3931,50 @@ static void Cmd_cleareffectsonfaint(void) } FaintClearSetData(); // Effects like attractions, trapping, etc. - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_jumpifstatus(void) { - u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); - u32 flags = T2_READ_32(gBattlescriptCurrInstr + 2); - const u8 *jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 6); + CMD_ARGS(u8 battler, u32 flags, const u8 *jumpInstr); + + u8 battlerId = GetBattlerForBattleScript(cmd->battler); + u32 flags = cmd->flags; + const u8 *jumpInstr = cmd->jumpInstr; if (gBattleMons[battlerId].status1 & flags && gBattleMons[battlerId].hp != 0) - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = jumpInstr; else - gBattlescriptCurrInstr += 10; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_jumpifstatus2(void) { - u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); - u32 flags = T2_READ_32(gBattlescriptCurrInstr + 2); - const u8 *jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 6); + CMD_ARGS(u8 battler, u32 flags, const u8 *jumpInstr); + + u8 battlerId = GetBattlerForBattleScript(cmd->battler); + u32 flags = cmd->flags; + const u8 *jumpInstr = cmd->jumpInstr; if (gBattleMons[battlerId].status2 & flags && gBattleMons[battlerId].hp != 0) - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = jumpInstr; else - gBattlescriptCurrInstr += 10; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_jumpifability(void) { + CMD_ARGS(u8 battler, u16 ability, const u8 *jumpInstr); + u32 battlerId; bool32 hasAbility = FALSE; - u32 ability = T2_READ_16(gBattlescriptCurrInstr + 2); + u32 ability = cmd->ability; - switch (gBattlescriptCurrInstr[1]) + switch (cmd->battler) { default: - battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + battlerId = GetBattlerForBattleScript(cmd->battler); if (GetBattlerAbility(battlerId) == ability) hasAbility = TRUE; break; @@ -3905,103 +3999,113 @@ static void Cmd_jumpifability(void) if (hasAbility) { gLastUsedAbility = ability; - gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 4); + gBattlescriptCurrInstr = cmd->jumpInstr; RecordAbilityBattle(battlerId, gLastUsedAbility); gBattlerAbility = battlerId; } else { - gBattlescriptCurrInstr += 8; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_jumpifsideaffecting(void) { + CMD_ARGS(u8 battler, u32 flags, const u8 *jumpInstr); + u8 side; u32 flags; - const u8 *jumpPtr; + const u8 *jumpInstr; - if (gBattlescriptCurrInstr[1] == BS_ATTACKER) + if (cmd->battler == BS_ATTACKER) side = GET_BATTLER_SIDE(gBattlerAttacker); else side = GET_BATTLER_SIDE(gBattlerTarget); - flags = T2_READ_32(gBattlescriptCurrInstr + 2); - jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 6); + flags = cmd->flags; + jumpInstr = cmd->jumpInstr; if (gSideStatuses[side] & flags) - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = jumpInstr; else - gBattlescriptCurrInstr += 10; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_jumpifstat(void) { - bool32 ret = 0; - u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); - u8 statId = gBattlescriptCurrInstr[3]; - u8 cmpTo = gBattlescriptCurrInstr[4]; - u8 cmpKind = gBattlescriptCurrInstr[2]; + CMD_ARGS(u8 battler, u8 comparison, u8 stat, u8 value, const u8 *jumpInstr); - ret = CompareStat(battlerId, statId, cmpTo, cmpKind); + bool32 ret = 0; + u8 battlerId = GetBattlerForBattleScript(cmd->battler); + u8 stat = cmd->stat; + u8 value = cmd->value; + u8 comparison = cmd->comparison; + + ret = CompareStat(battlerId, stat, value, comparison); if (ret) - gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 5); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 9; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_jumpifstatus3condition(void) { - u32 status; - const u8 *jumpPtr; + CMD_ARGS(u8 battler, u32 flags, bool8 jumpIfTrue, const u8 *jumpInstr); - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); - status = T2_READ_32(gBattlescriptCurrInstr + 2); - jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 7); + u32 flags; + const u8 *jumpInstr; - if (gBattlescriptCurrInstr[6]) + gActiveBattler = GetBattlerForBattleScript(cmd->battler); + flags = cmd->flags; + jumpInstr = cmd->jumpInstr; + + if (cmd->jumpIfTrue) { - if ((gStatuses3[gActiveBattler] & status) != 0) - gBattlescriptCurrInstr += 11; + if ((gStatuses3[gActiveBattler] & flags) != 0) + gBattlescriptCurrInstr = cmd->nextInstr; else - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = jumpInstr; } else { - if ((gStatuses3[gActiveBattler] & status) != 0) - gBattlescriptCurrInstr = jumpPtr; + if ((gStatuses3[gActiveBattler] & flags) != 0) + gBattlescriptCurrInstr = jumpInstr; else - gBattlescriptCurrInstr += 11; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_jumpbasedontype(void) { - u8 battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); - u8 type = gBattlescriptCurrInstr[2]; - const u8 *jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 4); + CMD_ARGS(u8 battler, u8 type, u8 jumpIfType, const u8 *jumpInstr); + + u8 battlerId = GetBattlerForBattleScript(cmd->battler); + u8 type = cmd->type; + const u8 *jumpInstr = cmd->jumpInstr; // jumpiftype - if (gBattlescriptCurrInstr[3]) + if (cmd->jumpIfType) { if (IS_BATTLER_OF_TYPE(battlerId, type)) - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = jumpInstr; else - gBattlescriptCurrInstr += 8; + gBattlescriptCurrInstr = cmd->nextInstr; } // jumpifnottype else { if (!IS_BATTLER_OF_TYPE(battlerId, type)) - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = jumpInstr; else - gBattlescriptCurrInstr += 8; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_getexp(void) { + CMD_ARGS(u8 battler); + u16 item; s32 i; // also used as stringId u8 holdEffect; @@ -4009,7 +4113,7 @@ static void Cmd_getexp(void) s32 viaExpShare = 0; u32 *exp = &gBattleStruct->expValue; - gBattlerFainted = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gBattlerFainted = GetBattlerForBattleScript(cmd->battler); sentIn = gSentPokesToOpponent[(gBattlerFainted & 2) >> 1]; switch (gBattleScripting.getexpState) @@ -4307,7 +4411,7 @@ static void Cmd_getexp(void) // not sure why gf clears the item and ability here gBattleMons[gBattlerFainted].item = ITEM_NONE; gBattleMons[gBattlerFainted].ability = ABILITY_NONE; - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } break; } @@ -4393,6 +4497,8 @@ bool32 NoAliveMonsForEitherParty(void) // sets gBattleOutcome accordingly, if necessary. static void Cmd_checkteamslost(void) { + CMD_ARGS(const u8 *jumpInstr); + if (gBattleControllerExecFlags) return; @@ -4437,21 +4543,21 @@ static void Cmd_checkteamslost(void) if (gBattleTypeFlags & BATTLE_TYPE_MULTI) { if (emptyOpponentSpots + emptyPlayerSpots > 1) - gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { if (emptyOpponentSpots != 0 && emptyPlayerSpots != 0) - gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } else { - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -4467,315 +4573,361 @@ static void MoveValuesCleanUp(void) static void Cmd_movevaluescleanup(void) { + CMD_ARGS(); + MoveValuesCleanUp(); - gBattlescriptCurrInstr += 1; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_setmultihit(void) { - gMultiHitCounter = gBattlescriptCurrInstr[1]; - gBattlescriptCurrInstr += 2; + CMD_ARGS(u8 value); + + gMultiHitCounter = cmd->value; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_decrementmultihit(void) { + CMD_ARGS(const u8 *loopInstr); + if (--gMultiHitCounter == 0) - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; else - gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->loopInstr; } static void Cmd_goto(void) { - gBattlescriptCurrInstr = T2_READ_PTR(gBattlescriptCurrInstr + 1); + CMD_ARGS(const u8 *instr); + + gBattlescriptCurrInstr = cmd->instr; } static void Cmd_jumpifbyte(void) { - u8 caseID = gBattlescriptCurrInstr[1]; - const u8 *memByte = T2_READ_PTR(gBattlescriptCurrInstr + 2); - u8 value = gBattlescriptCurrInstr[6]; - const u8 *jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 7); + CMD_ARGS(u8 comparison, const u8 *bytePtr, u8 value, const u8 *jumpInstr); - gBattlescriptCurrInstr += 11; + u8 comparison = cmd->comparison; + const u8 *bytePtr = cmd->bytePtr; + u8 value = cmd->value; + const u8 *jumpInstr = cmd->jumpInstr; - switch (caseID) + gBattlescriptCurrInstr = cmd->nextInstr; + + switch (comparison) { case CMP_EQUAL: - if (*memByte == value) - gBattlescriptCurrInstr = jumpPtr; + if (*bytePtr == value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_NOT_EQUAL: - if (*memByte != value) - gBattlescriptCurrInstr = jumpPtr; + if (*bytePtr != value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_GREATER_THAN: - if (*memByte > value) - gBattlescriptCurrInstr = jumpPtr; + if (*bytePtr > value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_LESS_THAN: - if (*memByte < value) - gBattlescriptCurrInstr = jumpPtr; + if (*bytePtr < value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_COMMON_BITS: - if (*memByte & value) - gBattlescriptCurrInstr = jumpPtr; + if (*bytePtr & value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_NO_COMMON_BITS: - if (!(*memByte & value)) - gBattlescriptCurrInstr = jumpPtr; + if (!(*bytePtr & value)) + gBattlescriptCurrInstr = jumpInstr; break; } } static void Cmd_jumpifhalfword(void) { - u8 caseID = gBattlescriptCurrInstr[1]; - const u16 *memHword = T2_READ_PTR(gBattlescriptCurrInstr + 2); - u16 value = T2_READ_16(gBattlescriptCurrInstr + 6); - const u8 *jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 8); + CMD_ARGS(u8 comparison, const u16 *halfwordPtr, u16 value, const u8 *jumpInstr); - gBattlescriptCurrInstr += 12; + u8 comparison = cmd->comparison; + const u16 *halfwordPtr = cmd->halfwordPtr; + u16 value = cmd->value; + const u8 *jumpInstr = cmd->jumpInstr; - switch (caseID) + gBattlescriptCurrInstr = cmd->nextInstr; + + switch (comparison) { case CMP_EQUAL: - if (*memHword == value) - gBattlescriptCurrInstr = jumpPtr; + if (*halfwordPtr == value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_NOT_EQUAL: - if (*memHword != value) - gBattlescriptCurrInstr = jumpPtr; + if (*halfwordPtr != value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_GREATER_THAN: - if (*memHword > value) - gBattlescriptCurrInstr = jumpPtr; + if (*halfwordPtr > value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_LESS_THAN: - if (*memHword < value) - gBattlescriptCurrInstr = jumpPtr; + if (*halfwordPtr < value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_COMMON_BITS: - if (*memHword & value) - gBattlescriptCurrInstr = jumpPtr; + if (*halfwordPtr & value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_NO_COMMON_BITS: - if (!(*memHword & value)) - gBattlescriptCurrInstr = jumpPtr; + if (!(*halfwordPtr & value)) + gBattlescriptCurrInstr = jumpInstr; break; } } static void Cmd_jumpifword(void) { - u8 caseID = gBattlescriptCurrInstr[1]; - const u32 *memWord = T2_READ_PTR(gBattlescriptCurrInstr + 2); - u32 value = T1_READ_32(gBattlescriptCurrInstr + 6); - const u8 *jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 10); + CMD_ARGS(u8 comparison, const u32 *wordPtr, u32 value, const u8 *jumpInstr); - gBattlescriptCurrInstr += 14; + u8 comparison = cmd->comparison; + const u32 *wordPtr = cmd->wordPtr; + u32 value = cmd->value; + const u8 *jumpInstr = cmd->jumpInstr; - switch (caseID) + gBattlescriptCurrInstr = cmd->nextInstr; + + switch (comparison) { case CMP_EQUAL: - if (*memWord == value) - gBattlescriptCurrInstr = jumpPtr; + if (*wordPtr == value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_NOT_EQUAL: - if (*memWord != value) - gBattlescriptCurrInstr = jumpPtr; + if (*wordPtr != value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_GREATER_THAN: - if (*memWord > value) - gBattlescriptCurrInstr = jumpPtr; + if (*wordPtr > value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_LESS_THAN: - if (*memWord < value) - gBattlescriptCurrInstr = jumpPtr; + if (*wordPtr < value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_COMMON_BITS: - if (*memWord & value) - gBattlescriptCurrInstr = jumpPtr; + if (*wordPtr & value) + gBattlescriptCurrInstr = jumpInstr; break; case CMP_NO_COMMON_BITS: - if (!(*memWord & value)) - gBattlescriptCurrInstr = jumpPtr; + if (!(*wordPtr & value)) + gBattlescriptCurrInstr = jumpInstr; break; } } static void Cmd_jumpifarrayequal(void) { - const u8 *mem1 = T2_READ_PTR(gBattlescriptCurrInstr + 1); - const u8 *mem2 = T2_READ_PTR(gBattlescriptCurrInstr + 5); - u32 size = gBattlescriptCurrInstr[9]; - const u8 *jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 10); + CMD_ARGS(const u8 *array1, const u8 *array2, u8 size, const u8 *jumpInstr); + + const u8 *array1 = cmd->array1; + const u8 *array2 = cmd->array2; + u32 size = cmd->size; + const u8 *jumpInstr = cmd->jumpInstr; u8 i; for (i = 0; i < size; i++) { - if (*mem1 != *mem2) + if (*array1 != *array2) { - gBattlescriptCurrInstr += 14; + gBattlescriptCurrInstr = cmd->nextInstr; break; } - mem1++, mem2++; + array1++, array2++; } if (i == size) - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = jumpInstr; } static void Cmd_jumpifarraynotequal(void) { + CMD_ARGS(const u8 *array1, const u8 *array2, u8 size, const u8 *jumpInstr); + u8 equalBytes = 0; - const u8 *mem1 = T2_READ_PTR(gBattlescriptCurrInstr + 1); - const u8 *mem2 = T2_READ_PTR(gBattlescriptCurrInstr + 5); - u32 size = gBattlescriptCurrInstr[9]; - const u8 *jumpPtr = T2_READ_PTR(gBattlescriptCurrInstr + 10); + const u8 *array1 = cmd->array1; + const u8 *array2 = cmd->array2; + u32 size = cmd->size; + const u8 *jumpInstr = cmd->jumpInstr; u8 i; for (i = 0; i < size; i++) { - if (*mem1 == *mem2) + if (*array1 == *array2) equalBytes++; - mem1++, mem2++; + array1++, array2++; } if (equalBytes != size) - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = jumpInstr; else - gBattlescriptCurrInstr += 14; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_setbyte(void) { - u8 *memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1); - *memByte = gBattlescriptCurrInstr[5]; + CMD_ARGS(u8 *bytePtr, u8 value); - gBattlescriptCurrInstr += 6; + u8 *bytePtr = cmd->bytePtr; + *bytePtr = cmd->value; + + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_addbyte(void) { - u8 *memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1); - *memByte += gBattlescriptCurrInstr[5]; - gBattlescriptCurrInstr += 6; + CMD_ARGS(u8 *bytePtr, u8 value); + + u8 *bytePtr = cmd->bytePtr; + *bytePtr += cmd->value; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_subbyte(void) { - u8 *memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1); - *memByte -= gBattlescriptCurrInstr[5]; - gBattlescriptCurrInstr += 6; + CMD_ARGS(u8 *bytePtr, u8 value); + + u8 *bytePtr = cmd->bytePtr; + *bytePtr -= cmd->value; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_copyarray(void) { - u8 *dest = T2_READ_PTR(gBattlescriptCurrInstr + 1); - const u8 *src = T2_READ_PTR(gBattlescriptCurrInstr + 5); - s32 size = gBattlescriptCurrInstr[9]; + CMD_ARGS(u8 *dest, const u8 *src, u8 size); + + u8 *dest = cmd->dest; + const u8 *src = cmd->src; + s32 size = cmd->size; s32 i; for (i = 0; i < size; i++) dest[i] = src[i]; - gBattlescriptCurrInstr += 10; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_copyarraywithindex(void) { - u8 *dest = T2_READ_PTR(gBattlescriptCurrInstr + 1); - const u8 *src = T2_READ_PTR(gBattlescriptCurrInstr + 5); - const u8 *index = T2_READ_PTR(gBattlescriptCurrInstr + 9); - s32 size = gBattlescriptCurrInstr[13]; + CMD_ARGS(u8 *dest, const u8 *src, const u8 *indexPtr, u8 size); + + u8 *dest = cmd->dest; + const u8 *src = cmd->src; + const u8 *indexPtr = cmd->indexPtr; + s32 size = cmd->size; s32 i; for (i = 0; i < size; i++) - dest[i] = src[i + *index]; + dest[i] = src[i + *indexPtr]; - gBattlescriptCurrInstr += 14; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_orbyte(void) { - u8 *memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1); - *memByte |= gBattlescriptCurrInstr[5]; - gBattlescriptCurrInstr += 6; + CMD_ARGS(u8 *bytePtr, u8 value); + + u8 *bytePtr = cmd->bytePtr; + *bytePtr |= cmd->value; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_orhalfword(void) { - u16 *memHword = T2_READ_PTR(gBattlescriptCurrInstr + 1); - u16 val = T2_READ_16(gBattlescriptCurrInstr + 5); + CMD_ARGS(u16 *halfwordPtr, u16 value); - *memHword |= val; - gBattlescriptCurrInstr += 7; + u16 *halfwordPtr = cmd->halfwordPtr; + u16 value = cmd->value; + + *halfwordPtr |= value; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_orword(void) { - u32 *memWord = T2_READ_PTR(gBattlescriptCurrInstr + 1); - u32 val = T2_READ_32(gBattlescriptCurrInstr + 5); + CMD_ARGS(u32 *wordPtr, u32 value); - *memWord |= val; - gBattlescriptCurrInstr += 9; + u32 *wordPtr = cmd->wordPtr; + u32 value = cmd->value; + + *wordPtr |= value; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_bicbyte(void) { - u8 *memByte = T2_READ_PTR(gBattlescriptCurrInstr + 1); - *memByte &= ~(gBattlescriptCurrInstr[5]); - gBattlescriptCurrInstr += 6; + CMD_ARGS(u8 *bytePtr, u8 value); + + u8 *bytePtr = cmd->bytePtr; + *bytePtr &= ~cmd->value; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_bichalfword(void) { - u16 *memHword = T2_READ_PTR(gBattlescriptCurrInstr + 1); - u16 val = T2_READ_16(gBattlescriptCurrInstr + 5); + CMD_ARGS(u16 *halfwordPtr, u16 value); - *memHword &= ~val; - gBattlescriptCurrInstr += 7; + u16 *halfwordPtr = cmd->halfwordPtr; + u16 value = cmd->value; + + *halfwordPtr &= ~value; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_bicword(void) { - u32 *memWord = T2_READ_PTR(gBattlescriptCurrInstr + 1); - u32 val = T2_READ_32(gBattlescriptCurrInstr + 5); + CMD_ARGS(u32 *wordPtr, u32 value); - *memWord &= ~val; - gBattlescriptCurrInstr += 9; + u32 *wordPtr = cmd->wordPtr; + u32 value = cmd->value; + + *wordPtr &= ~value; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_pause(void) { + CMD_ARGS(u16 frames); + if (gBattleControllerExecFlags == 0) { - u16 value = T2_READ_16(gBattlescriptCurrInstr + 1); + u16 value = cmd->frames; if (++gPauseCounterBattle >= value) { gPauseCounterBattle = 0; - gBattlescriptCurrInstr += 3; + gBattlescriptCurrInstr = cmd->nextInstr; } } } static void Cmd_waitstate(void) { + CMD_ARGS(); + if (gBattleControllerExecFlags == 0) - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_healthbar_update(void) { - if (gBattlescriptCurrInstr[1] == BS_TARGET) + CMD_ARGS(u8 battler); + + if (cmd->battler == BS_TARGET) gActiveBattler = gBattlerTarget; else gActiveBattler = gBattlerAttacker; BtlController_EmitHealthBarUpdate(BUFFER_A, gBattleMoveDamage); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_return(void) @@ -4785,6 +4937,8 @@ static void Cmd_return(void) static void Cmd_end(void) { + CMD_ARGS(); + if (gBattleTypeFlags & BATTLE_TYPE_ARENA) BattleArena_AddSkillPoints(gBattlerAttacker); @@ -4795,6 +4949,8 @@ static void Cmd_end(void) static void Cmd_end2(void) { + CMD_ARGS(); + gActiveBattler = 0; gCurrentActionFuncId = B_ACTION_TRY_FINISH; } @@ -4802,6 +4958,8 @@ static void Cmd_end2(void) // Pops the main function stack static void Cmd_end3(void) { + CMD_ARGS(); + BattleScriptPop(); if (gBattleResources->battleCallbackStack->size != 0) gBattleResources->battleCallbackStack->size--; @@ -4810,12 +4968,16 @@ static void Cmd_end3(void) static void Cmd_call(void) { - BattleScriptPush(gBattlescriptCurrInstr + 5); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + CMD_ARGS(const u8 *instr); + + BattleScriptPush(cmd->nextInstr); + gBattlescriptCurrInstr = cmd->instr; } static void Cmd_setroost(void) { + CMD_ARGS(); + gBattleResources->flags->flags[gBattlerAttacker] |= RESOURCE_FLAG_ROOST; // Pure flying type. @@ -4846,35 +5008,41 @@ static void Cmd_setroost(void) gBattleStruct->roostTypes[gBattlerAttacker][1] = gBattleMons[gBattlerAttacker].type2; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_jumpifabilitypresent(void) { - if (IsAbilityOnField(T1_READ_16(gBattlescriptCurrInstr + 1))) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + CMD_ARGS(u16 ability, const u8 *jumpInstr); + + if (IsAbilityOnField(cmd->ability)) + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_endselectionscript(void) { + CMD_ARGS(); + *(gBattlerAttacker + gBattleStruct->selectionScriptFinished) = TRUE; } static void Cmd_playanimation(void) { - const u16 *argumentPtr; - u8 animId = gBattlescriptCurrInstr[2]; + CMD_ARGS(u8 battler, u8 animId, const u16 *argPtr); - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); - argumentPtr = T2_READ_PTR(gBattlescriptCurrInstr + 3); + const u16 *argPtr; + u8 animId = cmd->animId; + + gActiveBattler = GetBattlerForBattleScript(cmd->battler); + argPtr = cmd->argPtr; #if B_TERRAIN_BG_CHANGE == FALSE if (animId == B_ANIM_RESTORE_BG) { // workaround for .if not working - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; } #endif @@ -4887,13 +5055,13 @@ static void Cmd_playanimation(void) || animId == B_ANIM_SUBSTITUTE_FADE || animId == B_ANIM_PRIMAL_REVERSION) { - BtlController_EmitBattleAnimation(BUFFER_A, animId, *argumentPtr); + BtlController_EmitBattleAnimation(BUFFER_A, animId, *argPtr); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } else if (gHitMarker & HITMARKER_NO_ANIMATIONS && animId != B_ANIM_RESTORE_BG) { - BattleScriptPush(gBattlescriptCurrInstr + 7); + BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_Pausex20; } else if (animId == B_ANIM_RAIN_CONTINUES @@ -4901,71 +5069,75 @@ static void Cmd_playanimation(void) || animId == B_ANIM_SANDSTORM_CONTINUES || animId == B_ANIM_HAIL_CONTINUES) { - BtlController_EmitBattleAnimation(BUFFER_A, animId, *argumentPtr); + BtlController_EmitBattleAnimation(BUFFER_A, animId, *argPtr); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } else if (gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) { - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - BtlController_EmitBattleAnimation(BUFFER_A, animId, *argumentPtr); + BtlController_EmitBattleAnimation(BUFFER_A, animId, *argPtr); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } } // Same as playanimation, except it takes a pointer to some animation id, instead of taking the value directly static void Cmd_playanimation_var(void) { - const u16 *argumentPtr; - const u8 *animationIdPtr; + CMD_ARGS(u8 battler, const u8 *animIdPtr, const u16 *argPtr); - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); - animationIdPtr = T2_READ_PTR(gBattlescriptCurrInstr + 2); - argumentPtr = T2_READ_PTR(gBattlescriptCurrInstr + 6); + const u16 *argPtr; + const u8 *animIdPtr; - if (*animationIdPtr == B_ANIM_STATS_CHANGE - || *animationIdPtr == B_ANIM_SNATCH_MOVE - || *animationIdPtr == B_ANIM_MEGA_EVOLUTION - || *animationIdPtr == B_ANIM_ILLUSION_OFF - || *animationIdPtr == B_ANIM_FORM_CHANGE - || *animationIdPtr == B_ANIM_SUBSTITUTE_FADE - || *animationIdPtr == B_ANIM_PRIMAL_REVERSION) + gActiveBattler = GetBattlerForBattleScript(cmd->battler); + animIdPtr = cmd->animIdPtr; + argPtr = cmd->argPtr; + + if (*animIdPtr == B_ANIM_STATS_CHANGE + || *animIdPtr == B_ANIM_SNATCH_MOVE + || *animIdPtr == B_ANIM_MEGA_EVOLUTION + || *animIdPtr == B_ANIM_ILLUSION_OFF + || *animIdPtr == B_ANIM_FORM_CHANGE + || *animIdPtr == B_ANIM_SUBSTITUTE_FADE + || *animIdPtr == B_ANIM_PRIMAL_REVERSION) { - BtlController_EmitBattleAnimation(BUFFER_A, *animationIdPtr, *argumentPtr); + BtlController_EmitBattleAnimation(BUFFER_A, *animIdPtr, *argPtr); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 10; + gBattlescriptCurrInstr = cmd->nextInstr; } else if (gHitMarker & HITMARKER_NO_ANIMATIONS) { - gBattlescriptCurrInstr += 10; + gBattlescriptCurrInstr = cmd->nextInstr; } - else if (*animationIdPtr == B_ANIM_RAIN_CONTINUES - || *animationIdPtr == B_ANIM_SUN_CONTINUES - || *animationIdPtr == B_ANIM_SANDSTORM_CONTINUES - || *animationIdPtr == B_ANIM_HAIL_CONTINUES) + else if (*animIdPtr == B_ANIM_RAIN_CONTINUES + || *animIdPtr == B_ANIM_SUN_CONTINUES + || *animIdPtr == B_ANIM_SANDSTORM_CONTINUES + || *animIdPtr == B_ANIM_HAIL_CONTINUES) { - BtlController_EmitBattleAnimation(BUFFER_A, *animationIdPtr, *argumentPtr); + BtlController_EmitBattleAnimation(BUFFER_A, *animIdPtr, *argPtr); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 10; + gBattlescriptCurrInstr = cmd->nextInstr; } else if (gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) { - gBattlescriptCurrInstr += 10; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - BtlController_EmitBattleAnimation(BUFFER_A, *animationIdPtr, *argumentPtr); + BtlController_EmitBattleAnimation(BUFFER_A, *animIdPtr, *argPtr); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 10; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_setgraphicalstatchangevalues(void) { + CMD_ARGS(); + u8 value = GET_STAT_BUFF_VALUE_WITH_SIGN(gBattleScripting.statChanger); switch (value) @@ -4997,22 +5169,24 @@ static void Cmd_setgraphicalstatchangevalues(void) } gBattleScripting.animArg1 = GET_STAT_BUFF_ID(gBattleScripting.statChanger) + value - 1; gBattleScripting.animArg2 = 0; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_playstatchangeanimation(void) { + CMD_ARGS(u8 battler, u8 stats, u8 flags); + u32 ability; u32 currStat = 0; u32 statAnimId = 0; u32 changeableStatsCount = 0; - u32 statsToCheck = 0; + u32 stats = 0; u32 startingStatAnimId = 0; - u32 flags = gBattlescriptCurrInstr[3]; + u32 flags = cmd->flags; - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); ability = GetBattlerAbility(gActiveBattler); - statsToCheck = gBattlescriptCurrInstr[2]; + stats = cmd->stats; // Handle Contrary and Simple if (ability == ABILITY_CONTRARY) @@ -5027,9 +5201,9 @@ static void Cmd_playstatchangeanimation(void) else startingStatAnimId = STAT_ANIM_MINUS1 - 1; - while (statsToCheck != 0) + while (stats != 0) { - if (statsToCheck & 1) + if (stats & 1) { if (flags & STAT_CHANGE_CANT_PREVENT) { @@ -5055,7 +5229,7 @@ static void Cmd_playstatchangeanimation(void) } } } - statsToCheck >>= 1, currStat++; + stats >>= 1, currStat++; } if (changeableStatsCount > 1) // more than one stat, so the color is gray @@ -5073,14 +5247,14 @@ static void Cmd_playstatchangeanimation(void) else startingStatAnimId = STAT_ANIM_PLUS1 - 1; - while (statsToCheck != 0) + while (stats != 0) { - if (statsToCheck & 1 && gBattleMons[gActiveBattler].statStages[currStat] < MAX_STAT_STAGE) + if (stats & 1 && gBattleMons[gActiveBattler].statStages[currStat] < MAX_STAT_STAGE) { statAnimId = startingStatAnimId + currStat; changeableStatsCount++; } - statsToCheck >>= 1, currStat++; + stats >>= 1, currStat++; } if (changeableStatsCount > 1) // more than one stat, so the color is gray @@ -5094,7 +5268,7 @@ static void Cmd_playstatchangeanimation(void) if (flags & STAT_CHANGE_MULTIPLE_STATS && changeableStatsCount < 2) { - gBattlescriptCurrInstr += 4; + gBattlescriptCurrInstr = cmd->nextInstr; } else if (changeableStatsCount != 0 && !gBattleScripting.statAnimPlayed) { @@ -5102,11 +5276,11 @@ static void Cmd_playstatchangeanimation(void) MarkBattlerForControllerExec(gActiveBattler); if (flags & STAT_CHANGE_MULTIPLE_STATS && changeableStatsCount > 1) gBattleScripting.statAnimPlayed = TRUE; - gBattlescriptCurrInstr += 4; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr += 4; + gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -5165,6 +5339,8 @@ static u32 GetNextTarget(u32 moveTarget) static void Cmd_moveend(void) { + CMD_ARGS(u8 endMode, u8 endState); + s32 i; bool32 effect = FALSE; u32 moveType = 0; @@ -5178,8 +5354,8 @@ static void Cmd_moveend(void) else originallyUsedMove = gChosenMove; - endMode = gBattlescriptCurrInstr[1]; - endState = gBattlescriptCurrInstr[2]; + endMode = cmd->endMode; + endState = cmd->endState; holdEffectAtk = GetBattlerHoldEffect(gBattlerAttacker, TRUE); choicedMoveAtk = &gBattleStruct->choicedMove[gBattlerAttacker]; @@ -6035,51 +6211,59 @@ static void Cmd_moveend(void) } while (gBattleScripting.moveendState != MOVEEND_COUNT && effect == FALSE); if (gBattleScripting.moveendState == MOVEEND_COUNT && effect == FALSE) - gBattlescriptCurrInstr += 3; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_sethealblock(void) { + CMD_ARGS(const u8 *failInstr); + if (gStatuses3[gBattlerTarget] & STATUS3_HEAL_BLOCK) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { gStatuses3[gBattlerTarget] |= STATUS3_HEAL_BLOCK; gDisableStructs[gBattlerTarget].healBlockTimer = 5; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_returnatktoball(void) { + CMD_ARGS(); + gActiveBattler = gBattlerAttacker; if (!(gHitMarker & HITMARKER_FAINTED(gActiveBattler))) { BtlController_EmitReturnMonToBall(BUFFER_A, FALSE); MarkBattlerForControllerExec(gActiveBattler); } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_getswitchedmondata(void) { + CMD_ARGS(u8 battler); + if (gBattleControllerExecFlags) return; - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); gBattlerPartyIndexes[gActiveBattler] = *(gBattleStruct->monToSwitchIntoId + gActiveBattler); BtlController_EmitGetMonData(BUFFER_A, REQUEST_ALL_BATTLE, gBitTable[gBattlerPartyIndexes[gActiveBattler]]); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_switchindataupdate(void) { + CMD_ARGS(u8 battler); + struct BattlePokemon oldData; s32 i; u8 *monData; @@ -6087,7 +6271,7 @@ static void Cmd_switchindataupdate(void) if (gBattleControllerExecFlags) return; - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); oldData = gBattleMons[gActiveBattler]; monData = (u8 *)(&gBattleMons[gActiveBattler]); @@ -6129,15 +6313,17 @@ static void Cmd_switchindataupdate(void) PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gActiveBattler, gBattlerPartyIndexes[gActiveBattler]); - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_switchinanim(void) { + CMD_ARGS(u8 battler, bool8 dontClearSubstitute); + if (gBattleControllerExecFlags) return; - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT && !(gBattleTypeFlags & (BATTLE_TYPE_LINK @@ -6149,10 +6335,10 @@ static void Cmd_switchinanim(void) gAbsentBattlerFlags &= ~(gBitTable[gActiveBattler]); - BtlController_EmitSwitchInAnim(BUFFER_A, gBattlerPartyIndexes[gActiveBattler], gBattlescriptCurrInstr[2]); + BtlController_EmitSwitchInAnim(BUFFER_A, gBattlerPartyIndexes[gActiveBattler], cmd->dontClearSubstitute); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 3; + gBattlescriptCurrInstr = cmd->nextInstr; if (gBattleTypeFlags & BATTLE_TYPE_ARENA) BattleArena_InitPoints(); @@ -6309,19 +6495,20 @@ bool32 CanBattlerSwitch(u32 battlerId) static void Cmd_jumpifcantswitch(void) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1] & ~SWITCH_IGNORE_ESCAPE_PREVENTION); + CMD_ARGS(u8 battler:7, u8 ignoreEscapePrevention:1, const u8 *jumpInstr); - if (!(gBattlescriptCurrInstr[1] & SWITCH_IGNORE_ESCAPE_PREVENTION) - && !CanBattlerEscape(gActiveBattler)) + gActiveBattler = GetBattlerForBattleScript(cmd->battler); + + if (!cmd->ignoreEscapePrevention && !CanBattlerEscape(gActiveBattler)) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + gBattlescriptCurrInstr = cmd->jumpInstr; } else { if (CanBattlerSwitch(gActiveBattler)) - gBattlescriptCurrInstr += 6; + gBattlescriptCurrInstr = cmd->nextInstr; else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + gBattlescriptCurrInstr = cmd->jumpInstr; } } @@ -6340,16 +6527,18 @@ static void ChooseMonToSendOut(u8 slotId) static void Cmd_openpartyscreen(void) { + CMD_ARGS(u8 battler:7, u8 partyScreenOptional:1, const u8 *failInstr); + u32 flags; u8 hitmarkerFaintBits; u8 battlerId; - const u8 *jumpPtr; + const u8 *failInstr; battlerId = 0; flags = 0; - jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + failInstr = cmd->failInstr; - if (gBattlescriptCurrInstr[1] == BS_FAINTED_LINK_MULTIPLE_1) + if (cmd->battler == BS_FAINTED_LINK_MULTIPLE_1) { if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) || !(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) { @@ -6502,9 +6691,9 @@ static void Cmd_openpartyscreen(void) } } } - gBattlescriptCurrInstr += 6; + gBattlescriptCurrInstr = cmd->nextInstr; } - else if (gBattlescriptCurrInstr[1] == BS_FAINTED_LINK_MULTIPLE_2) + else if (cmd->battler == BS_FAINTED_LINK_MULTIPLE_2) { if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { @@ -6543,18 +6732,18 @@ static void Cmd_openpartyscreen(void) gSpecialStatuses[gActiveBattler].faintedHasReplacement = TRUE; } } - gBattlescriptCurrInstr += 6; + gBattlescriptCurrInstr = cmd->nextInstr; } else { // Not multi or double battle - gBattlescriptCurrInstr += 6; + gBattlescriptCurrInstr = cmd->nextInstr; } } else { // Multi battle - gBattlescriptCurrInstr += 6; + gBattlescriptCurrInstr = cmd->nextInstr; } hitmarkerFaintBits = gHitMarker >> 28; @@ -6565,26 +6754,26 @@ static void Cmd_openpartyscreen(void) gBattlerFainted++; if (gBattlerFainted == gBattlersCount) - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = failInstr; } else { - if (gBattlescriptCurrInstr[1] & PARTY_SCREEN_OPTIONAL) + if (cmd->partyScreenOptional) hitmarkerFaintBits = PARTY_ACTION_CHOOSE_MON; // Used here as the caseId for the EmitChoose function. else hitmarkerFaintBits = PARTY_ACTION_SEND_OUT; - battlerId = GetBattlerForBattleScript(gBattlescriptCurrInstr[1] & ~PARTY_SCREEN_OPTIONAL); + battlerId = GetBattlerForBattleScript(cmd->battler); if (gSpecialStatuses[battlerId].faintedHasReplacement) { - gBattlescriptCurrInstr += 6; + gBattlescriptCurrInstr = cmd->nextInstr; } else if (HasNoMonsToSwitch(battlerId, PARTY_SIZE, PARTY_SIZE)) { gActiveBattler = battlerId; gAbsentBattlerFlags |= gBitTable[gActiveBattler]; gHitMarker &= ~HITMARKER_FAINTED(gActiveBattler); - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = failInstr; } else { @@ -6596,7 +6785,7 @@ static void Cmd_openpartyscreen(void) BtlController_EmitChoosePokemon(BUFFER_A, hitmarkerFaintBits, *(gBattleStruct->monToSwitchIntoId + BATTLE_PARTNER(gActiveBattler)), ABILITY_NONE, gBattleStruct->battlerPartyOrders[gActiveBattler]); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 6; + gBattlescriptCurrInstr = cmd->nextInstr; if (GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_LEFT && gBattleResults.playerSwitchesCounter < 255) gBattleResults.playerSwitchesCounter++; @@ -6627,13 +6816,15 @@ static void Cmd_openpartyscreen(void) static void Cmd_switchhandleorder(void) { + CMD_ARGS(u8 battler, u8 state); + s32 i; if (gBattleControllerExecFlags) return; - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); - switch (gBattlescriptCurrInstr[2]) + switch (cmd->state) { case 0: for (i = 0; i < gBattlersCount; i++) @@ -6688,7 +6879,7 @@ static void Cmd_switchhandleorder(void) break; } - gBattlescriptCurrInstr += 3; + gBattlescriptCurrInstr = cmd->nextInstr; } static void SetDmgHazardsBattlescript(u8 battlerId, u8 multistringId) @@ -6709,9 +6900,11 @@ static void SetDmgHazardsBattlescript(u8 battlerId, u8 multistringId) static void Cmd_switchineffects(void) { + CMD_ARGS(u8 battler); + s32 i; - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); UpdateSentPokesToOpponentValue(gActiveBattler); gHitMarker &= ~HITMARKER_FAINTED(gActiveBattler); @@ -6838,7 +7031,7 @@ static void Cmd_switchineffects(void) gBattleStruct->hpOnSwitchout[GetBattlerSide(i)] = gBattleMons[i].hp; } - if (gBattlescriptCurrInstr[1] == BS_FAINTED_LINK_MULTIPLE_1) + if (cmd->battler == BS_FAINTED_LINK_MULTIPLE_1) { u32 hitmarkerFaintBits = gHitMarker >> 28; @@ -6852,70 +7045,84 @@ static void Cmd_switchineffects(void) gBattlerFainted++; } } - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_trainerslidein(void) { - gActiveBattler = GetBattlerAtPosition(gBattlescriptCurrInstr[1]); + CMD_ARGS(u8 battler); + + gActiveBattler = GetBattlerAtPosition(cmd->battler); BtlController_EmitTrainerSlide(BUFFER_A); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_playse(void) { + CMD_ARGS(u16 song); + gActiveBattler = gBattlerAttacker; - BtlController_EmitPlaySE(BUFFER_A, T2_READ_16(gBattlescriptCurrInstr + 1)); + BtlController_EmitPlaySE(BUFFER_A, cmd->song); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 3; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_fanfare(void) { + CMD_ARGS(u16 song); + gActiveBattler = gBattlerAttacker; - BtlController_EmitPlayFanfareOrBGM(BUFFER_A, T2_READ_16(gBattlescriptCurrInstr + 1), FALSE); + BtlController_EmitPlayFanfareOrBGM(BUFFER_A, cmd->song, FALSE); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 3; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_playfaintcry(void) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + CMD_ARGS(u8 battler); + + gActiveBattler = GetBattlerForBattleScript(cmd->battler); BtlController_EmitFaintingCry(BUFFER_A); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_endlinkbattle(void) { + CMD_ARGS(); + gActiveBattler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); BtlController_EmitEndLinkBattle(BUFFER_A, gBattleOutcome); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 1; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_returntoball(void) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + CMD_ARGS(u8 battler); + + gActiveBattler = GetBattlerForBattleScript(cmd->battler); BtlController_EmitReturnMonToBall(BUFFER_A, TRUE); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_handlelearnnewmove(void) { - const u8 *learnedMovePtr = T1_READ_PTR(gBattlescriptCurrInstr + 1); - const u8 *nothingToLearnPtr = T1_READ_PTR(gBattlescriptCurrInstr + 5); + CMD_ARGS(const u8 *learnedMovePtr, const u8 *nothingToLearnPtr, bool8 isFirstMove); - u16 learnMove = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterMonId], gBattlescriptCurrInstr[9]); + const u8 *learnedMovePtr = cmd->learnedMovePtr; + const u8 *nothingToLearnPtr = cmd->nothingToLearnPtr; + + u16 learnMove = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterMonId], cmd->isFirstMove); while (learnMove == MON_ALREADY_KNOWS_MOVE) learnMove = MonTryLearningNewMove(&gPlayerParty[gBattleStruct->expGetterMonId], FALSE); @@ -6925,7 +7132,7 @@ static void Cmd_handlelearnnewmove(void) } else if (learnMove == MON_HAS_MAX_MOVES) { - gBattlescriptCurrInstr += 10; + gBattlescriptCurrInstr = cmd->nextInstr; } else { @@ -6952,6 +7159,8 @@ static void Cmd_handlelearnnewmove(void) static void Cmd_yesnoboxlearnmove(void) { + CMD_ARGS(const u8 *forgotMovePtr); + gActiveBattler = 0; switch (gBattleScripting.learnMoveState) @@ -7030,7 +7239,7 @@ static void Cmd_yesnoboxlearnmove(void) } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->forgotMovePtr; PREPARE_MOVE_BUFFER(gBattleTextBuff2, moveId) @@ -7055,7 +7264,7 @@ static void Cmd_yesnoboxlearnmove(void) break; case 5: HandleBattleWindow(YESNOBOX_X_Y, WINDOW_CLEAR); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; break; case 6: if (gBattleControllerExecFlags == 0) @@ -7068,6 +7277,8 @@ static void Cmd_yesnoboxlearnmove(void) static void Cmd_yesnoboxstoplearningmove(void) { + CMD_ARGS(const u8 *noInstr); + switch (gBattleScripting.learnMoveState) { case 0: @@ -7097,16 +7308,16 @@ static void Cmd_yesnoboxstoplearningmove(void) PlaySE(SE_SELECT); if (gBattleCommunication[1] != 0) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->noInstr; else - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; HandleBattleWindow(YESNOBOX_X_Y, WINDOW_CLEAR); } else if (JOY_NEW(B_BUTTON)) { PlaySE(SE_SELECT); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->noInstr; HandleBattleWindow(YESNOBOX_X_Y, WINDOW_CLEAR); } break; @@ -7115,21 +7326,23 @@ static void Cmd_yesnoboxstoplearningmove(void) static void Cmd_hitanimation(void) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + CMD_ARGS(u8 battler); + + gActiveBattler = GetBattlerForBattleScript(cmd->battler); if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) { - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } else if (!(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE) || !(DoesSubstituteBlockMove(gBattlerAttacker, gActiveBattler, gCurrentMove)) || gDisableStructs[gActiveBattler].substituteHP == 0) { BtlController_EmitHitAnimation(BUFFER_A); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -7192,6 +7405,8 @@ static u32 GetTrainerMoneyToGive(u16 trainerId) static void Cmd_getmoneyreward(void) { + CMD_ARGS(); + u32 money; u8 sPartyLevel = 1; @@ -7224,13 +7439,15 @@ static void Cmd_getmoneyreward(void) } PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff1, 5, money); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } // Command is never used static void Cmd_updatebattlermoves(void) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + CMD_ARGS(u8 battler); + + gActiveBattler = GetBattlerForBattleScript(cmd->battler); switch (gBattleCommunication[0]) { @@ -7249,7 +7466,7 @@ static void Cmd_updatebattlermoves(void) gBattleMons[gActiveBattler].moves[i] = bufferPoke->moves[i]; gBattleMons[gActiveBattler].pp[i] = bufferPoke->pp[i]; } - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } break; } @@ -7257,6 +7474,8 @@ static void Cmd_updatebattlermoves(void) static void Cmd_swapattackerwithtarget(void) { + CMD_ARGS(); + gActiveBattler = gBattlerAttacker; gBattlerAttacker = gBattlerTarget; gBattlerTarget = gActiveBattler; @@ -7266,19 +7485,23 @@ static void Cmd_swapattackerwithtarget(void) else gHitMarker |= HITMARKER_SWAP_ATTACKER_TARGET; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_incrementgamestat(void) { - if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) - IncrementGameStat(gBattlescriptCurrInstr[1]); + CMD_ARGS(u8 stat); - gBattlescriptCurrInstr += 2; + if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) + IncrementGameStat(cmd->stat); + + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_drawpartystatussummary(void) { + CMD_ARGS(u8 battler); + s32 i; struct Pokemon *party; struct HpAndStatus hpStatuses[PARTY_SIZE]; @@ -7286,7 +7509,7 @@ static void Cmd_drawpartystatussummary(void) if (gBattleControllerExecFlags) return; - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) party = gPlayerParty; @@ -7311,21 +7534,25 @@ static void Cmd_drawpartystatussummary(void) BtlController_EmitDrawPartyStatusSummary(BUFFER_A, hpStatuses, 1); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_hidepartystatussummary(void) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + CMD_ARGS(u8 battler); + + gActiveBattler = GetBattlerForBattleScript(cmd->battler); BtlController_EmitHidePartyStatusSummary(BUFFER_A); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_jumptocalledmove(void) { - if (gBattlescriptCurrInstr[1]) + CMD_ARGS(bool8 notChosenMove); + + if (cmd->notChosenMove) gCurrentMove = gCalledMove; else gChosenMove = gCurrentMove = gCalledMove; @@ -7335,9 +7562,11 @@ static void Cmd_jumptocalledmove(void) static void Cmd_statusanimation(void) { + CMD_ARGS(u8 battler); + if (gBattleControllerExecFlags == 0) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBattler].substituteHP == 0 && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) @@ -7345,18 +7574,20 @@ static void Cmd_statusanimation(void) BtlController_EmitStatusAnimation(BUFFER_A, FALSE, gBattleMons[gActiveBattler].status1); MarkBattlerForControllerExec(gActiveBattler); } - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_status2animation(void) { + CMD_ARGS(u8 battler, u32 status2); + u32 wantedToAnimate; if (gBattleControllerExecFlags == 0) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); - wantedToAnimate = T1_READ_32(gBattlescriptCurrInstr + 2); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); + wantedToAnimate = cmd->status2; if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBattler].substituteHP == 0 && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) @@ -7364,31 +7595,35 @@ static void Cmd_status2animation(void) BtlController_EmitStatusAnimation(BUFFER_A, TRUE, gBattleMons[gActiveBattler].status2 & wantedToAnimate); MarkBattlerForControllerExec(gActiveBattler); } - gBattlescriptCurrInstr += 6; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_chosenstatusanimation(void) { + CMD_ARGS(u8 battler, bool8 isStatus2, u32 status); + u32 wantedStatus; if (gBattleControllerExecFlags == 0) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); - wantedStatus = T1_READ_32(gBattlescriptCurrInstr + 3); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); + wantedStatus = cmd->status; if (!(gStatuses3[gActiveBattler] & STATUS3_SEMI_INVULNERABLE) && gDisableStructs[gActiveBattler].substituteHP == 0 && !(gHitMarker & HITMARKER_NO_ANIMATIONS)) { - BtlController_EmitStatusAnimation(BUFFER_A, gBattlescriptCurrInstr[2], wantedStatus); + BtlController_EmitStatusAnimation(BUFFER_A, cmd->isStatus2, wantedStatus); MarkBattlerForControllerExec(gActiveBattler); } - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_yesnobox(void) { + CMD_ARGS(); + switch (gBattleCommunication[0]) { case 0: @@ -7418,13 +7653,13 @@ static void Cmd_yesnobox(void) gBattleCommunication[CURSOR_POSITION] = 1; PlaySE(SE_SELECT); HandleBattleWindow(YESNOBOX_X_Y, WINDOW_CLEAR); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } else if (JOY_NEW(A_BUTTON)) { PlaySE(SE_SELECT); HandleBattleWindow(YESNOBOX_X_Y, WINDOW_CLEAR); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } break; } @@ -7432,25 +7667,29 @@ static void Cmd_yesnobox(void) static void Cmd_cancelallactions(void) { + CMD_ARGS(); + s32 i; for (i = 0; i < gBattlersCount; i++) gActionsByTurnOrder[i] = B_ACTION_CANCEL_PARTNER; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_setgravity(void) { + CMD_ARGS(const u8 *failInstr); + if (gFieldStatuses & STATUS_FIELD_GRAVITY) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { gFieldStatuses |= STATUS_FIELD_GRAVITY; gFieldTimers.gravityTimer = 5; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -7519,16 +7758,18 @@ static bool32 TrySymbiosis(u32 battler, u32 itemId) static void Cmd_removeitem(void) { + CMD_ARGS(u8 battler); + u16 itemId = 0; if (gBattleScripting.overrideBerryRequirements) { // bug bite / pluck - don't remove current item - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; return; } - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); itemId = gBattleMons[gActiveBattler].item; // Popped Air Balloon cannot be restored by any means. @@ -7543,18 +7784,22 @@ static void Cmd_removeitem(void) ClearBattlerItemEffectHistory(gActiveBattler); if (!TryCheekPouch(gActiveBattler, itemId) && !TrySymbiosis(gActiveBattler, itemId)) - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_atknameinbuff1(void) { + CMD_ARGS(); + PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, gBattlerAttacker, gBattlerPartyIndexes[gBattlerAttacker]); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_drawlvlupbox(void) { + CMD_ARGS(); + if (gBattleScripting.drawlvlupboxState == 0) { // If the Pokémon getting exp is not in-battle then @@ -7648,7 +7893,7 @@ static void Cmd_drawlvlupbox(void) SetBgAttribute(1, BG_ATTR_PRIORITY, 1); ShowBg(0); ShowBg(1); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } break; } @@ -7836,33 +8081,41 @@ static bool32 IsMonGettingExpSentOut(void) static void Cmd_resetsentmonsvalue(void) { + CMD_ARGS(); + ResetSentPokesToOpponentValue(); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_setatktoplayer0(void) { + CMD_ARGS(); + gBattlerAttacker = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_makevisible(void) { + CMD_ARGS(u8 battler); + if (gBattleControllerExecFlags) return; - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); BtlController_EmitSpriteInvisibility(BUFFER_A, FALSE); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_recordability(void) { - u8 battler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + CMD_ARGS(u8 battler); + + u8 battler = GetBattlerForBattleScript(cmd->battler); RecordAbilityBattle(battler, gBattleMons[battler].ability); - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } void BufferMoveToLearnIntoBattleTextBuff2(void) @@ -7872,26 +8125,32 @@ void BufferMoveToLearnIntoBattleTextBuff2(void) static void Cmd_buffermovetolearn(void) { + CMD_ARGS(); + BufferMoveToLearnIntoBattleTextBuff2(); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_jumpifplayerran(void) { + CMD_ARGS(const u8 *jumpInstr); + if (TryRunFromBattle(gBattlerFainted)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_hpthresholds(void) { + CMD_ARGS(u8 battler); + u8 opposingBattler; s32 result; if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); opposingBattler = BATTLE_OPPOSITE(gActiveBattler); result = gBattleMons[opposingBattler].hp * 100 / gBattleMons[opposingBattler].maxHP; @@ -7908,18 +8167,20 @@ static void Cmd_hpthresholds(void) gBattleStruct->hpScale = 3; } - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_hpthresholds2(void) { + CMD_ARGS(u8 battler); + u8 opposingBattler; s32 result; u8 hpSwitchout; if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); opposingBattler = BATTLE_OPPOSITE(gActiveBattler); hpSwitchout = *(gBattleStruct->hpOnSwitchout + GetBattlerSide(opposingBattler)); result = (hpSwitchout - gBattleMons[opposingBattler].hp) * 100 / hpSwitchout; @@ -7934,14 +8195,16 @@ static void Cmd_hpthresholds2(void) gBattleStruct->hpScale = 3; } - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_useitemonopponent(void) { + CMD_ARGS(); + gBattlerInMenuId = gBattlerAttacker; PokemonUseItemEffects(&gEnemyParty[gBattlerPartyIndexes[gBattlerAttacker]], gLastUsedItem, gBattlerPartyIndexes[gBattlerAttacker], 0, TRUE); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static bool32 HasAttackerFaintedTarget(void) @@ -8320,6 +8583,8 @@ static bool32 CanTeleport(u8 battlerId) static void Cmd_various(void) { + CMD_ARGS(u8 battler, u8 id); + struct Pokemon *mon; s32 i, j; u8 data[10]; @@ -8328,93 +8593,125 @@ static void Cmd_various(void) if (gBattleControllerExecFlags) return; - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); - switch (gBattlescriptCurrInstr[2]) + switch (cmd->id) { // Roar will fail in a double wild battle when used by the player against one of the two alive wild mons. // Also when an opposing wild mon uses it againt its partner. case VARIOUS_JUMP_IF_ROAR_FAILS: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (WILD_DOUBLE_BATTLE && GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER && GetBattlerSide(gBattlerTarget) == B_SIDE_OPPONENT && IS_WHOLE_SIDE_ALIVE(gBattlerTarget)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else if (WILD_DOUBLE_BATTLE && GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT && GetBattlerSide(gBattlerTarget) == B_SIDE_OPPONENT) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_JUMP_IF_ABSENT: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (!IsBattlerAlive(gActiveBattler)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_JUMP_IF_SHIELDS_DOWN_PROTECTED: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (IsShieldsDownProtected(gActiveBattler)) { gBattlerAbility = gActiveBattler; - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; } else { - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_JUMP_IF_NO_HOLD_EFFECT: - if (GetBattlerHoldEffect(gActiveBattler, TRUE) != gBattlescriptCurrInstr[3]) + { + VARIOUS_ARGS(u8 holdEffect, const u8 *jumpInstr); + if (GetBattlerHoldEffect(gActiveBattler, TRUE) != cmd->holdEffect) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 4); + gBattlescriptCurrInstr = cmd->jumpInstr; } else { gLastUsedItem = gBattleMons[gActiveBattler].item; // For B_LAST_USED_ITEM - gBattlescriptCurrInstr += 8; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_JUMP_IF_NO_ALLY: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (!IsBattlerAlive(BATTLE_PARTNER(gActiveBattler))) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_INFATUATE_WITH_BATTLER: + { + VARIOUS_ARGS(u8 infatuateWith); gBattleScripting.battler = gActiveBattler; - gBattleMons[gActiveBattler].status2 |= STATUS2_INFATUATED_WITH(GetBattlerForBattleScript(gBattlescriptCurrInstr[3])); - gBattlescriptCurrInstr += 4; + gBattleMons[gActiveBattler].status2 |= STATUS2_INFATUATED_WITH(GetBattlerForBattleScript(cmd->infatuateWith)); + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_SET_LAST_USED_ITEM: + { + VARIOUS_ARGS(); gLastUsedItem = gBattleMons[gActiveBattler].item; break; + } case VARIOUS_TRY_FAIRY_LOCK: + { + VARIOUS_ARGS(const u8 *failInstr); if (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { gFieldStatuses |= STATUS_FIELD_FAIRY_LOCK; gFieldTimers.fairyLockTimer = 2; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_GET_STAT_VALUE: - i = gBattlescriptCurrInstr[3]; + { + VARIOUS_ARGS(u8 stat); + i = cmd->stat; gBattleMoveDamage = *(u16 *)(&gBattleMons[gActiveBattler].attack) + (i - 1); gBattleMoveDamage *= gStatStageRatios[gBattleMons[gActiveBattler].statStages[i]][0]; gBattleMoveDamage /= gStatStageRatios[gBattleMons[gActiveBattler].statStages[i]][1]; - gBattlescriptCurrInstr += 4; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_JUMP_IF_FULL_HP: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (BATTLER_MAX_HP(gActiveBattler)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_TRY_FRISK: + { + VARIOUS_ARGS(); while (gBattleStruct->friskedBattler < gBattlersCount) { gBattlerTarget = gBattleStruct->friskedBattler++; @@ -8441,54 +8738,78 @@ static void Cmd_various(void) gBattleStruct->friskedBattler = 0; gBattleStruct->friskedAbility = FALSE; break; + } case VARIOUS_POISON_TYPE_IMMUNITY: - if (!CanPoisonType(gActiveBattler, GetBattlerForBattleScript(gBattlescriptCurrInstr[3]))) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 4); + { + VARIOUS_ARGS(u8 target, const u8 *failInstr); + if (!CanPoisonType(gActiveBattler, GetBattlerForBattleScript(cmd->target))) + gBattlescriptCurrInstr = cmd->failInstr; else - gBattlescriptCurrInstr += 8; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_PARALYZE_TYPE_IMMUNITY: - if (!CanParalyzeType(gActiveBattler, GetBattlerForBattleScript(gBattlescriptCurrInstr[3]))) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 4); + { + VARIOUS_ARGS(u8 target, const u8 *failInstr); + if (!CanParalyzeType(gActiveBattler, GetBattlerForBattleScript(cmd->target))) + gBattlescriptCurrInstr = cmd->failInstr; else - gBattlescriptCurrInstr += 8; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_TRACE_ABILITY: + { + VARIOUS_ARGS(); gBattleMons[gActiveBattler].ability = gBattleStruct->overwrittenAbilities[gActiveBattler] = gBattleStruct->tracedAbility[gActiveBattler]; break; + } case VARIOUS_TRY_ILLUSION_OFF: + { + VARIOUS_ARGS(); if (GetIllusionMonPtr(gActiveBattler) != NULL) { - gBattlescriptCurrInstr += 3; + gBattlescriptCurrInstr = cmd->nextInstr; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_IllusionOff; return; } break; + } case VARIOUS_SET_SPRITEIGNORE0HP: - gBattleStruct->spriteIgnore0Hp = gBattlescriptCurrInstr[3]; - gBattlescriptCurrInstr += 4; + { + VARIOUS_ARGS(bool8 ignore0HP); + gBattleStruct->spriteIgnore0Hp = cmd->ignore0HP; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_UPDATE_NICK: + { + VARIOUS_ARGS(); if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]; else mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]; UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], mon, HEALTHBOX_NICK); break; + } case VARIOUS_JUMP_IF_NOT_BERRY: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (ItemId_GetPocket(gBattleMons[gActiveBattler].item) == POCKET_BERRIES) - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; return; + } case VARIOUS_CHECK_IF_GRASSY_TERRAIN_HEALS: + { + VARIOUS_ARGS(const u8 *failInstr); if ((gStatuses3[gActiveBattler] & (STATUS3_SEMI_INVULNERABLE | STATUS3_HEAL_BLOCK)) || BATTLER_MAX_HP(gActiveBattler) || !gBattleMons[gActiveBattler].hp || !(IsBattlerGrounded(gActiveBattler))) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -8497,17 +8818,23 @@ static void Cmd_various(void) gBattleMoveDamage = 1; gBattleMoveDamage *= -1; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_GRAVITY_ON_AIRBORNE_MONS: + { + VARIOUS_ARGS(); // Cancel all multiturn moves of IN_AIR Pokemon except those being targeted by Sky Drop. if (gStatuses3[gActiveBattler] & STATUS3_ON_AIR && !(gStatuses3[gActiveBattler] & STATUS3_SKY_DROPPED)) CancelMultiTurnMoves(gActiveBattler); gStatuses3[gActiveBattler] &= ~(STATUS3_MAGNET_RISE | STATUS3_TELEKINESIS | STATUS3_ON_AIR | STATUS3_SKY_DROPPED); break; + } case VARIOUS_SPECTRAL_THIEF: + { + VARIOUS_ARGS(); // Raise stats for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) { @@ -8524,10 +8851,16 @@ static void Cmd_various(void) } } break; + } case VARIOUS_SET_POWDER: + { + VARIOUS_ARGS(); gBattleMons[gActiveBattler].status2 |= STATUS2_POWDER; break; + } case VARIOUS_ACUPRESSURE: + { + VARIOUS_ARGS(const u8 *failInstr); bits = 0; for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) { @@ -8543,17 +8876,23 @@ static void Cmd_various(void) } while (!(bits & gBitTable[statId])); SET_STATCHANGER(statId, 2, FALSE); - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } return; + } case VARIOUS_CANCEL_MULTI_TURN_MOVES: + { + VARIOUS_ARGS(); CancelMultiTurnMoves(gActiveBattler); break; + } case VARIOUS_SET_MAGIC_COAT_TARGET: + { + VARIOUS_ARGS(); gBattleStruct->attackerBeforeBounce = gActiveBattler; gBattlerAttacker = gBattlerTarget; side = BATTLE_OPPOSITE(GetBattlerSide(gBattlerAttacker)); @@ -8562,23 +8901,38 @@ static void Cmd_various(void) else gBattlerTarget = gActiveBattler; break; + } case VARIOUS_IS_RUNNING_IMPOSSIBLE: + { + VARIOUS_ARGS(); gBattleCommunication[0] = IsRunningFromBattleImpossible(); break; + } case VARIOUS_GET_MOVE_TARGET: + { + VARIOUS_ARGS(); gBattlerTarget = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); break; + } case VARIOUS_GET_BATTLER_FAINTED: + { + VARIOUS_ARGS(); if (gHitMarker & HITMARKER_FAINTED(gActiveBattler)) gBattleCommunication[0] = TRUE; else gBattleCommunication[0] = FALSE; break; + } case VARIOUS_RESET_SWITCH_IN_ABILITY_BITS: + { + VARIOUS_ARGS(); gSpecialStatuses[gActiveBattler].traced = FALSE; gSpecialStatuses[gActiveBattler].switchInAbilityDone = FALSE; break; + } case VARIOUS_UPDATE_CHOICE_MOVE_ON_LVL_UP: + { + VARIOUS_ARGS(); if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId || gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId) { if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId) @@ -8595,7 +8949,10 @@ static void Cmd_various(void) gBattleStruct->choicedMove[gActiveBattler] = MOVE_NONE; } break; + } case VARIOUS_RESET_PLAYER_FAINTED: + { + VARIOUS_ARGS(); if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE)) && gBattleTypeFlags & BATTLE_TYPE_TRAINER && gBattleMons[0].hp != 0 @@ -8604,7 +8961,10 @@ static void Cmd_various(void) gHitMarker &= ~HITMARKER_PLAYER_FAINTED; } break; + } case VARIOUS_PALACE_FLAVOR_TEXT: + { + VARIOUS_ARGS(); // Try and print end-of-turn Battle Palace flavor text (e.g. "A glint appears in mon's eyes") gBattleCommunication[0] = FALSE; // whether or not msg should be printed gBattleScripting.battler = gActiveBattler = gBattleCommunication[1]; @@ -8618,7 +8978,11 @@ static void Cmd_various(void) gBattleCommunication[MULTISTRING_CHOOSER] = sBattlePalaceNatureToFlavorTextId[GetNatureFromPersonality(gBattleMons[gActiveBattler].personality)]; } break; + } case VARIOUS_ARENA_JUDGMENT_WINDOW: + { + VARIOUS_ARGS(); + i = BattleArena_ShowJudgmentWindow(&gBattleCommunication[0]); // BattleArena_ShowJudgmentWindow's last state was an intermediate step. @@ -8628,20 +8992,29 @@ static void Cmd_various(void) gBattleCommunication[1] = i; break; + } case VARIOUS_ARENA_OPPONENT_MON_LOST: + { + VARIOUS_ARGS(); gBattleMons[1].hp = 0; gHitMarker |= HITMARKER_FAINTED(1); gBattleStruct->arenaLostOpponentMons |= gBitTable[gBattlerPartyIndexes[1]]; gDisableStructs[1].truantSwitchInHack = 1; break; + } case VARIOUS_ARENA_PLAYER_MON_LOST: + { + VARIOUS_ARGS(); gBattleMons[0].hp = 0; gHitMarker |= HITMARKER_FAINTED(0); gHitMarker |= HITMARKER_PLAYER_FAINTED; gBattleStruct->arenaLostPlayerMons |= gBitTable[gBattlerPartyIndexes[0]]; gDisableStructs[0].truantSwitchInHack = 1; break; + } case VARIOUS_ARENA_BOTH_MONS_LOST: + { + VARIOUS_ARGS(); gBattleMons[0].hp = 0; gBattleMons[1].hp = 0; gHitMarker |= HITMARKER_FAINTED(0); @@ -8652,29 +9025,50 @@ static void Cmd_various(void) gDisableStructs[0].truantSwitchInHack = 1; gDisableStructs[1].truantSwitchInHack = 1; break; + } case VARIOUS_EMIT_YESNOBOX: + { + VARIOUS_ARGS(); BtlController_EmitYesNoBox(BUFFER_A); MarkBattlerForControllerExec(gActiveBattler); break; + } case VARIOUS_DRAW_ARENA_REF_TEXT_BOX: + { + VARIOUS_ARGS(); DrawArenaRefereeTextBox(); break; + } case VARIOUS_ERASE_ARENA_REF_TEXT_BOX: + { + VARIOUS_ARGS(); EraseArenaRefereeTextBox(); break; + } case VARIOUS_ARENA_JUDGMENT_STRING: - BattleStringExpandPlaceholdersToDisplayedString(gRefereeStringsTable[gBattlescriptCurrInstr[1]]); + { + CMD_ARGS(u8 id, u8 _); + BattleStringExpandPlaceholdersToDisplayedString(gRefereeStringsTable[cmd->id]); BattlePutTextOnWindow(gDisplayedStringBattle, ARENA_WIN_JUDGMENT_TEXT); break; + } case VARIOUS_ARENA_WAIT_STRING: + { + VARIOUS_ARGS(); if (IsTextPrinterActive(ARENA_WIN_JUDGMENT_TEXT)) return; break; + } case VARIOUS_WAIT_CRY: + { + VARIOUS_ARGS(); if (!IsCryFinished()) return; break; + } case VARIOUS_RETURN_OPPONENT_MON1: + { + VARIOUS_ARGS(); gActiveBattler = 1; if (gBattleMons[gActiveBattler].hp != 0) { @@ -8682,7 +9076,10 @@ static void Cmd_various(void) MarkBattlerForControllerExec(gActiveBattler); } break; + } case VARIOUS_RETURN_OPPONENT_MON2: + { + VARIOUS_ARGS(); if (gBattlersCount > 3) { gActiveBattler = 3; @@ -8693,20 +9090,35 @@ static void Cmd_various(void) } } break; + } case VARIOUS_VOLUME_DOWN: + { + VARIOUS_ARGS(); m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x55); break; + } case VARIOUS_VOLUME_UP: + { + VARIOUS_ARGS(); m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 0x100); break; + } case VARIOUS_SET_ALREADY_STATUS_MOVE_ATTEMPT: + { + VARIOUS_ARGS(); gBattleStruct->alreadyStatusedMoveAttempt |= gBitTable[gActiveBattler]; break; + } case VARIOUS_PALACE_TRY_ESCAPE_STATUS: + { + VARIOUS_ARGS(); if (BattlePalace_TryEscapeStatus(gActiveBattler)) return; break; + } case VARIOUS_SET_TELEPORT_OUTCOME: + { + VARIOUS_ARGS(); // Don't end the battle if one of the wild mons teleported from the wild double battle // and its partner is still alive. if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT && IsBattlerAlive(BATTLE_PARTNER(gActiveBattler))) @@ -8727,35 +9139,59 @@ static void Cmd_various(void) gBattleOutcome = B_OUTCOME_MON_TELEPORTED; } break; + } case VARIOUS_PLAY_TRAINER_DEFEATED_MUSIC: + { + VARIOUS_ARGS(); BtlController_EmitPlayFanfareOrBGM(BUFFER_A, MUS_VICTORY_TRAINER, TRUE); MarkBattlerForControllerExec(gActiveBattler); break; + } case VARIOUS_STAT_TEXT_BUFFER: + { + VARIOUS_ARGS(); PREPARE_STAT_BUFFER(gBattleTextBuff1, gBattleCommunication[0]); break; + } case VARIOUS_SWITCHIN_ABILITIES: - gBattlescriptCurrInstr += 3; + { + VARIOUS_ARGS(); + gBattlescriptCurrInstr = cmd->nextInstr; AbilityBattleEffects(ABILITYEFFECT_NEUTRALIZINGGAS, gActiveBattler, 0, 0, 0); AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gActiveBattler, 0, 0, 0); AbilityBattleEffects(ABILITYEFFECT_TRACE2, gActiveBattler, 0, 0, 0); return; + } case VARIOUS_SAVE_TARGET: + { + VARIOUS_ARGS(); gBattleStruct->savedBattlerTarget = gBattlerTarget; break; + } case VARIOUS_RESTORE_TARGET: + { + VARIOUS_ARGS(); gBattlerTarget = gBattleStruct->savedBattlerTarget; break; + } case VARIOUS_INSTANT_HP_DROP: + { + VARIOUS_ARGS(); BtlController_EmitHealthBarUpdate(BUFFER_A, INSTANT_HP_BAR_DROP); MarkBattlerForControllerExec(gActiveBattler); break; + } case VARIOUS_CLEAR_STATUS: + { + VARIOUS_ARGS(); gBattleMons[gActiveBattler].status1 = 0; BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gActiveBattler].status1), &gBattleMons[gActiveBattler].status1); MarkBattlerForControllerExec(gActiveBattler); break; + } case VARIOUS_RESTORE_PP: + { + VARIOUS_ARGS(); for (i = 0; i < 4; i++) { gBattleMons[gActiveBattler].pp[i] = CalculatePPWithBonus(gBattleMons[gActiveBattler].moves[i], gBattleMons[gActiveBattler].ppBonuses, i); @@ -8765,8 +9201,11 @@ static void Cmd_various(void) BtlController_EmitSetMonData(BUFFER_A, REQUEST_PP_DATA_BATTLE, 0, 5, data); MarkBattlerForControllerExec(gActiveBattler); break; + } case VARIOUS_TRY_ACTIVATE_MOXIE: // and chilling neigh + as one ice rider { + VARIOUS_ARGS(); + u16 battlerAbility = GetBattlerAbility(gActiveBattler); if ((battlerAbility == ABILITY_MOXIE @@ -8779,17 +9218,19 @@ static void Cmd_various(void) gBattleMons[gBattlerAttacker].statStages[STAT_ATK]++; SET_STATCHANGER(STAT_ATK, 1, FALSE); PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK); - BattleScriptPush(gBattlescriptCurrInstr + 3); + BattleScriptPush(cmd->nextInstr); gLastUsedAbility = battlerAbility; if (battlerAbility == ABILITY_AS_ONE_ICE_RIDER) gBattleScripting.abilityPopupOverwrite = gLastUsedAbility = ABILITY_CHILLING_NEIGH; gBattlescriptCurrInstr = BattleScript_RaiseStatOnFaintingTarget; return; } - } break; + } case VARIOUS_TRY_ACTIVATE_GRIM_NEIGH: // and as one shadow rider { + VARIOUS_ARGS(); + u16 battlerAbility = GetBattlerAbility(gActiveBattler); if ((battlerAbility == ABILITY_GRIM_NEIGH @@ -8801,16 +9242,18 @@ static void Cmd_various(void) gBattleMons[gBattlerAttacker].statStages[STAT_SPATK]++; SET_STATCHANGER(STAT_SPATK, 1, FALSE); PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_SPATK); - BattleScriptPush(gBattlescriptCurrInstr + 3); + BattleScriptPush(cmd->nextInstr); gLastUsedAbility = battlerAbility; if (battlerAbility == ABILITY_AS_ONE_SHADOW_RIDER) gBattleScripting.abilityPopupOverwrite = gLastUsedAbility = ABILITY_GRIM_NEIGH; gBattlescriptCurrInstr = BattleScript_RaiseStatOnFaintingTarget; return; } - } break; + } case VARIOUS_TRY_ACTIVATE_RECEIVER: // Partner gets fainted's ally ability + { + VARIOUS_ARGS(); gBattlerAbility = BATTLE_PARTNER(gActiveBattler); i = GetBattlerAbility(gBattlerAbility); if (IsBattlerAlive(gBattlerAbility) @@ -8832,13 +9275,16 @@ static void Cmd_various(void) default: gBattleStruct->tracedAbility[gBattlerAbility] = gBattleMons[gActiveBattler].ability; // re-using the variable for trace gBattleScripting.battler = gActiveBattler; - BattleScriptPush(gBattlescriptCurrInstr + 3); + BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_ReceiverActivates; return; } } break; + } case VARIOUS_TRY_ACTIVATE_BEAST_BOOST: + { + VARIOUS_ARGS(); i = GetHighestStatId(gActiveBattler); if (GetBattlerAbility(gActiveBattler) == ABILITY_BEAST_BOOST && HasAttackerFaintedTarget() @@ -8848,12 +9294,15 @@ static void Cmd_various(void) gBattleMons[gBattlerAttacker].statStages[i]++; SET_STATCHANGER(i, 1, FALSE); PREPARE_STAT_BUFFER(gBattleTextBuff1, i); - BattleScriptPush(gBattlescriptCurrInstr + 3); + BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_AttackerAbilityStatRaise; return; } break; + } case VARIOUS_TRY_ACTIVATE_SOULHEART: + { + VARIOUS_ARGS(); while (gBattleStruct->soulheartBattlerId < gBattlersCount) { gBattleScripting.battler = gBattleStruct->soulheartBattlerId++; @@ -8872,7 +9321,10 @@ static void Cmd_various(void) } gBattleStruct->soulheartBattlerId = 0; break; + } case VARIOUS_TRY_ACTIVATE_FELL_STINGER: + { + VARIOUS_ARGS(); if (gBattleMoves[gCurrentMove].effect == EFFECT_FELL_STINGER && HasAttackerFaintedTarget() && !NoAliveMonsForEitherParty() @@ -8884,50 +9336,62 @@ static void Cmd_various(void) SET_STATCHANGER(STAT_ATK, 2, FALSE); #endif PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK); - BattleScriptPush(gBattlescriptCurrInstr + 3); + BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_FellStingerRaisesStat; return; } break; + } case VARIOUS_PLAY_MOVE_ANIMATION: - BtlController_EmitMoveAnimation(BUFFER_A, T1_READ_16(gBattlescriptCurrInstr + 3), gBattleScripting.animTurn, 0, 0, gBattleMons[gActiveBattler].friendship, &gDisableStructs[gActiveBattler], gMultiHitCounter); + { + VARIOUS_ARGS(u16 move); + BtlController_EmitMoveAnimation(BUFFER_A, cmd->move, gBattleScripting.animTurn, 0, 0, gBattleMons[gActiveBattler].friendship, &gDisableStructs[gActiveBattler], gMultiHitCounter); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_SET_LUCKY_CHANT: + { + VARIOUS_ARGS(const u8 *failInstr); if (!(gSideStatuses[GET_BATTLER_SIDE(gActiveBattler)] & SIDE_STATUS_LUCKY_CHANT)) { gSideStatuses[GET_BATTLER_SIDE(gActiveBattler)] |= SIDE_STATUS_LUCKY_CHANT; gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].luckyChantBattlerId = gActiveBattler; gSideTimers[GET_BATTLER_SIDE(gActiveBattler)].luckyChantTimer = 5; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } return; + } case VARIOUS_SUCKER_PUNCH_CHECK: + { + VARIOUS_ARGS(const u8 *failInstr); if (gProtectStructs[gBattlerTarget].obstructed) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; else if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; else if (IS_MOVE_STATUS(gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]])) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_SET_SIMPLE_BEAM: + { + VARIOUS_ARGS(const u8 *failInstr); if (IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability) || gBattleMons[gBattlerTarget].ability == ABILITY_SIMPLE) { RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_ABILITY_SHIELD); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -8935,41 +9399,50 @@ static void Cmd_various(void) gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = TRUE; gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = ABILITY_SIMPLE; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_TRY_ENTRAINMENT: + { + VARIOUS_ARGS(const u8 *failInstr); if (IsEntrainmentBannedAbilityAttacker(gBattleMons[gBattlerAttacker].ability) || IsEntrainmentTargetOrSimpleBeamBannedAbility(gBattleMons[gBattlerTarget].ability)) { RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_ABILITY_SHIELD); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { if (gBattleMons[gBattlerTarget].ability == gBattleMons[gBattlerAttacker].ability) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = gBattleMons[gBattlerAttacker].ability; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } } return; + } case VARIOUS_SET_LAST_USED_ABILITY: + { + VARIOUS_ARGS(); gLastUsedAbility = gBattleMons[gActiveBattler].ability; break; + } case VARIOUS_TRY_HEAL_PULSE: + { + VARIOUS_ARGS(const u8 *failInstr); if (BATTLER_MAX_HP(gActiveBattler)) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -8980,21 +9453,27 @@ static void Cmd_various(void) if (gBattleMoveDamage == 0) gBattleMoveDamage = -1; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_TRY_QUASH: + { + VARIOUS_ARGS(const u8 *failInstr); if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) // It's true if foe is faster, has a bigger priority, or switches { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // This replaces the current battlescript with the "fail" script. + gBattlescriptCurrInstr = cmd->failInstr; // This replaces the current battlescript with the "fail" script. } else // If the condition is not true, it means we are faster than the foe, so we can set the quash bit { gProtectStructs[gBattlerTarget].quash = TRUE; - gBattlescriptCurrInstr += 7; // and then we proceed with the rest of our battlescript + gBattlescriptCurrInstr = cmd->nextInstr; // and then we proceed with the rest of our battlescript } return; + } case VARIOUS_INVERT_STAT_STAGES: + { + VARIOUS_ARGS(); for (i = 0; i < NUM_BATTLE_STATS; i++) { if (gBattleMons[gActiveBattler].statStages[i] < DEFAULT_STAT_STAGE) // Negative becomes positive. @@ -9003,14 +9482,20 @@ static void Cmd_various(void) gBattleMons[gActiveBattler].statStages[i] = DEFAULT_STAT_STAGE - (gBattleMons[gActiveBattler].statStages[i] - DEFAULT_STAT_STAGE); } break; + } case VARIOUS_SET_TERRAIN: + { + VARIOUS_ARGS(const u8 *failInstr); HandleTerrainMove(gCurrentMove); return; + } case VARIOUS_TRY_ME_FIRST: + { + VARIOUS_ARGS(const u8 *failInstr); if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; else if (IS_MOVE_STATUS(gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]])) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; else { u16 move = gBattleMons[gBattlerTarget].moves[gBattleStruct->chosenMovePositions[gBattlerTarget]]; @@ -9026,84 +9511,100 @@ static void Cmd_various(void) case MOVE_METAL_BURST: case MOVE_ME_FIRST: case MOVE_BEAK_BLAST: - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; break; default: gCalledMove = move; gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); gStatuses3[gBattlerAttacker] |= STATUS3_ME_FIRST; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; break; } } return; + } case VARIOUS_JUMP_IF_BATTLE_END: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (NoAliveMonsForEitherParty()) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_TRY_ELECTRIFY: + { + VARIOUS_ARGS(const u8 *failInstr); if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { gStatuses4[gBattlerTarget] |= STATUS4_ELECTRIFIED; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_TRY_REFLECT_TYPE: + { + VARIOUS_ARGS(const u8 *failInstr); if (gBattleMons[gBattlerTarget].species == SPECIES_ARCEUS || gBattleMons[gBattlerTarget].species == SPECIES_SILVALLY) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else if (gBattleMons[gBattlerTarget].type1 == TYPE_MYSTERY && gBattleMons[gBattlerTarget].type2 != TYPE_MYSTERY) { gBattleMons[gBattlerAttacker].type1 = gBattleMons[gBattlerTarget].type2; gBattleMons[gBattlerAttacker].type2 = gBattleMons[gBattlerTarget].type2; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } else if (gBattleMons[gBattlerTarget].type1 != TYPE_MYSTERY && gBattleMons[gBattlerTarget].type2 == TYPE_MYSTERY) { gBattleMons[gBattlerAttacker].type1 = gBattleMons[gBattlerTarget].type1; gBattleMons[gBattlerAttacker].type2 = gBattleMons[gBattlerTarget].type1; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } else if (gBattleMons[gBattlerTarget].type1 == TYPE_MYSTERY && gBattleMons[gBattlerTarget].type2 == TYPE_MYSTERY) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { gBattleMons[gBattlerAttacker].type1 = gBattleMons[gBattlerTarget].type1; gBattleMons[gBattlerAttacker].type2 = gBattleMons[gBattlerTarget].type2; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_TRY_SOAK: + { + VARIOUS_ARGS(const u8 *failInstr); if (gBattleMons[gBattlerTarget].type1 == gBattleMoves[gCurrentMove].type && gBattleMons[gBattlerTarget].type2 == gBattleMoves[gCurrentMove].type) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { SET_BATTLER_TYPE(gBattlerTarget, gBattleMoves[gCurrentMove].type); PREPARE_TYPE_BUFFER(gBattleTextBuff1, gBattleMoves[gCurrentMove].type); - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_HANDLE_MEGA_EVO: + { + VARIOUS_ARGS(u8 case_); + if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT) mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]; else mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]; // Change species. - if (gBattlescriptCurrInstr[3] == 0) + if (cmd->case_ == 0) { u16 megaSpecies; gBattleStruct->mega.evolvedSpecies[gActiveBattler] = gBattleMons[gActiveBattler].species; @@ -9127,7 +9628,7 @@ static void Cmd_various(void) MarkBattlerForControllerExec(gActiveBattler); } // Change stats. - else if (gBattlescriptCurrInstr[3] == 1) + else if (cmd->case_ == 1) { RecalcBattlerStats(gActiveBattler, mon); gBattleStruct->mega.alreadyEvolved[GetBattlerPosition(gActiveBattler)] = TRUE; @@ -9141,16 +9642,19 @@ static void Cmd_various(void) if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT) SetBattlerShadowSpriteCallback(gActiveBattler, gBattleMons[gActiveBattler].species); } - gBattlescriptCurrInstr += 4; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_HANDLE_PRIMAL_REVERSION: + { + VARIOUS_ARGS(u8 case_); if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT) mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]; else mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]; // Change species. - if (gBattlescriptCurrInstr[3] == 0) + if (cmd->case_ == 0) { u16 primalSpecies; gBattleStruct->mega.primalRevertedSpecies[gActiveBattler] = gBattleMons[gActiveBattler].species; @@ -9169,7 +9673,7 @@ static void Cmd_various(void) MarkBattlerForControllerExec(gActiveBattler); } // Change stats. - else if (gBattlescriptCurrInstr[3] == 1) + else if (cmd->case_ == 1) { RecalcBattlerStats(gActiveBattler, mon); gBattleStruct->mega.primalRevertedPartyIds[GetBattlerSide(gActiveBattler)] |= gBitTable[gBattlerPartyIndexes[gActiveBattler]]; @@ -9182,16 +9686,19 @@ static void Cmd_various(void) if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT) SetBattlerShadowSpriteCallback(gActiveBattler, gBattleMons[gActiveBattler].species); } - gBattlescriptCurrInstr += 4; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_HANDLE_FORM_CHANGE: + { + VARIOUS_ARGS(u8 case_); if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT) mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]; else mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]; // Change species. - if (gBattlescriptCurrInstr[3] == 0) + if (cmd->case_ == 0) { if (!gBattleTextBuff1) PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].species); @@ -9199,7 +9706,7 @@ static void Cmd_various(void) MarkBattlerForControllerExec(gActiveBattler); } // Change stats. - else if (gBattlescriptCurrInstr[3] == 1) + else if (cmd->case_ == 1) { RecalcBattlerStats(gActiveBattler, mon); } @@ -9208,15 +9715,21 @@ static void Cmd_various(void) { UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], mon, HEALTHBOX_ALL); } - gBattlescriptCurrInstr += 4; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_TRY_LAST_RESORT: + { + VARIOUS_ARGS(const u8 *failInstr); if (CanUseLastResort(gActiveBattler)) - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; return; + } case VARIOUS_ARGUMENT_STATUS_EFFECT: + { + VARIOUS_ARGS(); switch (gBattleMoves[gCurrentMove].argument) { case STATUS1_SLEEP: @@ -9243,12 +9756,15 @@ static void Cmd_various(void) } if (gBattleScripting.moveEffect != 0) { - BattleScriptPush(gBattlescriptCurrInstr + 3); + BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_EffectWithChance; return; } break; + } case VARIOUS_TRY_HIT_SWITCH_TARGET: + { + VARIOUS_ARGS(const u8 *failInstr); if (IsBattlerAlive(gBattlerAttacker) && IsBattlerAlive(gBattlerTarget) && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) @@ -9260,38 +9776,47 @@ static void Cmd_various(void) } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } return; + } case VARIOUS_TRY_AUTOTOMIZE: + { + VARIOUS_ARGS(const u8 *failInstr); if (GetBattlerWeight(gActiveBattler) > 1) { gDisableStructs[gActiveBattler].autotomizeCount++; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } return; + } case VARIOUS_TRY_COPYCAT: + { + VARIOUS_ARGS(const u8 *failInstr); if (gLastUsedMove == 0xFFFF || (sForbiddenMoves[gLastUsedMove] & FORBIDDEN_COPYCAT)) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { gCalledMove = gLastUsedMove; gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_TRY_INSTRUCT: + { + VARIOUS_ARGS(const u8 *failInstr); if ((sForbiddenMoves[gLastMoves[gBattlerTarget]] & FORBIDDEN_INSTRUCT) || gLastMoves[gBattlerTarget] == 0xFFFF) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -9308,59 +9833,80 @@ static void Cmd_various(void) } } if (i != 4 || gBattleMons[gBattlerAttacker].pp[gCurrMovePos] == 0) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; else { gBattlerTarget = gBattleStruct->lastMoveTarget[gBattlerAttacker]; gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gActiveBattler, gBattlerPartyIndexes[gActiveBattler]); - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } } return; + } case VARIOUS_ABILITY_POPUP: + { + VARIOUS_ARGS(); CreateAbilityPopUp(gActiveBattler, gBattleMons[gActiveBattler].ability, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0); break; + } case VARIOUS_UPDATE_ABILITY_POPUP: + { + VARIOUS_ARGS(); UpdateAbilityPopup(gActiveBattler); break; + } case VARIOUS_DEFOG: - if (T1_READ_8(gBattlescriptCurrInstr + 3)) // Clear + { + VARIOUS_ARGS(bool8 clear, const u8 *failInstr); + if (cmd->clear) // Clear { if (ClearDefogHazards(gEffectBattler, TRUE)) return; else - gBattlescriptCurrInstr += 8; + gBattlescriptCurrInstr = cmd->nextInstr; } else { if (ClearDefogHazards(gActiveBattler, FALSE)) - gBattlescriptCurrInstr += 8; + gBattlescriptCurrInstr = cmd->nextInstr; else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 4); + gBattlescriptCurrInstr = cmd->failInstr; } return; + } case VARIOUS_JUMP_IF_TARGET_ALLY: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)) - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; return; + } case VARIOUS_TRY_SYNCHRONOISE: + { + VARIOUS_ARGS(const u8 *failInstr); if (!DoBattlersShareType(gBattlerAttacker, gBattlerTarget)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_LOSE_TYPE: + { + VARIOUS_ARGS(u8 type); for (i = 0; i < 3; i++) { - if (*(u8 *)(&gBattleMons[gActiveBattler].type1 + i) == gBattlescriptCurrInstr[3]) + if (*(u8 *)(&gBattleMons[gActiveBattler].type1 + i) == cmd->type) *(u8 *)(&gBattleMons[gActiveBattler].type1 + i) = TYPE_MYSTERY; } - gBattlescriptCurrInstr += 4; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_PSYCHO_SHIFT: + { + VARIOUS_ARGS(const u8 *failInstr); // Psycho shift works if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_POISON) && CanBePoisoned(gBattlerAttacker, gBattlerTarget)) gBattleCommunication[MULTISTRING_CHOOSER] = 0; @@ -9374,29 +9920,38 @@ static void Cmd_various(void) gBattleCommunication[MULTISTRING_CHOOSER] = 4; else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; return; } gBattleMons[gBattlerTarget].status1 = gBattleMons[gBattlerAttacker].status1 & STATUS1_ANY; gActiveBattler = gBattlerTarget; BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gActiveBattler].status1), &gBattleMons[gActiveBattler].status1); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 7; - return; + gBattlescriptCurrInstr = cmd->nextInstr; + return; + } case VARIOUS_CURE_STATUS: + { + VARIOUS_ARGS(); gBattleMons[gActiveBattler].status1 = 0; BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gActiveBattler].status1), &gBattleMons[gActiveBattler].status1); MarkBattlerForControllerExec(gActiveBattler); break; + } case VARIOUS_POWER_TRICK: + { + VARIOUS_ARGS(); gStatuses3[gActiveBattler] ^= STATUS3_POWER_TRICK; SWAP(gBattleMons[gActiveBattler].attack, gBattleMons[gActiveBattler].defense, i); break; + } case VARIOUS_AFTER_YOU: + { + VARIOUS_ARGS(const u8 *failInstr); if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget) || GetBattlerTurnOrderNum(gBattlerAttacker) + 1 == GetBattlerTurnOrderNum(gBattlerTarget)) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -9420,39 +9975,51 @@ static void Cmd_various(void) gBattlerByTurnOrder[3] = data[2]; } gSpecialStatuses[gBattlerTarget].afterYou = 1; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_BESTOW: + { + VARIOUS_ARGS(const u8 *failInstr); if (gBattleMons[gBattlerAttacker].item == ITEM_NONE || gBattleMons[gBattlerTarget].item != ITEM_NONE || !CanBattlerGetOrLoseItem(gBattlerAttacker, gBattleMons[gBattlerAttacker].item) || !CanBattlerGetOrLoseItem(gBattlerTarget, gBattleMons[gBattlerAttacker].item)) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { BestowItem(gBattlerAttacker, gBattlerTarget); - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_ARGUMENT_TO_MOVE_EFFECT: + { + VARIOUS_ARGS(); gBattleScripting.moveEffect = gBattleMoves[gCurrentMove].argument; break; + } case VARIOUS_JUMP_IF_NOT_GROUNDED: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (!IsBattlerGrounded(gActiveBattler)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_HANDLE_TRAINER_SLIDE_MSG: - if (gBattlescriptCurrInstr[3] == 0) + { + VARIOUS_ARGS(u8 case_); + if (cmd->case_ == 0) { gBattleScripting.savedDmg = gBattlerSpriteIds[gActiveBattler]; HideBattlerShadowSprite(gActiveBattler); } - else if (gBattlescriptCurrInstr[3] == 1) + else if (cmd->case_ == 1) { BtlController_EmitPrintString(BUFFER_A, STRINGID_TRAINERSLIDE); MarkBattlerForControllerExec(gActiveBattler); @@ -9466,27 +10033,36 @@ static void Cmd_various(void) BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], gActiveBattler); } } - gBattlescriptCurrInstr += 4; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_TRY_TRAINER_SLIDE_MSG_FIRST_OFF: + { + VARIOUS_ARGS(); if (ShouldDoTrainerSlide(gActiveBattler, gTrainerBattleOpponent_A, TRAINER_SLIDE_FIRST_DOWN)) { gBattleScripting.battler = gActiveBattler; - BattleScriptPush(gBattlescriptCurrInstr + 3); + BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_TrainerSlideMsgRet; return; } break; + } case VARIOUS_TRY_TRAINER_SLIDE_MSG_LAST_ON: + { + VARIOUS_ARGS(); if (ShouldDoTrainerSlide(gActiveBattler, gTrainerBattleOpponent_A, TRAINER_SLIDE_LAST_SWITCHIN)) { gBattleScripting.battler = gActiveBattler; - BattleScriptPush(gBattlescriptCurrInstr + 3); + BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_TrainerSlideMsgRet; return; } break; + } case VARIOUS_SET_AURORA_VEIL: + { + VARIOUS_ARGS(); if (gSideStatuses[GET_BATTLER_SIDE(gActiveBattler)] & SIDE_STATUS_AURORA_VEIL || !(WEATHER_HAS_EFFECT && gBattleWeather & B_WEATHER_HAIL)) { @@ -9508,26 +10084,35 @@ static void Cmd_various(void) gBattleCommunication[MULTISTRING_CHOOSER] = 5; } break; + } case VARIOUS_TRY_THIRD_TYPE: + { + VARIOUS_ARGS(const u8 *failInstr); if (IS_BATTLER_OF_TYPE(gActiveBattler, gBattleMoves[gCurrentMove].argument)) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { gBattleMons[gActiveBattler].type3 = gBattleMoves[gCurrentMove].argument; PREPARE_TYPE_BUFFER(gBattleTextBuff1, gBattleMoves[gCurrentMove].argument); - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_DESTROY_ABILITY_POPUP: + { + VARIOUS_ARGS(); DestroyAbilityPopUp(gActiveBattler); break; + } case VARIOUS_TOTEM_BOOST: + { + VARIOUS_ARGS(const u8 *jumpInstr); gActiveBattler = gBattlerAttacker; if (gTotemBoosts[gActiveBattler].stats == 0) { - gBattlescriptCurrInstr += 7; // stats done, exit + gBattlescriptCurrInstr = cmd->nextInstr; // stats done, exit } else { @@ -9550,22 +10135,31 @@ static void Cmd_various(void) } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // do boost + gBattlescriptCurrInstr = cmd->jumpInstr; // do boost } return; } } - gBattlescriptCurrInstr += 7; // exit if loop failed (failsafe) + gBattlescriptCurrInstr = cmd->nextInstr; // exit if loop failed (failsafe) } return; + } case VARIOUS_SET_Z_EFFECT: + { + VARIOUS_ARGS(); SetZEffect(); //handles battle script jumping internally return; + } case VARIOUS_MOVEEND_ITEM_EFFECTS: + { + VARIOUS_ARGS(); if (ItemBattleEffects(ITEMEFFECT_NORMAL, gActiveBattler, FALSE)) return; break; + } case VARIOUS_ROOM_SERVICE: + { + VARIOUS_ARGS(const u8 *failInstr); if (GetBattlerHoldEffect(gActiveBattler, TRUE) == HOLD_EFFECT_ROOM_SERVICE && TryRoomService(gActiveBattler)) { BattleScriptPushCursor(); @@ -9573,10 +10167,13 @@ static void Cmd_various(void) } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } return; + } case VARIOUS_TERRAIN_SEED: + { + VARIOUS_ARGS(const u8 *failInstr); if (GetBattlerHoldEffect(gActiveBattler, TRUE) == HOLD_EFFECT_SEEDS) { u8 effect = 0; @@ -9600,25 +10197,32 @@ static void Cmd_various(void) if (effect) return; } - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; return; + } case VARIOUS_MAKE_INVISIBLE: + { + VARIOUS_ARGS(); if (gBattleControllerExecFlags) break; BtlController_EmitSpriteInvisibility(BUFFER_A, TRUE); MarkBattlerForControllerExec(gActiveBattler); break; + } case VARIOUS_JUMP_IF_TERRAIN_AFFECTED: { - u32 flags = T1_READ_32(gBattlescriptCurrInstr + 3); + VARIOUS_ARGS(u32 flags, const u8 *jumpInstr); + u32 flags = cmd->flags; if (IsBattlerTerrainAffected(gActiveBattler, flags)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 7); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 11; + gBattlescriptCurrInstr = cmd->nextInstr; + return; } - return; case VARIOUS_EERIE_SPELL_PP_REDUCE: + { + VARIOUS_ARGS(const u8 *failInstr); if (gLastMoves[gActiveBattler] != 0 && gLastMoves[gActiveBattler] != 0xFFFF) { s32 i; @@ -9650,48 +10254,57 @@ static void Cmd_various(void) if (gBattleMons[gActiveBattler].pp[i] == 0 && gBattleStruct->skyDropTargets[gActiveBattler] == 0xFF) CancelMultiTurnMoves(gActiveBattler); - gBattlescriptCurrInstr += 7; // continue + gBattlescriptCurrInstr = cmd->nextInstr; // continue } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // cant reduce pp + gBattlescriptCurrInstr = cmd->failInstr; // cant reduce pp } } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // cant reduce pp + gBattlescriptCurrInstr = cmd->failInstr; // cant reduce pp } return; + } case VARIOUS_JUMP_IF_TEAM_HEALTHY: + { + VARIOUS_ARGS(const u8 *jumpInstr); if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && IsBattlerAlive(BATTLE_PARTNER(gActiveBattler))) { u8 partner = BATTLE_PARTNER(gActiveBattler); if ((gBattleMons[gActiveBattler].hp == gBattleMons[gActiveBattler].maxHP && !(gBattleMons[gActiveBattler].status1 & STATUS1_ANY)) && (gBattleMons[partner].hp == gBattleMons[partner].maxHP && !(gBattleMons[partner].status1 & STATUS1_ANY))) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // fail + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } else // single battle { if (gBattleMons[gActiveBattler].hp == gBattleMons[gActiveBattler].maxHP && !(gBattleMons[gActiveBattler].status1 & STATUS1_ANY)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // fail + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_TRY_HEAL_QUARTER_HP: + { + VARIOUS_ARGS(const u8 *failInstr); gBattleMoveDamage = gBattleMons[gActiveBattler].maxHP / 4; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; gBattleMoveDamage *= -1; if (gBattleMons[gActiveBattler].hp == gBattleMons[gActiveBattler].maxHP) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // fail + gBattlescriptCurrInstr = cmd->failInstr; // fail else - gBattlescriptCurrInstr += 7; // can heal + gBattlescriptCurrInstr = cmd->nextInstr; // can heal return; + } case VARIOUS_REMOVE_TERRAIN: + { + VARIOUS_ARGS(); gFieldTimers.terrainTimer = 0; switch (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) { @@ -9713,14 +10326,20 @@ static void Cmd_various(void) } gFieldStatuses &= ~STATUS_FIELD_TERRAIN_ANY; // remove the terrain break; + } case VARIOUS_JUMP_IF_UNDER_200: + { + VARIOUS_ARGS(const u8 *jumpInstr); // If the Pokemon is less than 200 kg, or weighing less than 441 lbs, then Sky Drop will work. Otherwise, it will fail. if (GetBattlerWeight(gBattlerTarget) < 2000) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_SET_SKY_DROP: + { + VARIOUS_ARGS(); gStatuses3[gBattlerTarget] |= (STATUS3_SKY_DROPPED | STATUS3_ON_AIR); /* skyDropTargets holds the information of who is in a particular instance of Sky Drop. This is needed in the case that multiple Pokemon use Sky Drop in the same turn or if @@ -9740,24 +10359,30 @@ static void Cmd_various(void) gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTimer = 0; break; + } case VARIOUS_CLEAR_SKY_DROP: + { + VARIOUS_ARGS(const u8 *failInstr); // Check to see if the initial target of this Sky Drop fainted before the 2nd turn of Sky Drop. // If so, make the move fail. If not, clear all of the statuses and continue the move. if (gBattleStruct->skyDropTargets[gBattlerAttacker] == 0xFF) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; else { gBattleStruct->skyDropTargets[gBattlerAttacker] = 0xFF; gBattleStruct->skyDropTargets[gBattlerTarget] = 0xFF; gStatuses3[gBattlerTarget] &= ~(STATUS3_SKY_DROPPED | STATUS3_ON_AIR); - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } // Confuse target if they were in the middle of Petal Dance/Outrage/Thrash when targeted. if (gBattleMons[gBattlerTarget].status2 & STATUS2_LOCK_CONFUSE) gBattleScripting.moveEffect = (MOVE_EFFECT_CONFUSION | MOVE_EFFECT_CERTAIN); return; + } case VARIOUS_SKY_DROP_YAWN: // If the mon that's sleeping due to Yawn was holding a Pokemon in Sky Drop, release the target and clear Sky Drop data. + { + VARIOUS_ARGS(); if (gBattleStruct->skyDropTargets[gEffectBattler] != 0xFF && !(gStatuses3[gEffectBattler] & STATUS3_SKY_DROPPED)) { // Set the target of Sky Drop as gEffectBattler @@ -9778,12 +10403,16 @@ static void Cmd_various(void) } } break; + } case VARIOUS_JUMP_IF_PRANKSTER_BLOCKED: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (BlocksPrankster(gCurrentMove, gBattlerAttacker, gActiveBattler, TRUE)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_TRY_TO_CLEAR_PRIMAL_WEATHER: { bool8 shouldNotClear = FALSE; @@ -9818,15 +10447,20 @@ static void Cmd_various(void) break; } case VARIOUS_TRY_END_NEUTRALIZING_GAS: + { + VARIOUS_ARGS(); if (gSpecialStatuses[gActiveBattler].neutralizingGasRemoved) { gSpecialStatuses[gActiveBattler].neutralizingGasRemoved = FALSE; - BattleScriptPush(gBattlescriptCurrInstr + 3); + BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_NeutralizingGasExits; return; } break; + } case VARIOUS_GET_ROTOTILLER_TARGETS: + { + VARIOUS_ARGS(const u8 *failInstr); // Gets the battlers to be affected by rototiller. If there are none, print 'But it failed!' { u32 count = 0; @@ -9841,23 +10475,29 @@ static void Cmd_various(void) } if (count == 0) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // Rototiller fails + gBattlescriptCurrInstr = cmd->failInstr; // Rototiller fails else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_JUMP_IF_NOT_ROTOTILLER_AFFECTED: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (gSpecialStatuses[gActiveBattler].rototillerAffected) { gSpecialStatuses[gActiveBattler].rototillerAffected = FALSE; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // Unaffected by rototiller - print STRINGID_NOEFFECTONTARGET + gBattlescriptCurrInstr = cmd->jumpInstr; // Unaffected by rototiller - print STRINGID_NOEFFECTONTARGET } return; + } case VARIOUS_TRY_ACTIVATE_BATTLE_BOND: + { + VARIOUS_ARGS(); if (gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_BATTLE_BOND && HasAttackerFaintedTarget() && CalculateEnemyPartyCount() > 1 @@ -9872,23 +10512,28 @@ static void Cmd_various(void) return; } break; + } case VARIOUS_CONSUME_BERRY: + { + VARIOUS_ARGS(bool8 fromBattler); if (gBattleScripting.overrideBerryRequirements == 2) { - gBattlescriptCurrInstr += 4; + gBattlescriptCurrInstr = cmd->nextInstr; return; } - if (gBattlescriptCurrInstr[3]) + if (cmd->fromBattler) gLastUsedItem = gBattleMons[gActiveBattler].item; gBattleScripting.battler = gEffectBattler = gBattlerTarget = gActiveBattler; // Cover all berry effect battlerId cases. e.g. ChangeStatBuffs uses target ID if (ItemBattleEffects(ITEMEFFECT_USE_LAST_ITEM, gActiveBattler, FALSE)) return; - gBattlescriptCurrInstr += 4; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL: { + VARIOUS_ARGS(const u8 *jumpInstr); bool8 canDoPrimalReversion = FALSE; for (i = 0; i < EVOS_PER_MON; i++) @@ -9898,35 +10543,47 @@ static void Cmd_various(void) canDoPrimalReversion = TRUE; } if (!canDoPrimalReversion) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; } case VARIOUS_JUMP_IF_WEATHER_AFFECTED: { - u32 weatherFlags = T1_READ_32(gBattlescriptCurrInstr + 3); - if (IsBattlerWeatherAffected(gActiveBattler, weatherFlags)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 7); + VARIOUS_ARGS(u32 flags, const u8 *jumpInstr); + u32 flags = cmd->flags; + if (IsBattlerWeatherAffected(gActiveBattler, flags)) + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 11; + gBattlescriptCurrInstr = cmd->nextInstr; + return; } - return; case VARIOUS_APPLY_PLASMA_FISTS: + { + VARIOUS_ARGS(); for (i = 0; i < gBattlersCount; i++) gStatuses4[i] |= STATUS4_PLASMA_FISTS; break; + } case VARIOUS_JUMP_IF_SPECIES: - if (gBattleMons[gActiveBattler].species == T1_READ_16(gBattlescriptCurrInstr + 3)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 5); + { + VARIOUS_ARGS(u16 species, const u8 *jumpInstr); + if (gBattleMons[gActiveBattler].species == cmd->species) + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 9; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_PHOTON_GEYSER_CHECK: + { + VARIOUS_ARGS(); gBattleStruct->swapDamageCategory = (GetSplitBasedOnStats(gActiveBattler) == SPLIT_SPECIAL); break; + } case VARIOUS_SHELL_SIDE_ARM_CHECK: // 0% chance GameFreak actually checks this way according to DaWobblefet, but this is the only functional explanation at the moment { + VARIOUS_ARGS(); + u32 attackerAtkStat = gBattleMons[gBattlerAttacker].attack; u32 targetDefStat = gBattleMons[gBattlerTarget].defense; u32 attackerSpAtkStat = gBattleMons[gBattlerAttacker].spAttack; @@ -9962,17 +10619,22 @@ static void Cmd_various(void) break; } case VARIOUS_JUMP_IF_LEAF_GUARD_PROTECTED: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (IsLeafGuardProtected(gActiveBattler)) { gBattlerAbility = gActiveBattler; - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; } else { - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_SET_ATTACKER_STICKY_WEB_USER: + { + VARIOUS_ARGS(); // For Mirror Armor: "If the Pokémon with this Ability is affected by Sticky Web, the effect is reflected back to the Pokémon which set it up. // If Pokémon which set up Sticky Web is not on the field, no Pokémon have their Speed lowered." gBattlerAttacker = gBattlerTarget; // Initialize 'fail' condition @@ -9980,8 +10642,11 @@ static void Cmd_various(void) if (gBattleStruct->stickyWebUser != 0xFF) gBattlerAttacker = gBattleStruct->stickyWebUser; break; + } case VARIOUS_CUT_1_3_HP_RAISE_STATS: { + VARIOUS_ARGS(const u8 *failInstr); + bool8 atLeastOneStatBoosted = FALSE; u16 hpFraction = max(1, gBattleMons[gBattlerAttacker].maxHP / 3); @@ -9996,79 +10661,99 @@ static void Cmd_various(void) if (atLeastOneStatBoosted && gBattleMons[gBattlerAttacker].hp > hpFraction) { gBattleMoveDamage = hpFraction; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } + return; } - return; case VARIOUS_SET_OCTOLOCK: + { + VARIOUS_ARGS(const u8 *failInstr); if (gDisableStructs[gActiveBattler].octolock) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { gDisableStructs[gActiveBattler].octolock = TRUE; gBattleMons[gActiveBattler].status2 |= STATUS2_ESCAPE_PREVENTION; gDisableStructs[gActiveBattler].battlerPreventingEscape = gBattlerAttacker; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_CHECK_POLTERGEIST: + { + VARIOUS_ARGS(const u8 *failInstr); if (gBattleMons[gActiveBattler].item == ITEM_NONE || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM || GetBattlerAbility(gActiveBattler) == ABILITY_KLUTZ) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { PREPARE_ITEM_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].item); gLastUsedItem = gBattleMons[gActiveBattler].item; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_TRY_NO_RETREAT: + { + VARIOUS_ARGS(const u8 *failInstr); if (gDisableStructs[gActiveBattler].noRetreat) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { if (!(gBattleMons[gActiveBattler].status2 & STATUS2_ESCAPE_PREVENTION)) gDisableStructs[gActiveBattler].noRetreat = TRUE; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_TRY_TAR_SHOT: + { + VARIOUS_ARGS(const u8 *failInstr); if (gDisableStructs[gActiveBattler].tarShot) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } else { gDisableStructs[gActiveBattler].tarShot = TRUE; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } return; + } case VARIOUS_CAN_TAR_SHOT_WORK: + { + VARIOUS_ARGS(const u8 *failInstr); // Tar Shot will fail if it's already been used on the target and its speed can't be lowered further if (!gDisableStructs[gActiveBattler].tarShot && CompareStat(gActiveBattler, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN)) - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; return; + } case VARIOUS_JUMP_IF_CANT_FLING: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (!CanFling(gActiveBattler)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_CURE_CERTAIN_STATUSES: + { + VARIOUS_ARGS(); // Check infatuation if (gBattleMons[gActiveBattler].status2 & STATUS2_INFATUATION) { @@ -10109,43 +10794,70 @@ static void Cmd_various(void) gDisableStructs[gActiveBattler].disabledMove = 0; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_MENTALHERBCURE_DISABLE; } - gBattlescriptCurrInstr += 3; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_TRY_RESET_NEGATIVE_STAT_STAGES: + { + VARIOUS_ARGS(); gActiveBattler = gBattlerTarget; for (i = 0; i < NUM_BATTLE_STATS; i++) if (gBattleMons[gActiveBattler].statStages[i] < DEFAULT_STAT_STAGE) gBattleMons[gActiveBattler].statStages[i] = DEFAULT_STAT_STAGE; - gBattlescriptCurrInstr += 3; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_JUMP_IF_LAST_USED_ITEM_BERRY: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (ItemId_GetPocket(gLastUsedItem) == POCKET_BERRIES) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_JUMP_IF_LAST_USED_ITEM_HOLD_EFFECT: - if (ItemId_GetHoldEffect(gLastUsedItem) == gBattlescriptCurrInstr[3]) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 4); + { + VARIOUS_ARGS(u8 holdEffect, const u8 *jumpInstr); + if (ItemId_GetHoldEffect(gLastUsedItem) == cmd->holdEffect) + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 8; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_SAVE_BATTLER_ITEM: + { + VARIOUS_ARGS(); gBattleResources->battleHistory->heldItems[gActiveBattler] = gBattleMons[gActiveBattler].item; break; + } case VARIOUS_RESTORE_BATTLER_ITEM: + { + VARIOUS_ARGS(); gBattleMons[gActiveBattler].item = gBattleResources->battleHistory->heldItems[gActiveBattler]; break; + } case VARIOUS_BATTLER_ITEM_TO_LAST_USED_ITEM: + { + VARIOUS_ARGS(); gBattleMons[gActiveBattler].item = gLastUsedItem; break; + } case VARIOUS_SET_BEAK_BLAST: + { + VARIOUS_ARGS(); gProtectStructs[gActiveBattler].beakBlastCharge = TRUE; break; + } case VARIOUS_SWAP_SIDE_STATUSES: + { + VARIOUS_ARGS(); CourtChangeSwapSideStatuses(); break; + } case VARIOUS_TRY_SYMBIOSIS: //called by Bestow, Fling, and Bug Bite, which don't work with Cmd_removeitem. + { + VARIOUS_ARGS(); if (SYMBIOSIS_CHECK(gActiveBattler, BATTLE_PARTNER(gActiveBattler))) { BestowItem(BATTLE_PARTNER(gActiveBattler), gActiveBattler); @@ -10157,33 +10869,42 @@ static void Cmd_various(void) return; } break; + } case VARIOUS_CAN_TELEPORT: + { + VARIOUS_ARGS(); gBattleCommunication[0] = CanTeleport(gActiveBattler); break; + } case VARIOUS_GET_BATTLER_SIDE: + { + VARIOUS_ARGS(); if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) gBattleCommunication[0] = B_SIDE_PLAYER; else gBattleCommunication[0] = B_SIDE_OPPONENT; break; + } case VARIOUS_CHECK_PARENTAL_BOND_COUNTER: { + VARIOUS_ARGS(u8 counter, const u8 *jumpInstr); // Some effects should only happen on the first or second strike of Parental Bond, // so a way to check this in battle scripts is useful - u8 counter = T1_READ_8(gBattlescriptCurrInstr + 3); + u8 counter = cmd->counter; if (gSpecialStatuses[gBattlerAttacker].parentalBondState == counter && gBattleMons[gBattlerTarget].hp != 0) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 4); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 8; + gBattlescriptCurrInstr = cmd->nextInstr; return; } - break; case VARIOUS_SWAP_STATS: { - u8 statId = T1_READ_8(gBattlescriptCurrInstr + 3); + VARIOUS_ARGS(u8 stat); + + u8 stat = cmd->stat; u16 temp; - switch (statId) + switch (stat) { case STAT_HP: SWAP(gBattleMons[gBattlerAttacker].hp, gBattleMons[gBattlerTarget].hp, temp); @@ -10204,13 +10925,13 @@ static void Cmd_various(void) SWAP(gBattleMons[gBattlerAttacker].spDefense, gBattleMons[gBattlerTarget].spDefense, temp); break; } - PREPARE_STAT_BUFFER(gBattleTextBuff1, statId); - gBattlescriptCurrInstr += 4; + PREPARE_STAT_BUFFER(gBattleTextBuff1, stat); + gBattlescriptCurrInstr = cmd->nextInstr; return; } - break; case VARIOUS_TEATIME_TARGETS: { + VARIOUS_ARGS(const u8 *jumpInstr); u32 count = 0; for (i = 0; i < gBattlersCount; i++) @@ -10219,37 +10940,50 @@ static void Cmd_various(void) count++; } if (count == 0) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); // Teatime fails + gBattlescriptCurrInstr = cmd->jumpInstr; // Teatime fails else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; + return; } - return; - case VARIOUS_TEATIME_INVUL: + case VARIOUS_TEATIME_INVUL: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (ItemId_GetPocket(gBattleMons[gActiveBattler].item) == POCKET_BERRIES && !(gStatuses3[gBattlerTarget] & (STATUS3_SEMI_INVULNERABLE))) - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; return; - case VARIOUS_JUMP_IF_ROD: + } + case VARIOUS_JUMP_IF_ROD: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (IsAbilityRodAffected()) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; - case VARIOUS_JUMP_IF_MOTOR: + } + case VARIOUS_JUMP_IF_MOTOR: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (IsAbilityMotorAffected()) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; - case VARIOUS_JUMP_IF_ABSORB: + } + case VARIOUS_JUMP_IF_ABSORB: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (IsAbilityAbsorbAffected()) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; + } case VARIOUS_TRY_WIND_RIDER_POWER: { + VARIOUS_ARGS(const u8 *failInstr); u16 ability = GetBattlerAbility(gActiveBattler); if (GetBattlerSide(gActiveBattler) == GetBattlerSide(gBattlerAttacker) && (ability == ABILITY_WIND_RIDER || ability == ABILITY_WIND_POWER)) @@ -10257,24 +10991,31 @@ static void Cmd_various(void) gLastUsedAbility = ability; RecordAbilityBattle(gActiveBattler, gLastUsedAbility); gBattlerAbility = gBattleScripting.battler = gActiveBattler; - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->failInstr; } + return; } - return; case VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES: - gBattlescriptCurrInstr += 3; + { + VARIOUS_ARGS(); + gBattlescriptCurrInstr = cmd->nextInstr; AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, gActiveBattler, 0, 0, 0); return; + } case VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES: - gBattlescriptCurrInstr += 3; + { + VARIOUS_ARGS(); + gBattlescriptCurrInstr = cmd->nextInstr; AbilityBattleEffects(ABILITYEFFECT_ON_TERRAIN, gActiveBattler, 0, 0, 0); return; + } case VARIOUS_JUMP_IF_NO_VALID_TARGETS: { + VARIOUS_ARGS(const u8 *jumpInstr); u32 count = 0; for (i = 0; i < gBattlersCount; i++) @@ -10283,24 +11024,29 @@ static void Cmd_various(void) count++; } if (count == 0) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; + return; } - return; case VARIOUS_JUMP_IF_EMERGENCY_EXITED: + { + VARIOUS_ARGS(const u8 *jumpInstr); if (gSpecialStatuses[gActiveBattler].emergencyExited) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr = cmd->nextInstr; return; - } // End of switch (gBattlescriptCurrInstr[2]) + } + } // End of switch (cmd->id) - gBattlescriptCurrInstr += 3; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_setprotectlike(void) { + CMD_ARGS(); + bool32 fail = TRUE; bool32 notLastTurn = TRUE; @@ -10393,11 +11139,13 @@ static void Cmd_setprotectlike(void) gMoveResultFlags |= MOVE_RESULT_MISSED; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_tryexplosion(void) { + CMD_ARGS(); + if (gBattleControllerExecFlags) return; @@ -10414,7 +11162,7 @@ static void Cmd_tryexplosion(void) gBattleMoveDamage = gBattleMons[gActiveBattler].hp; BtlController_EmitHealthBarUpdate(BUFFER_A, INSTANT_HP_BAR_DROP); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++) { @@ -10427,6 +11175,8 @@ static void Cmd_tryexplosion(void) static void Cmd_setatkhptozero(void) { + CMD_ARGS(); + if (gBattleControllerExecFlags) return; @@ -10435,12 +11185,14 @@ static void Cmd_setatkhptozero(void) BtlController_EmitSetMonData(BUFFER_A, REQUEST_HP_BATTLE, 0, sizeof(gBattleMons[gActiveBattler].hp), &gBattleMons[gActiveBattler].hp); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_jumpifnexttargetvalid(void) { - const u8 *jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + CMD_ARGS(const u8 *jumpInstr); + + const u8 *jumpInstr = cmd->jumpInstr; for (gBattlerTarget++; gBattlerTarget < gBattlersCount; gBattlerTarget++) { @@ -10451,16 +11203,18 @@ static void Cmd_jumpifnexttargetvalid(void) } if (gBattlerTarget >= gBattlersCount) - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; else - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = jumpInstr; } static void Cmd_tryhealhalfhealth(void) { - const u8 *failPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + CMD_ARGS(const u8 *failInstr, u8 battler); - if (gBattlescriptCurrInstr[5] == BS_ATTACKER) + const u8 *failInstr = cmd->failInstr; + + if (cmd->battler == BS_ATTACKER) gBattlerTarget = gBattlerAttacker; gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP / 2; @@ -10469,13 +11223,15 @@ static void Cmd_tryhealhalfhealth(void) gBattleMoveDamage *= -1; if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP) - gBattlescriptCurrInstr = failPtr; + gBattlescriptCurrInstr = failInstr; else - gBattlescriptCurrInstr += 6; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_trymirrormove(void) { + CMD_ARGS(); + s32 validMovesCount; s32 i; u16 move; @@ -10515,12 +11271,14 @@ static void Cmd_trymirrormove(void) else // no valid moves found { gSpecialStatuses[gBattlerAttacker].ppNotAffectedByPressure = TRUE; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_setrain(void) { + CMD_ARGS(); + if (!TryChangeBattleWeather(gBattlerAttacker, ENUM_WEATHER_RAIN, FALSE)) { gMoveResultFlags |= MOVE_RESULT_MISSED; @@ -10530,11 +11288,13 @@ static void Cmd_setrain(void) { gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STARTED_RAIN; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_setreflect(void) { + CMD_ARGS(); + if (gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] & SIDE_STATUS_REFLECT) { gMoveResultFlags |= MOVE_RESULT_MISSED; @@ -10554,11 +11314,13 @@ static void Cmd_setreflect(void) else gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_REFLECT_SINGLE; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_setseeded(void) { + CMD_ARGS(); + if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT || gStatuses3[gBattlerTarget] & STATUS3_LEECHSEED) { gMoveResultFlags |= MOVE_RESULT_MISSED; @@ -10576,12 +11338,14 @@ static void Cmd_setseeded(void) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_LEECH_SEED_SET; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_manipulatedamage(void) { - switch (gBattlescriptCurrInstr[1]) + CMD_ARGS(u8 mode); + + switch (cmd->mode) { case DMG_CHANGE_SIGN: gBattleMoveDamage *= -1; @@ -10623,18 +11387,20 @@ static void Cmd_manipulatedamage(void) break; } - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_trysetrest(void) { - const u8 *failJump = T1_READ_PTR(gBattlescriptCurrInstr + 1); + CMD_ARGS(const u8 *failInstr); + + const u8 *failInstr = cmd->failInstr; gActiveBattler = gBattlerTarget = gBattlerAttacker; gBattleMoveDamage = gBattleMons[gBattlerTarget].maxHP * (-1); if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP) { - gBattlescriptCurrInstr = failJump; + gBattlescriptCurrInstr = failInstr; } else if (IsBattlerTerrainAffected(gBattlerTarget, STATUS_FIELD_ELECTRIC_TERRAIN)) { @@ -10654,30 +11420,34 @@ static void Cmd_trysetrest(void) gBattleMons[gBattlerTarget].status1 = STATUS1_SLEEP_TURN(3); BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gActiveBattler].status1), &gBattleMons[gActiveBattler].status1); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_jumpifnotfirstturn(void) { - const u8 *failJump = T1_READ_PTR(gBattlescriptCurrInstr + 1); + CMD_ARGS(const u8 *jumpInstr); + + const u8 *jumpInstr = cmd->jumpInstr; if (gDisableStructs[gBattlerAttacker].isFirstTurn) - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; else - gBattlescriptCurrInstr = failJump; + gBattlescriptCurrInstr = jumpInstr; } static void Cmd_setmiracleeye(void) { + CMD_ARGS(const u8 *failInstr); + if (!(gStatuses3[gBattlerTarget] & STATUS3_MIRACLE_EYED)) { gStatuses3[gBattlerTarget] |= STATUS3_MIRACLE_EYED; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } @@ -10710,15 +11480,22 @@ bool8 UproarWakeUpCheck(u8 battlerId) static void Cmd_jumpifuproarwakes(void) { + CMD_ARGS(const u8 *jumpInstr); + + const u8 *jumpInstr = cmd->jumpInstr; + u32 ability = GetBattlerAbility(gBattlerTarget); + if (UproarWakeUpCheck(gBattlerTarget)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = jumpInstr; else - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_stockpile(void) { - switch (gBattlescriptCurrInstr[1]) + CMD_ARGS(u8 id); + + switch (cmd->id) { case 0: if (gDisableStructs[gBattlerAttacker].stockpileCounter >= 3) @@ -10744,15 +11521,17 @@ static void Cmd_stockpile(void) break; } - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_stockpiletobasedamage(void) { - const u8 *jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + CMD_ARGS(const u8 *failInstr); + + const u8 *failInstr = cmd->failInstr; if (gDisableStructs[gBattlerAttacker].stockpileCounter == 0) { - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = failInstr; } else { @@ -10766,17 +11545,19 @@ static void Cmd_stockpiletobasedamage(void) gBattleMons[gBattlerAttacker].statStages[STAT_DEF] -= gDisableStructs[gBattlerAttacker].stockpileDef; gBattleMons[gBattlerAttacker].statStages[STAT_SPDEF] -= gDisableStructs[gBattlerAttacker].stockpileSpDef; } - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_stockpiletohpheal(void) { - const u8 *jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + CMD_ARGS(const u8 *failInstr); + + const u8 *failInstr = cmd->failInstr; if (gDisableStructs[gBattlerAttacker].stockpileCounter == 0) { - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = failInstr; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWALLOW_FAILED; } else @@ -10784,7 +11565,7 @@ static void Cmd_stockpiletohpheal(void) if (gBattleMons[gBattlerAttacker].maxHP == gBattleMons[gBattlerAttacker].hp) { gDisableStructs[gBattlerAttacker].stockpileCounter = 0; - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = failInstr; gBattlerTarget = gBattlerAttacker; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SWALLOW_FULL_HP; } @@ -10798,7 +11579,7 @@ static void Cmd_stockpiletohpheal(void) gBattleScripting.animTurn = gDisableStructs[gBattlerAttacker].stockpileCounter; gDisableStructs[gBattlerAttacker].stockpileCounter = 0; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; gBattlerTarget = gBattlerAttacker; } @@ -10811,6 +11592,8 @@ static void Cmd_stockpiletohpheal(void) // Sign change for drained HP handled in GetDrainedBigRootHp static void Cmd_setdrainedhp(void) { + CMD_ARGS(); + if (gBattleMoves[gCurrentMove].argument != 0) gBattleMoveDamage = (gHpDealt * gBattleMoves[gCurrentMove].argument / 100); else @@ -10819,7 +11602,7 @@ static void Cmd_setdrainedhp(void) if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static u16 ReverseStatChangeMoveEffect(u16 moveEffect) @@ -11145,14 +11928,16 @@ static u32 ChangeStatBuffs(s8 statValue, u32 statId, u32 flags, const u8 *BS_ptr static void Cmd_statbuffchange(void) { - u16 flags = T1_READ_16(gBattlescriptCurrInstr + 1); - const u8 *ptrBefore = gBattlescriptCurrInstr; - const u8 *jumpPtr = T1_READ_PTR(gBattlescriptCurrInstr + 3); + CMD_ARGS(u16 flags, const u8 *failInstr); - if (ChangeStatBuffs(GET_STAT_BUFF_VALUE_WITH_SIGN(gBattleScripting.statChanger), GET_STAT_BUFF_ID(gBattleScripting.statChanger), flags, jumpPtr) == STAT_CHANGE_WORKED) - gBattlescriptCurrInstr += 7; + u16 flags = cmd->flags; + const u8 *ptrBefore = gBattlescriptCurrInstr; + const u8 *failInstr = cmd->failInstr; + + if (ChangeStatBuffs(GET_STAT_BUFF_VALUE_WITH_SIGN(gBattleScripting.statChanger), GET_STAT_BUFF_ID(gBattleScripting.statChanger), flags, failInstr) == STAT_CHANGE_WORKED) + gBattlescriptCurrInstr = cmd->nextInstr; else if (gBattlescriptCurrInstr == ptrBefore) // Prevent infinite looping. - gBattlescriptCurrInstr = jumpPtr; + gBattlescriptCurrInstr = failInstr; } bool32 TryResetBattlerStatChanges(u8 battler) @@ -11176,37 +11961,45 @@ bool32 TryResetBattlerStatChanges(u8 battler) // Haze static void Cmd_normalisebuffs(void) { + CMD_ARGS(); + s32 i, j; for (i = 0; i < gBattlersCount; i++) TryResetBattlerStatChanges(i); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_setbide(void) { + CMD_ARGS(); + gBattleMons[gBattlerAttacker].status2 |= STATUS2_MULTIPLETURNS; gLockedMoves[gBattlerAttacker] = gCurrentMove; gTakenDmg[gBattlerAttacker] = 0; gBattleMons[gBattlerAttacker].status2 |= STATUS2_BIDE_TURN(2); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_confuseifrepeatingattackends(void) { + CMD_ARGS(); + if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_LOCK_CONFUSE) && !gSpecialStatuses[gBattlerAttacker].dancerUsedMove) gBattleScripting.moveEffect = (MOVE_EFFECT_THRASH | MOVE_EFFECT_AFFECTS_USER); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_setmultihitcounter(void) { - if (gBattlescriptCurrInstr[1]) + CMD_ARGS(u8 value); + + if (cmd->value) { - gMultiHitCounter = gBattlescriptCurrInstr[1]; + gMultiHitCounter = cmd->value; } else { @@ -11243,18 +12036,22 @@ static void Cmd_setmultihitcounter(void) } } - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_initmultihitstring(void) { + CMD_ARGS(); + PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 1, 0) - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_forcerandomswitch(void) { + CMD_ARGS(const u8 *failInstr); + s32 i; s32 battler1PartyId = 0; s32 battler2PartyId = 0; @@ -11420,7 +12217,7 @@ static void Cmd_forcerandomswitch(void) if (!redCardForcedSwitch && validMons <= minNeeded) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -11462,12 +12259,14 @@ static void Cmd_forcerandomswitch(void) if (gBattleMons[gBattlerAttacker].level >= gBattleMons[gBattlerTarget].level) gBattlescriptCurrInstr = BattleScript_RoarSuccessEndBattle; else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } static void Cmd_tryconversiontypechange(void) { + CMD_ARGS(const u8 *failInstr); + u8 validMoves = 0; u8 moveChecked; u8 moveType; @@ -11484,13 +12283,13 @@ static void Cmd_tryconversiontypechange(void) } if (IS_BATTLER_OF_TYPE(gBattlerAttacker, moveType)) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { SET_BATTLER_TYPE(gBattlerAttacker, moveType); PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } #else // Randomly changes user's type to one of its moves' type @@ -11523,7 +12322,7 @@ static void Cmd_tryconversiontypechange(void) if (moveChecked == validMoves) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -11546,13 +12345,15 @@ static void Cmd_tryconversiontypechange(void) SET_BATTLER_TYPE(gBattlerAttacker, moveType); PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } #endif } static void Cmd_givepaydaymoney(void) { + CMD_ARGS(); + if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK)) && gPaydayMoney != 0) { u32 bonusMoney = gPaydayMoney * gBattleStruct->moneyMultiplier; @@ -11560,17 +12361,19 @@ static void Cmd_givepaydaymoney(void) PREPARE_HWORD_NUMBER_BUFFER(gBattleTextBuff1, 5, bonusMoney) - BattleScriptPush(gBattlescriptCurrInstr + 1); + BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_PrintPayDayMoneyString; } else { - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_setlightscreen(void) { + CMD_ARGS(); + if (gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] & SIDE_STATUS_LIGHTSCREEN) { gMoveResultFlags |= MOVE_RESULT_MISSED; @@ -11591,11 +12394,13 @@ static void Cmd_setlightscreen(void) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_LIGHTSCREEN_SINGLE; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_tryKO(void) { + CMD_ARGS(const u8 *failInstr); + bool32 lands = FALSE; u32 holdEffect = GetBattlerHoldEffect(gBattlerTarget, TRUE); u16 targetAbility = GetBattlerAbility(gBattlerTarget); @@ -11666,7 +12471,7 @@ static void Cmd_tryKO(void) gBattleMoveDamage = gBattleMons[gBattlerTarget].hp; gMoveResultFlags |= MOVE_RESULT_ONE_HIT_KO; } - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { @@ -11675,7 +12480,7 @@ static void Cmd_tryKO(void) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_KO_MISS; else gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_KO_UNAFFECTED; - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } } @@ -11683,15 +12488,19 @@ static void Cmd_tryKO(void) // Super Fang static void Cmd_damagetohalftargethp(void) { + CMD_ARGS(); + gBattleMoveDamage = gBattleMons[gBattlerTarget].hp / 2; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_setsandstorm(void) { + CMD_ARGS(); + if (!TryChangeBattleWeather(gBattlerAttacker, ENUM_WEATHER_SANDSTORM, FALSE)) { gMoveResultFlags |= MOVE_RESULT_MISSED; @@ -11701,11 +12510,13 @@ static void Cmd_setsandstorm(void) { gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STARTED_SANDSTORM; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_weatherdamage(void) { + CMD_ARGS(); + u32 ability = GetBattlerAbility(gBattlerAttacker); gBattleMoveDamage = 0; @@ -11755,11 +12566,13 @@ static void Cmd_weatherdamage(void) } } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_tryinfatuating(void) { + CMD_ARGS(const u8 *failInstr); + struct Pokemon *monAttacker, *monTarget; u16 speciesAttacker, speciesTarget; u32 personalityAttacker, personalityTarget; @@ -11793,27 +12606,29 @@ static void Cmd_tryinfatuating(void) || GetGenderFromSpeciesAndPersonality(speciesAttacker, personalityAttacker) == MON_GENDERLESS || GetGenderFromSpeciesAndPersonality(speciesTarget, personalityTarget) == MON_GENDERLESS) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { gBattleMons[gBattlerTarget].status2 |= STATUS2_INFATUATED_WITH(gBattlerAttacker); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } } static void Cmd_updatestatusicon(void) { + CMD_ARGS(u8 battler); + if (gBattleControllerExecFlags) return; - if (gBattlescriptCurrInstr[1] != BS_ATTACKER_WITH_PARTNER) + if (cmd->battler != BS_ATTACKER_WITH_PARTNER) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + gActiveBattler = GetBattlerForBattleScript(cmd->battler); BtlController_EmitStatusIconUpdate(BUFFER_A, gBattleMons[gActiveBattler].status1, gBattleMons[gActiveBattler].status2); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } else { @@ -11832,12 +12647,14 @@ static void Cmd_updatestatusicon(void) MarkBattlerForControllerExec(gActiveBattler); } } - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_setmist(void) { + CMD_ARGS(); + if (gSideTimers[GET_BATTLER_SIDE(gBattlerAttacker)].mistTimer) { gMoveResultFlags |= MOVE_RESULT_FAILED; @@ -11850,11 +12667,13 @@ static void Cmd_setmist(void) gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] |= SIDE_STATUS_MIST; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_MIST; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_setfocusenergy(void) { + CMD_ARGS(); + if (gBattleMons[gBattlerAttacker].status2 & STATUS2_FOCUS_ENERGY) { gMoveResultFlags |= MOVE_RESULT_FAILED; @@ -11865,13 +12684,15 @@ static void Cmd_setfocusenergy(void) gBattleMons[gBattlerAttacker].status2 |= STATUS2_FOCUS_ENERGY; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_GETTING_PUMPED; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_transformdataexecution(void) { + CMD_ARGS(); + gChosenMove = MOVE_UNAVAILABLE; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; if (gBattleMons[gBattlerTarget].status2 & STATUS2_TRANSFORMED || gBattleStruct->illusion[gBattlerTarget].on || gStatuses3[gBattlerTarget] & STATUS3_SEMI_INVULNERABLE) @@ -11917,6 +12738,8 @@ static void Cmd_transformdataexecution(void) static void Cmd_setsubstitute(void) { + CMD_ARGS(); + u32 hp = gBattleMons[gBattlerAttacker].maxHP / 4; if (gBattleMons[gBattlerAttacker].maxHP / 4 == 0) hp = 1; @@ -11939,16 +12762,18 @@ static void Cmd_setsubstitute(void) gHitMarker |= HITMARKER_IGNORE_SUBSTITUTE; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_mimicattackcopy(void) { + CMD_ARGS(const u8 *failInstr); + if ((sForbiddenMoves[gLastMoves[gBattlerTarget]] & FORBIDDEN_MIMIC) || (gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED) || gLastMoves[gBattlerTarget] == MOVE_UNAVAILABLE) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -11972,17 +12797,19 @@ static void Cmd_mimicattackcopy(void) PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastMoves[gBattlerTarget]) gDisableStructs[gBattlerAttacker].mimickedMoves |= gBitTable[gCurrMovePos]; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } } static void Cmd_metronome(void) { + CMD_ARGS(); + #if B_METRONOME_MOVES >= GEN_9 u16 moveCount = MOVES_COUNT_GEN9; #elif B_METRONOME_MOVES >= GEN_8 @@ -12017,12 +12844,16 @@ static void Cmd_metronome(void) static void Cmd_dmgtolevel(void) { + CMD_ARGS(); + gBattleMoveDamage = gBattleMons[gBattlerAttacker].level; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_psywavedamageeffect(void) { + CMD_ARGS(); + s32 randDamage; #if B_PSYWAVE_DMG >= GEN_6 randDamage = (Random() % 101); @@ -12030,11 +12861,13 @@ static void Cmd_psywavedamageeffect(void) randDamage = (Random() % 11) * 10; #endif gBattleMoveDamage = gBattleMons[gBattlerAttacker].level * (randDamage + 50) / 100; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_counterdamagecalculator(void) { + CMD_ARGS(const u8 *failInstr); + u8 sideAttacker = GetBattlerSide(gBattlerAttacker); u8 sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].physicalBattlerId); @@ -12049,18 +12882,20 @@ static void Cmd_counterdamagecalculator(void) else gBattlerTarget = gProtectStructs[gBattlerAttacker].physicalBattlerId; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { gSpecialStatuses[gBattlerAttacker].ppNotAffectedByPressure = TRUE; - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } // A copy of Cmd with the physical -> special field changes static void Cmd_mirrorcoatdamagecalculator(void) { + CMD_ARGS(const u8 *failInstr); + u8 sideAttacker = GetBattlerSide(gBattlerAttacker); u8 sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].specialBattlerId); @@ -12075,17 +12910,19 @@ static void Cmd_mirrorcoatdamagecalculator(void) else gBattlerTarget = gProtectStructs[gBattlerAttacker].specialBattlerId; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { gSpecialStatuses[gBattlerAttacker].ppNotAffectedByPressure = TRUE; - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } static void Cmd_disablelastusedattack(void) { + CMD_ARGS(const u8 *failInstr); + s32 i; for (i = 0; i < MAX_MON_MOVES; i++) @@ -12106,16 +12943,18 @@ static void Cmd_disablelastusedattack(void) #else gDisableStructs[gBattlerTarget].disableTimer = 4; #endif - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } static void Cmd_trysetencore(void) { + CMD_ARGS(const u8 *failInstr); + s32 i; for (i = 0; i < MAX_MON_MOVES; i++) @@ -12141,16 +12980,18 @@ static void Cmd_trysetencore(void) gDisableStructs[gBattlerTarget].encoredMovePos = i; gDisableStructs[gBattlerTarget].encoreTimer = 3; gDisableStructs[gBattlerTarget].encoreTimer; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } static void Cmd_painsplitdmgcalc(void) { + CMD_ARGS(const u8 *failInstr); + if (!(DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove))) { s32 hpDiff = (gBattleMons[gBattlerAttacker].hp + gBattleMons[gBattlerTarget].hp) / 2; @@ -12165,26 +13006,28 @@ static void Cmd_painsplitdmgcalc(void) gBattleMoveDamage = gBattleMons[gBattlerAttacker].hp - hpDiff; gSpecialStatuses[gBattlerTarget].dmg = 0xFFFF; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } // Conversion 2 static void Cmd_settypetorandomresistance(void) { + CMD_ARGS(const u8 *failInstr); + if (gLastLandedMoves[gBattlerAttacker] == MOVE_NONE || gLastLandedMoves[gBattlerAttacker] == MOVE_UNAVAILABLE) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else if (IsTwoTurnsMove(gLastLandedMoves[gBattlerAttacker]) && gBattleMons[gLastHitBy[gBattlerAttacker]].status2 & STATUS2_MULTIPLETURNS) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -12215,27 +13058,31 @@ static void Cmd_settypetorandomresistance(void) { SET_BATTLER_TYPE(gBattlerAttacker, i); PREPARE_TYPE_BUFFER(gBattleTextBuff1, i); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; return; } } } - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } static void Cmd_setalwayshitflag(void) { + CMD_ARGS(); + gStatuses3[gBattlerTarget] &= ~STATUS3_ALWAYS_HITS; gStatuses3[gBattlerTarget] |= STATUS3_ALWAYS_HITS_TURN(2); gDisableStructs[gBattlerTarget].battlerWithSureHit = gBattlerAttacker; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } // Sketch static void Cmd_copymovepermanently(void) { + CMD_ARGS(const u8 *failInstr); + gChosenMove = MOVE_UNAVAILABLE; if (!(gBattleMons[gBattlerAttacker].status2 & STATUS2_TRANSFORMED) @@ -12256,7 +13103,7 @@ static void Cmd_copymovepermanently(void) if (i != MAX_MON_MOVES) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else // sketch worked { @@ -12278,12 +13125,12 @@ static void Cmd_copymovepermanently(void) PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastPrintedMoves[gBattlerTarget]) - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } @@ -12322,6 +13169,8 @@ static u8 AttacksThisTurn(u8 battlerId, u16 move) // Note: returns 1 if it's a c static void Cmd_trychoosesleeptalkmove(void) { + CMD_ARGS(const u8 *failInstr); + u32 i, unusableMovesBits = 0, movePosition; for (i = 0; i < MAX_MON_MOVES; i++) @@ -12336,7 +13185,7 @@ static void Cmd_trychoosesleeptalkmove(void) unusableMovesBits = CheckMoveLimitations(gBattlerAttacker, unusableMovesBits, ~MOVE_LIMITATION_PP); if (unusableMovesBits == (1 << MAX_MON_MOVES) - 1) // all 4 moves cannot be chosen { - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else // at least one move can be chosen { @@ -12349,14 +13198,16 @@ static void Cmd_trychoosesleeptalkmove(void) gCurrMovePos = movePosition; gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } static void Cmd_setdestinybond(void) { + CMD_ARGS(); + gBattleMons[gBattlerAttacker].status2 |= STATUS2_DESTINY_BOND; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void TrySetDestinyBondToHappen(void) @@ -12373,12 +13224,16 @@ static void TrySetDestinyBondToHappen(void) static void Cmd_trysetdestinybondtohappen(void) { + CMD_ARGS(); + TrySetDestinyBondToHappen(); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_settailwind(void) { + CMD_ARGS(const u8 *failInstr); + u8 side = GetBattlerSide(gBattlerAttacker); if (!(gSideStatuses[side] & SIDE_STATUS_TAILWIND)) @@ -12390,16 +13245,18 @@ static void Cmd_settailwind(void) #else gSideTimers[side].tailwindTimer = 3; #endif - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } static void Cmd_tryspiteppreduce(void) { + CMD_ARGS(const u8 *failInstr); + if (gLastMoves[gBattlerTarget] != MOVE_NONE && gLastMoves[gBattlerTarget] != MOVE_UNAVAILABLE) { @@ -12443,7 +13300,7 @@ static void Cmd_tryspiteppreduce(void) MarkBattlerForControllerExec(gActiveBattler); } - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; // Don't cut off Sky Drop if pp is brought to zero. if (gBattleMons[gBattlerTarget].pp[i] == 0 && gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF) @@ -12451,17 +13308,19 @@ static void Cmd_tryspiteppreduce(void) } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } static void Cmd_healpartystatus(void) { + CMD_ARGS(); + u32 zero = 0; u8 toHeal = 0; @@ -12555,14 +13414,16 @@ static void Cmd_healpartystatus(void) MarkBattlerForControllerExec(gActiveBattler); } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_cursetarget(void) { + CMD_ARGS(const u8 *failInstr); + if (gBattleMons[gBattlerTarget].status2 & STATUS2_CURSED) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -12571,35 +13432,41 @@ static void Cmd_cursetarget(void) if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_trysetspikes(void) { + CMD_ARGS(const u8 *failInstr); + u8 targetSide = BATTLE_OPPOSITE(GetBattlerSide(gBattlerAttacker)); if (gSideTimers[targetSide].spikesAmount == 3) { gSpecialStatuses[gBattlerAttacker].ppNotAffectedByPressure = TRUE; - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { gSideStatuses[targetSide] |= SIDE_STATUS_SPIKES; gSideTimers[targetSide].spikesAmount++; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_setforesight(void) { + CMD_ARGS(); + gBattleMons[gBattlerTarget].status2 |= STATUS2_FORESIGHT; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_trysetperishsong(void) { + CMD_ARGS(const u8 *failInstr); + s32 i; s32 notAffectedCount = 0; @@ -12621,13 +13488,15 @@ static void Cmd_trysetperishsong(void) PressurePPLoseOnUsingPerishSong(gBattlerAttacker); if (notAffectedCount == gBattlersCount) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; else - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_handlerollout(void) { + CMD_ARGS(); + if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) { CancelMultiTurnMoves(gBattlerAttacker); @@ -12647,21 +13516,25 @@ static void Cmd_handlerollout(void) gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_MULTIPLETURNS; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_jumpifconfusedandstatmaxed(void) { + CMD_ARGS(u8 stat, const u8 *jumpInstr); + if (gBattleMons[gBattlerTarget].status2 & STATUS2_CONFUSION - && !CompareStat(gBattlerTarget, gBattlescriptCurrInstr[1], MAX_STAT_STAGE, CMP_LESS_THAN)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); // Fails if we're confused AND stat cannot be raised + && !CompareStat(gBattlerTarget, cmd->stat, MAX_STAT_STAGE, CMP_LESS_THAN)) + gBattlescriptCurrInstr = cmd->jumpInstr; // Fails if we're confused AND stat cannot be raised else - gBattlescriptCurrInstr += 6; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_handlefurycutter(void) { + CMD_ARGS(); + if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) { gDisableStructs[gBattlerAttacker].furyCutterCounter = 0; @@ -12673,26 +13546,30 @@ static void Cmd_handlefurycutter(void) && gSpecialStatuses[gBattlerAttacker].parentalBondState != PARENTAL_BOND_1ST_HIT) // Don't increment counter on first hit gDisableStructs[gBattlerAttacker].furyCutterCounter++; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_setembargo(void) { + CMD_ARGS(const u8 *failInstr); + if (gStatuses3[gBattlerTarget] & STATUS3_EMBARGO) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { gStatuses3[gBattlerTarget] |= STATUS3_EMBARGO; gDisableStructs[gBattlerTarget].embargoTimer = 5; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_presentdamagecalculation(void) { + CMD_ARGS(); + u32 rand = Random() & 0xFF; /* Don't reroll present effect/power for the second hit of Parental Bond. @@ -12742,6 +13619,8 @@ static void Cmd_presentdamagecalculation(void) static void Cmd_setsafeguard(void) { + CMD_ARGS(); + if (gSideStatuses[GET_BATTLER_SIDE(gBattlerAttacker)] & SIDE_STATUS_SAFEGUARD) { gMoveResultFlags |= MOVE_RESULT_MISSED; @@ -12755,11 +13634,13 @@ static void Cmd_setsafeguard(void) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_SAFEGUARD; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_magnitudedamagecalculation(void) { + CMD_ARGS(); + u32 magnitude = Random() % 100; if (magnitude < 5) @@ -12808,11 +13689,13 @@ static void Cmd_magnitudedamagecalculation(void) break; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_jumpifnopursuitswitchdmg(void) { + CMD_ARGS(const u8 *jumpInstr); + if (gMultiHitCounter == 1) { if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) @@ -12845,18 +13728,20 @@ static void Cmd_jumpifnopursuitswitchdmg(void) gCurrentMove = MOVE_PURSUIT; gCurrMovePos = gChosenMovePos = *(gBattleStruct->chosenMovePositions + gBattlerTarget); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; gBattleScripting.animTurn = 1; gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->jumpInstr; } } static void Cmd_setsunny(void) { + CMD_ARGS(); + if (!TryChangeBattleWeather(gBattlerAttacker, ENUM_WEATHER_SUN, FALSE)) { gMoveResultFlags |= MOVE_RESULT_MISSED; @@ -12867,12 +13752,14 @@ static void Cmd_setsunny(void) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STARTED_SUNLIGHT; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } // Belly Drum static void Cmd_maxattackhalvehp(void) { + CMD_ARGS(const u8 *failInstr); + u32 halfHp = gBattleMons[gBattlerAttacker].maxHP / 2; if (!(gBattleMons[gBattlerAttacker].maxHP / 2)) @@ -12887,17 +13774,19 @@ static void Cmd_maxattackhalvehp(void) if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } // Psych Up static void Cmd_copyfoestats(void) { + CMD_ARGS(const u8 *unused); + s32 i; for (i = 0; i < NUM_BATTLE_STATS; i++) @@ -12905,11 +13794,13 @@ static void Cmd_copyfoestats(void) gBattleMons[gBattlerAttacker].statStages[i] = gBattleMons[gBattlerTarget].statStages[i]; } - gBattlescriptCurrInstr += 5; // Has an unused jump ptr(possibly for a failed attempt) parameter. + gBattlescriptCurrInstr = cmd->nextInstr; // Has an unused jump ptr(possibly for a failed attempt) parameter. } static void Cmd_rapidspinfree(void) { + CMD_ARGS(); + u8 atkSide = GetBattlerSide(gBattlerAttacker); if (gBattleMons[gBattlerAttacker].status2 & STATUS2_WRAPPED) @@ -12958,18 +13849,22 @@ static void Cmd_rapidspinfree(void) } else { - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_setdefensecurlbit(void) { + CMD_ARGS(); + gBattleMons[gBattlerAttacker].status2 |= STATUS2_DEFENSE_CURL; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_recoverbasedonsunlight(void) { + CMD_ARGS(const u8 *failInstr); + gBattlerTarget = gBattlerAttacker; if (gBattleMons[gBattlerAttacker].hp != gBattleMons[gBattlerAttacker].maxHP) { @@ -12994,21 +13889,23 @@ static void Cmd_recoverbasedonsunlight(void) gBattleMoveDamage = 1; gBattleMoveDamage *= -1; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } static void Cmd_setstickyweb(void) { + CMD_ARGS(const u8 *failInstr); + u8 targetSide = GetBattlerSide(gBattlerTarget); if (gSideStatuses[targetSide] & SIDE_STATUS_STICKY_WEB) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -13016,12 +13913,14 @@ static void Cmd_setstickyweb(void) gSideTimers[targetSide].stickyWebBattlerSide = GetBattlerSide(gBattlerAttacker); // For Court Change/Defiant - set this to the user's side gSideTimers[targetSide].stickyWebAmount = 1; gBattleStruct->stickyWebUser = gBattlerAttacker; // For Mirror Armor - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_selectfirstvalidtarget(void) { + CMD_ARGS(); + for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++) { if (gBattlerTarget == gBattlerAttacker && !(GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove) & MOVE_TARGET_USER)) @@ -13029,14 +13928,16 @@ static void Cmd_selectfirstvalidtarget(void) if (IsBattlerAlive(gBattlerTarget)) break; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_trysetfutureattack(void) { + CMD_ARGS(const u8 *failInstr); + if (gWishFutureKnock.futureSightCounter[gBattlerTarget] != 0) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -13050,15 +13951,17 @@ static void Cmd_trysetfutureattack(void) else gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FUTURE_SIGHT; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_trydobeatup(void) { + CMD_ARGS(const u8 *endInstr, const u8 *failInstr); + #if B_BEAT_UP >= GEN_5 gBattleStruct->beatUpSlot++; - gBattlescriptCurrInstr += 9; + gBattlescriptCurrInstr = cmd->nextInstr; #else struct Pokemon *party; @@ -13069,7 +13972,7 @@ static void Cmd_trydobeatup(void) if (gBattleMons[gBattlerTarget].hp == 0) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->endInstr; } else { @@ -13086,7 +13989,7 @@ static void Cmd_trydobeatup(void) { PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gBattlerAttacker, gBattleCommunication[0]) - gBattlescriptCurrInstr += 9; + gBattlescriptCurrInstr = cmd->nextInstr; gBattleMoveDamage = gSpeciesInfo[GetMonData(&party[gBattleCommunication[0]], MON_DATA_SPECIES)].baseAttack; gBattleMoveDamage *= gBattleMoves[gCurrentMove].power; @@ -13099,15 +14002,17 @@ static void Cmd_trydobeatup(void) gBattleCommunication[0]++; } else if (beforeLoop != 0) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->endInstr; else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 5); + gBattlescriptCurrInstr = cmd->failInstr; } #endif } static void Cmd_setsemiinvulnerablebit(void) { + CMD_ARGS(); + switch (gCurrentMove) { case MOVE_FLY: @@ -13127,25 +14032,31 @@ static void Cmd_setsemiinvulnerablebit(void) break; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_clearsemiinvulnerablebit(void) { + CMD_ARGS(); + gStatuses3[gBattlerAttacker] &= ~STATUS3_SEMI_INVULNERABLE; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_setminimize(void) { + CMD_ARGS(); + if (gHitMarker & HITMARKER_OBEYS) gStatuses3[gBattlerAttacker] |= STATUS3_MINIMIZED; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_sethail(void) { + CMD_ARGS(); + if (!TryChangeBattleWeather(gBattlerAttacker, ENUM_WEATHER_HAIL, FALSE)) { gMoveResultFlags |= MOVE_RESULT_MISSED; @@ -13156,11 +14067,13 @@ static void Cmd_sethail(void) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_STARTED_HAIL; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_trymemento(void) { + CMD_ARGS(const u8 *failInstr); + #if B_MEMENTO_FAIL == GEN_3 if (gBattleMons[gBattlerTarget].statStages[STAT_ATK] == MIN_STAT_STAGE && gBattleMons[gBattlerTarget].statStages[STAT_SPATK] == MIN_STAT_STAGE @@ -13173,7 +14086,7 @@ static void Cmd_trymemento(void) #endif { // Failed, unprotected target already has minimum Attack and Special Attack. - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -13182,34 +14095,41 @@ static void Cmd_trymemento(void) gBattleMoveDamage = gBattleMons[gActiveBattler].hp; BtlController_EmitHealthBarUpdate(BUFFER_A, INSTANT_HP_BAR_DROP); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } // Follow Me static void Cmd_setforcedtarget(void) { + CMD_ARGS(); + gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTimer = 1; gSideTimers[GetBattlerSide(gBattlerTarget)].followmeTarget = gBattlerTarget; gSideTimers[GetBattlerSide(gBattlerTarget)].followmePowder = TestMoveFlags(gCurrentMove, FLAG_POWDER); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_setcharge(void) { + CMD_ARGS(); + gStatuses3[gBattlerAttacker] |= STATUS3_CHARGED_UP; gDisableStructs[gBattlerAttacker].chargeTimer = 2; gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } // Nature Power static void Cmd_callterrainattack(void) { + CMD_ARGS(); + gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; gCurrentMove = GetNaturePowerMove(); gBattlerTarget = GetMoveTarget(gCurrentMove, NO_TARGET_OVERRIDE); BattleScriptPush(gBattleScriptsForMoveEffects[gBattleMoves[gCurrentMove].effect]); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } u16 GetNaturePowerMove(void) @@ -13230,43 +14150,51 @@ u16 GetNaturePowerMove(void) // Refresh static void Cmd_cureifburnedparalysedorpoisoned(void) { + CMD_ARGS(const u8 *failInstr); + if (gBattleMons[gBattlerAttacker].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON)) { gBattleMons[gBattlerAttacker].status1 = 0; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; gActiveBattler = gBattlerAttacker; BtlController_EmitSetMonData(BUFFER_A, REQUEST_STATUS_BATTLE, 0, sizeof(gBattleMons[gActiveBattler].status1), &gBattleMons[gActiveBattler].status1); MarkBattlerForControllerExec(gActiveBattler); } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } static void Cmd_settorment(void) { + CMD_ARGS(const u8 *failInstr); + if (gBattleMons[gBattlerTarget].status2 & STATUS2_TORMENT) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { gBattleMons[gBattlerTarget].status2 |= STATUS2_TORMENT; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_jumpifnodamage(void) { + CMD_ARGS(const u8 *jumpInstr); + if (gProtectStructs[gBattlerAttacker].physicalDmg || gProtectStructs[gBattlerAttacker].specialDmg) - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->jumpInstr; } static void Cmd_settaunt(void) { + CMD_ARGS(const u8 *failInstr); + #if B_OBLIVIOUS_TAUNT >= GEN_6 if (GetBattlerAbility(gBattlerTarget) == ABILITY_OBLIVIOUS) { @@ -13289,16 +14217,18 @@ static void Cmd_settaunt(void) #endif gDisableStructs[gBattlerTarget].tauntTimer = turns; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } static void Cmd_trysethelpinghand(void) { + CMD_ARGS(const u8 *failInstr); + gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker))); if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE @@ -13307,17 +14237,19 @@ static void Cmd_trysethelpinghand(void) && !gProtectStructs[gBattlerTarget].helpingHand) { gProtectStructs[gBattlerTarget].helpingHand = TRUE; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } // Trick static void Cmd_tryswapitems(void) { + CMD_ARGS(const u8 *failInstr); + // opponent can't swap items with player in regular battles if (gBattleTypeFlags & BATTLE_TYPE_TRAINER_HILL || (GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT @@ -13331,7 +14263,7 @@ static void Cmd_tryswapitems(void) #endif )))) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -13347,7 +14279,7 @@ static void Cmd_tryswapitems(void) && (gWishFutureKnock.knockedOffMons[sideAttacker] & gBitTable[gBattlerPartyIndexes[gBattlerAttacker]] || gWishFutureKnock.knockedOffMons[sideTarget] & gBitTable[gBattlerPartyIndexes[gBattlerTarget]])) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } // can't swap if two pokemon don't have an item // or if either of them is an enigma berry or a mail @@ -13357,7 +14289,7 @@ static void Cmd_tryswapitems(void) || !CanBattlerGetOrLoseItem(gBattlerTarget, gBattleMons[gBattlerTarget].item) || !CanBattlerGetOrLoseItem(gBattlerTarget, gBattleMons[gBattlerAttacker].item)) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } // check if ability prevents swapping else if (GetBattlerAbility(gBattlerTarget) == ABILITY_STICKY_HOLD) @@ -13392,7 +14324,7 @@ static void Cmd_tryswapitems(void) gBattleStruct->choicedMove[gBattlerTarget] = MOVE_NONE; gBattleStruct->choicedMove[gBattlerAttacker] = MOVE_NONE; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; PREPARE_ITEM_BUFFER(gBattleTextBuff1, *newItemAtk) PREPARE_ITEM_BUFFER(gBattleTextBuff2, oldItemAtk) @@ -13429,6 +14361,8 @@ static void Cmd_tryswapitems(void) // Role Play static void Cmd_trycopyability(void) { + CMD_ARGS(const u8 *failInstr); + u16 defAbility = gBattleMons[gBattlerTarget].ability; if (gBattleMons[gBattlerAttacker].ability == defAbility @@ -13436,31 +14370,33 @@ static void Cmd_trycopyability(void) || IsRolePlayBannedAbilityAtk(gBattleMons[gBattlerAttacker].ability) || IsRolePlayBannedAbility(defAbility)) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { gBattleScripting.abilityPopupOverwrite = gBattleMons[gBattlerAttacker].ability; gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = defAbility; gLastUsedAbility = defAbility; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_trywish(void) { - switch (gBattlescriptCurrInstr[1]) + CMD_ARGS(u8 turnNumber, const u8 *failInstr); + + switch (cmd->turnNumber) { case 0: // use wish if (gWishFutureKnock.wishCounter[gBattlerAttacker] == 0) { gWishFutureKnock.wishCounter[gBattlerAttacker] = 2; gWishFutureKnock.wishPartyId[gBattlerAttacker] = gBattlerPartyIndexes[gBattlerAttacker]; - gBattlescriptCurrInstr += 6; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + gBattlescriptCurrInstr = cmd->failInstr; } break; case 1: // heal effect @@ -13476,9 +14412,9 @@ static void Cmd_trywish(void) gBattleMoveDamage *= -1; if (gBattleMons[gBattlerTarget].hp == gBattleMons[gBattlerTarget].maxHP) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + gBattlescriptCurrInstr = cmd->failInstr; else - gBattlescriptCurrInstr += 6; + gBattlescriptCurrInstr = cmd->nextInstr; break; } @@ -13486,24 +14422,28 @@ static void Cmd_trywish(void) static void Cmd_settoxicspikes(void) { + CMD_ARGS(const u8 *failInstr); + u8 targetSide = GetBattlerSide(gBattlerTarget); if (gSideTimers[targetSide].toxicSpikesAmount >= 2) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { gSideTimers[targetSide].toxicSpikesAmount++; gSideStatuses[targetSide] |= SIDE_STATUS_TOXIC_SPIKES; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_setgastroacid(void) { + CMD_ARGS(const u8 *failInstr); + if (IsGastroAcidBannedAbility(gBattleMons[gBattlerTarget].ability)) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -13511,16 +14451,18 @@ static void Cmd_setgastroacid(void) gSpecialStatuses[gBattlerTarget].neutralizingGasRemoved = TRUE; gStatuses3[gBattlerTarget] |= STATUS3_GASTRO_ACID; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_setyawn(void) { + CMD_ARGS(const u8 *failInstr); + if (gStatuses3[gBattlerTarget] & STATUS3_YAWN || gBattleMons[gBattlerTarget].status1 & STATUS1_ANY) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else if (IsBattlerTerrainAffected(gBattlerTarget, STATUS_FIELD_ELECTRIC_TERRAIN)) { @@ -13537,20 +14479,22 @@ static void Cmd_setyawn(void) else { gStatuses3[gBattlerTarget] |= STATUS3_YAWN_TURN(2); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_setdamagetohealthdifference(void) { + CMD_ARGS(const u8 *failInstr); + if (gBattleMons[gBattlerTarget].hp <= gBattleMons[gBattlerAttacker].hp) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - gBattleMons[gBattlerAttacker].hp; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -13572,6 +14516,8 @@ static void HandleRoomMove(u32 statusFlag, u8 *timer, u8 stringId) static void Cmd_setroom(void) { + CMD_ARGS(); + switch (gBattleMoves[gCurrentMove].effect) { case EFFECT_TRICK_ROOM: @@ -13587,28 +14533,30 @@ static void Cmd_setroom(void) gBattleCommunication[MULTISTRING_CHOOSER] = 6; break; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } // Skill Swap static void Cmd_tryswapabilities(void) { + CMD_ARGS(const u8 *failInstr); + if (IsSkillSwapBannedAbility(gBattleMons[gBattlerAttacker].ability) || IsSkillSwapBannedAbility(gBattleMons[gBattlerTarget].ability)) { RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_ABILITY_SHIELD); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -13616,16 +14564,18 @@ static void Cmd_tryswapabilities(void) gBattleMons[gBattlerAttacker].ability = gBattleStruct->overwrittenAbilities[gBattlerAttacker] = gBattleMons[gBattlerTarget].ability; gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = abilityAtk; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } } static void Cmd_tryimprison(void) { + CMD_ARGS(const u8 *failInstr); + if ((gStatuses3[gBattlerAttacker] & STATUS3_IMPRISONED_OTHERS)) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -13653,38 +14603,42 @@ static void Cmd_tryimprison(void) if (attackerMoveId != MAX_MON_MOVES) { gStatuses3[gBattlerAttacker] |= STATUS3_IMPRISONED_OTHERS; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; break; } } } if (battlerId == gBattlersCount) // In Generation 3 games, Imprison fails if the user doesn't share any moves with any of the foes. - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } static void Cmd_setstealthrock(void) { + CMD_ARGS(const u8 *failInstr); + u8 targetSide = GetBattlerSide(gBattlerTarget); if (gSideStatuses[targetSide] & SIDE_STATUS_STEALTH_ROCK) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { gSideStatuses[targetSide] |= SIDE_STATUS_STEALTH_ROCK; gSideTimers[targetSide].stealthRockAmount = 1; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_setuserstatus3(void) { - u32 flags = T1_READ_32(gBattlescriptCurrInstr + 1); + CMD_ARGS(u32 flags, const u8 *failInstr); + + u32 flags = cmd->flags; if (gStatuses3[gBattlerAttacker] & flags) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 5); + gBattlescriptCurrInstr = cmd->failInstr; } else { @@ -13693,12 +14647,14 @@ static void Cmd_setuserstatus3(void) gDisableStructs[gBattlerAttacker].magnetRiseTimer = 5; if (flags & STATUS3_LASER_FOCUS) gDisableStructs[gBattlerAttacker].laserFocusTimer = 2; - gBattlescriptCurrInstr += 9; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_assistattackselect(void) { + CMD_ARGS(const u8 *failInstr); + s32 chooseableMovesNo = 0; struct Pokemon *party; s32 monId, moveId; @@ -13735,41 +14691,45 @@ static void Cmd_assistattackselect(void) gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED; gCalledMove = validMoves[((Random() & 0xFF) * chooseableMovesNo) >> 8]; gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } static void Cmd_trysetmagiccoat(void) { + CMD_ARGS(const u8 *failInstr); + gBattlerTarget = gBattlerAttacker; gSpecialStatuses[gBattlerAttacker].ppNotAffectedByPressure = TRUE; if (gCurrentTurnActionNumber == gBattlersCount - 1) // moves last turn { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { gProtectStructs[gBattlerAttacker].bounceMove = TRUE; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } // Snatch static void Cmd_trysetsnatch(void) { + CMD_ARGS(const u8 *failInstr); + gSpecialStatuses[gBattlerAttacker].ppNotAffectedByPressure = TRUE; if (gCurrentTurnActionNumber == gBattlersCount - 1) // moves last turn { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { gProtectStructs[gBattlerAttacker].stealMove = TRUE; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } @@ -13779,7 +14739,9 @@ static void Cmd_unused2(void) static void Cmd_switchoutabilities(void) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + CMD_ARGS(u8 battler); + + gActiveBattler = GetBattlerForBattleScript(cmd->battler); if (gBattleMons[gActiveBattler].ability == ABILITY_NEUTRALIZING_GAS) { gBattleMons[gActiveBattler].ability = ABILITY_NONE; @@ -13811,24 +14773,28 @@ static void Cmd_switchoutabilities(void) break; } - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_jumpifhasnohp(void) { - gActiveBattler = GetBattlerForBattleScript(gBattlescriptCurrInstr[1]); + CMD_ARGS(u8 battler, const u8 *jumpInstr); + + gActiveBattler = GetBattlerForBattleScript(cmd->battler); if (gBattleMons[gActiveBattler].hp == 0) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 2); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 6; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_getsecretpowereffect(void) { + CMD_ARGS(); + gBattleScripting.moveEffect = GetSecretPowerMoveEffect(); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } u16 GetSecretPowerMoveEffect(void) @@ -13925,6 +14891,8 @@ u16 GetSecretPowerMoveEffect(void) static void Cmd_pickup(void) { + CMD_ARGS(); + s32 i; u16 species, heldItem; u16 ability; @@ -14018,11 +14986,13 @@ static void Cmd_pickup(void) } } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_doweatherformchangeanimation(void) { + CMD_ARGS(); + gActiveBattler = gBattleScripting.battler; if (gBattleMons[gActiveBattler].status2 & STATUS2_SUBSTITUTE) @@ -14031,14 +15001,16 @@ static void Cmd_doweatherformchangeanimation(void) BtlController_EmitBattleAnimation(BUFFER_A, B_ANIM_CASTFORM_CHANGE, gBattleStruct->formToChangeInto); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_tryweatherformdatachange(void) { + CMD_ARGS(); + u8 form; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; form = TryWeatherFormChange(gBattleScripting.battler); if (form) { @@ -14050,6 +15022,8 @@ static void Cmd_tryweatherformdatachange(void) // Water and Mud Sport static void Cmd_settypebasedhalvers(void) { + CMD_ARGS(const u8 *failInstr); + bool8 worked = FALSE; if (gBattleMoves[gCurrentMove].effect == EFFECT_MUD_SPORT) @@ -14092,9 +15066,9 @@ static void Cmd_settypebasedhalvers(void) } if (worked) - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } bool32 DoesSubstituteBlockMove(u8 battlerAtk, u8 battlerDef, u32 move) @@ -14127,14 +15101,18 @@ bool32 DoesDisguiseBlockMove(u8 battlerAtk, u8 battlerDef, u32 move) static void Cmd_jumpifsubstituteblocks(void) { + CMD_ARGS(const u8 *jumpInstr); + if (DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_tryrecycleitem(void) { + CMD_ARGS(const u8 *failInstr); + u16 *usedHeldItem; gActiveBattler = gBattlerAttacker; @@ -14148,11 +15126,11 @@ static void Cmd_tryrecycleitem(void) BtlController_EmitSetMonData(BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[gActiveBattler].item), &gBattleMons[gActiveBattler].item); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } @@ -14165,6 +15143,8 @@ bool32 CanCamouflage(u8 battlerId) static void Cmd_settypetoterrain(void) { + CMD_ARGS(const u8 *failInstr); + u8 terrainType; switch(gFieldStatuses & STATUS_FIELD_TERRAIN_ANY) { @@ -14190,17 +15170,19 @@ static void Cmd_settypetoterrain(void) SET_BATTLER_TYPE(gBattlerAttacker, terrainType); PREPARE_TYPE_BUFFER(gBattleTextBuff1, terrainType); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } // Unused static void Cmd_pursuitdoubles(void) { + CMD_ARGS(const u8 *failInstr); + gActiveBattler = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker))); if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE @@ -14210,19 +15192,21 @@ static void Cmd_pursuitdoubles(void) { gActionsByTurnOrder[gActiveBattler] = B_ACTION_TRY_FINISH; gCurrentMove = MOVE_PURSUIT; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; gBattleScripting.animTurn = 1; gBattleScripting.savedBattler = gBattlerAttacker; gBattlerAttacker = gActiveBattler; } else { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } } static void Cmd_snatchsetbattlers(void) { + CMD_ARGS(); + gEffectBattler = gBattlerAttacker; if (gBattlerAttacker == gBattlerTarget) @@ -14231,12 +15215,14 @@ static void Cmd_snatchsetbattlers(void) gBattlerTarget = gBattleScripting.battler; gBattleScripting.battler = gEffectBattler; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } // Brick Break static void Cmd_removelightscreenreflect(void) { + CMD_ARGS(); + u8 side; bool32 failed; @@ -14273,7 +15259,7 @@ static void Cmd_removelightscreenreflect(void) gBattleScripting.animTargetsHit = 0; } - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } u8 GetCatchingBattler(void) @@ -14286,6 +15272,8 @@ u8 GetCatchingBattler(void) static void Cmd_handleballthrow(void) { + CMD_ARGS(); + u16 ballMultiplier = 100; s8 ballAddition = 0; @@ -14604,6 +15592,8 @@ static void Cmd_handleballthrow(void) static void Cmd_givecaughtmon(void) { + CMD_ARGS(); + if (GiveMonToPlayer(&gEnemyParty[gBattlerPartyIndexes[GetCatchingBattler()]]) != MON_GIVEN_TO_PARTY) { if (!ShouldShowBoxWasFullMessage()) @@ -14629,27 +15619,31 @@ static void Cmd_givecaughtmon(void) GetMonData(&gEnemyParty[gBattlerPartyIndexes[GetCatchingBattler()]], MON_DATA_NICKNAME, gBattleResults.caughtMonNick); gBattleResults.caughtMonBall = GetMonData(&gEnemyParty[gBattlerPartyIndexes[GetCatchingBattler()]], MON_DATA_POKEBALL, NULL); - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_trysetcaughtmondexflags(void) { + CMD_ARGS(const u8 *failInstr); + u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[GetCatchingBattler()]], MON_DATA_SPECIES, NULL); u32 personality = GetMonData(&gEnemyParty[gBattlerPartyIndexes[GetCatchingBattler()]], MON_DATA_PERSONALITY, NULL); if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT)) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { HandleSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_SET_CAUGHT, personality); - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_displaydexinfo(void) { + CMD_ARGS(); + u16 species = GetMonData(&gEnemyParty[gBattlerPartyIndexes[GetCatchingBattler()]], MON_DATA_SPECIES, NULL); switch (gBattleCommunication[0]) @@ -14694,7 +15688,7 @@ static void Cmd_displaydexinfo(void) break; case 5: if (!gPaletteFade.active) - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; break; } } @@ -14767,6 +15761,8 @@ void BattleDestroyYesNoCursorAt(u8 cursorPosition) static void Cmd_trygivecaughtmonnick(void) { + CMD_ARGS(const u8 *successInstr); + switch (gBattleCommunication[MULTIUSE_STATE]) { case 0: @@ -14829,48 +15825,58 @@ static void Cmd_trygivecaughtmonnick(void) if (gMain.callback2 == BattleMainCB2 && !gPaletteFade.active) { SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_NICKNAME, gBattleStruct->caughtMonNick); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->successInstr; } break; case 4: if (CalculatePlayerPartyCount() == PARTY_SIZE) - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; else - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->successInstr; break; } } static void Cmd_subattackerhpbydmg(void) { + CMD_ARGS(); + gBattleMons[gBattlerAttacker].hp -= gBattleMoveDamage; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_removeattackerstatus1(void) { + CMD_ARGS(); + gBattleMons[gBattlerAttacker].status1 = 0; - gBattlescriptCurrInstr++; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_finishaction(void) { + CMD_ARGS(); + gCurrentActionFuncId = B_ACTION_FINISHED; } static void Cmd_finishturn(void) { + CMD_ARGS(); + gCurrentActionFuncId = B_ACTION_FINISHED; gCurrentTurnActionNumber = gBattlersCount; } static void Cmd_trainerslideout(void) { - gActiveBattler = GetBattlerAtPosition(gBattlescriptCurrInstr[1]); + CMD_ARGS(u8 position); + + gActiveBattler = GetBattlerAtPosition(cmd->position); BtlController_EmitTrainerSlideBack(BUFFER_A); MarkBattlerForControllerExec(gActiveBattler); - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static const u16 sTelekinesisBanList[] = @@ -14898,54 +15904,62 @@ bool32 IsTelekinesisBannedSpecies(u16 species) static void Cmd_settelekinesis(void) { + CMD_ARGS(const u8 *failInstr); + if (gStatuses3[gBattlerTarget] & (STATUS3_TELEKINESIS | STATUS3_ROOTED | STATUS3_SMACKED_DOWN) || gFieldStatuses & STATUS_FIELD_GRAVITY || IsTelekinesisBannedSpecies(gBattleMons[gBattlerTarget].species)) { - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { gStatuses3[gBattlerTarget] |= STATUS3_TELEKINESIS; gDisableStructs[gBattlerTarget].telekinesisTimer = 3; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_swapstatstages(void) { - u8 statId = T1_READ_8(gBattlescriptCurrInstr + 1); - s8 atkStatStage = gBattleMons[gBattlerAttacker].statStages[statId]; - s8 defStatStage = gBattleMons[gBattlerTarget].statStages[statId]; + CMD_ARGS(u8 stat); - gBattleMons[gBattlerAttacker].statStages[statId] = defStatStage; - gBattleMons[gBattlerTarget].statStages[statId] = atkStatStage; + u8 stat = cmd->stat; + s8 atkStatStage = gBattleMons[gBattlerAttacker].statStages[stat]; + s8 defStatStage = gBattleMons[gBattlerTarget].statStages[stat]; - gBattlescriptCurrInstr += 2; + gBattleMons[gBattlerAttacker].statStages[stat] = defStatStage; + gBattleMons[gBattlerTarget].statStages[stat] = atkStatStage; + + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_averagestats(void) { - u8 statId = T1_READ_8(gBattlescriptCurrInstr + 1); - u16 atkStat = *(u16 *)((&gBattleMons[gBattlerAttacker].attack) + (statId - 1)); - u16 defStat = *(u16 *)((&gBattleMons[gBattlerTarget].attack) + (statId - 1)); + CMD_ARGS(u8 stat); + + u8 stat = cmd->stat; + u16 atkStat = *(u16 *)((&gBattleMons[gBattlerAttacker].attack) + (stat - 1)); + u16 defStat = *(u16 *)((&gBattleMons[gBattlerTarget].attack) + (stat - 1)); u16 average = (atkStat + defStat) / 2; - *(u16 *)((&gBattleMons[gBattlerAttacker].attack) + (statId - 1)) = average; - *(u16 *)((&gBattleMons[gBattlerTarget].attack) + (statId - 1)) = average; + *(u16 *)((&gBattleMons[gBattlerAttacker].attack) + (stat - 1)) = average; + *(u16 *)((&gBattleMons[gBattlerTarget].attack) + (stat - 1)) = average; - gBattlescriptCurrInstr += 2; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_jumpifoppositegenders(void) { + CMD_ARGS(const u8 *jumpInstr); + u32 atkGender = GetGenderFromSpeciesAndPersonality(gBattleMons[gBattlerAttacker].species, gBattleMons[gBattlerAttacker].personality); u32 defGender = GetGenderFromSpeciesAndPersonality(gBattleMons[gBattlerTarget].species, gBattleMons[gBattlerTarget].personality); if ((atkGender == MON_MALE && defGender == MON_FEMALE) || (atkGender == MON_FEMALE && defGender == MON_MALE)) - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->jumpInstr; else - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_unused(void) @@ -14954,32 +15968,38 @@ static void Cmd_unused(void) static void Cmd_tryworryseed(void) { + CMD_ARGS(const u8 *failInstr); + if (IsWorrySeedBannedAbility(gBattleMons[gBattlerTarget].ability)) { RecordAbilityBattle(gBattlerTarget, gBattleMons[gBattlerTarget].ability); gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else if (GetBattlerHoldEffect(gBattlerTarget, TRUE) == HOLD_EFFECT_ABILITY_SHIELD) { RecordItemEffectBattle(gBattlerTarget, HOLD_EFFECT_ABILITY_SHIELD); - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1); + gBattlescriptCurrInstr = cmd->failInstr; } else { gBattleMons[gBattlerTarget].ability = gBattleStruct->overwrittenAbilities[gBattlerTarget] = ABILITY_INSOMNIA; - gBattlescriptCurrInstr += 5; + gBattlescriptCurrInstr = cmd->nextInstr; } } static void Cmd_callnative(void) { - void (*func)() = (void *)T1_READ_PTR(gBattlescriptCurrInstr + 1); + CMD_ARGS(void (*func)(void)); + void (*func)(void) = cmd->func; func(); } // Callnative Funcs void BS_CalcMetalBurstDmg(void) { + NATIVE_ARGS(const u8 *failInstr); + u8 sideAttacker = GetBattlerSide(gBattlerAttacker); u8 sideTarget = 0; @@ -14994,7 +16014,7 @@ void BS_CalcMetalBurstDmg(void) else gBattlerTarget = gProtectStructs[gBattlerAttacker].physicalBattlerId; - gBattlescriptCurrInstr += 9; + gBattlescriptCurrInstr = cmd->nextInstr; } else if (gProtectStructs[gBattlerAttacker].specialDmg && sideAttacker != (sideTarget = GetBattlerSide(gProtectStructs[gBattlerAttacker].specialBattlerId)) @@ -15007,12 +16027,12 @@ void BS_CalcMetalBurstDmg(void) else gBattlerTarget = gProtectStructs[gBattlerAttacker].specialBattlerId; - gBattlescriptCurrInstr += 9; + gBattlescriptCurrInstr = cmd->nextInstr; } else { gSpecialStatuses[gBattlerAttacker].ppNotAffectedByPressure = TRUE; - gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 5); + gBattlescriptCurrInstr = cmd->failInstr; } } From 56c9564e7aadf45a41e9fcf3ef3a68024a26f7c8 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Fri, 17 Feb 2023 11:28:46 +0100 Subject: [PATCH 68/69] 8th gen Howl's effect (#2700) * Howl gen8 effect --- data/battle_scripts_1.s | 38 +++++++++++++ include/constants/battle_move_effects.h | 3 +- include/constants/battle_script_commands.h | 1 + src/battle_util.c | 3 + src/data/battle_moves.h | 3 +- test/move_effect_attack_up_user_ally.c | 65 ++++++++++++++++++++++ test/test_battle.h | 14 ++--- 7 files changed, 118 insertions(+), 9 deletions(-) create mode 100644 test/move_effect_attack_up_user_ally.c diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 33af9f16e..12b32c3f1 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -416,6 +416,44 @@ gBattleScriptsForMoveEffects:: .4byte BattleScript_EffectSpecialAttackUpHit @ EFFECT_SPECIAL_ATTACK_UP_HIT .4byte BattleScript_EffectVictoryDance @ EFFECT_VICTORY_DANCE .4byte BattleScript_EffectTeatime @ EFFECT_TEATIME + .4byte BattleScript_EffectAttackUpUserAlly @ EFFECT_ATTACK_UP_USER_ALLY + +BattleScript_EffectAttackUpUserAlly: + jumpifnoally BS_ATTACKER, BattleScript_EffectAttackUp + attackcanceler + attackstring + ppreduce + jumpifstat BS_ATTACKER, CMP_NOT_EQUAL, STAT_ATK, MAX_STAT_STAGE, BattleScript_EffectAttackUpUserAlly_Works + jumpifstat BS_ATTACKER_PARTNER, CMP_EQUAL, STAT_ATK, MAX_STAT_STAGE, BattleScript_ButItFailed +BattleScript_EffectAttackUpUserAlly_Works: + attackanimation + waitanimation + setstatchanger STAT_ATK, 1, FALSE + statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_ALLOW_PTR, BattleScript_EffectAttackUpUserAlly_TryAlly + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_EffectAttackUpUserAllyUser_PrintString + setgraphicalstatchangevalues + playanimation BS_ATTACKER, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 +BattleScript_EffectAttackUpUserAllyUser_PrintString: + printfromtable gStatUpStringIds + waitmessage B_WAIT_TIME_LONG +BattleScript_EffectAttackUpUserAlly_TryAlly: + setallytonexttarget BattleScript_EffectAttackUpUserAlly_TryAlly_ +BattleScript_EffectAttackUpUserAlly_End: + goto BattleScript_MoveEnd +BattleScript_EffectAttackUpUserAlly_TryAlly_: + setstatchanger STAT_ATK, 1, FALSE + statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_EffectAttackUpUserAlly_End + jumpifbyte CMP_NOT_EQUAL, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_INCREASE, BattleScript_EffectAttackUpUserAlly_AllyAnim + pause B_WAIT_TIME_SHORTEST + printstring STRINGID_TARGETSTATWONTGOHIGHER + waitmessage B_WAIT_TIME_LONG + goto BattleScript_EffectAttackUpUserAlly_End +BattleScript_EffectAttackUpUserAlly_AllyAnim: + setgraphicalstatchangevalues + playanimation BS_TARGET, B_ANIM_STATS_CHANGE, sB_ANIM_ARG1 + printfromtable gStatUpStringIds + waitmessage B_WAIT_TIME_LONG + goto BattleScript_EffectAttackUpUserAlly_End BattleScript_EffectTeatime:: attackcanceler diff --git a/include/constants/battle_move_effects.h b/include/constants/battle_move_effects.h index 2cf8d2f9c..beab88151 100644 --- a/include/constants/battle_move_effects.h +++ b/include/constants/battle_move_effects.h @@ -397,7 +397,8 @@ #define EFFECT_SPECIAL_ATTACK_UP_HIT 391 #define EFFECT_VICTORY_DANCE 392 #define EFFECT_TEATIME 393 +#define EFFECT_ATTACK_UP_USER_ALLY 394 // Howl 8th Gen -#define NUM_BATTLE_MOVE_EFFECTS 394 +#define NUM_BATTLE_MOVE_EFFECTS 395 #endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index 935121394..68e927d75 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -74,6 +74,7 @@ #define BS_PLAYER2 13 // for Cmd_updatestatusicon #define BS_OPPONENT2 14 #define BS_ABILITY_BATTLER 15 +#define BS_ATTACKER_PARTNER 16 // Cmd_accuracycheck #define NO_ACC_CALC_CHECK_LOCK_ON 0xFFFF diff --git a/src/battle_util.c b/src/battle_util.c index 8d350553d..4bded150b 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1287,6 +1287,9 @@ u8 GetBattlerForBattleScript(u8 caseId) case BS_ATTACKER: ret = gBattlerAttacker; break; + case BS_ATTACKER_PARTNER: + ret = BATTLE_PARTNER(gBattlerAttacker); + break; case BS_EFFECT_BATTLER: ret = gEffectBattler; break; diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index eed91d524..997e7f4b3 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -6073,10 +6073,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] = { #if B_UPDATED_MOVE_DATA >= GEN_8 .flags = FLAG_SNATCH_AFFECTED | FLAG_SOUND, + .effect = EFFECT_ATTACK_UP_USER_ALLY, #else .flags = FLAG_SNATCH_AFFECTED, + .effect = EFFECT_ATTACK_UP, #endif - .effect = EFFECT_ATTACK_UP, .power = 0, .type = TYPE_NORMAL, .accuracy = 0, diff --git a/test/move_effect_attack_up_user_ally.c b/test/move_effect_attack_up_user_ally.c new file mode 100644 index 000000000..e98df30d8 --- /dev/null +++ b/test/move_effect_attack_up_user_ally.c @@ -0,0 +1,65 @@ +#include "global.h" +#include "test_battle.h" + +ASSUMPTIONS +{ + ASSUME(gBattleMoves[MOVE_HOWL].effect == EFFECT_ATTACK_UP_USER_ALLY); +} + +SINGLE_BATTLE_TEST("Howl raises user's Attack", s16 damage) +{ + bool32 raiseAttack; + PARAMETRIZE { raiseAttack = FALSE; } + PARAMETRIZE { raiseAttack = TRUE; } + GIVEN { + ASSUME(gBattleMoves[MOVE_TACKLE].split == SPLIT_PHYSICAL); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + if (raiseAttack) TURN { MOVE(player, MOVE_HOWL); } + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + if (raiseAttack) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_HOWL, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's attack rose!"); + } + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage); + } +} + +DOUBLE_BATTLE_TEST("Howl raises user's and partner's Attack", s16 damageLeft, s16 damageRight) +{ + bool32 raiseAttack; + PARAMETRIZE { raiseAttack = FALSE; } + PARAMETRIZE { raiseAttack = TRUE; } + GIVEN { + ASSUME(gBattleMoves[MOVE_TACKLE].split == SPLIT_PHYSICAL); + PLAYER(SPECIES_WOBBUFFET) { Speed(15); }; + PLAYER(SPECIES_WYNAUT) { Speed(10); }; + OPPONENT(SPECIES_WOBBUFFET) { Speed(13); }; + OPPONENT(SPECIES_WYNAUT) { Speed(12); }; + } WHEN { + if (raiseAttack) TURN { MOVE(playerLeft, MOVE_HOWL); } + TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); } + TURN { MOVE(playerRight, MOVE_TACKLE, target: opponentRight); } + } SCENE { + if (raiseAttack) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_HOWL, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); + MESSAGE("Wobbuffet's attack rose!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight); + MESSAGE("Wynaut's attack rose!"); + } + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerLeft); + HP_BAR(opponentLeft, captureDamage: &results[i].damageLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight); + HP_BAR(opponentRight, captureDamage: &results[i].damageRight); + } FINALLY { + EXPECT_MUL_EQ(results[0].damageLeft, Q_4_12(1.5), results[1].damageLeft); + EXPECT_MUL_EQ(results[0].damageRight, Q_4_12(1.5), results[1].damageRight); + } +} diff --git a/test/test_battle.h b/test/test_battle.h index 8fb1ce6d3..806e7947e 100644 --- a/test/test_battle.h +++ b/test/test_battle.h @@ -112,17 +112,17 @@ * NOT STATUS_ICON(opponent, paralysis: TRUE); to say that Oddish was * not paralyzed without specifying the exact outputs which led to that. * - * As a final example, to test that Howl works you might: - * 1. Put a Wobbuffet that knows Howl and Tackle in your party. + * As a final example, to test that Meditate works you might: + * 1. Put a Wobbuffet that knows Meditate and Tackle in your party. * 2. Battle a wild Wobbuffet. * 3. Use Tackle and note the amount the HP bar reduced. * 4. Battle a wild Wobbuffet. - * 5. Use Howl and that that the stat change animation and message play. + * 5. Use Meditate and that the stat change animation and message play. * 6. Use Tackle and check that the HP bar reduced by more than in 3. * * This can be translated to an automated test as follows: * - * SINGLE_BATTLE_TEST("Howl raises Attack", s16 damage) + * SINGLE_BATTLE_TEST("Meditate raises Attack", s16 damage) * { * bool32 raiseAttack; * PARAMETRIZE { raiseAttack = FALSE; } @@ -132,11 +132,11 @@ * PLAYER(SPECIES_WOBBUFFET); * OPPONENT(SPECIES_WOBBUFFET); * } WHEN { - * if (raiseAttack) TURN { MOVE(player, MOVE_HOWL); } // 5. + * if (raiseAttack) TURN { MOVE(player, MOVE_MEDITATE); } // 5. * TURN { MOVE(player, MOVE_TACKLE); } // 3 & 6. * } SCENE { * if (raiseAttack) { - * ANIMATION(ANIM_TYPE_MOVE, MOVE_HOWL, player); + * ANIMATION(ANIM_TYPE_MOVE, MOVE_MEDITATE, player); * ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); // 5. * MESSAGE("Wobbuffet's attack rose!"); // 5. * } @@ -159,7 +159,7 @@ * of the first battle (with a small tolerance to account for rounding). * * You might notice that all the tests check the outputs the player - * could see rather than the internal battle state. e.g. the Howl test + * could see rather than the internal battle state. e.g. the Meditate test * could have used gBattleMons[B_POSITION_OPPONENT_LEFT].hp instead of * using HP_BAR to capture the damage. This is a deliberate choice, by * checking what the player can observe the tests are more robust to From 0c523f951886b7e1b85ee576fa2ece7e7543da15 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Fri, 17 Feb 2023 14:55:51 +0100 Subject: [PATCH 69/69] Fix Magic bounce powder moves against grass types (#2633) * Fix Magic bounce powder moves against grass types --- data/battle_scripts_1.s | 5 ++- include/battle_util.h | 29 +++++++++++++ src/battle_script_commands.c | 4 +- src/battle_util.c | 34 ++------------- test/ability_magic_bounce.c | 84 ++++++++++++++++++++++++++++++++++++ test/powder_moves.c | 47 ++++++++++++++++++++ 6 files changed, 171 insertions(+), 32 deletions(-) create mode 100644 test/ability_magic_bounce.c create mode 100644 test/powder_moves.c diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 12b32c3f1..ae92aba7c 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -7683,11 +7683,14 @@ BattleScript_GrudgeTakesPp:: printstring STRINGID_PKMNLOSTPPGRUDGE waitmessage B_WAIT_TIME_LONG return - + BattleScript_MagicCoatBounce:: attackstring ppreduce pause B_WAIT_TIME_SHORT + jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0, BattleScript_MagicCoatBounce_Print + call BattleScript_AbilityPopUp +BattleScript_MagicCoatBounce_Print: printfromtable gMagicCoatBounceStringIds waitmessage B_WAIT_TIME_LONG orword gHitMarker, HITMARKER_ATTACKSTRING_PRINTED | HITMARKER_NO_PPDEDUCT | HITMARKER_ALLOW_NO_PP diff --git a/include/battle_util.h b/include/battle_util.h index 1c3f486cd..bf3943a9d 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -64,6 +64,35 @@ struct TypePower u16 effect; }; +enum +{ + CANCELLER_FLAGS, + CANCELLER_SKY_DROP, + CANCELLER_ASLEEP, + CANCELLER_FROZEN, + CANCELLER_TRUANT, + CANCELLER_RECHARGE, + CANCELLER_FLINCH, + CANCELLER_DISABLED, + CANCELLER_GRAVITY, + CANCELLER_HEAL_BLOCKED, + CANCELLER_TAUNTED, + CANCELLER_IMPRISONED, + CANCELLER_CONFUSED, + CANCELLER_PARALYSED, + CANCELLER_IN_LOVE, + CANCELLER_BIDE, + CANCELLER_THAW, + CANCELLER_POWDER_MOVE, + CANCELLER_POWDER_STATUS, + CANCELLER_THROAT_CHOP, + CANCELLER_MULTIHIT_MOVES, + CANCELLER_Z_MOVES, + CANCELLER_END, + CANCELLER_PSYCHIC_TERRAIN, + CANCELLER_END2, +}; + extern const struct TypePower gNaturalGiftTable[]; void HandleAction_ThrowBall(void); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 57311e671..b5629c2cc 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1530,6 +1530,7 @@ static void Cmd_attackcanceler(void) PressurePPLose(gBattlerAttacker, gBattlerTarget, MOVE_MAGIC_COAT); gProtectStructs[gBattlerTarget].usesBouncedMove = TRUE; gBattleCommunication[MULTISTRING_CHOOSER] = 0; + gBattleStruct->atkCancellerTracker = CANCELLER_POWDER_MOVE; // Edge case for bouncing a powder move against a grass type pokemon. if (BlocksPrankster(gCurrentMove, gBattlerTarget, gBattlerAttacker, TRUE)) { // Opponent used a prankster'd magic coat -> reflected status move should fail against a dark-type attacker @@ -1547,11 +1548,12 @@ static void Cmd_attackcanceler(void) && gBattleMoves[gCurrentMove].flags & FLAG_MAGIC_COAT_AFFECTED && !gProtectStructs[gBattlerAttacker].usesBouncedMove) { - RecordAbilityBattle(gBattlerTarget, ABILITY_MAGIC_BOUNCE); gProtectStructs[gBattlerTarget].usesBouncedMove = TRUE; gBattleCommunication[MULTISTRING_CHOOSER] = 1; + gBattleStruct->atkCancellerTracker = CANCELLER_POWDER_MOVE; // Edge case for bouncing a powder move against a grass type pokemon. BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_MagicCoatBounce; + gBattlerAbility = gBattlerTarget; return; } diff --git a/src/battle_util.c b/src/battle_util.c index 4bded150b..46f8d3a3d 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3410,35 +3410,6 @@ void TryClearRageAndFuryCutter(void) } } -enum -{ - CANCELLER_FLAGS, - CANCELLER_SKY_DROP, - CANCELLER_ASLEEP, - CANCELLER_FROZEN, - CANCELLER_TRUANT, - CANCELLER_RECHARGE, - CANCELLER_FLINCH, - CANCELLER_DISABLED, - CANCELLER_GRAVITY, - CANCELLER_HEAL_BLOCKED, - CANCELLER_TAUNTED, - CANCELLER_IMPRISONED, - CANCELLER_CONFUSED, - CANCELLER_PARALYSED, - CANCELLER_IN_LOVE, - CANCELLER_BIDE, - CANCELLER_THAW, - CANCELLER_POWDER_MOVE, - CANCELLER_POWDER_STATUS, - CANCELLER_THROAT_CHOP, - CANCELLER_MULTIHIT_MOVES, - CANCELLER_Z_MOVES, - CANCELLER_END, - CANCELLER_PSYCHIC_TERRAIN, - CANCELLER_END2, -}; - u8 AtkCanceller_UnableToUseMove(void) { u8 effect = 0; @@ -3753,7 +3724,10 @@ u8 AtkCanceller_UnableToUseMove(void) if (effect != 0) gBattlescriptCurrInstr = BattleScript_PowderMoveNoEffect; } - gBattleStruct->atkCancellerTracker++; + if (gProtectStructs[gBattlerAttacker].usesBouncedMove) // Edge case for bouncing a powder move against a grass type pokemon. + gBattleStruct->atkCancellerTracker = CANCELLER_END; + else + gBattleStruct->atkCancellerTracker++; break; case CANCELLER_POWDER_STATUS: if (gBattleMons[gBattlerAttacker].status2 & STATUS2_POWDER) diff --git a/test/ability_magic_bounce.c b/test/ability_magic_bounce.c new file mode 100644 index 000000000..d52b93c4a --- /dev/null +++ b/test/ability_magic_bounce.c @@ -0,0 +1,84 @@ +#include "global.h" +#include "test_battle.h" + + +SINGLE_BATTLE_TEST("Magic Bounce bounces back status moves") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_TOXIC].effect == EFFECT_TOXIC); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE);}; + } WHEN { + TURN { MOVE(player, MOVE_TOXIC); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_MAGIC_BOUNCE); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TOXIC, player); + MESSAGE("Wynaut's Toxic was bounced back by Foe Espeon's Magic Bounce!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TOXIC, opponent); + STATUS_ICON(player, badPoison: TRUE); + } +} + +SINGLE_BATTLE_TEST("Magic Bounce bounces back powder moves") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_STUN_SPORE].flags & FLAG_POWDER); + ASSUME(gBattleMoves[MOVE_STUN_SPORE].effect == EFFECT_PARALYZE); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE);}; + } WHEN { + TURN { MOVE(player, MOVE_STUN_SPORE); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_MAGIC_BOUNCE); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TOXIC, player); + MESSAGE("Wynaut's Stun Spore was bounced back by Foe Espeon's Magic Bounce!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_STUN_SPORE, opponent); + STATUS_ICON(player, paralysis: TRUE); + } +} + +SINGLE_BATTLE_TEST("Magic Bounce cannot bounce back powder moves against Grass Types") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_STUN_SPORE].flags & FLAG_POWDER); + ASSUME(gSpeciesInfo[SPECIES_ODDISH].types[0] == TYPE_GRASS); + PLAYER(SPECIES_ODDISH); + OPPONENT(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE);}; + } WHEN { + TURN { MOVE(player, MOVE_STUN_SPORE); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_MAGIC_BOUNCE); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_STUN_SPORE, player); + MESSAGE("Oddish's Stun Spore was bounced back by Foe Espeon's Magic Bounce!"); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_STUN_SPORE, opponent); + MESSAGE("It doesn't affect Oddish…"); + NOT STATUS_ICON(player, paralysis: TRUE); + } +} + + +DOUBLE_BATTLE_TEST("Magic Bounce bounces back moves hitting both foes at two foes") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_LEER].effect == EFFECT_DEFENSE_DOWN); + ASSUME(gBattleMoves[MOVE_LEER].target == MOVE_TARGET_BOTH); + PLAYER(SPECIES_ABRA); + PLAYER(SPECIES_KADABRA); + OPPONENT(SPECIES_ESPEON) { Ability(ABILITY_MAGIC_BOUNCE);}; + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(playerLeft, MOVE_LEER); } + } SCENE { + ABILITY_POPUP(opponentLeft, ABILITY_MAGIC_BOUNCE); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_LEER, playerLeft); + MESSAGE("Abra's Leer was bounced back by Foe Espeon's Magic Bounce!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_LEER, opponentLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); + MESSAGE("Abra's defense fell!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight); + MESSAGE("Kadabra's defense fell!"); + // Also check if second original target gets hit by Leer as this was once bugged + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight); + MESSAGE("Foe Wynaut's defense fell!"); + } +} diff --git a/test/powder_moves.c b/test/powder_moves.c new file mode 100644 index 000000000..cb0aee528 --- /dev/null +++ b/test/powder_moves.c @@ -0,0 +1,47 @@ +#include "global.h" +#include "test_battle.h" + +SINGLE_BATTLE_TEST("Powder Moves are blocked by Grass Types") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_STUN_SPORE].flags & FLAG_POWDER); + ASSUME(gSpeciesInfo[SPECIES_ODDISH].types[0] == TYPE_GRASS); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_ODDISH); + } WHEN { + TURN { MOVE(player, MOVE_STUN_SPORE); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_STUN_SPORE, player); + MESSAGE("It doesn't affect Foe Oddish…"); + } +} + +SINGLE_BATTLE_TEST("Powder Moves are blocked by Ability Overcoat") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_STUN_SPORE].flags & FLAG_POWDER); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_PINECO) { Ability(ABILITY_OVERCOAT);}; + } WHEN { + TURN { MOVE(player, MOVE_STUN_SPORE); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_OVERCOAT); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_STUN_SPORE, player); + MESSAGE("It doesn't affect Foe Pineco…"); + } +} + +SINGLE_BATTLE_TEST("Powder Moves are blocked by Item Safety Goggles") +{ + GIVEN { + ASSUME(gBattleMoves[MOVE_STUN_SPORE].flags & FLAG_POWDER); + ASSUME(gItems[ITEM_SAFETY_GOGGLES].holdEffect == HOLD_EFFECT_SAFETY_GOGGLES); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_ABRA) { Item(ITEM_SAFETY_GOGGLES);}; + } WHEN { + TURN { MOVE(player, MOVE_STUN_SPORE); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_STUN_SPORE, player); + MESSAGE("Foe Abra is not affected thanks to its SafetyGoggles!"); + } +}