Merge branch 'rh-hideout:master' into master

This commit is contained in:
RoamerX 2025-04-26 21:52:42 +08:00 committed by GitHub
commit df515d0057
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 600 additions and 30 deletions

View File

@ -4750,6 +4750,8 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect)
speed = (GetHighestStatId(battler) == STAT_SPEED) ? (speed * 150) / 100 : speed;
else if (ability == ABILITY_QUARK_DRIVE && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED) && (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gDisableStructs[battler].boosterEnergyActivates))
speed = (GetHighestStatId(battler) == STAT_SPEED) ? (speed * 150) / 100 : speed;
else if (ability == ABILITY_UNBURDEN && gDisableStructs[battler].unburdenActive)
speed *= 2;
// stat stages
speed *= gStatStageRatios[gBattleMons[battler].statStages[STAT_SPEED]][0];
@ -4776,8 +4778,6 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect)
// various effects
if (gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_TAILWIND)
speed *= 2;
if (gDisableStructs[battler].unburdenActive)
speed *= 2;
// paralysis drop
if (gBattleMons[battler].status1 & STATUS1_PARALYSIS && ability != ABILITY_QUICK_FEET)

View File

@ -8240,13 +8240,7 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler)
else if (IsBattlerAffectedByHazards(battler, TRUE))
{
i = GetBattlerAbility(battler);
if (!(gBattleMons[battler].status1 & STATUS1_ANY)
&& !IS_BATTLER_OF_TYPE(battler, TYPE_STEEL)
&& i != ABILITY_IMMUNITY
&& i != ABILITY_PURIFYING_SALT
&& !IsAbilityOnSide(battler, ABILITY_PASTEL_VEIL)
&& !(gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD)
&& !(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN))
if (CanBePoisoned(gBattlerAttacker, battler, i))
{
if (gSideTimers[GetBattlerSide(battler)].toxicSpikesAmount >= 2)
gBattleMons[battler].status1 |= STATUS1_TOXIC_POISON;

View File

@ -1,7 +1,25 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Analytic increases the power of moves by 30% if it's the last one that uses its move");
SINGLE_BATTLE_TEST("Analytic increases the power of moves by 30% if it's the last one that uses its move", s16 damage)
{
u32 speed;
PARAMETRIZE { speed = 3; }
PARAMETRIZE { speed = 1; }
GIVEN {
PLAYER(SPECIES_MAGNEMITE) { Ability(ABILITY_ANALYTIC); Speed(speed); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(2); }
} WHEN {
TURN { MOVE(player, MOVE_TACKLE); }
} SCENE {
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.3), results[1].damage);
}
}
TO_DO_BATTLE_TEST("Analytic takes into account modifications to speeed an priority (Gen 5-8)"); //Eg. Paralysis, Power Weight, Stall
TO_DO_BATTLE_TEST("Analytic does not take into account modifications to speeed an priority (Gen 8)"); //Eg. Paralysis, Power Weight, Stall
TO_DO_BATTLE_TEST("Analytic takes into account the turn order of what fainted Pokémon would've moved");

View File

@ -55,3 +55,35 @@ SINGLE_BATTLE_TEST("Comatose may be suppressed if pokemon transformed into a pok
else if (move == MOVE_SLEEP_POWDER) { STATUS_ICON(opponent, sleep: TRUE); }
}
}
SINGLE_BATTLE_TEST("Comatose pokemon doesn't get poisoned by Toxic Spikes on switch-in")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_KOMALA) { Ability(ABILITY_COMATOSE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_TOXIC_SPIKES); }
TURN { SWITCH(player, 1); }
} SCENE {
NOT STATUS_ICON(player, STATUS1_POISON);
ABILITY_POPUP(player, ABILITY_COMATOSE);
NOT HP_BAR(player);
}
}
SINGLE_BATTLE_TEST("Comatose pokemon don't get poisoned by Toxic Spikes on switch-in if forced in by phazing with Mold Breaker")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_KOMALA) { Ability(ABILITY_COMATOSE); }
OPPONENT(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); }
} WHEN {
TURN { MOVE(opponent, MOVE_TOXIC_SPIKES); }
TURN { MOVE(opponent, MOVE_DRAGON_TAIL); }
} SCENE {
NOT STATUS_ICON(player, STATUS1_POISON);
ABILITY_POPUP(player, ABILITY_COMATOSE);
NOT HP_BAR(player);
}
}

