Add critical capture (#402)
* add critical capture * synax and format fixes
This commit is contained in:
parent
b32f3433ae
commit
8f669bb57d
7 changed files with 161 additions and 20 deletions
|
@ -786,6 +786,7 @@ gBattleAnims_Special::
|
||||||
.4byte Special_SafariBallThrow @ B_ANIM_SAFARI_BALL_THROW
|
.4byte Special_SafariBallThrow @ B_ANIM_SAFARI_BALL_THROW
|
||||||
.4byte Special_SubstituteToMon @ B_ANIM_SUBSTITUTE_TO_MON
|
.4byte Special_SubstituteToMon @ B_ANIM_SUBSTITUTE_TO_MON
|
||||||
.4byte Special_MonToSubstitute @ B_ANIM_MON_TO_SUBSTITUTE
|
.4byte Special_MonToSubstitute @ B_ANIM_MON_TO_SUBSTITUTE
|
||||||
|
.4byte Special_CriticalCaptureBallThrow @ B_ANIM_CRITICAL_CAPTURE_THROW
|
||||||
|
|
||||||
Move_ROOST:
|
Move_ROOST:
|
||||||
loadspritegfx ANIM_TAG_WHITE_FEATHER
|
loadspritegfx ANIM_TAG_WHITE_FEATHER
|
||||||
|
@ -24449,3 +24450,13 @@ Special_SubstituteToMon:
|
||||||
Special_MonToSubstitute:
|
Special_MonToSubstitute:
|
||||||
createvisualtask AnimTask_SwapMonSpriteToFromSubstitute, 2, FALSE
|
createvisualtask AnimTask_SwapMonSpriteToFromSubstitute, 2, FALSE
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Special_CriticalCaptureBallThrow:
|
||||||
|
createvisualtask AnimTask_LoadBallGfx, 2
|
||||||
|
delay 0
|
||||||
|
playsewithpan SE_RU_HYUU, 0
|
||||||
|
createvisualtask AnimTask_ThrowBall, 2
|
||||||
|
createvisualtask AnimTask_IsBallBlockedByTrainer, 2
|
||||||
|
jumpreteq -1, BallThrowTrainerBlock
|
||||||
|
goto BallThrowEnd
|
||||||
|
|
||||||
|
|
|
@ -642,7 +642,9 @@ struct BattleAnimationInfo
|
||||||
u8 field_5;
|
u8 field_5;
|
||||||
u8 field_6;
|
u8 field_6;
|
||||||
u8 field_7;
|
u8 field_7;
|
||||||
u8 ballThrowCaseId;
|
u8 ballThrowCaseId:6;
|
||||||
|
u8 isCriticalCapture:1;
|
||||||
|
u8 criticalCaptureSuccess:1;
|
||||||
u8 field_9_x1:1;
|
u8 field_9_x1:1;
|
||||||
u8 field_9_x2:1;
|
u8 field_9_x2:1;
|
||||||
u8 field_9_x1C:3;
|
u8 field_9_x1C:3;
|
||||||
|
|
|
@ -219,6 +219,7 @@ void sub_8172EF0(u8 battler, struct Pokemon *mon);
|
||||||
u8 ItemIdToBallId(u16 itemId);
|
u8 ItemIdToBallId(u16 itemId);
|
||||||
u8 AnimateBallOpenParticles(u8 x, u8 y, u8 priority, u8 subpriority, u8 ballId);
|
u8 AnimateBallOpenParticles(u8 x, u8 y, u8 priority, u8 subpriority, u8 ballId);
|
||||||
u8 LaunchBallFadeMonTask(bool8 unFadeLater, u8 battlerId, u32 selectedPalettes, u8 ballId);
|
u8 LaunchBallFadeMonTask(bool8 unFadeLater, u8 battlerId, u32 selectedPalettes, u8 ballId);
|
||||||
|
bool32 IsCriticalCapture(void);
|
||||||
|
|
||||||
// battle_anim_utility_funcs.c
|
// battle_anim_utility_funcs.c
|
||||||
void sub_8116EB4(u8);
|
void sub_8116EB4(u8);
|
||||||
|
|
|
@ -533,6 +533,7 @@
|
||||||
#define B_ANIM_SAFARI_BALL_THROW 0x4
|
#define B_ANIM_SAFARI_BALL_THROW 0x4
|
||||||
#define B_ANIM_SUBSTITUTE_TO_MON 0x5
|
#define B_ANIM_SUBSTITUTE_TO_MON 0x5
|
||||||
#define B_ANIM_MON_TO_SUBSTITUTE 0x6
|
#define B_ANIM_MON_TO_SUBSTITUTE 0x6
|
||||||
|
#define B_ANIM_CRITICAL_CAPTURE_THROW 0x7
|
||||||
|
|
||||||
// status animation table
|
// status animation table
|
||||||
#define B_ANIM_STATUS_PSN 0x0
|
#define B_ANIM_STATUS_PSN 0x0
|
||||||
|
|
|
@ -77,6 +77,7 @@ static void RepeatBallOpenParticleAnimation(u8);
|
||||||
static void TimerBallOpenParticleAnimation(u8);
|
static void TimerBallOpenParticleAnimation(u8);
|
||||||
static void PremierBallOpenParticleAnimation(u8);
|
static void PremierBallOpenParticleAnimation(u8);
|
||||||
static void sub_817330C(struct Sprite *);
|
static void sub_817330C(struct Sprite *);
|
||||||
|
static void CB_CriticalCaptureThrownBallMovement(struct Sprite *sprite);
|
||||||
|
|
||||||
struct BallCaptureSuccessStarData
|
struct BallCaptureSuccessStarData
|
||||||
{
|
{
|
||||||
|
@ -923,7 +924,10 @@ static void sub_817138C(struct Sprite *sprite)
|
||||||
angle = 0;
|
angle = 0;
|
||||||
sprite->pos1.y += Cos(angle, 40);
|
sprite->pos1.y += Cos(angle, 40);
|
||||||
sprite->pos2.y = -Cos(angle, sprite->data[4]);
|
sprite->pos2.y = -Cos(angle, sprite->data[4]);
|
||||||
sprite->callback = sub_81713D0;
|
if (IsCriticalCapture())
|
||||||
|
sprite->callback = CB_CriticalCaptureThrownBallMovement;
|
||||||
|
else
|
||||||
|
sprite->callback = sub_81713D0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1116,22 +1120,38 @@ static void sub_8171520(struct Sprite *sprite)
|
||||||
case 5:
|
case 5:
|
||||||
sprite->data[3] += 0x100;
|
sprite->data[3] += 0x100;
|
||||||
state = sprite->data[3] >> 8;
|
state = sprite->data[3] >> 8;
|
||||||
if (state == gBattleSpritesDataPtr->animationData->ballThrowCaseId)
|
if (IsCriticalCapture())
|
||||||
{
|
{
|
||||||
sprite->affineAnimPaused = 1;
|
if (gBattleSpritesDataPtr->animationData->criticalCaptureSuccess)
|
||||||
sprite->callback = sub_81717B4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (gBattleSpritesDataPtr->animationData->ballThrowCaseId == BALL_3_SHAKES_SUCCESS && state == 3)
|
|
||||||
{
|
{
|
||||||
sprite->callback = sub_81717D8;
|
sprite->callback = sub_81717D8;
|
||||||
sprite->affineAnimPaused = 1;
|
sprite->affineAnimPaused = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprite->data[3]++;
|
|
||||||
sprite->affineAnimPaused = 1;
|
sprite->affineAnimPaused = 1;
|
||||||
|
sprite->callback = sub_81717B4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (state == gBattleSpritesDataPtr->animationData->ballThrowCaseId)
|
||||||
|
{
|
||||||
|
sprite->affineAnimPaused = 1;
|
||||||
|
sprite->callback = sub_81717B4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (gBattleSpritesDataPtr->animationData->ballThrowCaseId == BALL_3_SHAKES_SUCCESS && state == 3)
|
||||||
|
{
|
||||||
|
sprite->callback = sub_81717D8;
|
||||||
|
sprite->affineAnimPaused = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprite->data[3]++;
|
||||||
|
sprite->affineAnimPaused = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2271,3 +2291,53 @@ void AnimTask_GetBattlersFromArg(u8 taskId)
|
||||||
gBattleAnimTarget = gBattleSpritesDataPtr->animationData->animArg >> 8;
|
gBattleAnimTarget = gBattleSpritesDataPtr->animationData->animArg >> 8;
|
||||||
DestroyAnimVisualTask(taskId);
|
DestroyAnimVisualTask(taskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool8 IsCriticalCapture(void)
|
||||||
|
{
|
||||||
|
return gBattleSpritesDataPtr->animationData->isCriticalCapture;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CB_CriticalCaptureThrownBallMovement(struct Sprite *sprite)
|
||||||
|
{
|
||||||
|
bool8 lastBounce = FALSE;
|
||||||
|
u8 maxBounces = 6;
|
||||||
|
int bounceCount = sprite->data[3] >> 8;
|
||||||
|
|
||||||
|
if (bounceCount == 0)
|
||||||
|
PlaySE(SE_BOWA);
|
||||||
|
|
||||||
|
switch (sprite->data[3] & 0xFF)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (bounceCount < 3)
|
||||||
|
sprite->pos2.x++;
|
||||||
|
|
||||||
|
if (++sprite->data[5] >= 3)
|
||||||
|
sprite->data[3] += 257;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (bounceCount < 3 || sprite->pos2.x != 0)
|
||||||
|
sprite->pos2.x--;
|
||||||
|
|
||||||
|
if (--sprite->data[5] <= 0)
|
||||||
|
{
|
||||||
|
sprite->data[5] = 0;
|
||||||
|
sprite->data[3] &= -0x100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bounceCount >= maxBounces)
|
||||||
|
lastBounce = TRUE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastBounce)
|
||||||
|
{
|
||||||
|
sprite->data[3] = 0;
|
||||||
|
sprite->data[4] = 40; //starting max height
|
||||||
|
sprite->data[5] = 0;
|
||||||
|
sprite->callback = sub_81713D0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -2512,7 +2512,11 @@ static void PlayerHandleSuccessBallThrowAnim(void)
|
||||||
{
|
{
|
||||||
gBattleSpritesDataPtr->animationData->ballThrowCaseId = BALL_3_SHAKES_SUCCESS;
|
gBattleSpritesDataPtr->animationData->ballThrowCaseId = BALL_3_SHAKES_SUCCESS;
|
||||||
gDoingBattleAnim = TRUE;
|
gDoingBattleAnim = TRUE;
|
||||||
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gBattlerTarget, B_ANIM_BALL_THROW);
|
if (IsCriticalCapture())
|
||||||
|
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gBattlerTarget, B_ANIM_CRITICAL_CAPTURE_THROW);
|
||||||
|
else
|
||||||
|
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gBattlerTarget, B_ANIM_BALL_THROW);
|
||||||
|
|
||||||
gBattlerControllerFuncs[gActiveBattler] = CompleteOnSpecialAnimDone;
|
gBattlerControllerFuncs[gActiveBattler] = CompleteOnSpecialAnimDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2522,7 +2526,11 @@ static void PlayerHandleBallThrowAnim(void)
|
||||||
|
|
||||||
gBattleSpritesDataPtr->animationData->ballThrowCaseId = ballThrowCaseId;
|
gBattleSpritesDataPtr->animationData->ballThrowCaseId = ballThrowCaseId;
|
||||||
gDoingBattleAnim = TRUE;
|
gDoingBattleAnim = TRUE;
|
||||||
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gBattlerTarget, B_ANIM_BALL_THROW);
|
if (IsCriticalCapture())
|
||||||
|
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gBattlerTarget, B_ANIM_CRITICAL_CAPTURE_THROW);
|
||||||
|
else
|
||||||
|
InitAndLaunchSpecialAnimation(gActiveBattler, gActiveBattler, gBattlerTarget, B_ANIM_BALL_THROW);
|
||||||
|
|
||||||
gBattlerControllerFuncs[gActiveBattler] = CompleteOnSpecialAnimDone;
|
gBattlerControllerFuncs[gActiveBattler] = CompleteOnSpecialAnimDone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ static void DrawLevelUpWindow2(void);
|
||||||
static bool8 sub_804F344(void);
|
static bool8 sub_804F344(void);
|
||||||
static void PutMonIconOnLvlUpBox(void);
|
static void PutMonIconOnLvlUpBox(void);
|
||||||
static void PutLevelAndGenderOnLvlUpBox(void);
|
static void PutLevelAndGenderOnLvlUpBox(void);
|
||||||
|
static bool32 CriticalCapture(u32 odds);
|
||||||
|
|
||||||
static void SpriteCB_MonIconOnLvlUpBox(struct Sprite* sprite);
|
static void SpriteCB_MonIconOnLvlUpBox(struct Sprite* sprite);
|
||||||
|
|
||||||
|
@ -11668,23 +11669,41 @@ static void Cmd_handleballthrow(void)
|
||||||
else // mon may be caught, calculate shakes
|
else // mon may be caught, calculate shakes
|
||||||
{
|
{
|
||||||
u8 shakes;
|
u8 shakes;
|
||||||
|
u8 maxShakes;
|
||||||
|
|
||||||
odds = Sqrt(Sqrt(16711680 / odds));
|
gBattleSpritesDataPtr->animationData->isCriticalCapture = 0; //initialize
|
||||||
odds = 1048560 / odds;
|
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = 0;
|
||||||
|
if (CriticalCapture(odds))
|
||||||
for (shakes = 0; shakes < BALL_3_SHAKES_SUCCESS && Random() < odds; shakes++);
|
{
|
||||||
|
maxShakes = 1; //critical capture doesn't gauarantee capture
|
||||||
|
gBattleSpritesDataPtr->animationData->isCriticalCapture = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxShakes = 4;
|
||||||
|
}
|
||||||
|
|
||||||
if (gLastUsedItem == ITEM_MASTER_BALL)
|
if (gLastUsedItem == ITEM_MASTER_BALL)
|
||||||
shakes = BALL_3_SHAKES_SUCCESS; // why calculate the shakes before that check?
|
{
|
||||||
|
shakes = maxShakes;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
odds = Sqrt(Sqrt(16711680 / odds));
|
||||||
|
odds = 1048560 / odds;
|
||||||
|
for (shakes = 0; shakes < maxShakes && Random() < odds; shakes++);
|
||||||
|
}
|
||||||
|
|
||||||
BtlController_EmitBallThrowAnim(0, shakes);
|
BtlController_EmitBallThrowAnim(0, shakes);
|
||||||
MarkBattlerForControllerExec(gActiveBattler);
|
MarkBattlerForControllerExec(gActiveBattler);
|
||||||
|
|
||||||
if (shakes == BALL_3_SHAKES_SUCCESS) // mon caught, copy of the code above
|
if (shakes == maxShakes) // mon caught, copy of the code above
|
||||||
{
|
{
|
||||||
|
if (IsCriticalCapture())
|
||||||
|
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = 1;
|
||||||
|
|
||||||
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow;
|
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow;
|
||||||
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_POKEBALL, &gLastUsedItem);
|
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_POKEBALL, &gLastUsedItem);
|
||||||
|
|
||||||
if (CalculatePlayerPartyCount() == PARTY_SIZE)
|
if (CalculatePlayerPartyCount() == PARTY_SIZE)
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||||
else
|
else
|
||||||
|
@ -11692,7 +11711,11 @@ static void Cmd_handleballthrow(void)
|
||||||
}
|
}
|
||||||
else // not caught
|
else // not caught
|
||||||
{
|
{
|
||||||
gBattleCommunication[MULTISTRING_CHOOSER] = shakes;
|
if (IsCriticalCapture())
|
||||||
|
gBattleCommunication[MULTISTRING_CHOOSER] = shakes + 3;
|
||||||
|
else
|
||||||
|
gBattleCommunication[MULTISTRING_CHOOSER] = shakes;
|
||||||
|
|
||||||
gBattlescriptCurrInstr = BattleScript_ShakeBallThrow;
|
gBattlescriptCurrInstr = BattleScript_ShakeBallThrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12094,3 +12117,28 @@ static void Cmd_metalburstdamagecalculator(void)
|
||||||
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
gBattlescriptCurrInstr = T1_READ_PTR(gBattlescriptCurrInstr + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool32 CriticalCapture(u32 odds)
|
||||||
|
{
|
||||||
|
u16 numCaught = GetNationalPokedexCount(FLAG_GET_CAUGHT);
|
||||||
|
|
||||||
|
if (numCaught <= 30)
|
||||||
|
odds = 0;
|
||||||
|
else if (numCaught <= 150)
|
||||||
|
odds /= 2;
|
||||||
|
else if (numCaught <= 300)
|
||||||
|
;
|
||||||
|
else if (numCaught <= 450)
|
||||||
|
odds = (odds * 150) / 100;
|
||||||
|
else if (numCaught <= 600)
|
||||||
|
odds *= 2;
|
||||||
|
else
|
||||||
|
odds = (odds * 250) / 100;
|
||||||
|
|
||||||
|
odds /= 6;
|
||||||
|
if ((Random() % 255) < odds)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue