mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-25 19:24:16 +01:00
Tests for 6 more abilities (#3399)
* Tests for 6 more abilities * Fix most of Egg's comments * Update Purifying Salt and Leaf Guard * Parenthesis fixes
This commit is contained in:
parent
f5b149b971
commit
231ebea3f0
@ -3853,6 +3853,7 @@ BattleScript_EffectRest::
|
||||
jumpifuproarwakes BattleScript_RestCantSleep
|
||||
jumpifability BS_TARGET, ABILITY_INSOMNIA, BattleScript_InsomniaProtects
|
||||
jumpifability BS_TARGET, ABILITY_VITAL_SPIRIT, BattleScript_InsomniaProtects
|
||||
jumpifability BS_ATTACKER, ABILITY_PURIFYING_SALT, BattleScript_InsomniaProtects
|
||||
.if B_LEAF_GUARD_PREVENTS_REST >= GEN_5
|
||||
jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardPreventsRest
|
||||
.endif
|
||||
|
@ -92,6 +92,7 @@ enum RandomTag
|
||||
RNG_TRI_ATTACK,
|
||||
RNG_TRIPLE_ARROWS_DEFENSE_DOWN,
|
||||
RNG_TRIPLE_ARROWS_FLINCH,
|
||||
RNG_QUICK_DRAW,
|
||||
};
|
||||
|
||||
#define RandomWeighted(tag, ...) \
|
||||
|
@ -4745,7 +4745,7 @@ u32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMov
|
||||
|
||||
// Battler 1
|
||||
// Quick Draw
|
||||
if (!ignoreChosenMoves && ability1 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler1]) && Random() % 100 < 30)
|
||||
if (!ignoreChosenMoves && ability1 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler1]) && RandomPercentage(RNG_QUICK_DRAW, 30))
|
||||
gProtectStructs[battler1].quickDraw = TRUE;
|
||||
// Quick Claw and Custap Berry
|
||||
if (!gProtectStructs[battler1].quickDraw
|
||||
@ -4755,7 +4755,7 @@ u32 GetWhichBattlerFasterArgs(u32 battler1, u32 battler2, bool32 ignoreChosenMov
|
||||
|
||||
// Battler 2
|
||||
// Quick Draw
|
||||
if (!ignoreChosenMoves && ability2 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler2]) && Random() % 100 < 30)
|
||||
if (!ignoreChosenMoves && ability2 == ABILITY_QUICK_DRAW && !IS_MOVE_STATUS(gChosenMoveByBattler[battler2]) && RandomPercentage(RNG_QUICK_DRAW, 30))
|
||||
gProtectStructs[battler2].quickDraw = TRUE;
|
||||
// Quick Claw and Custap Berry
|
||||
if (!gProtectStructs[battler2].quickDraw
|
||||
|
43
test/battle/ability/beast_boost.c
Normal file
43
test/battle/ability/beast_boost.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(P_GEN_7_POKEMON == TRUE); // Because only Ultra Beasts have this ability
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Beast Boost boosts the most proficient stat when knocking out a target")
|
||||
{
|
||||
u8 stats[] = {1, 1, 1, 1, 1};
|
||||
PARAMETRIZE { stats[0] = 255; }
|
||||
PARAMETRIZE { stats[1] = 255; }
|
||||
PARAMETRIZE { stats[2] = 255; }
|
||||
PARAMETRIZE { stats[3] = 255; }
|
||||
PARAMETRIZE { stats[4] = 255; }
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_NIHILEGO) { Ability(ABILITY_BEAST_BOOST); Attack(stats[0]); Defense(stats[1]); SpAttack(stats[2]); SpDefense(stats[3]); Speed(stats[4]); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(1); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(1); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); SEND_OUT(opponent, 1); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(player, ABILITY_BEAST_BOOST);
|
||||
switch(i) {
|
||||
case 0:
|
||||
MESSAGE("Nihilego's Beast Boost raised its Attack!");
|
||||
break;
|
||||
case 1:
|
||||
MESSAGE("Nihilego's Beast Boost raised its Defense!");
|
||||
break;
|
||||
case 2:
|
||||
MESSAGE("Nihilego's Beast Boost raised its Sp. Atk!");
|
||||
break;
|
||||
case 3:
|
||||
MESSAGE("Nihilego's Beast Boost raised its Sp. Def!");
|
||||
break;
|
||||
case 4:
|
||||
MESSAGE("Nihilego's Beast Boost raised its Speed!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
35
test/battle/ability/ice_scales.c
Normal file
35
test/battle/ability/ice_scales.c
Normal file
@ -0,0 +1,35 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(P_GEN_8_POKEMON == TRUE); // Because only Frosmoth can have this ability.
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Ice Scales halves the damage from special moves", s16 damage)
|
||||
{
|
||||
u32 move;
|
||||
u16 ability;
|
||||
PARAMETRIZE { ability = ABILITY_SHIELD_DUST; move = MOVE_PSYCHIC; }
|
||||
PARAMETRIZE { ability = ABILITY_ICE_SCALES; move = MOVE_PSYCHIC; }
|
||||
PARAMETRIZE { ability = ABILITY_SHIELD_DUST; move = MOVE_PSYSHOCK; }
|
||||
PARAMETRIZE { ability = ABILITY_ICE_SCALES; move = MOVE_PSYSHOCK; }
|
||||
PARAMETRIZE { ability = ABILITY_SHIELD_DUST; move = MOVE_TACKLE; }
|
||||
PARAMETRIZE { ability = ABILITY_ICE_SCALES; move = MOVE_TACKLE; }
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_PSYCHIC].split == SPLIT_SPECIAL);
|
||||
ASSUME(gBattleMoves[MOVE_PSYSHOCK].split == SPLIT_SPECIAL);
|
||||
ASSUME(gBattleMoves[MOVE_PSYSHOCK].effect == EFFECT_PSYSHOCK);
|
||||
ASSUME(gBattleMoves[MOVE_TACKLE].split == SPLIT_PHYSICAL);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_FROSMOTH) { Ability(ability); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, move); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, UQ_4_12(0.5), results[1].damage); // Ice Scales halves the damage of Psychic
|
||||
EXPECT_MUL_EQ(results[2].damage, UQ_4_12(0.5), results[3].damage); // Ice Scales halves the damage of Psyshock, even if it targets Defense
|
||||
EXPECT_EQ(results[4].damage, results[5].damage); // Ice Scales doesn't affect the damage of physical moves
|
||||
}
|
||||
}
|
@ -4,11 +4,12 @@
|
||||
SINGLE_BATTLE_TEST("Leaf Guard prevents non-volatile status conditions in sun")
|
||||
{
|
||||
u32 move;
|
||||
PARAMETRIZE { move = MOVE_WILL_O_WISP; }
|
||||
PARAMETRIZE { move = MOVE_HYPNOSIS; }
|
||||
PARAMETRIZE { move = MOVE_THUNDER_WAVE; }
|
||||
PARAMETRIZE { move = MOVE_TOXIC; }
|
||||
PARAMETRIZE { move = MOVE_POWDER_SNOW; }
|
||||
u16 status;
|
||||
PARAMETRIZE { move = MOVE_WILL_O_WISP; status = STATUS1_BURN; }
|
||||
PARAMETRIZE { move = MOVE_HYPNOSIS; status = STATUS1_SLEEP; }
|
||||
PARAMETRIZE { move = MOVE_THUNDER_WAVE; status = STATUS1_PARALYSIS; }
|
||||
PARAMETRIZE { move = MOVE_TOXIC; status = STATUS1_TOXIC_POISON; }
|
||||
PARAMETRIZE { move = MOVE_POWDER_SNOW; status = STATUS1_FREEZE; }
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_WILL_O_WISP].effect == EFFECT_WILL_O_WISP);
|
||||
ASSUME(gBattleMoves[MOVE_HYPNOSIS].effect == EFFECT_SLEEP);
|
||||
@ -20,39 +21,14 @@ SINGLE_BATTLE_TEST("Leaf Guard prevents non-volatile status conditions in sun")
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SUNNY_DAY); MOVE(opponent, move); }
|
||||
} SCENE {
|
||||
switch (move)
|
||||
{
|
||||
case MOVE_WILL_O_WISP:
|
||||
MESSAGE("Foe Wobbuffet used Will-o-Wisp!");
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_WILL_O_WISP, opponent);
|
||||
if (move != MOVE_POWDER_SNOW) {
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, move, opponent);
|
||||
ABILITY_POPUP(player, ABILITY_LEAF_GUARD);
|
||||
MESSAGE("It doesn't affect Leafeon…");
|
||||
break;
|
||||
case MOVE_HYPNOSIS:
|
||||
MESSAGE("Foe Wobbuffet used Hypnosis!");
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_HYPNOSIS, opponent);
|
||||
ABILITY_POPUP(player, ABILITY_LEAF_GUARD);
|
||||
MESSAGE("It doesn't affect Leafeon…");
|
||||
break;
|
||||
case MOVE_THUNDER_WAVE:
|
||||
MESSAGE("Foe Wobbuffet used Thunder Wave!");
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDER_WAVE, opponent);
|
||||
ABILITY_POPUP(player, ABILITY_LEAF_GUARD);
|
||||
MESSAGE("It doesn't affect Leafeon…");
|
||||
break;
|
||||
case MOVE_TOXIC:
|
||||
MESSAGE("Foe Wobbuffet used Toxic!");
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TOXIC, opponent);
|
||||
ABILITY_POPUP(player, ABILITY_LEAF_GUARD);
|
||||
MESSAGE("It doesn't affect Leafeon…");
|
||||
break;
|
||||
case MOVE_POWDER_SNOW:
|
||||
MESSAGE("Foe Wobbuffet used Powder Snow!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_POWDER_SNOW, opponent);
|
||||
MESSAGE("It's super effective!");
|
||||
break;
|
||||
} else {
|
||||
NOT ABILITY_POPUP(player, ABILITY_LEAF_GUARD);
|
||||
}
|
||||
NONE_OF { STATUS_ICON(player, status1: TRUE); }
|
||||
NOT STATUS_ICON(player, status);
|
||||
}
|
||||
}
|
||||
|
||||
|
30
test/battle/ability/neuroforce.c
Normal file
30
test/battle/ability/neuroforce.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(P_GEN_7_POKEMON == TRUE); // Because only Necrozma can have this ability.
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Neuroforce increases the strength of super-effective moves by 25%", s16 damage)
|
||||
{
|
||||
u32 move;
|
||||
u16 ability;
|
||||
PARAMETRIZE { ability = ABILITY_NEUROFORCE; move = MOVE_SHADOW_BALL; }
|
||||
PARAMETRIZE { ability = ABILITY_KLUTZ; move = MOVE_SHADOW_BALL; }
|
||||
PARAMETRIZE { ability = ABILITY_NEUROFORCE; move = MOVE_TACKLE; }
|
||||
PARAMETRIZE { ability = ABILITY_KLUTZ; move = MOVE_TACKLE; }
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_SHADOW_BALL].type == TYPE_GHOST);
|
||||
ASSUME(gBattleMoves[MOVE_TACKLE].type == TYPE_NORMAL);
|
||||
PLAYER(SPECIES_NECROZMA_ULTRA) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, move); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[1].damage, UQ_4_12(1.25), results[0].damage); // Neuroforce boosts the power of super-effective moves
|
||||
EXPECT_EQ(results[2].damage, results[3].damage); // Neuroforce doesn't boost the power of other moves
|
||||
}
|
||||
}
|
65
test/battle/ability/purifying_salt.c
Normal file
65
test/battle/ability/purifying_salt.c
Normal file
@ -0,0 +1,65 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Purifying Salt halves damage from Ghost-type moves", s16 damage)
|
||||
{
|
||||
u16 ability;
|
||||
PARAMETRIZE { ability = ABILITY_STURDY; }
|
||||
PARAMETRIZE { ability = ABILITY_PURIFYING_SALT; }
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_SHADOW_BALL].type == TYPE_GHOST);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Ability(ability); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SHADOW_BALL); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[0].damage, UQ_4_12(0.5), results[1].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Purifying Salt makes Rest fail")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_PURIFYING_SALT); HP(1); MaxHP(100);}
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_REST); }
|
||||
} SCENE {
|
||||
NONE_OF {
|
||||
MESSAGE("Wobbuffet went to sleep!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Purifying Salt grants immunity to status effects")
|
||||
{
|
||||
u32 move;
|
||||
u16 status;
|
||||
PARAMETRIZE { move = MOVE_WILL_O_WISP; status = STATUS1_BURN; }
|
||||
PARAMETRIZE { move = MOVE_HYPNOSIS; status = STATUS1_SLEEP; }
|
||||
PARAMETRIZE { move = MOVE_THUNDER_WAVE; status = STATUS1_PARALYSIS; }
|
||||
PARAMETRIZE { move = MOVE_TOXIC; status = STATUS1_TOXIC_POISON; }
|
||||
PARAMETRIZE { move = MOVE_POWDER_SNOW; status = STATUS1_FREEZE; }
|
||||
GIVEN {
|
||||
ASSUME(gBattleMoves[MOVE_WILL_O_WISP].effect == EFFECT_WILL_O_WISP);
|
||||
ASSUME(gBattleMoves[MOVE_HYPNOSIS].effect == EFFECT_SLEEP);
|
||||
ASSUME(gBattleMoves[MOVE_THUNDER_WAVE].effect == EFFECT_PARALYZE);
|
||||
ASSUME(gBattleMoves[MOVE_TOXIC].effect == EFFECT_TOXIC);
|
||||
ASSUME(gBattleMoves[MOVE_POWDER_SNOW].effect == EFFECT_FREEZE_HIT);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_PURIFYING_SALT); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, move); }
|
||||
} SCENE {
|
||||
if (move != MOVE_POWDER_SNOW) {
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, move, opponent);
|
||||
ABILITY_POPUP(player, ABILITY_PURIFYING_SALT);
|
||||
MESSAGE("It doesn't affect Wobbuffet…");
|
||||
} else {
|
||||
NOT ABILITY_POPUP(player, ABILITY_PURIFYING_SALT);
|
||||
}
|
||||
NOT STATUS_ICON(player, status);
|
||||
}
|
||||
}
|
17
test/battle/ability/quick_draw.c
Normal file
17
test/battle/ability/quick_draw.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
SINGLE_BATTLE_TEST("Quick Draw has a 30% chance of going first")
|
||||
{
|
||||
PASSES_RANDOMLY(3, 10, RNG_QUICK_DRAW);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_SLOWBRO_GALARIAN) { Ability(ABILITY_QUICK_DRAW); Speed(1); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
} SCENE {
|
||||
ABILITY_POPUP(player, ABILITY_QUICK_DRAW);
|
||||
MESSAGE("Slowbro used Tackle!");
|
||||
MESSAGE("Foe Wobbuffet used Celebrate!");
|
||||
}
|
||||
}
|
29
test/battle/ability/sharpness.c
Normal file
29
test/battle/ability/sharpness.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(P_GEN_4_POKEMON == TRUE); // Because no <Gen4 mons have this ability
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sharpness increases the power of cutting moves", s16 damage)
|
||||
{
|
||||
u32 move;
|
||||
u16 ability;
|
||||
PARAMETRIZE { move = MOVE_AERIAL_ACE; ability = ABILITY_SHARPNESS; }
|
||||
PARAMETRIZE { move = MOVE_AERIAL_ACE; ability = ABILITY_STEADFAST; }
|
||||
PARAMETRIZE { move = MOVE_SCRATCH; ability = ABILITY_SHARPNESS; }
|
||||
PARAMETRIZE { move = MOVE_SCRATCH; ability = ABILITY_STEADFAST; }
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_GALLADE) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, move); }
|
||||
} SCENE {
|
||||
HP_BAR(opponent, captureDamage: &results[i].damage);
|
||||
} FINALLY {
|
||||
EXPECT_MUL_EQ(results[1].damage, Q_4_12(1.5), results[0].damage); // Sharpness affects slicing moves
|
||||
EXPECT_EQ(results[2].damage, results[3].damage); // Sharpness does not affect non-slicing moves
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user