View File

@ -45,3 +45,20 @@ SINGLE_BATTLE_TEST("Immunity prevents Toxic Spikes poison")
NOT STATUS_ICON(opponent, poison: TRUE);
}
}
SINGLE_BATTLE_TEST("Immunity doesn't prevent pokemon from being poisoned by Toxic Spikes on switch-in if forced in by phazing with Mold Breaker, but it cures it immediately")
{
GIVEN {
ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET);
ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_SNORLAX) { Ability(ABILITY_IMMUNITY); }
OPPONENT(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); }
} WHEN {
TURN { MOVE(opponent, MOVE_TOXIC_SPIKES); }
TURN { MOVE(opponent, MOVE_DRAGON_TAIL); }
} SCENE {
STATUS_ICON(player, STATUS1_POISON);
NOT HP_BAR(player);
}
}

View File

@ -100,3 +100,20 @@ SINGLE_BATTLE_TEST("Purifying Salt user can't be poisoned by Toxic Spikes")
EXPECT_EQ(player->status1, STATUS1_NONE);
}
}
SINGLE_BATTLE_TEST("Purifying Salt doesn't prevent pokemon from being poisoned by Toxic Spikes on switch-in if forced in by phazing with Mold Breaker")
{
GIVEN {
ASSUME(GetMoveEffect(MOVE_DRAGON_TAIL) == EFFECT_HIT_SWITCH_TARGET);
ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_GARGANACL) { Ability(ABILITY_PURIFYING_SALT); }
OPPONENT(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); }
} WHEN {
TURN { MOVE(opponent, MOVE_TOXIC_SPIKES); }
TURN { MOVE(opponent, MOVE_DRAGON_TAIL); }
} SCENE {
STATUS_ICON(player, STATUS1_POISON);
HP_BAR(player);
}
}

View File

@ -0,0 +1,101 @@
#include "global.h"
#include "test/battle.h"
SINGLE_BATTLE_TEST("Unburden doubles speed once user uses item")
{
GIVEN {
ASSUME(ItemId_GetHoldEffect(ITEM_GRASSY_SEED) == HOLD_EFFECT_SEEDS);
ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE);
PLAYER(SPECIES_DRIFBLIM) { Ability(ABILITY_UNBURDEN); Item(ITEM_GRASSY_SEED); Speed(5); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(7); }
OPPONENT(SPECIES_RILLABOOM) { Speed(7); Ability(ABILITY_GRASSY_SURGE); }
} WHEN {
TURN { MOVE(opponent, MOVE_U_TURN); SEND_OUT(opponent, 1); }
TURN { }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_U_TURN, opponent);
ABILITY_POPUP(opponent, ABILITY_GRASSY_SURGE);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
// Turn 2, doubled speed
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
}
}
SINGLE_BATTLE_TEST("Unburden doubles speed once user gets their item knocked off")
{
GIVEN {
ASSUME(MoveHasAdditionalEffect(MOVE_KNOCK_OFF, MOVE_EFFECT_KNOCK_OFF));
PLAYER(SPECIES_DRIFBLIM) { Ability(ABILITY_UNBURDEN); Item(ITEM_POTION); Speed(5); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(7); }
} WHEN {
TURN { MOVE(opponent, MOVE_KNOCK_OFF); }
TURN { }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_KNOCK_OFF, opponent);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ITEM_KNOCKOFF, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
// Turn 2, doubled speed
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
}
}
SINGLE_BATTLE_TEST("Unburden doesn't activate when item is consumed in Neutralizing Gas")
{
GIVEN {
ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE);
ASSUME(MoveHasAdditionalEffect(MOVE_KNOCK_OFF, MOVE_EFFECT_KNOCK_OFF));
PLAYER(SPECIES_DRIFBLIM) { Ability(ABILITY_UNBURDEN); Item(ITEM_POTION); Speed(5); }
OPPONENT(SPECIES_WEEZING) { Speed(7); Ability(ABILITY_NEUTRALIZING_GAS); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(7); }
} WHEN {
TURN { MOVE(opponent, MOVE_KNOCK_OFF); }
TURN { MOVE(opponent, MOVE_U_TURN); SEND_OUT(opponent, 1); }
TURN { }
} SCENE {
ABILITY_POPUP(opponent, ABILITY_NEUTRALIZING_GAS);
ANIMATION(ANIM_TYPE_MOVE, MOVE_KNOCK_OFF, opponent);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ITEM_KNOCKOFF, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
// Turn 2, no speed increase
ANIMATION(ANIM_TYPE_MOVE, MOVE_U_TURN, opponent);
MESSAGE("The effects of the neutralizing gas wore off!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
// Turn 3, no speed increase
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
}
}
SINGLE_BATTLE_TEST("Unburden doubling speed effect is ignored by Neutralizing Gas")
{
GIVEN {
ASSUME(GetMoveEffect(MOVE_U_TURN) == EFFECT_HIT_ESCAPE);
ASSUME(MoveHasAdditionalEffect(MOVE_KNOCK_OFF, MOVE_EFFECT_KNOCK_OFF));
PLAYER(SPECIES_DRIFBLIM) { Ability(ABILITY_UNBURDEN); Item(ITEM_POTION); Speed(5); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(7); }
OPPONENT(SPECIES_WEEZING) { Speed(7); Ability(ABILITY_NEUTRALIZING_GAS); }
} WHEN {
TURN { MOVE(opponent, MOVE_KNOCK_OFF); }
TURN { MOVE(opponent, MOVE_U_TURN); SEND_OUT(opponent, 1); }
TURN { MOVE(opponent, MOVE_U_TURN); SEND_OUT(opponent, 0); }
TURN { }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_KNOCK_OFF, opponent);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ITEM_KNOCKOFF, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
// Turn 2, doubled speed
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_U_TURN, opponent);
ABILITY_POPUP(opponent, ABILITY_NEUTRALIZING_GAS);
// Turn 3, no speed increase
ANIMATION(ANIM_TYPE_MOVE, MOVE_U_TURN, opponent);
MESSAGE("The effects of the neutralizing gas wore off!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
// Turn 4, doubled speed
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent);
}
}

View File

@ -1,6 +1,32 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Aqua Ring recovers 1/16th HP at end of turn");
TO_DO_BATTLE_TEST("Aqua Ring can be used under Heal Block but will not heal the user");
SINGLE_BATTLE_TEST("Aqua Ring recovers 1/16th HP at end of turn")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { HP(50); MaxHP(128); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_AQUA_RING); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_AQUA_RING, player);
} THEN {
EXPECT(player->hp == 58);
}
}
SINGLE_BATTLE_TEST("Aqua Ring can be used under Heal Block but will not heal the user")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { HP(50); MaxHP(128); Speed(50); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }
} WHEN {
TURN { MOVE(opponent, MOVE_HEAL_BLOCK); MOVE(player, MOVE_AQUA_RING); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_AQUA_RING, player);
} THEN {
EXPECT(player->hp == 50);
}
}
TO_DO_BATTLE_TEST("Baton Pass passes Aqua Ring's effect");

View File

@ -1,7 +1,105 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Attract causes the target to become infatuated with the user if they have opposite genders");
TO_DO_BATTLE_TEST("Attract ignores type immunity");
TO_DO_BATTLE_TEST("Attract bypasses Substitute");
TO_DO_BATTLE_TEST("Attract fails if the target is already infatuated");
ASSUMPTIONS
{
ASSUME(GetMoveEffect(MOVE_ATTRACT) == EFFECT_ATTRACT);
ASSUME(gSpeciesInfo[SPECIES_NIDOKING].genderRatio == MON_MALE);
ASSUME(gSpeciesInfo[SPECIES_NIDOQUEEN].genderRatio == MON_FEMALE);
}
SINGLE_BATTLE_TEST("Attract causes the target to become infatuated with the user if they have opposite genders")
{
GIVEN {
PLAYER(SPECIES_NIDOQUEEN);
OPPONENT(SPECIES_NIDOKING);
} WHEN {
TURN { MOVE(player, MOVE_ATTRACT); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_ATTRACT, player);
MESSAGE("The opposing Nidoking fell in love!");
} THEN {
EXPECT(opponent->status2 & STATUS2_INFATUATION);
}
}
SINGLE_BATTLE_TEST("Attract ignores type immunity")
{
GIVEN {
ASSUME(GetMoveType(MOVE_ATTRACT) == TYPE_NORMAL);
PLAYER(SPECIES_NIDOQUEEN);
OPPONENT(SPECIES_MISDREAVUS) { Gender(MON_MALE); }
} WHEN {
TURN { MOVE(player, MOVE_ATTRACT); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_ATTRACT, player);
MESSAGE("The opposing Misdreavus fell in love!");
} THEN {
EXPECT(opponent->status2 & STATUS2_INFATUATION);
}
}
SINGLE_BATTLE_TEST("Attract bypasses Substitute")
{
GIVEN {
PLAYER(SPECIES_NIDOQUEEN) { Speed(90); }
OPPONENT(SPECIES_NIDOKING) { Speed(100); }
} WHEN {
TURN { MOVE(opponent, MOVE_SUBSTITUTE); }
TURN { MOVE(player, MOVE_ATTRACT); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_ATTRACT, player);
MESSAGE("The opposing Nidoking fell in love!");
} THEN {
EXPECT(opponent->status2 & STATUS2_INFATUATION);
}
}
SINGLE_BATTLE_TEST("Attract fails if the target is already infatuated")
{
GIVEN {
PLAYER(SPECIES_NIDOQUEEN);
OPPONENT(SPECIES_NIDOKING);
} WHEN {
TURN { MOVE(player, MOVE_ATTRACT); }
TURN { MOVE(player, MOVE_ATTRACT); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_ATTRACT, player);
MESSAGE("The opposing Nidoking fell in love!");
MESSAGE("Nidoqueen used Attract!");
MESSAGE("But it failed!");
} THEN {
EXPECT(opponent->status2 & STATUS2_INFATUATION);
}
}
SINGLE_BATTLE_TEST("Attract fails when used on a Pokémon of the same gender")
{
GIVEN {
PLAYER(SPECIES_NIDOQUEEN);
OPPONENT(SPECIES_NIDOQUEEN);
} WHEN {
TURN { MOVE(player, MOVE_ATTRACT); }
} SCENE {
MESSAGE("Nidoqueen used Attract!");
MESSAGE("But it failed!");
} THEN {
EXPECT(!(opponent->status2 & STATUS2_INFATUATION));
}
}
SINGLE_BATTLE_TEST("Attract fails when used on a genderless Pokémon")
{
GIVEN {
ASSUME(gSpeciesInfo[SPECIES_STARMIE].genderRatio == MON_GENDERLESS);
PLAYER(SPECIES_NIDOQUEEN);
OPPONENT(SPECIES_STARMIE);
} WHEN {
TURN { MOVE(player, MOVE_ATTRACT); }
} SCENE {
MESSAGE("Nidoqueen used Attract!");
MESSAGE("But it failed!");
} THEN {
EXPECT(!(opponent->status2 & STATUS2_INFATUATION));
}
}

