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_SubstituteToMon @ B_ANIM_SUBSTITUTE_TO_MON
|
||||
.4byte Special_MonToSubstitute @ B_ANIM_MON_TO_SUBSTITUTE
|
||||
.4byte Special_CriticalCaptureBallThrow @ B_ANIM_CRITICAL_CAPTURE_THROW
|
||||
|
||||
Move_ROOST:
|
||||
loadspritegfx ANIM_TAG_WHITE_FEATHER
|
||||
|
@ -24449,3 +24450,13 @@ Special_SubstituteToMon:
|
|||
Special_MonToSubstitute:
|
||||
createvisualtask AnimTask_SwapMonSpriteToFromSubstitute, 2, FALSE
|
||||
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_6;
|
||||
u8 field_7;
|
||||
u8 ballThrowCaseId;
|
||||
u8 ballThrowCaseId:6;
|
||||
u8 isCriticalCapture:1;
|
||||
u8 criticalCaptureSuccess:1;
|
||||
u8 field_9_x1:1;
|
||||
u8 field_9_x2:1;
|
||||
u8 field_9_x1C:3;
|
||||
|
|
|
@ -219,6 +219,7 @@ void sub_8172EF0(u8 battler, struct Pokemon *mon);
|
|||
u8 ItemIdToBallId(u16 itemId);
|
||||
u8 AnimateBallOpenParticles(u8 x, u8 y, u8 priority, u8 subpriority, u8 ballId);
|
||||
u8 LaunchBallFadeMonTask(bool8 unFadeLater, u8 battlerId, u32 selectedPalettes, u8 ballId);
|
||||
bool32 IsCriticalCapture(void);
|
||||
|
||||
// battle_anim_utility_funcs.c
|
||||
void sub_8116EB4(u8);
|
||||
|
|
|
@ -533,6 +533,7 @@
|
|||
#define B_ANIM_SAFARI_BALL_THROW 0x4
|
||||
#define B_ANIM_SUBSTITUTE_TO_MON 0x5
|
||||
#define B_ANIM_MON_TO_SUBSTITUTE 0x6
|
||||
#define B_ANIM_CRITICAL_CAPTURE_THROW 0x7
|
||||
|
||||
// status animation table
|
||||
#define B_ANIM_STATUS_PSN 0x0
|
||||
|
|
|
@ -77,6 +77,7 @@ static void RepeatBallOpenParticleAnimation(u8);
|
|||
static void TimerBallOpenParticleAnimation(u8);
|
||||
static void PremierBallOpenParticleAnimation(u8);
|
||||
static void sub_817330C(struct Sprite *);
|
||||
static void CB_CriticalCaptureThrownBallMovement(struct Sprite *sprite);
|
||||
|
||||
struct BallCaptureSuccessStarData
|
||||
{
|
||||
|
@ -923,7 +924,10 @@ static void sub_817138C(struct Sprite *sprite)
|
|||
angle = 0;
|
||||
sprite->pos1.y += Cos(angle, 40);
|
||||
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:
|
||||
sprite->data[3] += 0x100;
|
||||
state = sprite->data[3] >> 8;
|
||||
if (state == gBattleSpritesDataPtr->animationData->ballThrowCaseId)
|
||||
if (IsCriticalCapture())
|
||||
{
|
||||
sprite->affineAnimPaused = 1;
|
||||
sprite->callback = sub_81717B4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gBattleSpritesDataPtr->animationData->ballThrowCaseId == BALL_3_SHAKES_SUCCESS && state == 3)
|
||||
if (gBattleSpritesDataPtr->animationData->criticalCaptureSuccess)
|
||||
{
|
||||
sprite->callback = sub_81717D8;
|
||||
sprite->affineAnimPaused = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite->data[3]++;
|
||||
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;
|
||||
|
@ -2271,3 +2291,53 @@ void AnimTask_GetBattlersFromArg(u8 taskId)
|
|||
gBattleAnimTarget = gBattleSpritesDataPtr->animationData->animArg >> 8;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2522,7 +2526,11 @@ static void PlayerHandleBallThrowAnim(void)
|
|||
|
||||
gBattleSpritesDataPtr->animationData->ballThrowCaseId = ballThrowCaseId;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ static void DrawLevelUpWindow2(void);
|
|||
static bool8 sub_804F344(void);
|
||||
static void PutMonIconOnLvlUpBox(void);
|
||||
static void PutLevelAndGenderOnLvlUpBox(void);
|
||||
static bool32 CriticalCapture(u32 odds);
|
||||
|
||||
static void SpriteCB_MonIconOnLvlUpBox(struct Sprite* sprite);
|
||||
|
||||
|
@ -11668,23 +11669,41 @@ static void Cmd_handleballthrow(void)
|
|||
else // mon may be caught, calculate shakes
|
||||
{
|
||||
u8 shakes;
|
||||
u8 maxShakes;
|
||||
|
||||
odds = Sqrt(Sqrt(16711680 / odds));
|
||||
odds = 1048560 / odds;
|
||||
|
||||
for (shakes = 0; shakes < BALL_3_SHAKES_SUCCESS && Random() < odds; shakes++);
|
||||
gBattleSpritesDataPtr->animationData->isCriticalCapture = 0; //initialize
|
||||
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = 0;
|
||||
if (CriticalCapture(odds))
|
||||
{
|
||||
maxShakes = 1; //critical capture doesn't gauarantee capture
|
||||
gBattleSpritesDataPtr->animationData->isCriticalCapture = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxShakes = 4;
|
||||
}
|
||||
|
||||
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);
|
||||
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;
|
||||
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_POKEBALL, &gLastUsedItem);
|
||||
|
||||
if (CalculatePlayerPartyCount() == PARTY_SIZE)
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
|
||||
else
|
||||
|
@ -11692,7 +11711,11 @@ static void Cmd_handleballthrow(void)
|
|||
}
|
||||
else // not caught
|
||||
{
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = shakes;
|
||||
if (IsCriticalCapture())
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = shakes + 3;
|
||||
else
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = shakes;
|
||||
|
||||
gBattlescriptCurrInstr = BattleScript_ShakeBallThrow;
|
||||
}
|
||||
}
|
||||
|
@ -12094,3 +12117,28 @@ static void Cmd_metalburstdamagecalculator(void)
|
|||
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