Fixes crash damage move against absorbing abilities (#6361)
This commit is contained in:
parent
2a0661db19
commit
3def0e751b
@ -3429,51 +3429,15 @@ BattleScript_EffectSuperFang::
|
||||
damagetohalftargethp
|
||||
goto BattleScript_HitFromAtkAnimation
|
||||
|
||||
BattleScript_EffectRecoilIfMiss::
|
||||
attackcanceler
|
||||
accuracycheck BattleScript_MoveMissedDoDamage, ACC_CURR_MOVE
|
||||
.if B_CRASH_IF_TARGET_IMMUNE >= GEN_4
|
||||
typecalc
|
||||
jumpifmoveresultflags MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_MoveMissedDoDamage
|
||||
.endif
|
||||
goto BattleScript_HitFromAtkString
|
||||
BattleScript_MoveMissedDoDamage::
|
||||
jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_PrintMoveMissed
|
||||
attackstring
|
||||
ppreduce
|
||||
pause B_WAIT_TIME_LONG
|
||||
resultmessage
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
.if B_CRASH_IF_TARGET_IMMUNE < GEN_4
|
||||
jumpifmoveresultflags MOVE_RESULT_DOESNT_AFFECT_FOE, BattleScript_MoveEnd
|
||||
.endif
|
||||
moveendcase MOVEEND_PROTECT_LIKE_EFFECT @ Spiky Shield's damage happens before recoil.
|
||||
jumpifhasnohp BS_ATTACKER, BattleScript_MoveEnd
|
||||
BattleScript_RecoilIfMiss::
|
||||
printstring STRINGID_PKMNCRASHED
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
damagecalc
|
||||
typecalc
|
||||
adjustdamage
|
||||
.if B_CRASH_IF_TARGET_IMMUNE == GEN_4
|
||||
manipulatedamage DMG_RECOIL_FROM_IMMUNE
|
||||
.else
|
||||
manipulatedamage DMG_RECOIL_FROM_MISS
|
||||
.endif
|
||||
.if B_CRASH_IF_TARGET_IMMUNE >= GEN_4
|
||||
clearmoveresultflags MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE
|
||||
.else
|
||||
clearmoveresultflags MOVE_RESULT_MISSED
|
||||
.endif
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_IGNORE_DISGUISE
|
||||
jumpifability BS_ATTACKER, ABILITY_MAGIC_GUARD, BattleScript_RecoilEnd
|
||||
orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE | HITMARKER_PASSIVE_DAMAGE | HITMARKER_IGNORE_DISGUISE
|
||||
healthbarupdate BS_ATTACKER
|
||||
datahpupdate BS_ATTACKER
|
||||
tryfaintmon BS_ATTACKER
|
||||
.if B_CRASH_IF_TARGET_IMMUNE >= GEN_4
|
||||
setmoveresultflags MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE
|
||||
.else
|
||||
setmoveresultflags MOVE_RESULT_MISSED
|
||||
.endif
|
||||
goto BattleScript_MoveEnd
|
||||
return
|
||||
|
||||
BattleScript_EffectMist::
|
||||
attackcanceler
|
||||
|
||||
@ -830,7 +830,7 @@ struct BattleStruct
|
||||
u8 printedStrongWindsWeakenedAttack:1;
|
||||
u8 numSpreadTargets:2;
|
||||
u8 bypassMoldBreakerChecks:1; // for ABILITYEFFECT_IMMUNITY
|
||||
u8 padding3:1;
|
||||
u8 noTargetPresent:1;
|
||||
u8 usedEjectItem;
|
||||
u8 usedMicleBerry;
|
||||
struct MessageStatus slideMessageStatus;
|
||||
|
||||
@ -597,7 +597,7 @@ extern const u8 BattleScript_EffectOHKO[];
|
||||
extern const u8 BattleScript_EffectSuperFang[];
|
||||
extern const u8 BattleScript_EffectFixedDamageArg[];
|
||||
extern const u8 BattleScript_EffectHealBlock[];
|
||||
extern const u8 BattleScript_EffectRecoilIfMiss[];
|
||||
extern const u8 BattleScript_RecoilIfMiss[];
|
||||
extern const u8 BattleScript_EffectMist[];
|
||||
extern const u8 BattleScript_EffectFocusEnergy[];
|
||||
extern const u8 BattleScript_EffectConfuse[];
|
||||
|
||||
@ -219,13 +219,11 @@ enum CmdVarious
|
||||
|
||||
// Cmd_manipulatedamage
|
||||
#define DMG_CHANGE_SIGN 1
|
||||
#define DMG_RECOIL_FROM_MISS 2
|
||||
#define DMG_DOUBLED 3
|
||||
#define DMG_1_8_TARGET_HP 4
|
||||
#define DMG_FULL_ATTACKER_HP 5
|
||||
#define DMG_CURR_ATTACKER_HP 6
|
||||
#define DMG_BIG_ROOT 7
|
||||
#define DMG_RECOIL_FROM_IMMUNE 8 // Used to calculate recoil for the Gen 4 version of Jump Kick
|
||||
#define DMG_DOUBLED 2
|
||||
#define DMG_1_8_TARGET_HP 3
|
||||
#define DMG_FULL_ATTACKER_HP 4
|
||||
#define DMG_CURR_ATTACKER_HP 5
|
||||
#define DMG_BIG_ROOT 6
|
||||
|
||||
// Cmd_jumpifcantswitch
|
||||
#define SWITCH_IGNORE_ESCAPE_PREVENTION (1 << 7)
|
||||
|
||||
@ -1216,6 +1216,8 @@ static void Cmd_attackcanceler(void)
|
||||
&& (!gBattleMoveEffects[effect].twoTurnEffect || (gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)))
|
||||
|| (IsMoveNotAllowedInSkyBattles(gCurrentMove)))
|
||||
{
|
||||
gBattleStruct->noTargetPresent = TRUE;
|
||||
|
||||
if (effect == EFFECT_FLING) // Edge case for removing a mon's item when there is no target available after using Fling.
|
||||
gBattlescriptCurrInstr = BattleScript_FlingFailConsumeItem;
|
||||
else
|
||||
@ -6360,6 +6362,25 @@ static void Cmd_moveend(void)
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
}
|
||||
else if (gMovesInfo[gCurrentMove].effect == EFFECT_RECOIL_IF_MISS
|
||||
&& (!IsBattlerTurnDamaged(gBattlerTarget) || gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
|
||||
&& !gBattleStruct->noTargetPresent
|
||||
&& IsBattlerAlive(gBattlerAttacker))
|
||||
{
|
||||
if (B_RECOIL_IF_MISS_DMG >= GEN_5 || (B_CRASH_IF_TARGET_IMMUNE == GEN_4 && gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_DOESNT_AFFECT_FOE))
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
|
||||
else if (B_RECOIL_IF_MISS_DMG == GEN_4 && (GetNonDynamaxMaxHP(gBattlerTarget) / 2) < gBattleStruct->moveDamage[gBattlerTarget])
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerTarget) / 2;
|
||||
else // Fallback if B_RECOIL_IF_MISS_DMG is set to gen3 or lower.
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerTarget) / 2;
|
||||
|
||||
if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = 1;
|
||||
|
||||
BattleScriptPushCursor();
|
||||
gBattlescriptCurrInstr = BattleScript_RecoilIfMiss;
|
||||
effect = TRUE;
|
||||
}
|
||||
else if (moveRecoil > 0
|
||||
&& !(gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
|
||||
&& IsBattlerAlive(gBattlerAttacker)
|
||||
@ -7253,6 +7274,7 @@ static void Cmd_moveend(void)
|
||||
gBattleStruct->fickleBeamBoosted = FALSE;
|
||||
gBattleStruct->redCardActivates = FALSE;
|
||||
gBattleStruct->battlerState[gBattlerAttacker].usedMicleBerry = FALSE;
|
||||
gBattleStruct->noTargetPresent = FALSE;
|
||||
if (gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE)
|
||||
gBattleStruct->pledgeMove = FALSE;
|
||||
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE)
|
||||
@ -11925,23 +11947,6 @@ static void Cmd_manipulatedamage(void)
|
||||
case DMG_CHANGE_SIGN:
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] *= -1;
|
||||
break;
|
||||
case DMG_RECOIL_FROM_MISS:
|
||||
if (B_RECOIL_IF_MISS_DMG >= GEN_5)
|
||||
{
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 2;
|
||||
}
|
||||
else if (B_RECOIL_IF_MISS_DMG == GEN_4)
|
||||
{
|
||||
if ((gBattleMons[gBattlerTarget].maxHP / 2) < gBattleStruct->moveDamage[gBattlerTarget])
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerTarget) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = gBattleStruct->moveDamage[gBattlerTarget] /= 2;
|
||||
}
|
||||
if (gBattleStruct->moveDamage[gBattlerAttacker] == 0)
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = 1;
|
||||
break;
|
||||
case DMG_DOUBLED:
|
||||
gBattleStruct->moveDamage[gBattlerTarget] *= 2;
|
||||
break;
|
||||
@ -11959,9 +11964,6 @@ static void Cmd_manipulatedamage(void)
|
||||
case DMG_CURR_ATTACKER_HP:
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxHP(gBattlerAttacker);
|
||||
break;
|
||||
case DMG_RECOIL_FROM_IMMUNE:
|
||||
gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerTarget) / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
|
||||
@ -238,7 +238,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] =
|
||||
|
||||
[EFFECT_RECOIL_IF_MISS] =
|
||||
{
|
||||
.battleScript = BattleScript_EffectRecoilIfMiss,
|
||||
.battleScript = BattleScript_EffectHit,
|
||||
.battleTvScore = 1,
|
||||
},
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ ASSUMPTIONS
|
||||
ASSUME(GetMoveEffect(MOVE_JUMP_KICK) == EFFECT_RECOIL_IF_MISS);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on miss")
|
||||
SINGLE_BATTLE_TEST("Recoil if miss: Jump Kick has 50% recoil on miss")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
@ -22,7 +22,7 @@ SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on miss")
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on protect")
|
||||
SINGLE_BATTLE_TEST("Recoil if miss: Jump Kick has 50% recoil on protect")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(!MoveIgnoresProtect(MOVE_JUMP_KICK));
|
||||
@ -38,7 +38,7 @@ SINGLE_BATTLE_TEST("Jump Kick has 50% recoil on protect")
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Jump Kick has no recoil if no target")
|
||||
SINGLE_BATTLE_TEST("Recoil if miss: Jump Kick has no recoil if no target")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(B_HEALING_WISH_SWITCH >= GEN_5);
|
||||
@ -54,7 +54,7 @@ SINGLE_BATTLE_TEST("Jump Kick has no recoil if no target")
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Jump Kick's recoil happens after Spiky Shield damage and Pokemon can faint from either of these")
|
||||
SINGLE_BATTLE_TEST("Recoil if miss: Jump Kick's recoil happens after Spiky Shield damage and Pokemon can faint from either of these")
|
||||
{
|
||||
s16 hp, maxHp = 256;
|
||||
bool32 faintOnSpiky = FALSE, faintOnJumpKick = FALSE;
|
||||
@ -98,3 +98,60 @@ SINGLE_BATTLE_TEST("Jump Kick's recoil happens after Spiky Shield damage and Pok
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Recoil if miss: Jump Kick recoil happens after Spiky Shield damage")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(!gMovesInfo[MOVE_JUMP_KICK].ignoresProtect);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_SPIKY_SHIELD); MOVE(player, MOVE_JUMP_KICK); }
|
||||
} SCENE {
|
||||
s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPIKY_SHIELD, opponent);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_JUMP_KICK, player);
|
||||
MESSAGE("Wobbuffet was hurt by the opposing Wobbuffet's Spiky Shield!");
|
||||
MESSAGE("Wobbuffet kept going and crashed!");
|
||||
HP_BAR(player, damage: maxHP / 2);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Recoil if miss: Supercell Slam causes recoil if it is absorbed")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_PIKACHU) { Ability(ABILITY_LIGHTNING_ROD); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SUPERCELL_SLAM); }
|
||||
} SCENE {
|
||||
s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP);
|
||||
ABILITY_POPUP(opponent, ABILITY_LIGHTNING_ROD);
|
||||
MESSAGE("Wobbuffet kept going and crashed!");
|
||||
HP_BAR(player, damage: maxHP / 2);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Recoil if miss: Disguise doesn't prevent crash damage from Jump Kick into ghost types")
|
||||
{
|
||||
u32 ability;
|
||||
PARAMETRIZE { ability = ABILITY_EARLY_BIRD; }
|
||||
PARAMETRIZE { ability = ABILITY_SCRAPPY; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_KANGASKHAN) { Ability(ability); };
|
||||
OPPONENT(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_JUMP_KICK); }
|
||||
} SCENE {
|
||||
s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP);
|
||||
MESSAGE("Kangaskhan used Jump Kick!");
|
||||
if (ability == ABILITY_SCRAPPY) {
|
||||
NONE_OF {
|
||||
MESSAGE("Kangaskhan kept going and crashed!");
|
||||
HP_BAR(player, damage: maxHP / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user