View File

@ -1,10 +1,130 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Bestow transfers its held item to the target");
TO_DO_BATTLE_TEST("Bestow fails if the user has no held item");
TO_DO_BATTLE_TEST("Bestow fails if the target already has a held item");
TO_DO_BATTLE_TEST("Bestow fails if the target is behind a Substitute");
TO_DO_BATTLE_TEST("Bestow fails if the user is holding Mail");
TO_DO_BATTLE_TEST("Bestow fails if the user's held item changes its form");
TO_DO_BATTLE_TEST("Bestow fails if the user's held item is a Z-Crystal");
SINGLE_BATTLE_TEST("Bestow transfers its held item to the target")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_BESTOW); }
} THEN {
EXPECT(player->item == ITEM_NONE);
EXPECT(opponent->item == ITEM_SITRUS_BERRY);
}
}
SINGLE_BATTLE_TEST("Bestow fails if the user has no held item")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_BESTOW); }
} SCENE {
MESSAGE("But it failed!");
} THEN {
EXPECT(player->item == ITEM_NONE);
EXPECT(opponent->item == ITEM_NONE);
}
}
SINGLE_BATTLE_TEST("Bestow fails if the target already has a held item")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_LUM_BERRY); }
} WHEN {
TURN { MOVE(player, MOVE_BESTOW); }
} SCENE {
MESSAGE("But it failed!");
} THEN {
EXPECT(player->item == ITEM_SITRUS_BERRY);
EXPECT(opponent->item == ITEM_LUM_BERRY);
}
}
#include "mail.h"
SINGLE_BATTLE_TEST("Bestow fails if the user is holding Mail")
{
KNOWN_FAILING;
GIVEN {
ASSUME(ItemIsMail(ITEM_ORANGE_MAIL));
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_ORANGE_MAIL); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_BESTOW); }
} SCENE {
MESSAGE("But it failed!");
} THEN {
EXPECT(player->item == ITEM_ORANGE_MAIL);
EXPECT(opponent->item == ITEM_NONE);
}
}
SINGLE_BATTLE_TEST("Bestow fails if the user's held item is a Mega Stone")
{
GIVEN {
PLAYER(SPECIES_BLAZIKEN) { Item(ITEM_BLAZIKENITE); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_BESTOW); }
} SCENE {
MESSAGE("But it failed!");
} THEN {
EXPECT(player->item == ITEM_BLAZIKENITE);
EXPECT(opponent->item == ITEM_NONE);
}
}
SINGLE_BATTLE_TEST("Bestow fails if the user's held item is a Z-Crystal")
{
GIVEN {
ASSUME(ItemId_GetHoldEffect(ITEM_FIGHTINIUM_Z) == HOLD_EFFECT_Z_CRYSTAL);
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_FIGHTINIUM_Z); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_BESTOW); }
} SCENE {
MESSAGE("But it failed!");
} THEN {
EXPECT(player->item == ITEM_FIGHTINIUM_Z);
EXPECT(opponent->item == ITEM_NONE);
}
}
SINGLE_BATTLE_TEST("Bestow fails if the target is behind a Substitute")
{
KNOWN_FAILING;
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); Speed(50); }
OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }
} WHEN {
TURN { MOVE(opponent, MOVE_SUBSTITUTE); MOVE(player, MOVE_BESTOW); }
} SCENE {
MESSAGE("But it failed!");
} THEN {
EXPECT(player->item == ITEM_SITRUS_BERRY);
EXPECT(opponent->item == ITEM_NONE);
}
}
SINGLE_BATTLE_TEST("Bestow fails if the user's held item changes its form")
{
KNOWN_FAILING;
GIVEN {
PLAYER(SPECIES_GIRATINA_ORIGIN) { Item(ITEM_GRISEOUS_ORB); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_BESTOW); }
} SCENE {
MESSAGE("But it failed!");
} THEN {
EXPECT(player->item == ITEM_GRISEOUS_ORB);
EXPECT(opponent->item == ITEM_NONE);
}
}

View File

@ -1,7 +1,112 @@
#include "global.h"
#include "test/battle.h"
TO_DO_BATTLE_TEST("Captivate decreases the target's Sp. Attack if they're opposite gender from the user");
TO_DO_BATTLE_TEST("Captivate fails if the target and user share gender");
TO_DO_BATTLE_TEST("Captivate fails if the target is genderless");
TO_DO_BATTLE_TEST("Captivate fails if the user is genderless");
ASSUMPTIONS
{
ASSUME(GetMoveEffect(MOVE_CAPTIVATE) == EFFECT_CAPTIVATE);
ASSUME(gSpeciesInfo[SPECIES_NIDOKING].genderRatio == MON_MALE);
ASSUME(gSpeciesInfo[SPECIES_NIDOQUEEN].genderRatio == MON_FEMALE);
ASSUME(gSpeciesInfo[SPECIES_STARMIE].genderRatio == MON_GENDERLESS);
}
SINGLE_BATTLE_TEST("Captivate decreases the target's Sp. Attack if they're opposite gender from the user")
{
GIVEN {
PLAYER(SPECIES_NIDOQUEEN);
OPPONENT(SPECIES_NIDOKING);
} WHEN {
TURN { MOVE(player, MOVE_CAPTIVATE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_CAPTIVATE, player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
MESSAGE("The opposing Nidoking's Sp. Atk harshly fell!");
} THEN {
EXPECT(opponent->statStages[STAT_SPATK] == 4);
}
}
SINGLE_BATTLE_TEST("Captivate fails if the target and user share gender")
{
GIVEN {
PLAYER(SPECIES_NIDOKING);
OPPONENT(SPECIES_NIDOKING);
} WHEN {
TURN { MOVE(player, MOVE_CAPTIVATE); }
} SCENE {
MESSAGE("But it failed!");
} THEN {
EXPECT(opponent->statStages[STAT_SPATK] == 6);
}
}
SINGLE_BATTLE_TEST("Captivate fails if the target is genderless")
{
GIVEN {
PLAYER(SPECIES_NIDOQUEEN);
OPPONENT(SPECIES_STARMIE);
} WHEN {
TURN { MOVE(player, MOVE_CAPTIVATE); }
} SCENE {
MESSAGE("But it failed!");
} THEN {
EXPECT(opponent->statStages[STAT_SPATK] == 6);
}
}
SINGLE_BATTLE_TEST("Captivate fails if the user is genderless")
{
GIVEN {
PLAYER(SPECIES_STARMIE);
OPPONENT(SPECIES_NIDOQUEEN);
} WHEN {
TURN { MOVE(player, MOVE_CAPTIVATE); }
} SCENE {
MESSAGE("But it failed!");
} THEN {
EXPECT(opponent->statStages[STAT_SPATK] == 6);
}
}
SINGLE_BATTLE_TEST("Captivate fails if both the user and the opponent are genderless")
{
GIVEN {
PLAYER(SPECIES_STARMIE);
OPPONENT(SPECIES_STARMIE);
} WHEN {
TURN { MOVE(player, MOVE_CAPTIVATE); }
} SCENE {
MESSAGE("But it failed!");
} THEN {
EXPECT(opponent->statStages[STAT_SPATK] == 6);
}
}
SINGLE_BATTLE_TEST("Attract fails when used by a genderless Pokémon")
{
GIVEN {
PLAYER(SPECIES_STARMIE);
OPPONENT(SPECIES_NIDOQUEEN);
} WHEN {
TURN { MOVE(player, MOVE_ATTRACT); }
} SCENE {
MESSAGE("Starmie used Attract!");
MESSAGE("But it failed!");
} THEN {
EXPECT(!(opponent->status2 & STATUS2_INFATUATION));
}
}
SINGLE_BATTLE_TEST("Attract fails if both the user and the target are genderless")
{
GIVEN {
PLAYER(SPECIES_STARMIE);
OPPONENT(SPECIES_STARMIE);
} WHEN {
TURN { MOVE(player, MOVE_ATTRACT); }
} SCENE {
MESSAGE("Starmie used Attract!");
MESSAGE("But it failed!");
} THEN {
EXPECT(!(opponent->status2 & STATUS2_INFATUATION));
}
}

View File

@ -14,6 +14,48 @@ AI_DOUBLE_BATTLE_TEST("AI prefers Entrainment'ing good abilities onto partner wi
}
}
TO_DO_BATTLE_TEST("Entrainment changes the target's Ability to match the user's");
TO_DO_BATTLE_TEST("Entrainment fails if the user's ability has cantBeCopied flag");
TO_DO_BATTLE_TEST("Entrainment fails if the targets's ability has cantBeOverwritten flag");
SINGLE_BATTLE_TEST("Entrainment changes the target's Ability to match the user's")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); }
OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_SHADOW_TAG); }
} WHEN {
TURN { MOVE(player, MOVE_ENTRAINMENT); }
} THEN {
EXPECT(opponent->ability == ABILITY_TELEPATHY);
}
}
SINGLE_BATTLE_TEST("Entrainment fails if the user's ability has cantBeCopied flag")
{
GIVEN {
ASSUME(gAbilitiesInfo[ABILITY_MULTITYPE].cantBeCopied);
PLAYER(SPECIES_ARCEUS) { Ability(ABILITY_MULTITYPE); }
OPPONENT(SPECIES_WOBBUFFET) { Ability(ABILITY_SHADOW_TAG); }
} WHEN {
TURN { MOVE(player, MOVE_ENTRAINMENT); }
} SCENE {
MESSAGE("But it failed!");
} THEN {
EXPECT(player->ability == ABILITY_MULTITYPE);
EXPECT(opponent->ability == ABILITY_SHADOW_TAG);
}
}
SINGLE_BATTLE_TEST("Entrainment fails if the target's ability has cantBeOverwritten flag")
{
GIVEN {
ASSUME(gAbilitiesInfo[ABILITY_MULTITYPE].cantBeOverwritten);
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_TELEPATHY); }
OPPONENT(SPECIES_ARCEUS) { Ability(ABILITY_MULTITYPE); }
} WHEN {
TURN { MOVE(player, MOVE_ENTRAINMENT); }
} SCENE {
MESSAGE("But it failed!");
} THEN {
EXPECT(player->ability == ABILITY_TELEPATHY);
EXPECT(opponent->ability == ABILITY_MULTITYPE);
}
}
TO_DO_BATTLE_TEST("Entrainment fails on Dynamaxed Pokémon");