Weather related Ability tests, fix for Leaf Guard not preventing Rest. (#2957)

This commit is contained in:
Shae 2023-05-02 11:08:05 -07:00 committed by GitHub
parent 8cce130643
commit ae2d5f7d1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 315 additions and 3 deletions

View File

@ -3984,6 +3984,9 @@ BattleScript_EffectRest::
jumpifuproarwakes BattleScript_RestCantSleep
jumpifability BS_TARGET, ABILITY_INSOMNIA, BattleScript_InsomniaProtects
jumpifability BS_TARGET, ABILITY_VITAL_SPIRIT, BattleScript_InsomniaProtects
.if B_LEAF_GUARD_PREVENTS_REST >= GEN_5
jumpifleafguardprotected BS_TARGET, BattleScript_LeafGuardPreventsRest
.endif
trysetrest BattleScript_AlreadyAtFullHp
pause B_WAIT_TIME_SHORT
printfromtable gRestUsedStringIds
@ -4005,6 +4008,12 @@ BattleScript_RestIsAlreadyAsleep::
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_LeafGuardPreventsRest::
pause B_WAIT_TIME_SHORT
printstring STRINGID_BUTITFAILED
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectOHKO::
attackcanceler
attackstring

View File

@ -120,6 +120,7 @@
#define B_SYMBIOSIS_GEMS GEN_LATEST // In Gen7+, Symbiosis passes an item after a gem-boosted attack. Previously, items are passed before the gem-boosted attack hits, making the item effect apply.
#define B_CHECK_IF_CHARGED_UP TRUE // If set to TRUE, certain abilities such as Electromorphosis WILL check if the STATUS3_CHARGED_UP status flag is applied.
#define B_ABSORBING_ABILITY_STRING GEN_LATEST // In Gen5+, the abilities that absorb moves of a certain type use a generic string for stat increases and decreases.
#define B_LEAF_GUARD_PREVENTS_REST GEN_LATEST // In Gen5+, Leaf Guard prevents the use of Rest in harsh sunlight.
// Item settings
#define B_HP_BERRIES GEN_LATEST // In Gen4+, berries which restore hp activate immediately after HP drops to half. In Gen3, the effect occurs at the end of the turn.

114
test/ability_dry_skin.c Normal file
View File

@ -0,0 +1,114 @@
#include "global.h"
#include "test_battle.h"
#define TEST_MAX_HP (200)
SINGLE_BATTLE_TEST("Dry Skin causes 1/8th Max HP damage in Sun")
{
GIVEN {
PLAYER(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); HP(100); MaxHP(TEST_MAX_HP); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_SUNNY_DAY); }
} SCENE {
ABILITY_POPUP(player, ABILITY_DRY_SKIN);
HP_BAR(player, damage: TEST_MAX_HP / 8);
MESSAGE("The Parasect's Dry Skin takes its toll!");
}
}
SINGLE_BATTLE_TEST("Dry Skin heals 1/8th Max HP in Rain")
{
GIVEN {
PLAYER(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); HP(100); MaxHP(TEST_MAX_HP); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_RAIN_DANCE); }
} SCENE {
ABILITY_POPUP(player, ABILITY_DRY_SKIN);
MESSAGE("Parasect's Dry Skin restored its HP a little!");
HP_BAR(player, hp: TEST_MAX_HP / 8 + 100);
}
}
SINGLE_BATTLE_TEST("Dry Skin increases damage taken from Fire-type moves by 25%", s16 damage)
{
GIVEN {
ASSUME(gBattleMoves[MOVE_EMBER].type == TYPE_FIRE);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); };
} WHEN {
TURN {MOVE(player, MOVE_EMBER); }
} SCENE {
MESSAGE("Wobbuffet used Ember!");
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.25), results[1].damage);
}
}
SINGLE_BATTLE_TEST("Dry Skin heals 25% when hit by water type moves")
{
GIVEN {
ASSUME(gBattleMoves[MOVE_BUBBLE].type == TYPE_WATER);
PLAYER(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); HP(100); MaxHP(TEST_MAX_HP); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_BUBBLE); }
} SCENE {
ABILITY_POPUP(player, ABILITY_DRY_SKIN);
HP_BAR(player, hp: TEST_MAX_HP / 4 + 100);
MESSAGE("Parasect restored HP using its Dry Skin!");
}
}
SINGLE_BATTLE_TEST("Dry Skin does not activate if protected")
{
GIVEN {
ASSUME(gBattleMoves[MOVE_BUBBLE].type == TYPE_WATER);
PLAYER(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); HP(100); MaxHP(TEST_MAX_HP); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_PROTECT); MOVE(opponent, MOVE_BUBBLE); }
} SCENE {
NONE_OF { ABILITY_POPUP(player, ABILITY_DRY_SKIN); HP_BAR(player); MESSAGE("Parasect restored HP using its Dry Skin!"); }
}
}
SINGLE_BATTLE_TEST("Dry Skin is only triggered once on multi strike moves")
{
GIVEN {
ASSUME(gBattleMoves[MOVE_WATER_SHURIKEN].type == TYPE_WATER);
ASSUME(gBattleMoves[MOVE_WATER_SHURIKEN].effect == EFFECT_MULTI_HIT);
PLAYER(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); HP(100); MaxHP(TEST_MAX_HP); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_WATER_SHURIKEN); }
} SCENE {
ABILITY_POPUP(player, ABILITY_DRY_SKIN);
HP_BAR(player, hp: TEST_MAX_HP / 4 + 100);
MESSAGE("Parasect restored HP using its Dry Skin!");
}
}
SINGLE_BATTLE_TEST("Dry Skin prevents Absorb Bulb and Luminous Moss from activating")
{
u32 item;
PARAMETRIZE { item = ITEM_ABSORB_BULB; }
PARAMETRIZE { item = ITEM_LUMINOUS_MOSS; }
GIVEN {
ASSUME(gBattleMoves[MOVE_BUBBLE].type == TYPE_WATER);
PLAYER(SPECIES_PARASECT) { Ability(ABILITY_DRY_SKIN); HP(100); MaxHP(TEST_MAX_HP); Item(item); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_BUBBLE); }
} SCENE {
ABILITY_POPUP(player, ABILITY_DRY_SKIN);
HP_BAR(player, hp: TEST_MAX_HP / 4 + 100);
MESSAGE("Parasect restored HP using its Dry Skin!");
NONE_OF {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
}
}
}

16
test/ability_hydration.c Normal file
View File

@ -0,0 +1,16 @@
#include "global.h"
#include "test_battle.h"
SINGLE_BATTLE_TEST("Hydration cures non-volatile Status conditions if it is raining")
{
GIVEN {
PLAYER(SPECIES_VAPOREON) { Ability(ABILITY_HYDRATION); Status1(STATUS1_BURN); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_RAIN_DANCE); }
} SCENE {
ABILITY_POPUP(player, ABILITY_HYDRATION);
MESSAGE("Vaporeon's Hydration cured its burn problem!");
STATUS_ICON(player, none: TRUE);
}
}

30
test/ability_ice_body.c Normal file
View File

@ -0,0 +1,30 @@
#include "global.h"
#include "test_battle.h"
#define TEST_MAX_HP (100)
SINGLE_BATTLE_TEST("Ice Body prevents damage from hail")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GLALIE) { Ability(ABILITY_ICE_BODY); };
} WHEN {
TURN { MOVE(player, MOVE_HAIL); MOVE(opponent, MOVE_SKILL_SWAP); }
} SCENE {
NONE_OF { HP_BAR(player); }
}
}
SINGLE_BATTLE_TEST("Ice Body recovers 1/16th of Max HP in hail.")
{
GIVEN {
PLAYER(SPECIES_GLALIE) { Ability(ABILITY_ICE_BODY); HP(1); MaxHP(TEST_MAX_HP); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_HAIL); }
} SCENE {
ABILITY_POPUP(player, ABILITY_ICE_BODY);
MESSAGE("Glalie's Ice Body healed it a little bit!");
HP_BAR(player, hp: TEST_MAX_HP / 16 + 1);
}
}

95
test/ability_leaf_guard.c Normal file
View File

