Refactor Poke Ball code to not rely on Master Ball being the first item internally.
This commit is contained in:
parent
b7706f1b99
commit
bca67ac683
6 changed files with 50 additions and 139 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
50
src/tv.c
50
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:
|
||||
|
|
Loading…
Reference in a new issue