Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 10 commits into from
May 2, 2023
9 changes: 9 additions & 0 deletions data/battle_scripts_1.s
Original file line number Diff line number Diff line change
Expand Up @@ -3969,6 +3969,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
Expand All @@ -3990,6 +3993,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
Expand Down
1 change: 1 addition & 0 deletions include/config/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,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.
Expand Down
114 changes: 114 additions & 0 deletions test/ability_dry_skin.c
Original file line number Diff line number Diff line change
@@ -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!");
}
ShaeTsuPog marked this conversation as resolved.
Show resolved Hide resolved
}

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 changes: 16 additions & 0 deletions test/ability_hydration.c
Original file line number Diff line number Diff line change
@@ -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 changes: 30 additions & 0 deletions test/ability_ice_body.c
Original file line number Diff line number Diff line change
@@ -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 changes: 95 additions & 0 deletions test/ability_leaf_guard.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include "global.h"
#include "test_battle.h"

SINGLE_BATTLE_TEST("Leaf Guard prevents non-volatile status conditions in sun")
ShaeTsuPog marked this conversation as resolved.
Show resolved Hide resolved
{
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);}
}
}
}
ShaeTsuPog marked this conversation as resolved.
Show resolved Hide resolved

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 changes: 18 additions & 0 deletions test/ability_rain_dish.c
Original file line number Diff line number Diff line change
@@ -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);
}
}
4 changes: 2 additions & 2 deletions test/ability_sand_veil.c
Original file line number Diff line number Diff line change
Expand Up @@ -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); }
Expand All @@ -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 {
Expand Down
29 changes: 29 additions & 0 deletions test/ability_snow_cloak.c
Original file line number Diff line number Diff line change
@@ -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);
}
}
2 changes: 1 addition & 1 deletion test/ability_water_absorb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down