From bca67ac6839654a46fa7cc2773de86f195140bdc Mon Sep 17 00:00:00 2001 From: ultima-soul Date: Fri, 11 Jun 2021 18:22:50 -0700 Subject: [PATCH] Refactor Poke Ball code to not rely on Master Ball being the first item internally. --- data/battle_scripts_2.s | 32 ------------ include/battle.h | 3 +- include/constants/items.h | 2 +- src/battle_script_commands.c | 97 ++++++++++++------------------------ src/battle_util.c | 5 +- src/tv.c | 50 ++++++------------- 6 files changed, 50 insertions(+), 139 deletions(-) diff --git a/data/battle_scripts_2.s b/data/battle_scripts_2.s index a5dcf864d..ffcf5baab 100644 --- a/data/battle_scripts_2.s +++ b/data/battle_scripts_2.s @@ -11,37 +11,6 @@ .section script_data, "aw", %progbits - .align 2 -gBattlescriptsForBallThrow:: @ 82DBD08 - .4byte BattleScript_BallThrow @ ITEM_NONE - .4byte BattleScript_BallThrow @ ITEM_MASTER_BALL - .4byte BattleScript_BallThrow @ ITEM_ULTRA_BALL - .4byte BattleScript_BallThrow @ ITEM_GREAT_BALL - .4byte BattleScript_BallThrow @ ITEM_POKE_BALL - .4byte BattleScript_SafariBallThrow @ ITEM_SAFARI_BALL - .4byte BattleScript_BallThrow @ ITEM_NET_BALL - .4byte BattleScript_BallThrow @ ITEM_DIVE_BALL - .4byte BattleScript_BallThrow @ ITEM_NEST_BALL - .4byte BattleScript_BallThrow @ ITEM_REPEAT_BALL - .4byte BattleScript_BallThrow @ ITEM_TIMER_BALL - .4byte BattleScript_BallThrow @ ITEM_LUXURY_BALL - .4byte BattleScript_BallThrow @ ITEM_DUSK_BALL - .4byte BattleScript_BallThrow @ ITEM_HEAL_BALL - .4byte BattleScript_BallThrow @ ITEM_QUICK_BALL - .4byte BattleScript_BallThrow @ ITEM_CHERISH_BALL - .4byte BattleScript_BallThrow @ ITEM_FAST_BALL - .4byte BattleScript_BallThrow @ ITEM_LEVEL_BALL - .4byte BattleScript_BallThrow @ ITEM_LURE_BALL - .4byte BattleScript_BallThrow @ ITEM_HEAVY_BALL - .4byte BattleScript_BallThrow @ ITEM_LOVE_BALL - .4byte BattleScript_BallThrow @ ITEM_FRIEND_BALL - .4byte BattleScript_BallThrow @ ITEM_MOON_BALL - .4byte BattleScript_BallThrow @ ITEM_SPORT_BALL - .4byte BattleScript_BallThrow @ ITEM_PARK_BALL - .4byte BattleScript_BallThrow @ ITEM_DREAM_BALL - .4byte BattleScript_BallThrow @ ITEM_BEAST_BALL - .4byte BattleScript_BallThrow @ ITEM_PREMIER_BALL - .align 2 gBattlescriptsForUsingItem:: @ 82DBD3C .4byte BattleScript_PlayerUsesItem @@ -77,7 +46,6 @@ BattleScript_SafariBallThrow:: handleballthrow BattleScript_SuccessBallThrow:: - jumpifhalfword CMP_EQUAL, gLastUsedItem, ITEM_SAFARI_BALL, BattleScript_PrintCaughtMonInfo incrementgamestat GAME_STAT_POKEMON_CAPTURES BattleScript_PrintCaughtMonInfo:: printstring STRINGID_GOTCHAPKMNCAUGHT diff --git a/include/battle.h b/include/battle.h index 14ecfbdd3..b1ca41ac1 100644 --- a/include/battle.h +++ b/include/battle.h @@ -242,7 +242,6 @@ struct BattleResults u8 numHealingItemsUsed; // 0x3 u8 numRevivesUsed; // 0x4 u8 playerMonWasDamaged:1; // 0x5 - u8 usedMasterBall:1; // 0x5 u8 caughtMonBall:4; // 0x5 u8 shinyWildMon:1; // 0x5 u16 playerMon1Species; // 0x6 @@ -257,7 +256,7 @@ struct BattleResults u16 caughtMonSpecies; // 0x28 u8 caughtMonNick[POKEMON_NAME_LENGTH + 1]; // 0x2A u8 filler35; // 0x35 - u8 catchAttempts[POKEBALL_COUNT - 1]; // 0x36 Doesn't include Master ball + u8 catchAttempts[POKEBALL_COUNT]; // 0x36 }; struct BattleTv_Side diff --git a/include/constants/items.h b/include/constants/items.h index 4b134bebf..630ab6414 100644 --- a/include/constants/items.h +++ b/include/constants/items.h @@ -32,7 +32,7 @@ #define ITEM_PREMIER_BALL 27 // Note: If moving ball IDs around, updating FIRST_BALL/LAST_BALL is not sufficient -// Several places expect the ball IDs to be first and contiguous (e.g. gBattlescriptsForBallThrow and MON_DATA_POKEBALL) +// Several places expect the ball IDs to be first and contiguous (e.g. MON_DATA_POKEBALL) // If adding new balls, it's easiest to insert them after the last ball and increment the below IDs (and removing ITEM_034 for example) #define FIRST_BALL ITEM_MASTER_BALL #define LAST_BALL ITEM_PREMIER_BALL diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 15e44dd75..c10e4762e 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -830,15 +830,6 @@ static const u8 sTerrainToType[] = [BATTLE_TERRAIN_PLAIN] = TYPE_NORMAL, }; -// - ITEM_ULTRA_BALL skips Master Ball and ITEM_NONE -static const u8 sBallCatchBonuses[] = -{ - [ITEM_ULTRA_BALL - ITEM_ULTRA_BALL] = 20, - [ITEM_GREAT_BALL - ITEM_ULTRA_BALL] = 15, - [ITEM_POKE_BALL - ITEM_ULTRA_BALL] = 10, - [ITEM_SAFARI_BALL - ITEM_ULTRA_BALL] = 15 -}; - // In Battle Palace, moves are chosen based on the pokemons nature rather than by the player // Moves are grouped into "Attack", "Defense", or "Support" (see PALACE_MOVE_GROUP_*) // Each nature has a certain percent chance of selecting a move from a particular group @@ -9754,7 +9745,7 @@ static void Cmd_removelightscreenreflect(void) // brick break static void Cmd_handleballthrow(void) { - u8 ballMultiplier = 0; + u8 ballMultiplier = 10; if (gBattleControllerExecFlags) return; @@ -9779,58 +9770,44 @@ static void Cmd_handleballthrow(void) u32 odds; u8 catchRate; - if (gLastUsedItem == ITEM_SAFARI_BALL) + if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) catchRate = gBattleStruct->safariCatchFactor * 1275 / 100; else catchRate = gBaseStats[gBattleMons[gBattlerTarget].species].catchRate; - if (gLastUsedItem > ITEM_SAFARI_BALL) + switch (gLastUsedItem) { - switch (gLastUsedItem) + case ITEM_ULTRA_BALL: + ballMultiplier = 20; + case ITEM_GREAT_BALL: + case ITEM_SAFARI_BALL: + ballMultiplier = 15; + case ITEM_NET_BALL: + if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_WATER) || IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_BUG)) + ballMultiplier = 30; + break; + case ITEM_DIVE_BALL: + if (GetCurrentMapType() == MAP_TYPE_UNDERWATER) + ballMultiplier = 35; + break; + case ITEM_NEST_BALL: + if (gBattleMons[gBattlerTarget].level < 40) { - case ITEM_NET_BALL: - if (IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_WATER) || IS_BATTLER_OF_TYPE(gBattlerTarget, TYPE_BUG)) - ballMultiplier = 30; - else + ballMultiplier = 40 - gBattleMons[gBattlerTarget].level; + if (ballMultiplier <= 9) ballMultiplier = 10; - break; - case ITEM_DIVE_BALL: - if (GetCurrentMapType() == MAP_TYPE_UNDERWATER) - ballMultiplier = 35; - else - ballMultiplier = 10; - break; - case ITEM_NEST_BALL: - if (gBattleMons[gBattlerTarget].level < 40) - { - ballMultiplier = 40 - gBattleMons[gBattlerTarget].level; - if (ballMultiplier <= 9) - ballMultiplier = 10; - } - else - { - ballMultiplier = 10; - } - break; - case ITEM_REPEAT_BALL: - if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gBattlerTarget].species), FLAG_GET_CAUGHT)) - ballMultiplier = 30; - else - ballMultiplier = 10; - break; - case ITEM_TIMER_BALL: - ballMultiplier = gBattleResults.battleTurnCounter + 10; - if (ballMultiplier > 40) - ballMultiplier = 40; - break; - case ITEM_LUXURY_BALL: - case ITEM_PREMIER_BALL: - ballMultiplier = 10; - break; } + break; + case ITEM_REPEAT_BALL: + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[gBattlerTarget].species), FLAG_GET_CAUGHT)) + ballMultiplier = 30; + break; + case ITEM_TIMER_BALL: + ballMultiplier = gBattleResults.battleTurnCounter + 10; + if (ballMultiplier > 40) + ballMultiplier = 40; + break; } - else - ballMultiplier = sBallCatchBonuses[gLastUsedItem - ITEM_ULTRA_BALL]; odds = (catchRate * ballMultiplier / 10) * (gBattleMons[gBattlerTarget].maxHP * 3 - gBattleMons[gBattlerTarget].hp * 2) @@ -9841,18 +9818,8 @@ static void Cmd_handleballthrow(void) if (gBattleMons[gBattlerTarget].status1 & (STATUS1_POISON | STATUS1_BURN | STATUS1_PARALYSIS | STATUS1_TOXIC_POISON)) odds = (odds * 15) / 10; - if (gLastUsedItem != ITEM_SAFARI_BALL) - { - if (gLastUsedItem == ITEM_MASTER_BALL) - { - gBattleResults.usedMasterBall = TRUE; - } - else - { - if (gBattleResults.catchAttempts[gLastUsedItem - ITEM_ULTRA_BALL] < 0xFF) - gBattleResults.catchAttempts[gLastUsedItem - ITEM_ULTRA_BALL]++; - } - } + if (gBattleResults.catchAttempts[gLastUsedItem - FIRST_BALL] < 0xFF) + gBattleResults.catchAttempts[gLastUsedItem - FIRST_BALL]++; if (odds > 254) // mon caught { diff --git a/src/battle_util.c b/src/battle_util.c index cbcd445b7..4554e0a51 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -44,7 +44,6 @@ functions instead of at the top of the file with the other declarations. */ extern const u8 *const gBattleScriptsForMoveEffects[]; -extern const u8 *const gBattlescriptsForBallThrow[]; extern const u8 *const gBattlescriptsForRunningByItem[]; extern const u8 *const gBattlescriptsForUsingItem[]; extern const u8 *const gBattlescriptsForSafariActions[]; @@ -319,7 +318,7 @@ void HandleAction_UseItem(void) if (gLastUsedItem <= LAST_BALL) // is ball { - gBattlescriptCurrInstr = gBattlescriptsForBallThrow[gLastUsedItem]; + gBattlescriptCurrInstr = BattleScript_BallThrow; } else if (gLastUsedItem == ITEM_POKE_DOLL || gLastUsedItem == ITEM_FLUFFY_TAIL) { @@ -550,7 +549,7 @@ void HandleAction_SafariZoneBallThrow(void) gBattle_BG0_Y = 0; gNumSafariBalls--; gLastUsedItem = ITEM_SAFARI_BALL; - gBattlescriptCurrInstr = gBattlescriptsForBallThrow[ITEM_SAFARI_BALL]; + gBattlescriptCurrInstr = BattleScript_SafariBallThrow; gCurrentActionFuncId = B_ACTION_EXEC_SCRIPT; } diff --git a/src/tv.c b/src/tv.c index 50adde3f4..f06bebd75 100644 --- a/src/tv.c +++ b/src/tv.c @@ -955,22 +955,14 @@ void GabbyAndTyBeforeInterview(void) else gSaveBlock1Ptr->gabbyAndTyData.playerUsedHealingItem = FALSE; - if (!gBattleResults.usedMasterBall) + for (i = 0; i < POKEBALL_COUNT; i++) { - for (i = 0; i < POKEBALL_COUNT - 1; i++) + if (gBattleResults.catchAttempts[i]) { - if (gBattleResults.catchAttempts[i]) - { - gSaveBlock1Ptr->gabbyAndTyData.playerThrewABall = TRUE; - break; - } + gSaveBlock1Ptr->gabbyAndTyData.playerThrewABall = TRUE; + break; } } - else - { - // Player threw a Master Ball at Gabby and Ty - gSaveBlock1Ptr->gabbyAndTyData.playerThrewABall = TRUE; - } TakeGabbyAndTyOffTheAir(); if (gSaveBlock1Ptr->gabbyAndTyData.lastMove == MOVE_NONE) @@ -1128,28 +1120,20 @@ void TryPutPokemonTodayOnAir(void) sCurTVShowSlot = FindFirstEmptyRecordMixTVShowSlot(gSaveBlock1Ptr->tvShows); if (sCurTVShowSlot != -1 && IsRecordMixShowAlreadySpawned(TVSHOW_POKEMON_TODAY_CAUGHT, FALSE) != TRUE) { - for (i = 0; i < POKEBALL_COUNT - 1; i++) + for (i = 0; i < POKEBALL_COUNT; i++) ballsUsed += gBattleResults.catchAttempts[i]; - if (ballsUsed != 0 || gBattleResults.usedMasterBall) + if (ballsUsed != 0) { ballsUsed = 0; show = &gSaveBlock1Ptr->tvShows[sCurTVShowSlot]; show->pokemonToday.kind = TVSHOW_POKEMON_TODAY_CAUGHT; show->pokemonToday.active = FALSE; // NOTE: Show is not active until passed via Record Mix. - if (gBattleResults.usedMasterBall) - { - ballsUsed = 1; - itemLastUsed = ITEM_MASTER_BALL; - } - else - { - for (i = 0; i < POKEBALL_COUNT - 1; i++) - ballsUsed += gBattleResults.catchAttempts[i]; - if (ballsUsed > 255) - ballsUsed = 255; - itemLastUsed = gLastUsedItem; - } + for (i = 0; i < POKEBALL_COUNT; i++) + ballsUsed += gBattleResults.catchAttempts[i]; + if (ballsUsed > 255) + ballsUsed = 255; + itemLastUsed = gLastUsedItem; show->pokemonToday.nBallsUsed = ballsUsed; show->pokemonToday.ball = itemLastUsed; StringCopy(show->pokemonToday.playerName, gSaveBlock2Ptr->playerName); @@ -1191,7 +1175,7 @@ static void TryPutPokemonTodayFailedOnTheAir(void) if (!rbernoulli(1, 1)) { - for (i = 0, ballsUsed = 0; i < POKEBALL_COUNT - 1; i++) + for (i = 0, ballsUsed = 0; i < POKEBALL_COUNT; i++) ballsUsed += gBattleResults.catchAttempts[i]; if (ballsUsed > 255) ballsUsed = 255; @@ -2123,11 +2107,8 @@ void TryPutBreakingNewsOnAir(void) show->breakingNews.kind = TVSHOW_BREAKING_NEWS; show->breakingNews.active = FALSE; // NOTE: Show is not active until passed via Record Mix. balls = 0; - for (i = 0; i < POKEBALL_COUNT - 1; i++) + for (i = 0; i < POKEBALL_COUNT; i++) balls += gBattleResults.catchAttempts[i]; - - if (gBattleResults.usedMasterBall) - balls++; show->breakingNews.location = gMapHeader.regionMapSectionId; StringCopy(show->breakingNews.playerName, gSaveBlock2Ptr->playerName); show->breakingNews.poke1Species = gBattleResults.playerMon1Species; @@ -2157,10 +2138,7 @@ void TryPutBreakingNewsOnAir(void) switch (show->breakingNews.outcome) { case 0: - if (gBattleResults.usedMasterBall) - show->breakingNews.caughtMonBall = ITEM_MASTER_BALL; - else - show->breakingNews.caughtMonBall = gBattleResults.caughtMonBall; + show->breakingNews.caughtMonBall = gBattleResults.caughtMonBall; show->breakingNews.balls = balls; break; case 1: