mirror of
https://github.com/rh-hideout/pokeemerald-expansion.git
synced 2026-04-26 02:14:22 -05:00
Master to upcoming, 2025-12-13 (#8517)
This commit is contained in:
commit
367140a611
|
|
@ -1549,7 +1549,7 @@ static u32 GetSwitchinHazardsDamage(u32 battler, struct BattlePokemon *battleMon
|
|||
if (IsHazardOnSide(side, HAZARDS_STEELSURGE) && heldItemEffect != HOLD_EFFECT_HEAVY_DUTY_BOOTS)
|
||||
hazardDamage += GetStealthHazardDamageByTypesAndHP(TYPE_SIDE_HAZARD_SHARP_STEEL, defType1, defType2, battleMon->maxHP);
|
||||
// Spikes
|
||||
if (IsHazardOnSide(side, HAZARDS_TOXIC_SPIKES) && IsSwitchinGrounded(heldItemEffect, ability, defType1, defType2))
|
||||
if (IsHazardOnSide(side, HAZARDS_SPIKES) && IsSwitchinGrounded(heldItemEffect, ability, defType1, defType2))
|
||||
{
|
||||
spikesDamage = maxHP / ((5 - gSideTimers[GetBattlerSide(battler)].spikesAmount) * 2);
|
||||
if (spikesDamage == 0)
|
||||
|
|
@ -1557,7 +1557,7 @@ static u32 GetSwitchinHazardsDamage(u32 battler, struct BattlePokemon *battleMon
|
|||
hazardDamage += spikesDamage;
|
||||
}
|
||||
|
||||
if (IsHazardOnSide(side, HAZARDS_SPIKES) && (defType1 != TYPE_POISON && defType2 != TYPE_POISON
|
||||
if (IsHazardOnSide(side, HAZARDS_TOXIC_SPIKES) && (defType1 != TYPE_POISON && defType2 != TYPE_POISON
|
||||
&& defType1 != TYPE_STEEL && defType2 != TYPE_STEEL
|
||||
&& ability != ABILITY_IMMUNITY && ability != ABILITY_POISON_HEAL && ability != ABILITY_COMATOSE
|
||||
&& status == 0
|
||||
|
|
|
|||
|
|
@ -1914,6 +1914,11 @@ static inline bool32 TryTeraShellDistortTypeMatchups(u32 battlerDef)
|
|||
// It doesn't have any impact on gameplay and is only a visual thing which can be adjusted later.
|
||||
static inline bool32 TryActivateWeaknessBerry(u32 battlerDef)
|
||||
{
|
||||
if (DoesDisguiseBlockMove(battlerDef, gCurrentMove))
|
||||
{
|
||||
gSpecialStatuses[battlerDef].berryReduced = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
if (gSpecialStatuses[battlerDef].berryReduced && gBattleMons[battlerDef].item != ITEM_NONE)
|
||||
{
|
||||
gBattleScripting.battler = battlerDef;
|
||||
|
|
@ -2179,6 +2184,7 @@ static void MoveDamageDataHpUpdate(u32 battler, u32 scriptBattler, const u8 *nex
|
|||
if (gBattleStruct->moveResultFlags[gBattlerTarget] & MOVE_RESULT_NO_EFFECT)
|
||||
{
|
||||
gBattlescriptCurrInstr = nextInstr;
|
||||
return;
|
||||
}
|
||||
else if (DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) && gDisableStructs[battler].substituteHP)
|
||||
{
|
||||
|
|
@ -2196,18 +2202,19 @@ static void MoveDamageDataHpUpdate(u32 battler, u32 scriptBattler, const u8 *nex
|
|||
{
|
||||
gBattlescriptCurrInstr = nextInstr;
|
||||
BattleScriptCall(BattleScript_SubstituteFade);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattlescriptCurrInstr = nextInstr;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (DoesDisguiseBlockMove(battler, gCurrentMove))
|
||||
{
|
||||
// TODO: Convert this to a proper FORM_CHANGE type.
|
||||
gBattleScripting.battler = battler;
|
||||
gBattleStruct->moveDamage[battler] = 0;
|
||||
gBattleStruct->moveResultFlags[battler] &= ~(MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_SUPER_EFFECTIVE);
|
||||
if (GetBattlerPartyState(battler)->changedSpecies == SPECIES_NONE)
|
||||
GetBattlerPartyState(battler)->changedSpecies = gBattleMons[battler].species;
|
||||
if (gBattleMons[battler].species == SPECIES_MIMIKYU_TOTEM_DISGUISED)
|
||||
|
|
@ -2246,28 +2253,6 @@ static void MoveDamageDataHpUpdate(u32 battler, u32 scriptBattler, const u8 *nex
|
|||
gBattleStruct->moveDamage[battler] = gBattleMons[battler].hp;
|
||||
gBattleMons[battler].hp = 0;
|
||||
}
|
||||
|
||||
// Note: While physicalDmg/specialDmg below are only distinguished between for Counter/Mirror Coat, they are
|
||||
// used in combination as general damage trackers for other purposes. specialDmg is additionally used
|
||||
// to help determine if a fire move should defrost the target.
|
||||
if (IsBattleMovePhysical(gCurrentMove))
|
||||
{
|
||||
gProtectStructs[battler].physicalDmg = gBattleStruct->moveDamage[battler];
|
||||
gSpecialStatuses[battler].physicalDmg = gBattleStruct->moveDamage[battler];
|
||||
if (scriptBattler == BS_TARGET) // What's the point of this??? It will be always target
|
||||
gProtectStructs[battler].physicalBattlerId = gBattlerAttacker;
|
||||
else
|
||||
gProtectStructs[battler].physicalBattlerId = gBattlerTarget;
|
||||
}
|
||||
else // Physical move
|
||||
{
|
||||
gProtectStructs[battler].specialDmg = gBattleStruct->moveDamage[battler];
|
||||
gSpecialStatuses[battler].specialDmg = gBattleStruct->moveDamage[battler];
|
||||
if (scriptBattler == BS_TARGET) // What's the point of this??? It will be always target
|
||||
gProtectStructs[battler].specialBattlerId = gBattlerAttacker;
|
||||
else
|
||||
gProtectStructs[battler].specialBattlerId = gBattlerTarget;
|
||||
}
|
||||
gProtectStructs[battler].assuranceDoubled = TRUE;
|
||||
gProtectStructs[battler].revengeDoubled |= 1u << gBattlerAttacker;
|
||||
|
||||
|
|
@ -2278,6 +2263,21 @@ static void MoveDamageDataHpUpdate(u32 battler, u32 scriptBattler, const u8 *nex
|
|||
gBattlescriptCurrInstr = nextInstr;
|
||||
}
|
||||
|
||||
// Note: While physicalDmg/specialDmg below are only distinguished between for Counter/Mirror Coat,
|
||||
// they are used in combination as general damage trackers for other purposes.
|
||||
if (IsBattleMovePhysical(gCurrentMove))
|
||||
{
|
||||
gProtectStructs[battler].physicalDmg = gBattleStruct->moveDamage[battler] + 1;
|
||||
gSpecialStatuses[battler].physicalDmg = gBattleStruct->moveDamage[battler] + 1;
|
||||
gProtectStructs[battler].physicalBattlerId = gBattlerAttacker;
|
||||
}
|
||||
else // Special move
|
||||
{
|
||||
gProtectStructs[battler].specialDmg = gBattleStruct->moveDamage[battler] + 1;
|
||||
gSpecialStatuses[battler].specialDmg = gBattleStruct->moveDamage[battler] + 1;
|
||||
gProtectStructs[battler].specialBattlerId = gBattlerAttacker;
|
||||
}
|
||||
|
||||
if (IsBattlerTurnDamaged(gBattlerTarget) && GetMoveCategory(gCurrentMove) != DAMAGE_CATEGORY_STATUS)
|
||||
GetBattlerPartyState(battler)->timesGotHit++;
|
||||
}
|
||||
|
|
@ -5749,7 +5749,7 @@ static bool32 HandleMoveEndMoveBlock(u32 moveEffect)
|
|||
}
|
||||
break;
|
||||
case EFFECT_RECOIL:
|
||||
if (IsBattlerTurnDamaged(gBattlerTarget) && IsBattlerAlive(gBattlerAttacker))
|
||||
if (IsBattlerTurnDamaged(gBattlerTarget) && IsBattlerAlive(gBattlerAttacker) && gBattleStruct->moveDamage[gBattlerTarget] > 0)
|
||||
{
|
||||
enum Ability ability = GetBattlerAbility(gBattlerAttacker);
|
||||
if (IsAbilityAndRecord(gBattlerAttacker, ability, ABILITY_ROCK_HEAD)
|
||||
|
|
@ -10900,6 +10900,13 @@ static void Cmd_unused_0xA0(void)
|
|||
{
|
||||
}
|
||||
|
||||
static void CalcReflectBackDamage(u32 baseDamage, u32 percentMult)
|
||||
{
|
||||
s32 damage = (baseDamage - 1) * percentMult / 100;
|
||||
damage = max(damage, 1);
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = damage;
|
||||
}
|
||||
|
||||
static void Cmd_counterdamagecalculator(void)
|
||||
{
|
||||
CMD_ARGS(const u8 *failInstr);
|
||||
|
|
@ -10916,7 +10923,7 @@ static void Cmd_counterdamagecalculator(void)
|
|||
else
|
||||
gBattlerTarget = gProtectStructs[gBattlerAttacker].physicalBattlerId;
|
||||
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = gProtectStructs[gBattlerAttacker].physicalDmg * 2;
|
||||
CalcReflectBackDamage(gProtectStructs[gBattlerAttacker].physicalDmg, 200);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
else
|
||||
|
|
@ -10943,7 +10950,7 @@ static void Cmd_mirrorcoatdamagecalculator(void)
|
|||
else
|
||||
gBattlerTarget = gProtectStructs[gBattlerAttacker].specialBattlerId;
|
||||
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = gProtectStructs[gBattlerAttacker].specialDmg * 2;
|
||||
CalcReflectBackDamage(gProtectStructs[gBattlerAttacker].specialDmg, 200);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
else
|
||||
|
|
@ -14032,7 +14039,7 @@ void BS_CalcMetalBurstDmg(void)
|
|||
else
|
||||
gBattlerTarget = gProtectStructs[gBattlerAttacker].physicalBattlerId;
|
||||
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = gProtectStructs[gBattlerAttacker].physicalDmg * 150 / 100;
|
||||
CalcReflectBackDamage(gProtectStructs[gBattlerAttacker].physicalDmg, 150);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
else if (gProtectStructs[gBattlerAttacker].specialDmg
|
||||
|
|
@ -14045,7 +14052,7 @@ void BS_CalcMetalBurstDmg(void)
|
|||
else
|
||||
gBattlerTarget = gProtectStructs[gBattlerAttacker].specialBattlerId;
|
||||
|
||||
gBattleStruct->moveDamage[gBattlerTarget] = gProtectStructs[gBattlerAttacker].specialDmg * 150 / 100;
|
||||
CalcReflectBackDamage(gProtectStructs[gBattlerAttacker].specialDmg, 150);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -124,3 +124,22 @@ SINGLE_BATTLE_TEST("Weakness berries do not decrease the power of Struggle", s16
|
|||
EXPECT_EQ(results[0].damage, results[1].damage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Weakness berries do not activate if Disguise blocks the damage")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetItemHoldEffect(ITEM_BABIRI_BERRY) == HOLD_EFFECT_RESIST_BERRY);
|
||||
ASSUME(GetItemHoldEffectParam(ITEM_BABIRI_BERRY) == TYPE_STEEL);
|
||||
ASSUME(GetMoveType(MOVE_METAL_CLAW) == TYPE_STEEL);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_MIMIKYU) { Item(ITEM_BABIRI_BERRY); Ability(ABILITY_DISGUISE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_METAL_CLAW); }
|
||||
} SCENE {
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
|
||||
MESSAGE("The Babiri Berry weakened the damage to the opposing Mimikyu!");
|
||||
}
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_METAL_CLAW, player);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,25 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(GetItemHoldEffect(ITEM_ROCKY_HELMET) == HOLD_EFFECT_ROCKY_HELMET);
|
||||
ASSUME(MoveMakesContact(MOVE_SCRATCH));
|
||||
ASSUME(MoveMakesContact(MOVE_SHADOW_SNEAK));
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Rocky Helmet damages attacker even if damage is blocked by Disguise")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_MIMIKYU) { Item(ITEM_ROCKY_HELMET); Ability(ABILITY_DISGUISE); };
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_SHADOW_SNEAK); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SHADOW_SNEAK, opponent);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player);
|
||||
HP_BAR(opponent);
|
||||
}
|
||||
}
|
||||
|
||||
TO_DO_BATTLE_TEST("TODO: Write Rocky Helmet (Hold Effect) test titles")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,31 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(GetItemHoldEffect(ITEM_WEAKNESS_POLICY) == HOLD_EFFECT_WEAKNESS_POLICY);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Weakness Policy does not activate if Disguise blocks the damage")
|
||||
{
|
||||
u32 species;
|
||||
|
||||
PARAMETRIZE { species = SPECIES_MIMIKYU_BUSTED; }
|
||||
PARAMETRIZE { species = SPECIES_MIMIKYU_DISGUISED; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(GetMoveType(MOVE_METAL_CLAW) == TYPE_STEEL);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(species) { Item(ITEM_WEAKNESS_POLICY); Ability(ABILITY_DISGUISE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_METAL_CLAW); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_METAL_CLAW, player);
|
||||
if (species == SPECIES_MIMIKYU_BUSTED)
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
|
||||
else
|
||||
NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent);
|
||||
}
|
||||
}
|
||||
|
||||
TO_DO_BATTLE_TEST("TODO: Write Weakness Policy (Hold Effect) test titles")
|
||||
|
|
|
|||
|
|
@ -118,3 +118,17 @@ SINGLE_BATTLE_TEST("Absorb does not drain any HP if user does 0 damage")
|
|||
NOT MESSAGE("The opposing Wobbuffet had its energy drained!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Absorb does not drain any HP if the move is blocked by Disguise")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
|
||||
OPPONENT(SPECIES_MIMIKYU) { Ability(ABILITY_DISGUISE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_ABSORB); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ABSORB, player);
|
||||
} THEN {
|
||||
EXPECT_EQ(player->hp, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ DOUBLE_BATTLE_TEST("Counter respects Follow me")
|
|||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Counter fails if mon that damaged counter user is no longer on the field")
|
||||
DOUBLE_BATTLE_TEST("Counter fails if mon that damaged Counter user is no longer on the field (Gen 1-4)")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
|
|
@ -149,6 +149,24 @@ DOUBLE_BATTLE_TEST("Counter fails if mon that damaged counter user is no longer
|
|||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Counter deals 1 damage when the attack received is blocked by Disguise")
|
||||
{
|
||||
s16 counterDmg;
|
||||
GIVEN {
|
||||
ASSUME(GetMoveCategory(MOVE_SHADOW_SNEAK) == DAMAGE_CATEGORY_PHYSICAL);
|
||||
PLAYER(SPECIES_MIMIKYU) { Ability(ABILITY_DISGUISE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_SHADOW_SNEAK); MOVE(player, MOVE_COUNTER); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SHADOW_SNEAK, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_COUNTER, player);
|
||||
HP_BAR(opponent, captureDamage: &counterDmg);
|
||||
} THEN {
|
||||
EXPECT_EQ(counterDmg, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Gen 1
|
||||
TO_DO_BATTLE_TEST("Counter can only counter Normal and Fighting-type moves (Gen 1)");
|
||||
TO_DO_BATTLE_TEST("Counter can hit ghost-type Pokémon (Gen 1)");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,131 @@
|
|||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
TO_DO_BATTLE_TEST("TODO: Write Mirror Coat (Move Effect) test titles")
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(GetMoveEffect(MOVE_MIRROR_COAT) == EFFECT_MIRROR_COAT);
|
||||
ASSUME(GetMoveCategory(MOVE_ROUND) == DAMAGE_CATEGORY_SPECIAL);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mirror Coat will do twice as much damage received from the opponent")
|
||||
{
|
||||
s16 normalDmg;
|
||||
s16 mirrorCoatDmg;
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_ROUND); MOVE(player, MOVE_MIRROR_COAT); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, opponent);
|
||||
HP_BAR(player, captureDamage: &normalDmg);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_MIRROR_COAT, player);
|
||||
HP_BAR(opponent, captureDamage: &mirrorCoatDmg);
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(normalDmg, Q_4_12(2.0), mirrorCoatDmg);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Mirror Coat cannot affect ally Pokémon")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(playerLeft, MOVE_ROUND, target: playerRight);
|
||||
MOVE(playerRight, MOVE_MIRROR_COAT, target: playerLeft);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, playerLeft);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_MIRROR_COAT, playerRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Mirror Coat hits the last opponent that hit the user")
|
||||
{
|
||||
s16 normalDmg;
|
||||
s16 mirrorCoatDmg;
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(opponentLeft, MOVE_ROUND, target: playerLeft);
|
||||
MOVE(opponentRight, MOVE_ROUND, target: playerLeft);
|
||||
MOVE(playerLeft, MOVE_MIRROR_COAT);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, opponentRight);
|
||||
HP_BAR(playerLeft, captureDamage: &normalDmg);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_MIRROR_COAT, playerLeft);
|
||||
HP_BAR(opponentRight, captureDamage: &mirrorCoatDmg);
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(normalDmg, Q_4_12(2.0), mirrorCoatDmg);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Mirror Coat respects Follow Me")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(opponentRight, MOVE_FOLLOW_ME);
|
||||
MOVE(opponentLeft, MOVE_ROUND, target: playerLeft);
|
||||
MOVE(playerLeft, MOVE_MIRROR_COAT, target: opponentLeft);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FOLLOW_ME, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_MIRROR_COAT, playerLeft);
|
||||
HP_BAR(opponentRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Mirror Coat fails if mon that damaged Mirror Coat user is no longer on the field (Gen 1-4)")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WYNAUT);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { HP(1); };
|
||||
OPPONENT(SPECIES_WYNAUT);
|
||||
} WHEN {
|
||||
TURN {
|
||||
MOVE(opponentLeft, MOVE_ROUND, target: playerLeft);
|
||||
MOVE(playerRight, MOVE_ROUND, target: opponentLeft);
|
||||
MOVE(playerLeft, MOVE_MIRROR_COAT, target: opponentLeft);
|
||||
}
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, playerRight);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_MIRROR_COAT, playerLeft);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Mirror Coat deals 1 damage when the attack received is blocked by Disguise")
|
||||
{
|
||||
s16 mirrorCoatDmg;
|
||||
GIVEN {
|
||||
ASSUME(GetMoveCategory(MOVE_HEX) == DAMAGE_CATEGORY_SPECIAL);
|
||||
PLAYER(SPECIES_MIMIKYU) { Ability(ABILITY_DISGUISE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_HEX); MOVE(player, MOVE_MIRROR_COAT); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_HEX, opponent);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_MIRROR_COAT, player);
|
||||
HP_BAR(opponent, captureDamage: &mirrorCoatDmg);
|
||||
} THEN {
|
||||
EXPECT_EQ(mirrorCoatDmg, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,3 +122,18 @@ SINGLE_BATTLE_TEST("Recoil: The correct amount of recoil damage is dealt after t
|
|||
EXPECT_MUL_EQ(directDamage, UQ_4_12(0.25), recoilDamage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Recoil: No recoil is taken if the move is blocked by Disguise")
|
||||
{
|
||||
GIVEN {
|
||||
ASSUME(GetMoveRecoil(MOVE_FLARE_BLITZ) > 0);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_MIMIKYU) { Ability(ABILITY_DISGUISE); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_FLARE_BLITZ); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FLARE_BLITZ, player);
|
||||
} THEN {
|
||||
EXPECT_EQ(player->hp, player->maxHP);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user