@ -0,0 +1,95 @@
#include "global.h"
#include "test_battle.h"
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; }
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_LEAFEON) { Ability(ABILITY_LEAF_GUARD); }
OPPONENT(SPECIES_WOBBUFFET);
} 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);
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;
}
NONE_OF {STATUS_ICON(player, status1: TRUE);}
}
}
SINGLE_BATTLE_TEST("Leaf Guard prevents status conditions from Flame Orb and Toxic Orb")
{
u32 item;
PARAMETRIZE { item = ITEM_FLAME_ORB; }
PARAMETRIZE { item = ITEM_TOXIC_ORB; }
GIVEN {
ASSUME(gItems[ITEM_FLAME_ORB].holdEffect == HOLD_EFFECT_FLAME_ORB);
ASSUME(gItems[ITEM_TOXIC_ORB].holdEffect == HOLD_EFFECT_TOXIC_ORB);
PLAYER(SPECIES_LEAFEON) {Ability(ABILITY_LEAF_GUARD); Item(item); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_SUNNY_DAY); }
} SCENE {
if (item == ITEM_FLAME_ORB) {
NONE_OF { MESSAGE("Leafeon was burned!"); STATUS_ICON(player, burn: TRUE);}
}
else {
NONE_OF { MESSAGE("Leafeon is badly poisoned!"); STATUS_ICON(player, poison: TRUE);}
}
}
}
SINGLE_BATTLE_TEST("Leaf Guard prevents Rest during sun")
{
GIVEN {
ASSUME(B_LEAF_GUARD_PREVENTS_REST >= GEN_5);
ASSUME(gBattleMoves[MOVE_REST].effect == EFFECT_REST);
PLAYER(SPECIES_LEAFEON) { Ability(ABILITY_LEAF_GUARD); HP(100); MaxHP(200); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_SUNNY_DAY); MOVE(player, MOVE_REST); }
} SCENE {
MESSAGE("But it failed!");
NOT STATUS_ICON(player, sleep: TRUE);
NONE_OF {HP_BAR(player);}
}
}

18
test/ability_rain_dish.c Normal file
View File

@ -0,0 +1,18 @@
#include "global.h"
#include "test_battle.h"
#define TEST_MAX_HP (100)
SINGLE_BATTLE_TEST("Rain Dish recovers 1/16th of Max HP in Rain")
{
GIVEN {
PLAYER(SPECIES_LUDICOLO) { Ability(ABILITY_RAIN_DISH); HP(1); MaxHP(TEST_MAX_HP); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_RAIN_DANCE); }
} SCENE {
ABILITY_POPUP(player, ABILITY_RAIN_DISH);
MESSAGE("Ludicolo's Rain Dish restored its HP a little!");
HP_BAR(player, hp: TEST_MAX_HP / 16 + 1);
}
}

View File

@ -4,7 +4,7 @@
SINGLE_BATTLE_TEST("Sand Veil prevents damage from sandstorm")
{
GIVEN {
PLAYER(SPECIES_SANDSHREW) { Ability(ABILITY_SAND_VEIL); };
PLAYER(SPECIES_CACNEA) { Ability(ABILITY_SAND_VEIL); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_SANDSTORM); }
@ -14,7 +14,7 @@ SINGLE_BATTLE_TEST("Sand Veil prevents damage from sandstorm")
}
}
SINGLE_BATTLE_TEST("Sand Veil reduces accuracy during sandstorm")
SINGLE_BATTLE_TEST("Sand Veil increases evasion during sandstorm")
{
PASSES_RANDOMLY(4, 5, RNG_ACCURACY);
GIVEN {

29
test/ability_snow_cloak.c Normal file
View File

@ -0,0 +1,29 @@
#include "global.h"
#include "test_battle.h"
SINGLE_BATTLE_TEST("Snow Cloak prevents damage from hail")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_GLACEON) { Ability(ABILITY_SNOW_CLOAK); };
} WHEN {
TURN { MOVE(player, MOVE_HAIL); MOVE(opponent, MOVE_SKILL_SWAP); }
} SCENE {
NONE_OF { HP_BAR(player); }
}
}
SINGLE_BATTLE_TEST("Snow Cloak increases evasion during hail")
{
PASSES_RANDOMLY(4, 5, RNG_ACCURACY);
GIVEN {
ASSUME(gBattleMoves[MOVE_POUND].accuracy == 100);
PLAYER(SPECIES_GLACEON) { Ability(ABILITY_SNOW_CLOAK); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_HAIL); }
TURN { MOVE(opponent, MOVE_POUND); }
} SCENE {
HP_BAR(player);
}
}

View File

@ -63,7 +63,7 @@ SINGLE_BATTLE_TEST("Water Absorb is only triggered once on multi strike moves")
}
}
SINGLE_BATTLE_TEST("Water Absorb prevents Items from activating")
SINGLE_BATTLE_TEST("Water Absorb prevents Absorb Bulb and Luminous Moss from activating")
{
u32 item;
PARAMETRIZE { item = ITEM_ABSORB_BULB; }